]>
Commit | Line | Data |
---|---|---|
c75c517d SB |
1 | # Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010 |
2 | # Free Software Foundation, Inc. | |
776dc15d KC |
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 | |
9dcd6f09 | 8 | # Free Software Foundation; either version 3, or (at your option) any |
776dc15d KC |
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 | |
9dcd6f09 NC |
17 | # along with this program; see the file COPYING3. If not see |
18 | # <http://www.gnu.org/licenses/>. | |
776dc15d KC |
19 | |
20 | # Some common subroutines for use by opt[ch]-gen.awk. | |
21 | ||
e4590d63 RW |
22 | # Define some helpful character classes, for portability. |
23 | BEGIN { | |
24 | lower = "abcdefghijklmnopqrstuvwxyz" | |
25 | upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
26 | digit = "0123456789" | |
27 | alnum = lower "" upper "" digit | |
28 | } | |
29 | ||
a56a0779 RS |
30 | # Return nonzero if FLAGS contains a flag matching REGEX. |
31 | function flag_set_p(regex, flags) | |
32 | { | |
33 | return (" " flags " ") ~ (" " regex " ") | |
34 | } | |
35 | ||
36 | # Return STRING if FLAGS contains a flag matching regexp REGEX, | |
37 | # otherwise return the empty string. | |
38 | function test_flag(regex, flags, string) | |
39 | { | |
40 | if (flag_set_p(regex, flags)) | |
41 | return string | |
42 | return "" | |
43 | } | |
44 | ||
75685792 RS |
45 | # If FLAGS contains a "NAME(...argument...)" flag, return the value |
46 | # of the argument. Return the empty string otherwise. | |
47 | function opt_args(name, flags) | |
48 | { | |
49 | flags = " " flags | |
50 | if (flags !~ " " name "\\(") | |
51 | return "" | |
52 | sub(".* " name "\\(", "", flags) | |
88c2fd3d DK |
53 | if (flags ~ "^{") |
54 | { | |
55 | sub ("^{", "", flags) | |
56 | sub("}\\).*", "", flags) | |
57 | } | |
58 | else | |
59 | sub("\\).*", "", flags) | |
75685792 RS |
60 | |
61 | return flags | |
62 | } | |
63 | ||
64 | # Return the Nth comma-separated element of S. Return the empty string | |
65 | # if S does not contain N elements. | |
66 | function nth_arg(n, s) | |
67 | { | |
68 | while (n-- > 0) { | |
69 | if (s !~ ",") | |
70 | return "" | |
71 | sub("[^,]*, *", "", s) | |
72 | } | |
73 | sub(",.*", "", s) | |
74 | return s | |
75 | } | |
76 | ||
77 | # Return a bitmask of CL_* values for option flags FLAGS. | |
776dc15d KC |
78 | function switch_flags (flags) |
79 | { | |
776dc15d KC |
80 | result = "0" |
81 | for (j = 0; j < n_langs; j++) { | |
a56a0779 | 82 | regex = langs[j] |
776dc15d | 83 | gsub ( "\\+", "\\+", regex ) |
a56a0779 | 84 | result = result test_flag(regex, flags, " | " macros[j]) |
776dc15d | 85 | } |
a56a0779 RS |
86 | result = result \ |
87 | test_flag("Common", flags, " | CL_COMMON") \ | |
88 | test_flag("Target", flags, " | CL_TARGET") \ | |
603349bf JM |
89 | test_flag("Driver", flags, " | CL_DRIVER") \ |
90 | test_flag("RejectDriver", flags, " | CL_REJECT_DRIVER") \ | |
c878765b | 91 | test_flag("NoDriverArg", flags, " | CL_NO_DRIVER_ARG") \ |
d1583032 | 92 | test_flag("SeparateAlias", flags, " | CL_SEPARATE_ALIAS") \ |
5779e713 | 93 | test_flag("Save", flags, " | CL_SAVE") \ |
a56a0779 RS |
94 | test_flag("Joined", flags, " | CL_JOINED") \ |
95 | test_flag("JoinedOrMissing", flags, " | CL_JOINED | CL_MISSING_OK") \ | |
96 | test_flag("Separate", flags, " | CL_SEPARATE") \ | |
97 | test_flag("RejectNegative", flags, " | CL_REJECT_NEGATIVE") \ | |
98 | test_flag("UInteger", flags, " | CL_UINTEGER") \ | |
99 | test_flag("Undocumented", flags, " | CL_UNDOCUMENTED") \ | |
c662432e NC |
100 | test_flag("Warning", flags, " | CL_WARNING") \ |
101 | test_flag("Optimization", flags, " | CL_OPTIMIZATION") \ | |
a56a0779 | 102 | test_flag("Report", flags, " | CL_REPORT") |
776dc15d KC |
103 | sub( "^0 \\| ", "", result ) |
104 | return result | |
105 | } | |
106 | ||
75685792 RS |
107 | # If FLAGS includes a Var flag, return the name of the variable it specifies. |
108 | # Return the empty string otherwise. | |
776dc15d KC |
109 | function var_name(flags) |
110 | { | |
75685792 | 111 | return nth_arg(0, opt_args("Var", flags)) |
776dc15d | 112 | } |
75685792 | 113 | |
ee133b69 RS |
114 | # Return true if the option described by FLAGS has a globally-visible state. |
115 | function global_state_p(flags) | |
116 | { | |
117 | return (var_name(flags) != "" \ | |
118 | || opt_args("Mask", flags) != "" \ | |
119 | || opt_args("InverseMask", flags) != "") | |
120 | } | |
121 | ||
122 | # Return true if the option described by FLAGS must have some state | |
123 | # associated with it. | |
124 | function needs_state_p(flags) | |
125 | { | |
2d2bd949 JM |
126 | return (flag_set_p("Target", flags) \ |
127 | && !flag_set_p("Alias.*", flags) \ | |
128 | && !flag_set_p("Ignore", flags)) | |
ee133b69 RS |
129 | } |
130 | ||
46625112 JM |
131 | # If FLAGS describes an option that needs state without a public |
132 | # variable name, return the name of that field, minus the initial | |
133 | # "x_", otherwise return "". NAME is the name of the option. | |
ee133b69 RS |
134 | function static_var(name, flags) |
135 | { | |
136 | if (global_state_p(flags) || !needs_state_p(flags)) | |
137 | return "" | |
e4590d63 | 138 | gsub ("[^" alnum "]", "_", name) |
ee133b69 RS |
139 | return "VAR_" name |
140 | } | |
141 | ||
55bea00a RS |
142 | # Return the type of variable that should be associated with the given flags. |
143 | function var_type(flags) | |
144 | { | |
603349bf | 145 | if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) |
55bea00a RS |
146 | return "int " |
147 | else if (flag_set_p("UInteger", flags)) | |
148 | return "int " | |
149 | else | |
150 | return "const char *" | |
151 | } | |
152 | ||
ab442df7 | 153 | # Return the type of variable that should be associated with the given flags |
a3f410a2 | 154 | # for use within a structure. Simple variables are changed to signed char |
ab442df7 MM |
155 | # type instead of int to save space. |
156 | function var_type_struct(flags) | |
157 | { | |
158 | if (flag_set_p("UInteger", flags)) | |
159 | return "int " | |
603349bf | 160 | else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) { |
ab442df7 MM |
161 | if (flag_set_p(".*Mask.*", flags)) |
162 | return "int " | |
163 | else | |
a3f410a2 | 164 | return "signed char " |
ab442df7 MM |
165 | } |
166 | else | |
167 | return "const char *" | |
168 | } | |
169 | ||
75685792 RS |
170 | # Given that an option has flags FLAGS, return an initializer for the |
171 | # "var_cond" and "var_value" fields of its cl_options[] entry. | |
776dc15d KC |
172 | function var_set(flags) |
173 | { | |
75685792 RS |
174 | s = nth_arg(1, opt_args("Var", flags)) |
175 | if (s != "") | |
176 | return "CLVC_EQUAL, " s | |
177 | s = opt_args("Mask", flags); | |
a45505d8 DD |
178 | if (s != "") { |
179 | vn = var_name(flags); | |
180 | if (vn) | |
181 | return "CLVC_BIT_SET, OPTION_MASK_" s | |
182 | else | |
183 | return "CLVC_BIT_SET, MASK_" s | |
184 | } | |
75685792 | 185 | s = nth_arg(0, opt_args("InverseMask", flags)); |
c1630cc5 DE |
186 | if (s != "") { |
187 | vn = var_name(flags); | |
188 | if (vn) | |
189 | return "CLVC_BIT_CLEAR, OPTION_MASK_" s | |
55bea00a | 190 | else |
c1630cc5 DE |
191 | return "CLVC_BIT_CLEAR, MASK_" s |
192 | } | |
55bea00a RS |
193 | if (var_type(flags) == "const char *") |
194 | return "CLVC_STRING, 0" | |
75685792 | 195 | return "CLVC_BOOLEAN, 0" |
776dc15d | 196 | } |
75685792 | 197 | |
ee133b69 RS |
198 | # Given that an option called NAME has flags FLAGS, return an initializer |
199 | # for the "flag_var" field of its cl_options[] entry. | |
200 | function var_ref(name, flags) | |
776dc15d | 201 | { |
ee133b69 | 202 | name = var_name(flags) static_var(name, flags) |
75685792 | 203 | if (name != "") |
46625112 | 204 | return "offsetof (struct gcc_options, x_" name ")" |
75685792 | 205 | if (opt_args("Mask", flags) != "") |
46625112 | 206 | return "offsetof (struct gcc_options, x_target_flags)" |
75685792 | 207 | if (opt_args("InverseMask", flags) != "") |
46625112 JM |
208 | return "offsetof (struct gcc_options, x_target_flags)" |
209 | return "-1" | |
776dc15d | 210 | } |
9db94baa MLI |
211 | |
212 | # Given the option called NAME return a sanitized version of its name. | |
213 | function opt_sanitized_name(name) | |
214 | { | |
e4590d63 | 215 | gsub ("[^" alnum "]", "_", name) |
9db94baa MLI |
216 | return name |
217 | } | |
218 | ||
219 | # Given the option called NAME return the appropriate enum for it. | |
220 | function opt_enum(name) | |
221 | { | |
222 | return "OPT_" opt_sanitized_name(name) | |
223 | } |