strlist.h: move safe_alloc declaration
[nasm.git] / asm / pragma.c
blob42c15ee9b6cb8791d43998de6dbf6be3bd4539d1
1 /* ----------------------------------------------------------------------- *
3 * Copyright 1996-2019 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
9 * conditions are met:
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * ----------------------------------------------------------------------- */
35 * Parse and handle [pragma] directives. The preprocessor handles
36 * %pragma preproc directives separately, all other namespaces are
37 * simply converted to [pragma].
40 #include "compiler.h"
42 #include "nctype.h"
44 #include "nasm.h"
45 #include "nasmlib.h"
46 #include "assemble.h"
47 #include "error.h"
48 #include "listing.h"
50 static enum directive_result ignore_pragma(const struct pragma *pragma);
51 static enum directive_result output_pragma(const struct pragma *pragma);
52 static enum directive_result debug_pragma(const struct pragma *pragma);
53 static enum directive_result limit_pragma(const struct pragma *pragma);
56 * Handle [pragma] directives. [pragma] is generally produced by
57 * the %pragma preprocessor directive, which simply passes on any
58 * string that it finds *except* %pragma preproc. The idea is
59 * that pragmas are of the form:
61 * %pragma <facility> <opname> [<options>...]
63 * ... where "facility" can be either a generic facility or a backend
64 * name.
66 * The following names are currently reserved for global facilities;
67 * so far none of these have any defined pragmas at all:
69 * preproc - preprocessor
70 * limit - limit setting
71 * asm - assembler
72 * list - listing generator
73 * file - generic file handling
74 * input - input file handling
75 * output - backend-independent output handling
76 * debug - backend-independent debug handling
77 * ignore - dummy pragma (can be used to "comment out")
79 * This function should generally not error out if it doesn't understand
80 * what a pragma is for, for unknown arguments, etc; the whole point of
81 * a pragma is that future releases might add new ones that should be
82 * ignored rather than be an error. Erroring out is acceptable for
83 * known pragmas suffering from parsing errors and so on.
85 * Adding default-suppressed warnings would, however, be a good idea
86 * at some point.
88 static struct pragma_facility global_pragmas[] =
90 { "asm", NULL },
91 { "limit", limit_pragma },
92 { "list", list_pragma },
93 { "file", NULL },
94 { "input", NULL },
95 { "output", output_pragma },
96 { "debug", debug_pragma },
97 { "ignore", ignore_pragma },
99 /* This will never actually get this far... */
100 { "preproc", NULL }, /* Handled in the preprocessor by necessity */
101 { NULL, NULL }
105 * Invoke a pragma handler
107 static enum directive_result
108 call_pragma(const struct pragma_facility *pf, struct pragma *pragma)
110 if (!pf || !pf->handler)
111 return DIRR_UNKNOWN;
113 pragma->facility = pf;
114 return pf->handler(pragma);
118 * Search a pragma list for a known pragma facility and if so, invoke
119 * the handler. Return true if processing is complete. The "default
120 * name", *or def->name*, if set, matches the final NULL entry (used
121 * for backends, so multiple backends can share the same list under
122 * some circumstances, and the backends can implement common operations.)
124 static enum directive_result
125 search_pragma_list(const struct pragma_facility *list,
126 const char *defaultname,
127 const struct pragma_facility *def,
128 const struct pragma *cpragma)
130 const struct pragma_facility *pf = NULL;
131 enum directive_result rv;
132 bool facility_match, is_default;
133 struct pragma pragma = *cpragma;
134 const char *facname = pragma.facility_name;
136 /* Is there a default facility and we match its name? */
137 is_default = def && def->name && !nasm_stricmp(facname, def->name);
138 facility_match = is_default;
141 * Promote def->name to defaultname if both are set. This handles
142 * e.g. output -> elf32 so that we can handle elf32-specific
143 * directives in that handler.
145 if (defaultname) {
146 if (is_default)
147 facname = defaultname;
148 else
149 facility_match = !nasm_stricmp(facname, defaultname);
152 if (facname && list) {
153 for (pf = list; pf->name; pf++) {
154 if (!nasm_stricmp(facname, pf->name)) {
155 facility_match = true;
156 rv = call_pragma(pf, &pragma);
157 if (rv != DIRR_UNKNOWN)
158 goto found_it;
162 if (facility_match) {
164 * Facility name match but no matching directive; handler in NULL
165 * entry at end of list?
167 rv = call_pragma(pf, &pragma);
168 if (rv != DIRR_UNKNOWN)
169 goto found_it;
173 if (facility_match) {
175 * Facility match but still nothing: def->handler if it exists
177 rv = call_pragma(def, &pragma);
178 } else {
180 * No facility matched
182 return DIRR_UNKNOWN;
186 * Otherwise we found the facility but not any supported directive,
187 * fall through...
190 found_it:
191 switch (rv) {
192 case DIRR_UNKNOWN:
193 switch (pragma.opcode) {
194 case D_none:
196 *!pragma-bad [off] malformed %pragma
197 *!=bad-pragma
198 *! warns about a malformed or otherwise unparsable
199 *! \c{%pragma} directive.
201 nasm_warn(ERR_PASS2|WARN_PRAGMA_BAD,
202 "empty %%pragma %s", pragma.facility_name);
203 break;
204 default:
206 *!pragma-unknown [off] unknown %pragma facility or directive
207 *!=unknown-pragma
208 *! warns about an unknown \c{%pragma} directive.
209 *! This is not yet implemented for most cases.
211 nasm_warn(ERR_PASS2|WARN_PRAGMA_UNKNOWN,
212 "unknown %%pragma %s %s",
213 pragma.facility_name, pragma.opname);
214 break;
216 rv = DIRR_ERROR; /* Already printed an error message */
217 break;
219 case DIRR_OK:
220 case DIRR_ERROR:
221 break; /* Nothing to do */
223 case DIRR_BADPARAM:
225 * This one is an error. Don't use it if forward compatibility
226 * would be compromised, as opposed to an inherent error.
228 nasm_error(ERR_NONFATAL, "bad argument to %%pragma %s %s",
229 pragma.facility_name, pragma.opname);
230 break;
232 default:
233 panic();
235 return rv;
238 /* This warning message is intended for future use */
240 *!pragma-na [off] %pragma not applicable to this compilation
241 *!=not-my-pragma
242 *! warns about a \c{%pragma} directive which is not applicable to
243 *! this particular assembly session. This is not yet implemented.
246 /* Naked %pragma */
248 *!pragma-empty [off] empty %pragma directive
249 *! warns about a \c{%pragma} directive containing nothing.
250 *! This is treated identically to \c{%pragma ignore} except
251 *! for this optional warning.
253 void process_pragma(char *str)
255 const struct pragma_facility *pf;
256 struct pragma pragma;
257 char *p;
259 nasm_zero(pragma);
261 pragma.facility_name = nasm_get_word(str, &p);
262 if (!pragma.facility_name) {
263 /* Empty %pragma */
264 nasm_warn(ERR_PASS2|WARN_PRAGMA_EMPTY,
265 "empty %%pragma directive, ignored");
266 return;
269 pragma.opname = nasm_get_word(p, &p);
270 if (!pragma.opname)
271 pragma.opcode = D_none;
272 else
273 pragma.opcode = directive_find(pragma.opname);
275 pragma.tail = nasm_trim_spaces(p);
278 * Search the global pragma namespaces. This is done
279 * as a loop rather than than letting search_pragma_list()
280 * just run, because we don't want to keep searching if
281 * we have a facility match, thus we want to call
282 * search_pragma_list() individually for each namespace.
284 for (pf = global_pragmas; pf->name; pf++) {
285 if (search_pragma_list(NULL, NULL, pf, &pragma) != DIRR_UNKNOWN)
286 return;
289 /* Is it an output pragma? */
290 if (output_pragma(&pragma) != DIRR_UNKNOWN)
291 return;
293 /* Is it a debug pragma */
294 if (debug_pragma(&pragma) != DIRR_UNKNOWN)
295 return;
298 * Note: it would be nice to warn for an unknown namespace,
299 * but in order to do so we need to walk *ALL* the backends
300 * in order to make sure we aren't dealing with a pragma that
301 * is for another backend. On the other hand, that could
302 * also be a warning with a separate warning flag.
304 * Leave this for the future, however, the warning classes are
305 * already defined for future compatibility.
309 /* %pragma ignore */
310 static enum directive_result ignore_pragma(const struct pragma *pragma)
312 (void)pragma;
313 return DIRR_OK; /* Even for D_none! */
317 * Process output and debug pragmas, by either list name or generic
318 * name. Note that the output/debug format list can hook the default
319 * names if they so choose.
321 static enum directive_result output_pragma_common(const struct pragma *);
322 static enum directive_result output_pragma(const struct pragma *pragma)
324 static const struct pragma_facility
325 output_pragma_def = { "output", output_pragma_common };
327 return search_pragma_list(ofmt->pragmas, ofmt->shortname,
328 &output_pragma_def, pragma);
331 /* Generic pragmas that apply to all output backends */
332 static enum directive_result output_pragma_common(const struct pragma *pragma)
334 switch (pragma->opcode) {
335 case D_PREFIX:
336 case D_GPREFIX:
337 set_label_mangle(LM_GPREFIX, pragma->tail);
338 return DIRR_OK;
339 case D_SUFFIX:
340 case D_GSUFFIX:
341 set_label_mangle(LM_GSUFFIX, pragma->tail);
342 return DIRR_OK;
343 case D_LPREFIX:
344 set_label_mangle(LM_LPREFIX, pragma->tail);
345 return DIRR_OK;
346 case D_LSUFFIX:
347 set_label_mangle(LM_LSUFFIX, pragma->tail);
348 return DIRR_OK;
349 default:
350 return DIRR_UNKNOWN;
354 static enum directive_result debug_pragma(const struct pragma *pragma)
356 static const struct pragma_facility
357 debug_pragma_def = { "debug", NULL };
359 return search_pragma_list(dfmt->pragmas, dfmt->shortname,
360 &debug_pragma_def, pragma);
364 * %pragma limit to set resource limits
366 static enum directive_result limit_pragma(const struct pragma *pragma)
368 return nasm_set_limit(pragma->opname, pragma->tail);