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