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# This Awk script reads in the option records generated from 20169689Skan# opt-gather.awk, combines the flags of duplicat options and generates a 21169689Skan# C file. 22169689Skan# 23169689Skan# This program uses functions from opt-functions.awk 24169689Skan# 25169689Skan# Usage: awk -f opt-functions.awk -f optc-gen.awk \ 26169689Skan# [-v header_name=header.h] < inputfile > options.c 27169689Skan 28169689SkanBEGIN { 29169689Skan n_opts = 0 30169689Skan n_langs = 0 31169689Skan quote = "\042" 32169689Skan comma = "," 33169689Skan FS=SUBSEP 34169689Skan # Default the name of header created from opth-gen.awk to options.h 35169689Skan if (header_name == "") header_name="options.h" 36169689Skan} 37169689Skan 38169689Skan# Collect the text and flags of each option into an array 39169689Skan { 40169689Skan if ($1 == "Language") { 41169689Skan langs[n_langs] = $2 42169689Skan n_langs++; 43169689Skan } 44169689Skan else { 45169689Skan name = opt_args("Mask", $1) 46169689Skan if (name == "") { 47169689Skan opts[n_opts] = $1 48169689Skan flags[n_opts] = $2 49169689Skan help[n_opts] = $3 50169689Skan n_opts++; 51169689Skan } 52169689Skan } 53169689Skan } 54169689Skan 55169689Skan# Dump that array of options into a C file. 56169689SkanEND { 57169689Skanprint "/* This file is auto-generated by opts.sh. */" 58169689Skanprint "" 59169689Skann_headers = split(header_name, headers, " ") 60169689Skanfor (i = 1; i <= n_headers; i++) 61169689Skan print "#include " quote headers[i] quote 62169689Skanprint "#include " quote "opts.h" quote 63169689Skanprint "#include " quote "intl.h" quote 64169689Skanprint "" 65169689Skanprint "#ifdef GCC_DRIVER" 66169689Skanprint "int target_flags;" 67169689Skanprint "#endif /* GCC_DRIVER */" 68169689Skanprint "" 69169689Skan 70169689Skanfor (i = 0; i < n_opts; i++) { 71169689Skan name = var_name(flags[i]); 72169689Skan if (name == "") 73169689Skan continue; 74169689Skan 75169689Skan if (flag_set_p("VarExists", flags[i])) { 76169689Skan # Need it for the gcc driver. 77169689Skan if (name in var_seen) 78169689Skan continue; 79169689Skan init = "" 80169689Skan gcc_driver = 1 81169689Skan } 82169689Skan else { 83169689Skan init = opt_args("Init", flags[i]) 84169689Skan if (init != "") 85169689Skan init = " = " init; 86169689Skan else if (name in var_seen) 87169689Skan continue; 88169689Skan gcc_driver = 0 89169689Skan } 90169689Skan 91169689Skan if (gcc_driver == 1) 92169689Skan print "#ifdef GCC_DRIVER" 93169689Skan print "/* Set by -" opts[i] "." 94169689Skan print " " help[i] " */" 95169689Skan print var_type(flags[i]) name init ";" 96169689Skan if (gcc_driver == 1) 97169689Skan print "#endif /* GCC_DRIVER */" 98169689Skan print "" 99169689Skan 100169689Skan var_seen[name] = 1; 101169689Skan} 102169689Skan 103169689Skanprint "" 104169689Skanprint "/* Local state variables. */" 105169689Skanfor (i = 0; i < n_opts; i++) { 106169689Skan name = static_var(opts[i], flags[i]); 107169689Skan if (name != "") 108169689Skan print "static " var_type(flags[i]) name ";" 109169689Skan} 110169689Skanprint "" 111169689Skan 112169689Skanprint "const char * const lang_names[] =\n{" 113169689Skanfor (i = 0; i < n_langs; i++) { 114169689Skan macros[i] = "CL_" langs[i] 115169689Skan gsub( "[^A-Za-z0-9_]", "X", macros[i] ) 116169689Skan s = substr(" ", length (macros[i])) 117169689Skan print " " quote langs[i] quote "," 118169689Skan } 119169689Skan 120169689Skanprint " 0\n};\n" 121169689Skanprint "const unsigned int cl_options_count = N_OPTS;\n" 122169689Skan 123169689Skanprint "const struct cl_option cl_options[] =\n{" 124169689Skan 125169689Skanj = 0 126169689Skanfor (i = 0; i < n_opts; i++) { 127169689Skan back_chain[i] = "N_OPTS"; 128169689Skan indices[opts[i]] = j; 129169689Skan # Combine the flags of identical switches. Switches 130169689Skan # appear many times if they are handled by many front 131169689Skan # ends, for example. 132169689Skan while( i + 1 != n_opts && opts[i] == opts[i + 1] ) { 133169689Skan flags[i + 1] = flags[i] " " flags[i + 1]; 134169689Skan i++; 135169689Skan back_chain[i] = "N_OPTS"; 136169689Skan indices[opts[i]] = j; 137169689Skan } 138169689Skan j++; 139169689Skan} 140169689Skan 141169689Skanfor (i = 0; i < n_opts; i++) { 142169689Skan # Combine the flags of identical switches. Switches 143169689Skan # appear many times if they are handled by many front 144169689Skan # ends, for example. 145169689Skan while( i + 1 != n_opts && opts[i] == opts[i + 1] ) { 146169689Skan flags[i + 1] = flags[i] " " flags[i + 1]; 147169689Skan i++; 148169689Skan } 149169689Skan 150169689Skan len = length (opts[i]); 151169689Skan enum = "OPT_" opts[i] 152169689Skan if (opts[i] == "finline-limit=") 153169689Skan enum = enum "eq" 154169689Skan gsub ("[^A-Za-z0-9]", "_", enum) 155169689Skan 156169689Skan # If this switch takes joined arguments, back-chain all 157169689Skan # subsequent switches to it for which it is a prefix. If 158169689Skan # a later switch S is a longer prefix of a switch T, T 159169689Skan # will be back-chained to S in a later iteration of this 160169689Skan # for() loop, which is what we want. 161169689Skan if (flag_set_p("Joined.*", flags[i])) { 162169689Skan for (j = i + 1; j < n_opts; j++) { 163169689Skan if (substr (opts[j], 1, len) != opts[i]) 164169689Skan break; 165169689Skan back_chain[j] = enum; 166169689Skan } 167169689Skan } 168169689Skan 169169689Skan s = substr(" ", length (opts[i])) 170169689Skan if (i + 1 == n_opts) 171169689Skan comma = "" 172169689Skan 173169689Skan if (help[i] == "") 174169689Skan hlp = "0" 175169689Skan else 176169689Skan hlp = quote help[i] quote; 177169689Skan 178169689Skan neg = opt_args("Negative", flags[i]); 179169689Skan if (neg != "") 180169689Skan idx = indices[neg] 181169689Skan else { 182169689Skan if (flag_set_p("RejectNegative", flags[i])) 183169689Skan idx = -1; 184169689Skan else { 185169689Skan if (opts[i] ~ "^[Wfm]") 186169689Skan idx = indices[opts[i]]; 187169689Skan else 188169689Skan idx = -1; 189169689Skan } 190169689Skan } 191169689Skan printf(" { %c-%s%c,\n %s,\n %s, %u, %d,\n", 192169689Skan quote, opts[i], quote, hlp, back_chain[i], len, idx) 193169689Skan condition = opt_args("Condition", flags[i]) 194169689Skan cl_flags = switch_flags(flags[i]) 195169689Skan if (condition != "") 196169689Skan printf("#if %s\n" \ 197169689Skan " %s,\n" \ 198169689Skan "#else\n" \ 199169689Skan " CL_DISABLED,\n" \ 200169689Skan "#endif\n", 201169689Skan condition, cl_flags, cl_flags) 202169689Skan else 203169689Skan printf(" %s,\n", cl_flags) 204169689Skan printf(" %s, %s }%s\n", var_ref(opts[i], flags[i]), 205169689Skan var_set(flags[i]), comma) 206169689Skan} 207169689Skan 208169689Skanprint "};" 209169689Skan} 210