1169689Skan# Copyright (C) 2003,2004 Free Software Foundation, Inc. 2169689Skan# Contributed by Kelley Cook, June 2004. 3169689Skan# Original code from Neil Booth, May 2003. 4169689Skan# 5169689Skan# This program is free software; you can redistribute it and/or modify it 6169689Skan# under the terms of the GNU General Public License as published by the 7169689Skan# Free Software Foundation; either version 2, or (at your option) any 8169689Skan# later version. 9169689Skan# 10169689Skan# This program is distributed in the hope that it will be useful, 11169689Skan# but WITHOUT ANY WARRANTY; without even the implied warranty of 12169689Skan# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13169689Skan# GNU General Public License for more details. 14169689Skan# 15169689Skan# You should have received a copy of the GNU General Public License 16169689Skan# along with this program; if not, write to the Free Software 17169689Skan# Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18169689Skan 19169689Skan# Some common subroutines for use by opt[ch]-gen.awk. 20169689Skan 21169689Skan# Return nonzero if FLAGS contains a flag matching REGEX. 22169689Skanfunction flag_set_p(regex, flags) 23169689Skan{ 24169689Skan return (" " flags " ") ~ (" " regex " ") 25169689Skan} 26169689Skan 27169689Skan# Return STRING if FLAGS contains a flag matching regexp REGEX, 28169689Skan# otherwise return the empty string. 29169689Skanfunction test_flag(regex, flags, string) 30169689Skan{ 31169689Skan if (flag_set_p(regex, flags)) 32169689Skan return string 33169689Skan return "" 34169689Skan} 35169689Skan 36169689Skan# If FLAGS contains a "NAME(...argument...)" flag, return the value 37169689Skan# of the argument. Return the empty string otherwise. 38169689Skanfunction opt_args(name, flags) 39169689Skan{ 40169689Skan flags = " " flags 41169689Skan if (flags !~ " " name "\\(") 42169689Skan return "" 43169689Skan sub(".* " name "\\(", "", flags) 44169689Skan sub("\\).*", "", flags) 45169689Skan 46169689Skan return flags 47169689Skan} 48169689Skan 49169689Skan# Return the Nth comma-separated element of S. Return the empty string 50169689Skan# if S does not contain N elements. 51169689Skanfunction nth_arg(n, s) 52169689Skan{ 53169689Skan while (n-- > 0) { 54169689Skan if (s !~ ",") 55169689Skan return "" 56169689Skan sub("[^,]*, *", "", s) 57169689Skan } 58169689Skan sub(",.*", "", s) 59169689Skan return s 60169689Skan} 61169689Skan 62169689Skan# Return a bitmask of CL_* values for option flags FLAGS. 63169689Skanfunction switch_flags (flags) 64169689Skan{ 65169689Skan result = "0" 66169689Skan for (j = 0; j < n_langs; j++) { 67169689Skan regex = langs[j] 68169689Skan gsub ( "\\+", "\\+", regex ) 69169689Skan result = result test_flag(regex, flags, " | " macros[j]) 70169689Skan } 71169689Skan result = result \ 72169689Skan test_flag("Common", flags, " | CL_COMMON") \ 73169689Skan test_flag("Target", flags, " | CL_TARGET") \ 74169689Skan test_flag("Joined", flags, " | CL_JOINED") \ 75169689Skan test_flag("JoinedOrMissing", flags, " | CL_JOINED | CL_MISSING_OK") \ 76169689Skan test_flag("Separate", flags, " | CL_SEPARATE") \ 77169689Skan test_flag("RejectNegative", flags, " | CL_REJECT_NEGATIVE") \ 78169689Skan test_flag("UInteger", flags, " | CL_UINTEGER") \ 79169689Skan test_flag("Undocumented", flags, " | CL_UNDOCUMENTED") \ 80169689Skan test_flag("Report", flags, " | CL_REPORT") 81169689Skan sub( "^0 \\| ", "", result ) 82169689Skan return result 83169689Skan} 84169689Skan 85169689Skan# If FLAGS includes a Var flag, return the name of the variable it specifies. 86169689Skan# Return the empty string otherwise. 87169689Skanfunction var_name(flags) 88169689Skan{ 89169689Skan return nth_arg(0, opt_args("Var", flags)) 90169689Skan} 91169689Skan 92169689Skan# Return true if the option described by FLAGS has a globally-visible state. 93169689Skanfunction global_state_p(flags) 94169689Skan{ 95169689Skan return (var_name(flags) != "" \ 96169689Skan || opt_args("Mask", flags) != "" \ 97169689Skan || opt_args("InverseMask", flags) != "") 98169689Skan} 99169689Skan 100169689Skan# Return true if the option described by FLAGS must have some state 101169689Skan# associated with it. 102169689Skanfunction needs_state_p(flags) 103169689Skan{ 104169689Skan return flag_set_p("Target", flags) 105169689Skan} 106169689Skan 107169689Skan# If FLAGS describes an option that needs a static state variable, 108169689Skan# return the name of that variable, otherwise return "". NAME is 109169689Skan# the name of the option. 110169689Skanfunction static_var(name, flags) 111169689Skan{ 112169689Skan if (global_state_p(flags) || !needs_state_p(flags)) 113169689Skan return "" 114169689Skan gsub ("[^A-Za-z0-9]", "_", name) 115169689Skan return "VAR_" name 116169689Skan} 117169689Skan 118169689Skan# Return the type of variable that should be associated with the given flags. 119169689Skanfunction var_type(flags) 120169689Skan{ 121169689Skan if (!flag_set_p("Joined.*", flags)) 122169689Skan return "int " 123169689Skan else if (flag_set_p("UInteger", flags)) 124169689Skan return "int " 125169689Skan else 126169689Skan return "const char *" 127169689Skan} 128169689Skan 129169689Skan# Given that an option has flags FLAGS, return an initializer for the 130169689Skan# "var_cond" and "var_value" fields of its cl_options[] entry. 131169689Skanfunction var_set(flags) 132169689Skan{ 133169689Skan s = nth_arg(1, opt_args("Var", flags)) 134169689Skan if (s != "") 135169689Skan return "CLVC_EQUAL, " s 136169689Skan s = opt_args("Mask", flags); 137169689Skan if (s != "") { 138169689Skan vn = var_name(flags); 139169689Skan if (vn) 140169689Skan return "CLVC_BIT_SET, OPTION_MASK_" s 141169689Skan else 142169689Skan return "CLVC_BIT_SET, MASK_" s 143169689Skan } 144169689Skan s = nth_arg(0, opt_args("InverseMask", flags)); 145169689Skan if (s != "") { 146169689Skan vn = var_name(flags); 147169689Skan if (vn) 148169689Skan return "CLVC_BIT_CLEAR, OPTION_MASK_" s 149169689Skan else 150169689Skan return "CLVC_BIT_CLEAR, MASK_" s 151169689Skan } 152169689Skan if (var_type(flags) == "const char *") 153169689Skan return "CLVC_STRING, 0" 154169689Skan return "CLVC_BOOLEAN, 0" 155169689Skan} 156169689Skan 157169689Skan# Given that an option called NAME has flags FLAGS, return an initializer 158169689Skan# for the "flag_var" field of its cl_options[] entry. 159169689Skanfunction var_ref(name, flags) 160169689Skan{ 161169689Skan name = var_name(flags) static_var(name, flags) 162169689Skan if (name != "") 163169689Skan return "&" name 164169689Skan if (opt_args("Mask", flags) != "") 165169689Skan return "&target_flags" 166169689Skan if (opt_args("InverseMask", flags) != "") 167169689Skan return "&target_flags" 168169689Skan return "0" 169169689Skan} 170