1169689Skan# Copyright (C) 2003,2004,2005,2006 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 duplicate options and generates a 21169689Skan# C header file. 22169689Skan# 23169689Skan# This program uses functions from opt-functions.awk 24169689Skan# Usage: awk -f opt-functions.awk -f opth-gen.awk < inputfile > options.h 25169689Skan 26169689SkanBEGIN { 27169689Skan n_opts = 0 28169689Skan n_langs = 0 29169689Skan n_extra_masks = 0 30169689Skan quote = "\042" 31169689Skan comma = "," 32169689Skan FS=SUBSEP 33169689Skan} 34169689Skan 35169689Skan# Collect the text and flags of each option into an array 36169689Skan { 37169689Skan if ($1 == "Language") { 38169689Skan langs[n_langs] = $2 39169689Skan n_langs++; 40169689Skan } 41169689Skan else { 42169689Skan name = opt_args("Mask", $1) 43169689Skan if (name == "") { 44169689Skan opts[n_opts] = $1 45169689Skan flags[n_opts] = $2 46169689Skan help[n_opts] = $3 47169689Skan n_opts++; 48169689Skan } 49169689Skan else { 50169689Skan extra_masks[n_extra_masks++] = name 51169689Skan } 52169689Skan } 53169689Skan } 54169689Skan 55169689Skan# Dump out an enumeration into a .h file. 56169689Skan# Combine the flags of duplicate options. 57169689SkanEND { 58169689Skanprint "/* This file is auto-generated by opts.sh. */" 59169689Skanprint "" 60169689Skanprint "#ifndef OPTIONS_H" 61169689Skanprint "#define OPTIONS_H" 62169689Skanprint "" 63169689Skanprint "extern int target_flags;" 64169689Skanprint "" 65169689Skan 66169689Skanfor (i = 0; i < n_opts; i++) { 67169689Skan name = var_name(flags[i]); 68169689Skan if (name == "") 69169689Skan continue; 70169689Skan 71169689Skan print "extern " var_type(flags[i]) name ";" 72169689Skan} 73169689Skanprint "" 74169689Skan 75169689Skanfor (i = 0; i < n_opts; i++) { 76169689Skan name = opt_args("Mask", flags[i]) 77169689Skan vname = var_name(flags[i]) 78169689Skan mask = "MASK_" 79169689Skan if (vname != "") { 80169689Skan mask = "OPTION_MASK_" 81169689Skan } 82169689Skan if (name != "" && !flag_set_p("MaskExists", flags[i])) 83169689Skan print "#define " mask name " (1 << " masknum[vname]++ ")" 84169689Skan} 85169689Skanfor (i = 0; i < n_extra_masks; i++) { 86169689Skan print "#define MASK_" extra_masks[i] " (1 << " masknum[""]++ ")" 87169689Skan} 88169689Skan 89169689Skanfor (var in masknum) { 90255185Sjmg if (masknum[var] > 32) { 91169689Skan if (var == "") 92169689Skan print "#error too many target masks" 93169689Skan else 94169689Skan print "#error too many masks for " var 95169689Skan } 96169689Skan} 97169689Skanprint "" 98169689Skan 99169689Skanfor (i = 0; i < n_opts; i++) { 100169689Skan name = opt_args("Mask", flags[i]) 101169689Skan vname = var_name(flags[i]) 102169689Skan macro = "OPTION_" 103169689Skan mask = "OPTION_MASK_" 104169689Skan if (vname == "") { 105169689Skan vname = "target_flags" 106169689Skan macro = "TARGET_" 107169689Skan mask = "MASK_" 108169689Skan } 109169689Skan if (name != "" && !flag_set_p("MaskExists", flags[i])) 110169689Skan print "#define " macro name \ 111169689Skan " ((" vname " & " mask name ") != 0)" 112169689Skan} 113169689Skanfor (i = 0; i < n_extra_masks; i++) { 114169689Skan print "#define TARGET_" extra_masks[i] \ 115169689Skan " ((target_flags & MASK_" extra_masks[i] ") != 0)" 116169689Skan} 117169689Skanprint "" 118169689Skan 119169689Skanfor (i = 0; i < n_opts; i++) { 120169689Skan opt = opt_args("InverseMask", flags[i]) 121169689Skan if (opt ~ ",") { 122169689Skan vname = var_name(flags[i]) 123169689Skan macro = "OPTION_" 124169689Skan mask = "OPTION_MASK_" 125169689Skan if (vname == "") { 126169689Skan vname = "target_flags" 127169689Skan macro = "TARGET_" 128169689Skan mask = "MASK_" 129169689Skan } 130169689Skan print "#define " macro nth_arg(1, opt) \ 131169689Skan " ((" vname " & " mask nth_arg(0, opt) ") == 0)" 132169689Skan } 133169689Skan} 134169689Skanprint "" 135169689Skan 136169689Skanfor (i = 0; i < n_langs; i++) { 137169689Skan macros[i] = "CL_" langs[i] 138169689Skan gsub( "[^A-Za-z0-9_]", "X", macros[i] ) 139169689Skan s = substr(" ", length (macros[i])) 140169689Skan print "#define " macros[i] s " (1 << " i ")" 141169689Skan } 142169689Skan 143169689Skanprint "" 144169689Skanprint "enum opt_code" 145169689Skanprint "{" 146169689Skan 147169689Skanfor (i = 0; i < n_opts; i++) 148169689Skan back_chain[i] = "N_OPTS"; 149169689Skan 150169689Skanfor (i = 0; i < n_opts; i++) { 151169689Skan # Combine the flags of identical switches. Switches 152169689Skan # appear many times if they are handled by many front 153169689Skan # ends, for example. 154169689Skan while( i + 1 != n_opts && opts[i] == opts[i + 1] ) { 155169689Skan flags[i + 1] = flags[i] " " flags[i + 1]; 156169689Skan i++; 157169689Skan } 158169689Skan 159169689Skan len = length (opts[i]); 160169689Skan enum = "OPT_" opts[i] 161169689Skan if (opts[i] == "finline-limit=") 162169689Skan enum = enum "eq" 163169689Skan gsub ("[^A-Za-z0-9]", "_", enum) 164169689Skan 165169689Skan # If this switch takes joined arguments, back-chain all 166169689Skan # subsequent switches to it for which it is a prefix. If 167169689Skan # a later switch S is a longer prefix of a switch T, T 168169689Skan # will be back-chained to S in a later iteration of this 169169689Skan # for() loop, which is what we want. 170169689Skan if (flag_set_p("Joined.*", flags[i])) { 171169689Skan for (j = i + 1; j < n_opts; j++) { 172169689Skan if (substr (opts[j], 1, len) != opts[i]) 173169689Skan break; 174169689Skan back_chain[j] = enum; 175169689Skan } 176169689Skan } 177169689Skan 178169689Skan s = substr(" ", length (opts[i])) 179169689Skan if (i + 1 == n_opts) 180169689Skan comma = "" 181169689Skan 182169689Skan if (help[i] == "") 183169689Skan hlp = "0" 184169689Skan else 185169689Skan hlp = "N_(\"" help[i] "\")"; 186169689Skan 187169689Skan print " " enum "," s "/* -" opts[i] " */" 188169689Skan} 189169689Skan 190169689Skanprint " N_OPTS" 191169689Skanprint "};" 192169689Skanprint "" 193169689Skanprint "#endif /* OPTIONS_H */" 194169689Skan} 195