1# Copyright (C) 2003,2004 Free Software Foundation, Inc. 2# Contributed by Kelley Cook, June 2004. 3# Original code from Neil Booth, May 2003. 4# 5# This program is free software; you can redistribute it and/or modify it 6# under the terms of the GNU General Public License as published by the 7# Free Software Foundation; either version 2, or (at your option) any 8# later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, write to the Free Software 17# Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 19# Some common subroutines for use by opt[ch]-gen.awk. 20 21# Return nonzero if FLAGS contains a flag matching REGEX. 22function flag_set_p(regex, flags) 23{ 24 return (" " flags " ") ~ (" " regex " ") 25} 26 27# Return STRING if FLAGS contains a flag matching regexp REGEX, 28# otherwise return the empty string. 29function test_flag(regex, flags, string) 30{ 31 if (flag_set_p(regex, flags)) 32 return string 33 return "" 34} 35 36# If FLAGS contains a "NAME(...argument...)" flag, return the value 37# of the argument. Return the empty string otherwise. 38function opt_args(name, flags) 39{ 40 flags = " " flags 41 if (flags !~ " " name "\\(") 42 return "" 43 sub(".* " name "\\(", "", flags) 44 sub("\\).*", "", flags) 45 46 return flags 47} 48 49# Return the Nth comma-separated element of S. Return the empty string 50# if S does not contain N elements. 51function nth_arg(n, s) 52{ 53 while (n-- > 0) { 54 if (s !~ ",") 55 return "" 56 sub("[^,]*, *", "", s) 57 } 58 sub(",.*", "", s) 59 return s 60} 61 62# Return a bitmask of CL_* values for option flags FLAGS. 63function switch_flags (flags) 64{ 65 result = "0" 66 for (j = 0; j < n_langs; j++) { 67 regex = langs[j] 68 gsub ( "\\+", "\\+", regex ) 69 result = result test_flag(regex, flags, " | " macros[j]) 70 } 71 result = result \ 72 test_flag("Common", flags, " | CL_COMMON") \ 73 test_flag("Target", flags, " | CL_TARGET") \ 74 test_flag("Joined", flags, " | CL_JOINED") \ 75 test_flag("JoinedOrMissing", flags, " | CL_JOINED | CL_MISSING_OK") \ 76 test_flag("Separate", flags, " | CL_SEPARATE") \ 77 test_flag("RejectNegative", flags, " | CL_REJECT_NEGATIVE") \ 78 test_flag("UInteger", flags, " | CL_UINTEGER") \ 79 test_flag("Undocumented", flags, " | CL_UNDOCUMENTED") \ 80 test_flag("Report", flags, " | CL_REPORT") 81 sub( "^0 \\| ", "", result ) 82 return result 83} 84 85# If FLAGS includes a Var flag, return the name of the variable it specifies. 86# Return the empty string otherwise. 87function var_name(flags) 88{ 89 return nth_arg(0, opt_args("Var", flags)) 90} 91 92# Return true if the option described by FLAGS has a globally-visible state. 93function global_state_p(flags) 94{ 95 return (var_name(flags) != "" \ 96 || opt_args("Mask", flags) != "" \ 97 || opt_args("InverseMask", flags) != "") 98} 99 100# Return true if the option described by FLAGS must have some state 101# associated with it. 102function needs_state_p(flags) 103{ 104 return flag_set_p("Target", flags) 105} 106 107# If FLAGS describes an option that needs a static state variable, 108# return the name of that variable, otherwise return "". NAME is 109# the name of the option. 110function static_var(name, flags) 111{ 112 if (global_state_p(flags) || !needs_state_p(flags)) 113 return "" 114 gsub ("[^A-Za-z0-9]", "_", name) 115 return "VAR_" name 116} 117 118# Return the type of variable that should be associated with the given flags. 119function var_type(flags) 120{ 121 if (!flag_set_p("Joined.*", flags)) 122 return "int " 123 else if (flag_set_p("UInteger", flags)) 124 return "int " 125 else 126 return "const char *" 127} 128 129# Given that an option has flags FLAGS, return an initializer for the 130# "var_cond" and "var_value" fields of its cl_options[] entry. 131function var_set(flags) 132{ 133 s = nth_arg(1, opt_args("Var", flags)) 134 if (s != "") 135 return "CLVC_EQUAL, " s 136 s = opt_args("Mask", flags); 137 if (s != "") { 138 vn = var_name(flags); 139 if (vn) 140 return "CLVC_BIT_SET, OPTION_MASK_" s 141 else 142 return "CLVC_BIT_SET, MASK_" s 143 } 144 s = nth_arg(0, opt_args("InverseMask", flags)); 145 if (s != "") { 146 vn = var_name(flags); 147 if (vn) 148 return "CLVC_BIT_CLEAR, OPTION_MASK_" s 149 else 150 return "CLVC_BIT_CLEAR, MASK_" s 151 } 152 if (var_type(flags) == "const char *") 153 return "CLVC_STRING, 0" 154 return "CLVC_BOOLEAN, 0" 155} 156 157# Given that an option called NAME has flags FLAGS, return an initializer 158# for the "flag_var" field of its cl_options[] entry. 159function var_ref(name, flags) 160{ 161 name = var_name(flags) static_var(name, flags) 162 if (name != "") 163 return "&" name 164 if (opt_args("Mask", flags) != "") 165 return "&target_flags" 166 if (opt_args("InverseMask", flags) != "") 167 return "&target_flags" 168 return "0" 169} 170