1*e4b17023SJohn Marino# Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011 2*e4b17023SJohn Marino# Free Software Foundation, Inc. 3*e4b17023SJohn Marino# Contributed by Kelley Cook, June 2004. 4*e4b17023SJohn Marino# Original code from Neil Booth, May 2003. 5*e4b17023SJohn Marino# 6*e4b17023SJohn Marino# This program is free software; you can redistribute it and/or modify it 7*e4b17023SJohn Marino# under the terms of the GNU General Public License as published by the 8*e4b17023SJohn Marino# Free Software Foundation; either version 3, or (at your option) any 9*e4b17023SJohn Marino# later version. 10*e4b17023SJohn Marino# 11*e4b17023SJohn Marino# This program is distributed in the hope that it will be useful, 12*e4b17023SJohn Marino# but WITHOUT ANY WARRANTY; without even the implied warranty of 13*e4b17023SJohn Marino# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*e4b17023SJohn Marino# GNU General Public License for more details. 15*e4b17023SJohn Marino# 16*e4b17023SJohn Marino# You should have received a copy of the GNU General Public License 17*e4b17023SJohn Marino# along with this program; see the file COPYING3. If not see 18*e4b17023SJohn Marino# <http://www.gnu.org/licenses/>. 19*e4b17023SJohn Marino 20*e4b17023SJohn Marino# Some common subroutines for use by opt[ch]-gen.awk. 21*e4b17023SJohn Marino 22*e4b17023SJohn Marino# Define some helpful character classes, for portability. 23*e4b17023SJohn MarinoBEGIN { 24*e4b17023SJohn Marino lower = "abcdefghijklmnopqrstuvwxyz" 25*e4b17023SJohn Marino upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 26*e4b17023SJohn Marino digit = "0123456789" 27*e4b17023SJohn Marino alnum = lower "" upper "" digit 28*e4b17023SJohn Marino} 29*e4b17023SJohn Marino 30*e4b17023SJohn Marino# Return nonzero if FLAGS contains a flag matching REGEX. 31*e4b17023SJohn Marinofunction flag_set_p(regex, flags) 32*e4b17023SJohn Marino{ 33*e4b17023SJohn Marino return (" " flags " ") ~ (" " regex " ") 34*e4b17023SJohn Marino} 35*e4b17023SJohn Marino 36*e4b17023SJohn Marino# Return STRING if FLAGS contains a flag matching regexp REGEX, 37*e4b17023SJohn Marino# otherwise return the empty string. 38*e4b17023SJohn Marinofunction test_flag(regex, flags, string) 39*e4b17023SJohn Marino{ 40*e4b17023SJohn Marino if (flag_set_p(regex, flags)) 41*e4b17023SJohn Marino return string 42*e4b17023SJohn Marino return "" 43*e4b17023SJohn Marino} 44*e4b17023SJohn Marino 45*e4b17023SJohn Marino# Return a field initializer, with trailing comma, for a field that is 46*e4b17023SJohn Marino# 1 if FLAGS contains a flag matching REGEX and 0 otherwise. 47*e4b17023SJohn Marinofunction flag_init(regex, flags) 48*e4b17023SJohn Marino{ 49*e4b17023SJohn Marino if (flag_set_p(regex, flags)) 50*e4b17023SJohn Marino return "1 /* " regex " */, " 51*e4b17023SJohn Marino else 52*e4b17023SJohn Marino return "0, " 53*e4b17023SJohn Marino} 54*e4b17023SJohn Marino 55*e4b17023SJohn Marino# If FLAGS contains a "NAME(...argument...)" flag, return the value 56*e4b17023SJohn Marino# of the argument. Return the empty string otherwise. 57*e4b17023SJohn Marinofunction opt_args(name, flags) 58*e4b17023SJohn Marino{ 59*e4b17023SJohn Marino flags = " " flags 60*e4b17023SJohn Marino if (flags !~ " " name "\\(") 61*e4b17023SJohn Marino return "" 62*e4b17023SJohn Marino sub(".* " name "\\(", "", flags) 63*e4b17023SJohn Marino if (flags ~ "^{") 64*e4b17023SJohn Marino { 65*e4b17023SJohn Marino sub ("^{", "", flags) 66*e4b17023SJohn Marino sub("}\\).*", "", flags) 67*e4b17023SJohn Marino } 68*e4b17023SJohn Marino else 69*e4b17023SJohn Marino sub("\\).*", "", flags) 70*e4b17023SJohn Marino 71*e4b17023SJohn Marino return flags 72*e4b17023SJohn Marino} 73*e4b17023SJohn Marino 74*e4b17023SJohn Marino# Return the Nth comma-separated element of S. Return the empty string 75*e4b17023SJohn Marino# if S does not contain N elements. 76*e4b17023SJohn Marinofunction nth_arg(n, s) 77*e4b17023SJohn Marino{ 78*e4b17023SJohn Marino while (n-- > 0) { 79*e4b17023SJohn Marino if (s !~ ",") 80*e4b17023SJohn Marino return "" 81*e4b17023SJohn Marino sub("[^,]*, *", "", s) 82*e4b17023SJohn Marino } 83*e4b17023SJohn Marino sub(",.*", "", s) 84*e4b17023SJohn Marino return s 85*e4b17023SJohn Marino} 86*e4b17023SJohn Marino 87*e4b17023SJohn Marino# Return a bitmask of CL_* values for option flags FLAGS. 88*e4b17023SJohn Marinofunction switch_flags (flags) 89*e4b17023SJohn Marino{ 90*e4b17023SJohn Marino result = "0" 91*e4b17023SJohn Marino for (j = 0; j < n_langs; j++) { 92*e4b17023SJohn Marino regex = langs[j] 93*e4b17023SJohn Marino gsub ( "\\+", "\\+", regex ) 94*e4b17023SJohn Marino result = result test_flag(regex, flags, " | " macros[j]) 95*e4b17023SJohn Marino } 96*e4b17023SJohn Marino result = result \ 97*e4b17023SJohn Marino test_flag("Common", flags, " | CL_COMMON") \ 98*e4b17023SJohn Marino test_flag("Target", flags, " | CL_TARGET") \ 99*e4b17023SJohn Marino test_flag("Driver", flags, " | CL_DRIVER") \ 100*e4b17023SJohn Marino test_flag("Joined", flags, " | CL_JOINED") \ 101*e4b17023SJohn Marino test_flag("JoinedOrMissing", flags, " | CL_JOINED") \ 102*e4b17023SJohn Marino test_flag("Separate", flags, " | CL_SEPARATE") \ 103*e4b17023SJohn Marino test_flag("Undocumented", flags, " | CL_UNDOCUMENTED") \ 104*e4b17023SJohn Marino test_flag("Warning", flags, " | CL_WARNING") \ 105*e4b17023SJohn Marino test_flag("Optimization", flags, " | CL_OPTIMIZATION") 106*e4b17023SJohn Marino sub( "^0 \\| ", "", result ) 107*e4b17023SJohn Marino return result 108*e4b17023SJohn Marino} 109*e4b17023SJohn Marino 110*e4b17023SJohn Marino# Return bit-field initializers for option flags FLAGS. 111*e4b17023SJohn Marinofunction switch_bit_fields (flags) 112*e4b17023SJohn Marino{ 113*e4b17023SJohn Marino vn = var_name(flags); 114*e4b17023SJohn Marino if (host_wide_int[vn] == "yes") 115*e4b17023SJohn Marino hwi = "Host_Wide_Int" 116*e4b17023SJohn Marino else 117*e4b17023SJohn Marino hwi = "" 118*e4b17023SJohn Marino result = "" 119*e4b17023SJohn Marino sep_args = opt_args("Args", flags) 120*e4b17023SJohn Marino if (sep_args == "") 121*e4b17023SJohn Marino sep_args = 0 122*e4b17023SJohn Marino else 123*e4b17023SJohn Marino sep_args-- 124*e4b17023SJohn Marino result = result sep_args ", " 125*e4b17023SJohn Marino 126*e4b17023SJohn Marino result = result \ 127*e4b17023SJohn Marino flag_init("SeparateAlias", flags) \ 128*e4b17023SJohn Marino flag_init("NegativeAlias", flags) \ 129*e4b17023SJohn Marino flag_init("NoDriverArg", flags) \ 130*e4b17023SJohn Marino flag_init("RejectDriver", flags) \ 131*e4b17023SJohn Marino flag_init("RejectNegative", flags) \ 132*e4b17023SJohn Marino flag_init("JoinedOrMissing", flags) \ 133*e4b17023SJohn Marino flag_init("UInteger", flags) \ 134*e4b17023SJohn Marino flag_init("Host_Wide_Int", hwi) \ 135*e4b17023SJohn Marino flag_init("ToLower", flags) \ 136*e4b17023SJohn Marino flag_init("Report", flags) 137*e4b17023SJohn Marino 138*e4b17023SJohn Marino sub(", $", "", result) 139*e4b17023SJohn Marino return result 140*e4b17023SJohn Marino} 141*e4b17023SJohn Marino 142*e4b17023SJohn Marino# If FLAGS includes a Var flag, return the name of the variable it specifies. 143*e4b17023SJohn Marino# Return the empty string otherwise. 144*e4b17023SJohn Marinofunction var_name(flags) 145*e4b17023SJohn Marino{ 146*e4b17023SJohn Marino return nth_arg(0, opt_args("Var", flags)) 147*e4b17023SJohn Marino} 148*e4b17023SJohn Marino 149*e4b17023SJohn Marino# Return the name of the variable if FLAGS has a HOST_WIDE_INT variable. 150*e4b17023SJohn Marino# Return the empty string otherwise. 151*e4b17023SJohn Marinofunction host_wide_int_var_name(flags) 152*e4b17023SJohn Marino{ 153*e4b17023SJohn Marino split (flags, array, "[ \t]+") 154*e4b17023SJohn Marino if (array[1] == "HOST_WIDE_INT") 155*e4b17023SJohn Marino return array[2] 156*e4b17023SJohn Marino else 157*e4b17023SJohn Marino return "" 158*e4b17023SJohn Marino} 159*e4b17023SJohn Marino 160*e4b17023SJohn Marino# Return true if the option described by FLAGS has a globally-visible state. 161*e4b17023SJohn Marinofunction global_state_p(flags) 162*e4b17023SJohn Marino{ 163*e4b17023SJohn Marino return (var_name(flags) != "" \ 164*e4b17023SJohn Marino || opt_args("Mask", flags) != "" \ 165*e4b17023SJohn Marino || opt_args("InverseMask", flags) != "") 166*e4b17023SJohn Marino} 167*e4b17023SJohn Marino 168*e4b17023SJohn Marino# Return true if the option described by FLAGS must have some state 169*e4b17023SJohn Marino# associated with it. 170*e4b17023SJohn Marinofunction needs_state_p(flags) 171*e4b17023SJohn Marino{ 172*e4b17023SJohn Marino return (flag_set_p("Target", flags) \ 173*e4b17023SJohn Marino && !flag_set_p("Alias.*", flags) \ 174*e4b17023SJohn Marino && !flag_set_p("Ignore", flags)) 175*e4b17023SJohn Marino} 176*e4b17023SJohn Marino 177*e4b17023SJohn Marino# If FLAGS describes an option that needs state without a public 178*e4b17023SJohn Marino# variable name, return the name of that field, minus the initial 179*e4b17023SJohn Marino# "x_", otherwise return "". NAME is the name of the option. 180*e4b17023SJohn Marinofunction static_var(name, flags) 181*e4b17023SJohn Marino{ 182*e4b17023SJohn Marino if (global_state_p(flags) || !needs_state_p(flags)) 183*e4b17023SJohn Marino return "" 184*e4b17023SJohn Marino gsub ("[^" alnum "]", "_", name) 185*e4b17023SJohn Marino return "VAR_" name 186*e4b17023SJohn Marino} 187*e4b17023SJohn Marino 188*e4b17023SJohn Marino# Return the type of variable that should be associated with the given flags. 189*e4b17023SJohn Marinofunction var_type(flags) 190*e4b17023SJohn Marino{ 191*e4b17023SJohn Marino if (flag_set_p("Defer", flags)) 192*e4b17023SJohn Marino return "void *" 193*e4b17023SJohn Marino else if (flag_set_p("Enum.*", flags)) { 194*e4b17023SJohn Marino en = opt_args("Enum", flags); 195*e4b17023SJohn Marino return enum_type[en] " " 196*e4b17023SJohn Marino } 197*e4b17023SJohn Marino else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) 198*e4b17023SJohn Marino return "int " 199*e4b17023SJohn Marino else if (flag_set_p("UInteger", flags)) 200*e4b17023SJohn Marino return "int " 201*e4b17023SJohn Marino else 202*e4b17023SJohn Marino return "const char *" 203*e4b17023SJohn Marino} 204*e4b17023SJohn Marino 205*e4b17023SJohn Marino# Return the type of variable that should be associated with the given flags 206*e4b17023SJohn Marino# for use within a structure. Simple variables are changed to signed char 207*e4b17023SJohn Marino# type instead of int to save space. 208*e4b17023SJohn Marinofunction var_type_struct(flags) 209*e4b17023SJohn Marino{ 210*e4b17023SJohn Marino if (flag_set_p("UInteger", flags)) 211*e4b17023SJohn Marino return "int " 212*e4b17023SJohn Marino else if (flag_set_p("Enum.*", flags)) { 213*e4b17023SJohn Marino en = opt_args("Enum", flags); 214*e4b17023SJohn Marino return enum_type[en] " " 215*e4b17023SJohn Marino } 216*e4b17023SJohn Marino else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) { 217*e4b17023SJohn Marino if (flag_set_p(".*Mask.*", flags)) { 218*e4b17023SJohn Marino if (host_wide_int[var_name(flags)] == "yes") 219*e4b17023SJohn Marino return "HOST_WIDE_INT " 220*e4b17023SJohn Marino else 221*e4b17023SJohn Marino return "int " 222*e4b17023SJohn Marino } 223*e4b17023SJohn Marino else 224*e4b17023SJohn Marino return "signed char " 225*e4b17023SJohn Marino } 226*e4b17023SJohn Marino else 227*e4b17023SJohn Marino return "const char *" 228*e4b17023SJohn Marino} 229*e4b17023SJohn Marino 230*e4b17023SJohn Marino# Given that an option has flags FLAGS, return an initializer for the 231*e4b17023SJohn Marino# "var_enum", "var_type" and "var_value" fields of its cl_options[] entry. 232*e4b17023SJohn Marinofunction var_set(flags) 233*e4b17023SJohn Marino{ 234*e4b17023SJohn Marino if (flag_set_p("Defer", flags)) 235*e4b17023SJohn Marino return "0, CLVC_DEFER, 0" 236*e4b17023SJohn Marino s = nth_arg(1, opt_args("Var", flags)) 237*e4b17023SJohn Marino if (s != "") 238*e4b17023SJohn Marino return "0, CLVC_EQUAL, " s 239*e4b17023SJohn Marino s = opt_args("Mask", flags); 240*e4b17023SJohn Marino if (s != "") { 241*e4b17023SJohn Marino vn = var_name(flags); 242*e4b17023SJohn Marino if (vn) 243*e4b17023SJohn Marino return "0, CLVC_BIT_SET, OPTION_MASK_" s 244*e4b17023SJohn Marino else 245*e4b17023SJohn Marino return "0, CLVC_BIT_SET, MASK_" s 246*e4b17023SJohn Marino } 247*e4b17023SJohn Marino s = nth_arg(0, opt_args("InverseMask", flags)); 248*e4b17023SJohn Marino if (s != "") { 249*e4b17023SJohn Marino vn = var_name(flags); 250*e4b17023SJohn Marino if (vn) 251*e4b17023SJohn Marino return "0, CLVC_BIT_CLEAR, OPTION_MASK_" s 252*e4b17023SJohn Marino else 253*e4b17023SJohn Marino return "0, CLVC_BIT_CLEAR, MASK_" s 254*e4b17023SJohn Marino } 255*e4b17023SJohn Marino if (flag_set_p("Enum.*", flags)) { 256*e4b17023SJohn Marino en = opt_args("Enum", flags); 257*e4b17023SJohn Marino return enum_index[en] ", CLVC_ENUM, 0" 258*e4b17023SJohn Marino } 259*e4b17023SJohn Marino if (var_type(flags) == "const char *") 260*e4b17023SJohn Marino return "0, CLVC_STRING, 0" 261*e4b17023SJohn Marino return "0, CLVC_BOOLEAN, 0" 262*e4b17023SJohn Marino} 263*e4b17023SJohn Marino 264*e4b17023SJohn Marino# Given that an option called NAME has flags FLAGS, return an initializer 265*e4b17023SJohn Marino# for the "flag_var" field of its cl_options[] entry. 266*e4b17023SJohn Marinofunction var_ref(name, flags) 267*e4b17023SJohn Marino{ 268*e4b17023SJohn Marino name = var_name(flags) static_var(name, flags) 269*e4b17023SJohn Marino if (name != "") 270*e4b17023SJohn Marino return "offsetof (struct gcc_options, x_" name ")" 271*e4b17023SJohn Marino if (opt_args("Mask", flags) != "") 272*e4b17023SJohn Marino return "offsetof (struct gcc_options, x_target_flags)" 273*e4b17023SJohn Marino if (opt_args("InverseMask", flags) != "") 274*e4b17023SJohn Marino return "offsetof (struct gcc_options, x_target_flags)" 275*e4b17023SJohn Marino return "-1" 276*e4b17023SJohn Marino} 277*e4b17023SJohn Marino 278*e4b17023SJohn Marino# Given the option called NAME return a sanitized version of its name. 279*e4b17023SJohn Marinofunction opt_sanitized_name(name) 280*e4b17023SJohn Marino{ 281*e4b17023SJohn Marino gsub ("[^" alnum "]", "_", name) 282*e4b17023SJohn Marino return name 283*e4b17023SJohn Marino} 284*e4b17023SJohn Marino 285*e4b17023SJohn Marino# Given the option called NAME return the appropriate enum for it. 286*e4b17023SJohn Marinofunction opt_enum(name) 287*e4b17023SJohn Marino{ 288*e4b17023SJohn Marino return "OPT_" opt_sanitized_name(name) 289*e4b17023SJohn Marino} 290