pre-proc: use uname() syscall instead of invoking uname
[smatch.git] / pre-process.c
blob05a5a79396a893e6d30f568590acdb69363e6317
1 /*
2 * Do C preprocessing, based on a token list gathered by
3 * the tokenizer.
5 * This may not be the smartest preprocessor on the planet.
7 * Copyright (C) 2003 Transmeta Corp.
8 * 2003-2004 Linus Torvalds
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 * THE SOFTWARE.
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
31 #include <stddef.h>
32 #include <string.h>
33 #include <ctype.h>
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include <limits.h>
37 #include <time.h>
38 #include <dirent.h>
39 #include <sys/stat.h>
40 #include <sys/utsname.h>
42 #include "lib.h"
43 #include "allocate.h"
44 #include "parse.h"
45 #include "token.h"
46 #include "symbol.h"
47 #include "expression.h"
48 #include "scope.h"
50 static struct ident_list *macros; // only needed for -dD
51 static int false_nesting = 0;
52 static int counter_macro = 0; // __COUNTER__ expansion
53 static int include_level = 0;
54 static int expanding = 0;
56 #define INCLUDEPATHS 300
57 const char *includepath[INCLUDEPATHS+1] = {
58 "",
59 "/usr/include",
60 "/usr/local/include",
61 NULL
64 static const char **quote_includepath = includepath;
65 static const char **angle_includepath = includepath + 1;
66 static const char **isys_includepath = includepath + 1;
67 static const char **sys_includepath = includepath + 1;
68 static const char **dirafter_includepath = includepath + 3;
70 #define dirty_stream(stream) \
71 do { \
72 if (!stream->dirty) { \
73 stream->dirty = 1; \
74 if (!stream->ifndef) \
75 stream->protect = NULL; \
76 } \
77 } while(0)
79 #define end_group(stream) \
80 do { \
81 if (stream->ifndef == stream->top_if) { \
82 stream->ifndef = NULL; \
83 if (!stream->dirty) \
84 stream->protect = NULL; \
85 else if (stream->protect) \
86 stream->dirty = 0; \
87 } \
88 } while(0)
90 #define nesting_error(stream) \
91 do { \
92 stream->dirty = 1; \
93 stream->ifndef = NULL; \
94 stream->protect = NULL; \
95 } while(0)
97 static struct token *alloc_token(struct position *pos)
99 struct token *token = __alloc_token(0);
101 token->pos.stream = pos->stream;
102 token->pos.line = pos->line;
103 token->pos.pos = pos->pos;
104 token->pos.whitespace = 1;
105 return token;
108 /* Expand symbol 'sym' at '*list' */
109 static int expand(struct token **, struct symbol *);
111 static void replace_with_string(struct token *token, const char *str)
113 int size = strlen(str) + 1;
114 struct string *s = __alloc_string(size);
116 s->length = size;
117 memcpy(s->data, str, size);
118 token_type(token) = TOKEN_STRING;
119 token->string = s;
122 static void replace_with_integer(struct token *token, unsigned int val)
124 char *buf = __alloc_bytes(11);
125 sprintf(buf, "%u", val);
126 token_type(token) = TOKEN_NUMBER;
127 token->number = buf;
130 static struct symbol *lookup_macro(struct ident *ident)
132 struct symbol *sym = lookup_symbol(ident, NS_MACRO | NS_UNDEF);
133 if (sym && sym->namespace != NS_MACRO)
134 sym = NULL;
135 return sym;
138 static int token_defined(struct token *token)
140 if (token_type(token) == TOKEN_IDENT) {
141 struct symbol *sym = lookup_macro(token->ident);
142 if (sym) {
143 sym->used_in = file_scope;
144 return 1;
146 return 0;
149 sparse_error(token->pos, "expected preprocessor identifier");
150 return 0;
153 static void replace_with_bool(struct token *token, bool val)
155 static const char *string[] = { "0", "1" };
157 token_type(token) = TOKEN_NUMBER;
158 token->number = string[val];
161 static void replace_with_defined(struct token *token)
163 replace_with_bool(token, token_defined(token));
166 static void expand_line(struct token *token)
168 replace_with_integer(token, token->pos.line);
171 static void expand_file(struct token *token)
173 replace_with_string(token, stream_name(token->pos.stream));
176 static void expand_basefile(struct token *token)
178 replace_with_string(token, base_filename);
181 static time_t t = 0;
182 static void expand_date(struct token *token)
184 static char buffer[12]; /* __DATE__: 3 + ' ' + 2 + ' ' + 4 + '\0' */
186 if (!t)
187 time(&t);
188 strftime(buffer, 12, "%b %e %Y", localtime(&t));
189 replace_with_string(token, buffer);
192 static void expand_time(struct token *token)
194 static char buffer[9]; /* __TIME__: 2 + ':' + 2 + ':' + 2 + '\0' */
196 if (!t)
197 time(&t);
198 strftime(buffer, 9, "%T", localtime(&t));
199 replace_with_string(token, buffer);
202 static void expand_counter(struct token *token)
204 replace_with_integer(token, counter_macro++);
207 static void expand_include_level(struct token *token)
209 replace_with_integer(token, include_level - 1);
212 static int expand_one_symbol(struct token **list)
214 struct token *token = *list;
215 struct symbol *sym;
217 if (token->pos.noexpand)
218 return 1;
220 sym = lookup_macro(token->ident);
221 if (!sym)
222 return 1;
223 store_macro_pos(token);
224 if (sym->expand_simple) {
225 sym->expand_simple(token);
226 return 1;
227 } else {
228 int rc;
230 sym->used_in = file_scope;
231 expanding = 1;
232 rc = expand(list, sym);
233 expanding = 0;
234 return rc;
238 static inline struct token *scan_next(struct token **where)
240 struct token *token = *where;
241 if (token_type(token) != TOKEN_UNTAINT)
242 return token;
243 do {
244 token->ident->tainted = 0;
245 token = token->next;
246 } while (token_type(token) == TOKEN_UNTAINT);
247 *where = token;
248 return token;
251 static void expand_list(struct token **list)
253 struct token *next;
254 while (!eof_token(next = scan_next(list))) {
255 if (token_type(next) != TOKEN_IDENT || expand_one_symbol(list))
256 list = &next->next;
260 static void preprocessor_line(struct stream *stream, struct token **line);
262 static struct token *collect_arg(struct token *prev, int vararg, struct position *pos, int count)
264 struct stream *stream = input_streams + prev->pos.stream;
265 struct token **p = &prev->next;
266 struct token *next;
267 int nesting = 0;
269 while (!eof_token(next = scan_next(p))) {
270 if (next->pos.newline && match_op(next, '#')) {
271 if (!next->pos.noexpand) {
272 preprocessor_line(stream, p);
273 __free_token(next); /* Free the '#' token */
274 continue;
277 switch (token_type(next)) {
278 case TOKEN_STREAMEND:
279 case TOKEN_STREAMBEGIN:
280 *p = &eof_token_entry;
281 return next;
282 case TOKEN_STRING:
283 case TOKEN_WIDE_STRING:
284 if (count > 1)
285 next->string->immutable = 1;
286 break;
288 if (false_nesting) {
289 *p = next->next;
290 __free_token(next);
291 continue;
293 if (match_op(next, '(')) {
294 nesting++;
295 } else if (match_op(next, ')')) {
296 if (!nesting--)
297 break;
298 } else if (match_op(next, ',') && !nesting && !vararg) {
299 break;
301 next->pos.stream = pos->stream;
302 next->pos.line = pos->line;
303 next->pos.pos = pos->pos;
304 next->pos.newline = 0;
305 p = &next->next;
307 *p = &eof_token_entry;
308 return next;
312 * We store arglist as <counter> [arg1] <number of uses for arg1> ... eof
315 struct arg {
316 struct token *arg;
317 struct token *expanded;
318 struct token *str;
319 int n_normal;
320 int n_quoted;
321 int n_str;
324 static int collect_arguments(struct token *start, struct token *arglist, struct arg *args, struct token *what)
326 int wanted = arglist->count.normal;
327 struct token *next = NULL;
328 int count = 0;
330 arglist = arglist->next; /* skip counter */
332 if (!wanted) {
333 next = collect_arg(start, 0, &what->pos, 0);
334 if (eof_token(next))
335 goto Eclosing;
336 if (!eof_token(start->next) || !match_op(next, ')')) {
337 count++;
338 goto Emany;
340 } else {
341 for (count = 0; count < wanted; count++) {
342 struct argcount *p = &arglist->next->count;
343 next = collect_arg(start, p->vararg, &what->pos, p->normal);
344 if (eof_token(next))
345 goto Eclosing;
346 if (p->vararg && wanted == 1 && eof_token(start->next))
347 break;
348 arglist = arglist->next->next;
349 args[count].arg = start->next;
350 args[count].n_normal = p->normal;
351 args[count].n_quoted = p->quoted;
352 args[count].n_str = p->str;
353 if (match_op(next, ')')) {
354 count++;
355 break;
357 start = next;
359 if (count == wanted && !match_op(next, ')'))
360 goto Emany;
361 if (count == wanted - 1) {
362 struct argcount *p = &arglist->next->count;
363 if (!p->vararg)
364 goto Efew;
365 args[count].arg = NULL;
366 args[count].n_normal = p->normal;
367 args[count].n_quoted = p->quoted;
368 args[count].n_str = p->str;
370 if (count < wanted - 1)
371 goto Efew;
373 what->next = next->next;
374 return 1;
376 Efew:
377 sparse_error(what->pos, "macro \"%s\" requires %d arguments, but only %d given",
378 show_token(what), wanted, count);
379 goto out;
380 Emany:
381 while (match_op(next, ',')) {
382 next = collect_arg(next, 0, &what->pos, 0);
383 count++;
385 if (eof_token(next))
386 goto Eclosing;
387 sparse_error(what->pos, "macro \"%s\" passed %d arguments, but takes just %d",
388 show_token(what), count, wanted);
389 goto out;
390 Eclosing:
391 sparse_error(what->pos, "unterminated argument list invoking macro \"%s\"",
392 show_token(what));
393 out:
394 what->next = next->next;
395 return 0;
398 static struct token *dup_list(struct token *list)
400 struct token *res = NULL;
401 struct token **p = &res;
403 while (!eof_token(list)) {
404 struct token *newtok = __alloc_token(0);
405 *newtok = *list;
406 *p = newtok;
407 p = &newtok->next;
408 list = list->next;
410 return res;
413 static const char *show_token_sequence(struct token *token, int quote)
415 static char buffer[MAX_STRING];
416 char *ptr = buffer;
417 int whitespace = 0;
419 if (!token && !quote)
420 return "<none>";
421 while (!eof_token(token)) {
422 const char *val = quote ? quote_token(token) : show_token(token);
423 int len = strlen(val);
425 if (ptr + whitespace + len >= buffer + sizeof(buffer)) {
426 sparse_error(token->pos, "too long token expansion");
427 break;
430 if (whitespace)
431 *ptr++ = ' ';
432 memcpy(ptr, val, len);
433 ptr += len;
434 token = token->next;
435 whitespace = token->pos.whitespace;
437 *ptr = 0;
438 return buffer;
441 static struct token *stringify(struct token *arg)
443 const char *s = show_token_sequence(arg, 1);
444 int size = strlen(s)+1;
445 struct token *token = __alloc_token(0);
446 struct string *string = __alloc_string(size);
448 memcpy(string->data, s, size);
449 string->length = size;
450 token->pos = arg->pos;
451 token_type(token) = TOKEN_STRING;
452 token->string = string;
453 token->next = &eof_token_entry;
454 return token;
457 static void expand_arguments(int count, struct arg *args)
459 int i;
460 for (i = 0; i < count; i++) {
461 struct token *arg = args[i].arg;
462 if (!arg)
463 arg = &eof_token_entry;
464 if (args[i].n_str)
465 args[i].str = stringify(arg);
466 if (args[i].n_normal) {
467 if (!args[i].n_quoted) {
468 args[i].expanded = arg;
469 args[i].arg = NULL;
470 } else if (eof_token(arg)) {
471 args[i].expanded = arg;
472 } else {
473 args[i].expanded = dup_list(arg);
475 expand_list(&args[i].expanded);
481 * Possibly valid combinations:
482 * - ident + ident -> ident
483 * - ident + number -> ident unless number contains '.', '+' or '-'.
484 * - 'L' + char constant -> wide char constant
485 * - 'L' + string literal -> wide string literal
486 * - number + number -> number
487 * - number + ident -> number
488 * - number + '.' -> number
489 * - number + '+' or '-' -> number, if number used to end on [eEpP].
490 * - '.' + number -> number, if number used to start with a digit.
491 * - special + special -> either special or an error.
493 static enum token_type combine(struct token *left, struct token *right, char *p)
495 int len;
496 enum token_type t1 = token_type(left), t2 = token_type(right);
498 if (t1 != TOKEN_IDENT && t1 != TOKEN_NUMBER && t1 != TOKEN_SPECIAL)
499 return TOKEN_ERROR;
501 if (t1 == TOKEN_IDENT && left->ident == &L_ident) {
502 if (t2 >= TOKEN_CHAR && t2 < TOKEN_WIDE_CHAR)
503 return t2 + TOKEN_WIDE_CHAR - TOKEN_CHAR;
504 if (t2 == TOKEN_STRING)
505 return TOKEN_WIDE_STRING;
508 if (t2 != TOKEN_IDENT && t2 != TOKEN_NUMBER && t2 != TOKEN_SPECIAL)
509 return TOKEN_ERROR;
511 strcpy(p, show_token(left));
512 strcat(p, show_token(right));
513 len = strlen(p);
515 if (len >= 256)
516 return TOKEN_ERROR;
518 if (t1 == TOKEN_IDENT) {
519 if (t2 == TOKEN_SPECIAL)
520 return TOKEN_ERROR;
521 if (t2 == TOKEN_NUMBER && strpbrk(p, "+-."))
522 return TOKEN_ERROR;
523 return TOKEN_IDENT;
526 if (t1 == TOKEN_NUMBER) {
527 if (t2 == TOKEN_SPECIAL) {
528 switch (right->special) {
529 case '.':
530 break;
531 case '+': case '-':
532 if (strchr("eEpP", p[len - 2]))
533 break;
534 default:
535 return TOKEN_ERROR;
538 return TOKEN_NUMBER;
541 if (p[0] == '.' && isdigit((unsigned char)p[1]))
542 return TOKEN_NUMBER;
544 return TOKEN_SPECIAL;
547 static int merge(struct token *left, struct token *right)
549 static char buffer[512];
550 enum token_type res = combine(left, right, buffer);
551 int n;
553 switch (res) {
554 case TOKEN_IDENT:
555 left->ident = built_in_ident(buffer);
556 left->pos.noexpand = 0;
557 return 1;
559 case TOKEN_NUMBER:
560 token_type(left) = TOKEN_NUMBER; /* could be . + num */
561 left->number = xstrdup(buffer);
562 return 1;
564 case TOKEN_SPECIAL:
565 if (buffer[2] && buffer[3])
566 break;
567 for (n = SPECIAL_BASE; n < SPECIAL_ARG_SEPARATOR; n++) {
568 if (!memcmp(buffer, combinations[n-SPECIAL_BASE], 3)) {
569 left->special = n;
570 return 1;
573 break;
575 case TOKEN_WIDE_CHAR:
576 case TOKEN_WIDE_STRING:
577 token_type(left) = res;
578 left->pos.noexpand = 0;
579 left->string = right->string;
580 return 1;
582 case TOKEN_WIDE_CHAR_EMBEDDED_0 ... TOKEN_WIDE_CHAR_EMBEDDED_3:
583 token_type(left) = res;
584 left->pos.noexpand = 0;
585 memcpy(left->embedded, right->embedded, 4);
586 return 1;
588 default:
591 sparse_error(left->pos, "'##' failed: concatenation is not a valid token");
592 return 0;
595 static struct token *dup_token(struct token *token, struct position *streampos)
597 struct token *alloc = alloc_token(streampos);
598 token_type(alloc) = token_type(token);
599 alloc->pos.newline = token->pos.newline;
600 alloc->pos.whitespace = token->pos.whitespace;
601 alloc->number = token->number;
602 alloc->pos.noexpand = token->pos.noexpand;
603 return alloc;
606 static struct token **copy(struct token **where, struct token *list, int *count)
608 int need_copy = --*count;
609 while (!eof_token(list)) {
610 struct token *token;
611 if (need_copy)
612 token = dup_token(list, &list->pos);
613 else
614 token = list;
615 if (token_type(token) == TOKEN_IDENT && token->ident->tainted)
616 token->pos.noexpand = 1;
617 *where = token;
618 where = &token->next;
619 list = list->next;
621 *where = &eof_token_entry;
622 return where;
625 static int handle_kludge(struct token **p, struct arg *args)
627 struct token *t = (*p)->next->next;
628 while (1) {
629 struct arg *v = &args[t->argnum];
630 if (token_type(t->next) != TOKEN_CONCAT) {
631 if (v->arg) {
632 /* ignore the first ## */
633 *p = (*p)->next;
634 return 0;
636 /* skip the entire thing */
637 *p = t;
638 return 1;
640 if (v->arg && !eof_token(v->arg))
641 return 0; /* no magic */
642 t = t->next->next;
646 static struct token **substitute(struct token **list, struct token *body, struct arg *args)
648 struct position *base_pos = &(*list)->pos;
649 int *count;
650 enum {Normal, Placeholder, Concat} state = Normal;
652 for (; !eof_token(body); body = body->next) {
653 struct token *added, *arg;
654 struct token **tail;
655 struct token *t;
657 switch (token_type(body)) {
658 case TOKEN_GNU_KLUDGE:
660 * GNU kludge: if we had <comma>##<vararg>, behaviour
661 * depends on whether we had enough arguments to have
662 * a vararg. If we did, ## is just ignored. Otherwise
663 * both , and ## are ignored. Worse, there can be
664 * an arbitrary number of ##<arg> in between; if all of
665 * those are empty, we act as if they hadn't been there,
666 * otherwise we act as if the kludge didn't exist.
668 t = body;
669 if (handle_kludge(&body, args)) {
670 if (state == Concat)
671 state = Normal;
672 else
673 state = Placeholder;
674 continue;
676 added = dup_token(t, base_pos);
677 token_type(added) = TOKEN_SPECIAL;
678 tail = &added->next;
679 break;
681 case TOKEN_STR_ARGUMENT:
682 arg = args[body->argnum].str;
683 count = &args[body->argnum].n_str;
684 goto copy_arg;
686 case TOKEN_QUOTED_ARGUMENT:
687 arg = args[body->argnum].arg;
688 count = &args[body->argnum].n_quoted;
689 if (!arg || eof_token(arg)) {
690 if (state == Concat)
691 state = Normal;
692 else
693 state = Placeholder;
694 continue;
696 goto copy_arg;
698 case TOKEN_MACRO_ARGUMENT:
699 arg = args[body->argnum].expanded;
700 count = &args[body->argnum].n_normal;
701 if (eof_token(arg)) {
702 state = Normal;
703 continue;
705 copy_arg:
706 tail = copy(&added, arg, count);
707 added->pos.newline = body->pos.newline;
708 added->pos.whitespace = body->pos.whitespace;
709 break;
711 case TOKEN_CONCAT:
712 if (state == Placeholder)
713 state = Normal;
714 else
715 state = Concat;
716 continue;
718 case TOKEN_IDENT:
719 added = dup_token(body, base_pos);
720 if (added->ident->tainted)
721 added->pos.noexpand = 1;
722 tail = &added->next;
723 break;
725 default:
726 added = dup_token(body, base_pos);
727 tail = &added->next;
728 break;
732 * if we got to doing real concatenation, we already have
733 * added something into the list, so containing_token() is OK.
735 if (state == Concat && merge(containing_token(list), added)) {
736 *list = added->next;
737 if (tail != &added->next)
738 list = tail;
739 } else {
740 *list = added;
741 list = tail;
743 state = Normal;
745 *list = &eof_token_entry;
746 return list;
749 static int expand(struct token **list, struct symbol *sym)
751 struct token *last;
752 struct token *token = *list;
753 struct ident *expanding = token->ident;
754 struct token **tail;
755 struct token *expansion = sym->expansion;
756 int nargs = sym->arglist ? sym->arglist->count.normal : 0;
757 struct arg args[nargs];
759 if (expanding->tainted) {
760 token->pos.noexpand = 1;
761 return 1;
764 if (sym->arglist) {
765 if (!match_op(scan_next(&token->next), '('))
766 return 1;
767 if (!collect_arguments(token->next, sym->arglist, args, token))
768 return 1;
769 expand_arguments(nargs, args);
772 if (sym->expand)
773 return sym->expand(token, args) ? 0 : 1;
775 expanding->tainted = 1;
777 last = token->next;
778 tail = substitute(list, expansion, args);
780 * Note that it won't be eof - at least TOKEN_UNTAINT will be there.
781 * We still can lose the newline flag if the sucker expands to nothing,
782 * but the price of dealing with that is probably too high (we'd need
783 * to collect the flags during scan_next())
785 (*list)->pos.newline = token->pos.newline;
786 (*list)->pos.whitespace = token->pos.whitespace;
787 *tail = last;
789 return 0;
792 static const char *token_name_sequence(struct token *token, int endop, struct token *start)
794 static char buffer[256];
795 char *ptr = buffer;
797 while (!eof_token(token) && !match_op(token, endop)) {
798 int len;
799 const char *val = token->string->data;
800 if (token_type(token) != TOKEN_STRING)
801 val = show_token(token);
802 len = strlen(val);
803 memcpy(ptr, val, len);
804 ptr += len;
805 token = token->next;
807 *ptr = 0;
808 if (endop && !match_op(token, endop))
809 sparse_error(start->pos, "expected '>' at end of filename");
810 return buffer;
813 static int already_tokenized(const char *path)
815 int stream, next;
817 for (stream = *hash_stream(path); stream >= 0 ; stream = next) {
818 struct stream *s = input_streams + stream;
820 next = s->next_stream;
821 if (s->once) {
822 if (strcmp(path, s->name))
823 continue;
824 return 1;
826 if (s->constant != CONSTANT_FILE_YES)
827 continue;
828 if (strcmp(path, s->name))
829 continue;
830 if (s->protect && !lookup_macro(s->protect))
831 continue;
832 return 1;
834 return 0;
837 /* Handle include of header files.
838 * The relevant options are made compatible with gcc. The only options that
839 * are not supported is -withprefix and friends.
841 * Three set of include paths are known:
842 * quote_includepath: Path to search when using #include "file.h"
843 * angle_includepath: Paths to search when using #include <file.h>
844 * isys_includepath: Paths specified with -isystem, come before the
845 * built-in system include paths. Gcc would suppress
846 * warnings from system headers. Here we separate
847 * them from the angle_ ones to keep search ordering.
849 * sys_includepath: Built-in include paths.
850 * dirafter_includepath Paths added with -dirafter.
852 * The above is implemented as one array with pointers
853 * +--------------+
854 * quote_includepath ---> | |
855 * +--------------+
856 * | |
857 * +--------------+
858 * angle_includepath ---> | |
859 * +--------------+
860 * isys_includepath ---> | |
861 * +--------------+
862 * sys_includepath ---> | |
863 * +--------------+
864 * dirafter_includepath -> | |
865 * +--------------+
867 * -I dir insert dir just before isys_includepath and move the rest
868 * -I- makes all dirs specified with -I before to quote dirs only and
869 * angle_includepath is set equal to isys_includepath.
870 * -nostdinc removes all sys dirs by storing NULL in entry pointed
871 * to by * sys_includepath. Note that this will reset all dirs built-in
872 * and added before -nostdinc by -isystem and -idirafter.
873 * -isystem dir adds dir where isys_includepath points adding this dir as
874 * first systemdir
875 * -idirafter dir adds dir to the end of the list
878 static void set_stream_include_path(struct stream *stream)
880 const char *path = stream->path;
881 if (!path) {
882 const char *p = strrchr(stream->name, '/');
883 path = "";
884 if (p) {
885 int len = p - stream->name + 1;
886 char *m = malloc(len+1);
887 /* This includes the final "/" */
888 memcpy(m, stream->name, len);
889 m[len] = 0;
890 path = m;
891 /* normalize this path */
892 while (path[0] == '.' && path[1] == '/') {
893 path += 2;
894 while (path[0] == '/')
895 path++;
898 stream->path = path;
900 includepath[0] = path;
903 static int try_include(struct position pos, const char *path, const char *filename, int flen, struct token **where, const char **next_path)
905 int fd;
906 int plen = strlen(path);
907 static char fullname[PATH_MAX];
909 memcpy(fullname, path, plen);
910 if (plen && path[plen-1] != '/') {
911 fullname[plen] = '/';
912 plen++;
914 memcpy(fullname+plen, filename, flen);
915 if (already_tokenized(fullname))
916 return 1;
917 fd = open(fullname, O_RDONLY);
918 if (fd >= 0) {
919 char *streamname = xmemdup(fullname, plen + flen);
920 *where = tokenize(&pos, streamname, fd, *where, next_path);
921 close(fd);
922 return 1;
924 return 0;
927 static int do_include_path(const char **pptr, struct token **list, struct token *token, const char *filename, int flen)
929 const char *path;
931 while ((path = *pptr++) != NULL) {
932 if (!try_include(token->pos, path, filename, flen, list, pptr))
933 continue;
934 return 1;
936 return 0;
939 static int free_preprocessor_line(struct token *token)
941 while (token_type(token) != TOKEN_EOF) {
942 struct token *free = token;
943 token = token->next;
944 __free_token(free);
946 return 1;
949 const char *find_include(const char *skip, const char *look_for)
951 DIR *dp;
952 struct dirent *entry;
953 struct stat statbuf;
954 const char *ret;
955 char cwd[PATH_MAX];
956 static char buf[PATH_MAX + 1];
958 dp = opendir(".");
959 if (!dp)
960 return NULL;
962 if (!getcwd(cwd, sizeof(cwd)))
963 goto close;
965 while ((entry = readdir(dp))) {
966 lstat(entry->d_name, &statbuf);
968 if (strcmp(entry->d_name, look_for) == 0) {
969 snprintf(buf, sizeof(buf), "%s/%s", cwd, entry->d_name);
970 closedir(dp);
971 return buf;
974 if (S_ISDIR(statbuf.st_mode)) {
975 /* Found a directory, but ignore . and .. */
976 if (strcmp(".", entry->d_name) == 0 ||
977 strcmp("..", entry->d_name) == 0 ||
978 strcmp(skip, entry->d_name) == 0)
979 continue;
981 chdir(entry->d_name);
982 ret = find_include("", look_for);
983 chdir("..");
984 if (ret) {
985 closedir(dp);
986 return ret;
990 close:
991 closedir(dp);
993 return NULL;
996 const char *search_dir(const char *stop, const char *look_for)
998 char cwd[PATH_MAX];
999 int len;
1000 const char *ret;
1001 int cnt = 0;
1003 if (!getcwd(cwd, sizeof(cwd)))
1004 return NULL;
1006 len = strlen(cwd);
1007 while (len >= 0) {
1008 ret = find_include(cnt++ ? cwd + len + 1 : "", look_for);
1009 if (ret)
1010 return ret;
1012 if (strcmp(cwd, stop) == 0 ||
1013 strcmp(cwd, "/usr/include") == 0 ||
1014 strcmp(cwd, "/usr/local/include") == 0 ||
1015 strlen(cwd) <= 10 || /* heck... don't search /usr/lib/ */
1016 strcmp(cwd, "/") == 0)
1017 return NULL;
1019 while (--len >= 0) {
1020 if (cwd[len] == '/') {
1021 cwd[len] = '\0';
1022 break;
1026 chdir("..");
1028 return NULL;
1031 static void use_best_guess_header_file(struct token *token, const char *filename, struct token **list)
1033 char cwd[PATH_MAX];
1034 char dir_part[PATH_MAX];
1035 const char *file_part;
1036 const char *include_name;
1037 static int cnt;
1038 int len;
1040 /* Avoid guessing includes recursively. */
1041 if (cnt++ > 1000)
1042 return;
1044 if (!filename || filename[0] == '\0')
1045 return;
1047 file_part = filename;
1048 while ((filename = strchr(filename, '/'))) {
1049 ++filename;
1050 if (filename[0])
1051 file_part = filename;
1054 snprintf(dir_part, sizeof(dir_part), "%s", stream_name(token->pos.stream));
1055 len = strlen(dir_part);
1056 while (--len >= 0) {
1057 if (dir_part[len] == '/') {
1058 dir_part[len] = '\0';
1059 break;
1062 if (len < 0)
1063 sprintf(dir_part, ".");
1065 if (!getcwd(cwd, sizeof(cwd)))
1066 return;
1068 chdir(dir_part);
1069 include_name = search_dir(cwd, file_part);
1070 chdir(cwd);
1071 if (!include_name)
1072 return;
1073 sparse_error(token->pos, "using '%s'", include_name);
1075 try_include(token->pos, "", include_name, strlen(include_name), list, includepath);
1078 static int handle_include_path(struct stream *stream, struct token **list, struct token *token, int how)
1080 const char *filename;
1081 struct token *next;
1082 const char **path;
1083 int expect;
1084 int flen;
1086 next = token->next;
1087 expect = '>';
1088 if (!match_op(next, '<')) {
1089 expand_list(&token->next);
1090 expect = 0;
1091 next = token;
1092 if (match_op(token->next, '<')) {
1093 next = token->next;
1094 expect = '>';
1098 token = next->next;
1099 filename = token_name_sequence(token, expect, token);
1100 flen = strlen(filename) + 1;
1102 /* Absolute path? */
1103 if (filename[0] == '/') {
1104 if (try_include(token->pos, "", filename, flen, list, includepath))
1105 return 0;
1106 goto out;
1109 switch (how) {
1110 case 1:
1111 path = stream->next_path;
1112 break;
1113 case 2:
1114 includepath[0] = "";
1115 path = includepath;
1116 break;
1117 default:
1118 /* Dir of input file is first dir to search for quoted includes */
1119 set_stream_include_path(stream);
1120 path = expect ? angle_includepath : quote_includepath;
1121 break;
1123 /* Check the standard include paths.. */
1124 if (do_include_path(path, list, token, filename, flen))
1125 return 0;
1126 out:
1127 sparse_error(token->pos, "unable to open '%s'", filename);
1128 use_best_guess_header_file(token, filename, list);
1129 return 0;
1132 static int handle_include(struct stream *stream, struct token **list, struct token *token)
1134 return handle_include_path(stream, list, token, 0);
1137 static int handle_include_next(struct stream *stream, struct token **list, struct token *token)
1139 return handle_include_path(stream, list, token, 1);
1142 static int handle_argv_include(struct stream *stream, struct token **list, struct token *token)
1144 return handle_include_path(stream, list, token, 2);
1147 static int token_different(struct token *t1, struct token *t2)
1149 int different;
1151 if (token_type(t1) != token_type(t2))
1152 return 1;
1154 switch (token_type(t1)) {
1155 case TOKEN_IDENT:
1156 different = t1->ident != t2->ident;
1157 break;
1158 case TOKEN_ARG_COUNT:
1159 case TOKEN_UNTAINT:
1160 case TOKEN_CONCAT:
1161 case TOKEN_GNU_KLUDGE:
1162 different = 0;
1163 break;
1164 case TOKEN_NUMBER:
1165 different = strcmp(t1->number, t2->number);
1166 break;
1167 case TOKEN_SPECIAL:
1168 different = t1->special != t2->special;
1169 break;
1170 case TOKEN_MACRO_ARGUMENT:
1171 case TOKEN_QUOTED_ARGUMENT:
1172 case TOKEN_STR_ARGUMENT:
1173 different = t1->argnum != t2->argnum;
1174 break;
1175 case TOKEN_CHAR_EMBEDDED_0 ... TOKEN_CHAR_EMBEDDED_3:
1176 case TOKEN_WIDE_CHAR_EMBEDDED_0 ... TOKEN_WIDE_CHAR_EMBEDDED_3:
1177 different = memcmp(t1->embedded, t2->embedded, 4);
1178 break;
1179 case TOKEN_CHAR:
1180 case TOKEN_WIDE_CHAR:
1181 case TOKEN_STRING:
1182 case TOKEN_WIDE_STRING: {
1183 struct string *s1, *s2;
1185 s1 = t1->string;
1186 s2 = t2->string;
1187 different = 1;
1188 if (s1->length != s2->length)
1189 break;
1190 different = memcmp(s1->data, s2->data, s1->length);
1191 break;
1193 default:
1194 different = 1;
1195 break;
1197 return different;
1200 static int token_list_different(struct token *list1, struct token *list2)
1202 for (;;) {
1203 if (list1 == list2)
1204 return 0;
1205 if (!list1 || !list2)
1206 return 1;
1207 if (token_different(list1, list2))
1208 return 1;
1209 list1 = list1->next;
1210 list2 = list2->next;
1214 static inline void set_arg_count(struct token *token)
1216 token_type(token) = TOKEN_ARG_COUNT;
1217 token->count.normal = token->count.quoted =
1218 token->count.str = token->count.vararg = 0;
1221 static struct token *parse_arguments(struct token *list)
1223 struct token *arg = list->next, *next = list;
1224 struct argcount *count = &list->count;
1226 set_arg_count(list);
1228 if (match_op(arg, ')')) {
1229 next = arg->next;
1230 list->next = &eof_token_entry;
1231 return next;
1234 while (token_type(arg) == TOKEN_IDENT) {
1235 if (arg->ident == &__VA_ARGS___ident)
1236 goto Eva_args;
1237 if (!++count->normal)
1238 goto Eargs;
1239 next = arg->next;
1241 if (match_op(next, ',')) {
1242 set_arg_count(next);
1243 arg = next->next;
1244 continue;
1247 if (match_op(next, ')')) {
1248 set_arg_count(next);
1249 next = next->next;
1250 arg->next->next = &eof_token_entry;
1251 return next;
1254 /* normal cases are finished here */
1256 if (match_op(next, SPECIAL_ELLIPSIS)) {
1257 if (match_op(next->next, ')')) {
1258 set_arg_count(next);
1259 next->count.vararg = 1;
1260 next = next->next;
1261 arg->next->next = &eof_token_entry;
1262 return next->next;
1265 arg = next;
1266 goto Enotclosed;
1269 if (eof_token(next)) {
1270 goto Enotclosed;
1271 } else {
1272 arg = next;
1273 goto Ebadstuff;
1277 if (match_op(arg, SPECIAL_ELLIPSIS)) {
1278 next = arg->next;
1279 token_type(arg) = TOKEN_IDENT;
1280 arg->ident = &__VA_ARGS___ident;
1281 if (!match_op(next, ')'))
1282 goto Enotclosed;
1283 if (!++count->normal)
1284 goto Eargs;
1285 set_arg_count(next);
1286 next->count.vararg = 1;
1287 next = next->next;
1288 arg->next->next = &eof_token_entry;
1289 return next;
1292 if (eof_token(arg)) {
1293 arg = next;
1294 goto Enotclosed;
1296 if (match_op(arg, ','))
1297 goto Emissing;
1298 else
1299 goto Ebadstuff;
1302 Emissing:
1303 sparse_error(arg->pos, "parameter name missing");
1304 return NULL;
1305 Ebadstuff:
1306 sparse_error(arg->pos, "\"%s\" may not appear in macro parameter list",
1307 show_token(arg));
1308 return NULL;
1309 Enotclosed:
1310 sparse_error(arg->pos, "missing ')' in macro parameter list");
1311 return NULL;
1312 Eva_args:
1313 sparse_error(arg->pos, "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro");
1314 return NULL;
1315 Eargs:
1316 sparse_error(arg->pos, "too many arguments in macro definition");
1317 return NULL;
1320 static int try_arg(struct token *token, enum token_type type, struct token *arglist)
1322 struct ident *ident = token->ident;
1323 int nr;
1325 if (!arglist || token_type(token) != TOKEN_IDENT)
1326 return 0;
1328 arglist = arglist->next;
1330 for (nr = 0; !eof_token(arglist); nr++, arglist = arglist->next->next) {
1331 if (arglist->ident == ident) {
1332 struct argcount *count = &arglist->next->count;
1333 int n;
1335 token->argnum = nr;
1336 token_type(token) = type;
1337 switch (type) {
1338 case TOKEN_MACRO_ARGUMENT:
1339 n = ++count->normal;
1340 break;
1341 case TOKEN_QUOTED_ARGUMENT:
1342 n = ++count->quoted;
1343 break;
1344 default:
1345 n = ++count->str;
1347 if (n)
1348 return count->vararg ? 2 : 1;
1350 * XXX - need saner handling of that
1351 * (>= 1024 instances of argument)
1353 token_type(token) = TOKEN_ERROR;
1354 return -1;
1357 return 0;
1360 static struct token *handle_hash(struct token **p, struct token *arglist)
1362 struct token *token = *p;
1363 if (arglist) {
1364 struct token *next = token->next;
1365 if (!try_arg(next, TOKEN_STR_ARGUMENT, arglist))
1366 goto Equote;
1367 next->pos.whitespace = token->pos.whitespace;
1368 __free_token(token);
1369 token = *p = next;
1370 } else {
1371 token->pos.noexpand = 1;
1373 return token;
1375 Equote:
1376 sparse_error(token->pos, "'#' is not followed by a macro parameter");
1377 return NULL;
1380 /* token->next is ## */
1381 static struct token *handle_hashhash(struct token *token, struct token *arglist)
1383 struct token *last = token;
1384 struct token *concat;
1385 int state = match_op(token, ',');
1387 try_arg(token, TOKEN_QUOTED_ARGUMENT, arglist);
1389 while (1) {
1390 struct token *t;
1391 int is_arg;
1393 /* eat duplicate ## */
1394 concat = token->next;
1395 while (match_op(t = concat->next, SPECIAL_HASHHASH)) {
1396 token->next = t;
1397 __free_token(concat);
1398 concat = t;
1400 token_type(concat) = TOKEN_CONCAT;
1402 if (eof_token(t))
1403 goto Econcat;
1405 if (match_op(t, '#')) {
1406 t = handle_hash(&concat->next, arglist);
1407 if (!t)
1408 return NULL;
1411 is_arg = try_arg(t, TOKEN_QUOTED_ARGUMENT, arglist);
1413 if (state == 1 && is_arg) {
1414 state = is_arg;
1415 } else {
1416 last = t;
1417 state = match_op(t, ',');
1420 token = t;
1421 if (!match_op(token->next, SPECIAL_HASHHASH))
1422 break;
1424 /* handle GNU ,##__VA_ARGS__ kludge, in all its weirdness */
1425 if (state == 2)
1426 token_type(last) = TOKEN_GNU_KLUDGE;
1427 return token;
1429 Econcat:
1430 sparse_error(concat->pos, "'##' cannot appear at the ends of macro expansion");
1431 return NULL;
1434 static struct token *parse_expansion(struct token *expansion, struct token *arglist, struct ident *name)
1436 struct token *token = expansion;
1437 struct token **p;
1439 if (match_op(token, SPECIAL_HASHHASH))
1440 goto Econcat;
1442 for (p = &expansion; !eof_token(token); p = &token->next, token = *p) {
1443 if (match_op(token, '#')) {
1444 token = handle_hash(p, arglist);
1445 if (!token)
1446 return NULL;
1448 if (match_op(token->next, SPECIAL_HASHHASH)) {
1449 token = handle_hashhash(token, arglist);
1450 if (!token)
1451 return NULL;
1452 } else {
1453 try_arg(token, TOKEN_MACRO_ARGUMENT, arglist);
1455 switch (token_type(token)) {
1456 case TOKEN_ERROR:
1457 goto Earg;
1459 case TOKEN_STRING:
1460 case TOKEN_WIDE_STRING:
1461 token->string->immutable = 1;
1462 break;
1465 token = alloc_token(&expansion->pos);
1466 token_type(token) = TOKEN_UNTAINT;
1467 token->ident = name;
1468 token->next = *p;
1469 *p = token;
1470 return expansion;
1472 Econcat:
1473 sparse_error(token->pos, "'##' cannot appear at the ends of macro expansion");
1474 return NULL;
1475 Earg:
1476 sparse_error(token->pos, "too many instances of argument in body");
1477 return NULL;
1480 static int do_define(struct position pos, struct token *token, struct ident *name,
1481 struct token *arglist, struct token *expansion, int attr)
1483 struct symbol *sym;
1484 int ret = 1;
1486 expansion = parse_expansion(expansion, arglist, name);
1487 if (!expansion)
1488 return 1;
1490 sym = lookup_symbol(name, NS_MACRO | NS_UNDEF);
1491 if (sym) {
1492 int clean;
1494 if (attr < sym->attr)
1495 goto out;
1497 clean = (attr == sym->attr && sym->namespace == NS_MACRO);
1499 if (token_list_different(sym->expansion, expansion) ||
1500 token_list_different(sym->arglist, arglist)) {
1501 ret = 0;
1502 if ((clean && attr == SYM_ATTR_NORMAL)
1503 || sym->used_in == file_scope) {
1504 warning(pos, "preprocessor token %.*s redefined",
1505 name->len, name->name);
1506 info(sym->pos, "this was the original definition");
1508 } else if (clean)
1509 goto out;
1512 if (!sym || sym->scope != file_scope) {
1513 sym = alloc_symbol(pos, SYM_NODE);
1514 bind_symbol(sym, name, NS_MACRO);
1515 add_ident(&macros, name);
1516 ret = 0;
1519 if (!ret) {
1520 sym->expansion = expansion;
1521 sym->arglist = arglist;
1522 if (token) /* Free the "define" token, but not the rest of the line */
1523 __free_token(token);
1526 sym->namespace = NS_MACRO;
1527 sym->used_in = NULL;
1528 sym->attr = attr;
1529 out:
1530 return ret;
1534 // predefine a macro with a printf-formatted value
1535 // @name: the name of the macro
1536 // @weak: 0/1 for a normal or a weak define
1537 // @fmt: the printf format followed by it's arguments.
1539 // The type of the value is automatically infered:
1540 // TOKEN_NUMBER if it starts by a digit, TOKEN_IDENT otherwise.
1541 // If @fmt is null or empty, the macro is defined with an empty definition.
1542 void predefine(const char *name, int weak, const char *fmt, ...)
1544 struct ident *ident = built_in_ident(name);
1545 struct token *value = &eof_token_entry;
1546 int attr = weak ? SYM_ATTR_WEAK : SYM_ATTR_NORMAL;
1548 if (fmt && fmt[0]) {
1549 static char buf[256];
1550 va_list ap;
1552 va_start(ap, fmt);
1553 vsnprintf(buf, sizeof(buf), fmt, ap);
1554 va_end(ap);
1556 value = __alloc_token(0);
1557 if (isdigit((unsigned char)buf[0])) {
1558 token_type(value) = TOKEN_NUMBER;
1559 value->number = xstrdup(buf);
1560 } else {
1561 token_type(value) = TOKEN_IDENT;
1562 value->ident = built_in_ident(buf);
1564 value->pos.whitespace = 1;
1565 value->next = &eof_token_entry;
1568 do_define(value->pos, NULL, ident, NULL, value, attr);
1572 // like predefine() but only if one of the non-standard dialect is chosen
1573 void predefine_nostd(const char *name)
1575 if ((standard & STANDARD_GNU) || (standard == STANDARD_NONE))
1576 predefine(name, 1, "1");
1579 static void predefine_fmt(const char *fmt, int weak, va_list ap)
1581 static char buf[256];
1583 vsnprintf(buf, sizeof(buf), fmt, ap);
1584 predefine(buf, weak, "1");
1587 void predefine_strong(const char *fmt, ...)
1589 va_list ap;
1591 va_start(ap, fmt);
1592 predefine_fmt(fmt, 0, ap);
1593 va_end(ap);
1596 void predefine_weak(const char *fmt, ...)
1598 va_list ap;
1600 va_start(ap, fmt);
1601 predefine_fmt(fmt, 1, ap);
1602 va_end(ap);
1605 static int do_handle_define(struct stream *stream, struct token **line, struct token *token, int attr)
1607 struct token *arglist, *expansion;
1608 struct token *left = token->next;
1609 struct ident *name;
1611 if (token_type(left) != TOKEN_IDENT) {
1612 sparse_error(token->pos, "expected identifier to 'define'");
1613 return 1;
1616 name = left->ident;
1618 arglist = NULL;
1619 expansion = left->next;
1620 if (!expansion->pos.whitespace) {
1621 if (match_op(expansion, '(')) {
1622 arglist = expansion;
1623 expansion = parse_arguments(expansion);
1624 if (!expansion)
1625 return 1;
1626 } else if (!eof_token(expansion)) {
1627 warning(expansion->pos,
1628 "no whitespace before object-like macro body");
1632 return do_define(left->pos, token, name, arglist, expansion, attr);
1635 static int handle_define(struct stream *stream, struct token **line, struct token *token)
1637 return do_handle_define(stream, line, token, SYM_ATTR_NORMAL);
1640 static int handle_weak_define(struct stream *stream, struct token **line, struct token *token)
1642 return do_handle_define(stream, line, token, SYM_ATTR_WEAK);
1645 static int handle_strong_define(struct stream *stream, struct token **line, struct token *token)
1647 return do_handle_define(stream, line, token, SYM_ATTR_STRONG);
1650 static int do_handle_undef(struct stream *stream, struct token **line, struct token *token, int attr)
1652 struct token *left = token->next;
1653 struct symbol *sym;
1655 if (token_type(left) != TOKEN_IDENT) {
1656 sparse_error(token->pos, "expected identifier to 'undef'");
1657 return 1;
1660 sym = lookup_symbol(left->ident, NS_MACRO | NS_UNDEF);
1661 if (sym) {
1662 if (attr < sym->attr)
1663 return 1;
1664 if (attr == sym->attr && sym->namespace == NS_UNDEF)
1665 return 1;
1666 } else if (attr <= SYM_ATTR_NORMAL)
1667 return 1;
1669 if (!sym || sym->scope != file_scope) {
1670 sym = alloc_symbol(left->pos, SYM_NODE);
1671 bind_symbol(sym, left->ident, NS_MACRO);
1674 sym->namespace = NS_UNDEF;
1675 sym->used_in = NULL;
1676 sym->attr = attr;
1678 return 1;
1681 static int handle_undef(struct stream *stream, struct token **line, struct token *token)
1683 return do_handle_undef(stream, line, token, SYM_ATTR_NORMAL);
1686 static int handle_strong_undef(struct stream *stream, struct token **line, struct token *token)
1688 return do_handle_undef(stream, line, token, SYM_ATTR_STRONG);
1691 static int preprocessor_if(struct stream *stream, struct token *token, int cond)
1693 token_type(token) = false_nesting ? TOKEN_SKIP_GROUPS : TOKEN_IF;
1694 free_preprocessor_line(token->next);
1695 token->next = stream->top_if;
1696 stream->top_if = token;
1697 if (false_nesting || cond != 1)
1698 false_nesting++;
1699 return 0;
1702 static int handle_ifdef(struct stream *stream, struct token **line, struct token *token)
1704 struct token *next = token->next;
1705 int arg;
1706 if (token_type(next) == TOKEN_IDENT) {
1707 arg = token_defined(next);
1708 } else {
1709 dirty_stream(stream);
1710 if (!false_nesting)
1711 sparse_error(token->pos, "expected preprocessor identifier");
1712 arg = -1;
1714 return preprocessor_if(stream, token, arg);
1717 static int handle_ifndef(struct stream *stream, struct token **line, struct token *token)
1719 struct token *next = token->next;
1720 int arg;
1721 if (token_type(next) == TOKEN_IDENT) {
1722 if (!stream->dirty && !stream->ifndef) {
1723 if (!stream->protect) {
1724 stream->ifndef = token;
1725 stream->protect = next->ident;
1726 } else if (stream->protect == next->ident) {
1727 stream->ifndef = token;
1728 stream->dirty = 1;
1731 arg = !token_defined(next);
1732 } else {
1733 dirty_stream(stream);
1734 if (!false_nesting)
1735 sparse_error(token->pos, "expected preprocessor identifier");
1736 arg = -1;
1739 return preprocessor_if(stream, token, arg);
1743 * Expression handling for #if and #elif; it differs from normal expansion
1744 * due to special treatment of "defined".
1746 static int expression_value(struct token **where)
1748 struct expression *expr;
1749 struct token *p;
1750 struct token **list = where, **beginning = NULL;
1751 long long value;
1752 int state = 0;
1754 while (!eof_token(p = scan_next(list))) {
1755 switch (state) {
1756 case 0:
1757 if (token_type(p) != TOKEN_IDENT)
1758 break;
1759 if (p->ident == &defined_ident) {
1760 state = 1;
1761 beginning = list;
1762 break;
1764 if (!expand_one_symbol(list))
1765 continue;
1766 if (token_type(p) != TOKEN_IDENT)
1767 break;
1768 token_type(p) = TOKEN_ZERO_IDENT;
1769 break;
1770 case 1:
1771 if (match_op(p, '(')) {
1772 state = 2;
1773 } else {
1774 state = 0;
1775 replace_with_defined(p);
1776 *beginning = p;
1778 break;
1779 case 2:
1780 if (token_type(p) == TOKEN_IDENT)
1781 state = 3;
1782 else
1783 state = 0;
1784 replace_with_defined(p);
1785 *beginning = p;
1786 break;
1787 case 3:
1788 state = 0;
1789 if (!match_op(p, ')'))
1790 sparse_error(p->pos, "missing ')' after \"defined\"");
1791 *list = p->next;
1792 continue;
1794 list = &p->next;
1797 p = constant_expression(*where, &expr);
1798 if (!eof_token(p))
1799 sparse_error(p->pos, "garbage at end: %s", show_token_sequence(p, 0));
1800 value = get_expression_value(expr);
1801 return value != 0;
1804 static int handle_if(struct stream *stream, struct token **line, struct token *token)
1806 int value = 0;
1807 if (!false_nesting)
1808 value = expression_value(&token->next);
1810 dirty_stream(stream);
1811 return preprocessor_if(stream, token, value);
1814 static int handle_elif(struct stream * stream, struct token **line, struct token *token)
1816 struct token *top_if = stream->top_if;
1817 end_group(stream);
1819 if (!top_if) {
1820 nesting_error(stream);
1821 sparse_error(token->pos, "unmatched #elif within stream");
1822 return 1;
1825 if (token_type(top_if) == TOKEN_ELSE) {
1826 nesting_error(stream);
1827 sparse_error(token->pos, "#elif after #else");
1828 if (!false_nesting)
1829 false_nesting = 1;
1830 return 1;
1833 dirty_stream(stream);
1834 if (token_type(top_if) != TOKEN_IF)
1835 return 1;
1836 if (false_nesting) {
1837 false_nesting = 0;
1838 if (!expression_value(&token->next))
1839 false_nesting = 1;
1840 } else {
1841 false_nesting = 1;
1842 token_type(top_if) = TOKEN_SKIP_GROUPS;
1844 return 1;
1847 static int handle_else(struct stream *stream, struct token **line, struct token *token)
1849 struct token *top_if = stream->top_if;
1850 end_group(stream);
1852 if (!top_if) {
1853 nesting_error(stream);
1854 sparse_error(token->pos, "unmatched #else within stream");
1855 return 1;
1858 if (token_type(top_if) == TOKEN_ELSE) {
1859 nesting_error(stream);
1860 sparse_error(token->pos, "#else after #else");
1862 if (false_nesting) {
1863 if (token_type(top_if) == TOKEN_IF)
1864 false_nesting = 0;
1865 } else {
1866 false_nesting = 1;
1868 token_type(top_if) = TOKEN_ELSE;
1869 return 1;
1872 static int handle_endif(struct stream *stream, struct token **line, struct token *token)
1874 struct token *top_if = stream->top_if;
1875 end_group(stream);
1876 if (!top_if) {
1877 nesting_error(stream);
1878 sparse_error(token->pos, "unmatched #endif in stream");
1879 return 1;
1881 if (false_nesting)
1882 false_nesting--;
1883 stream->top_if = top_if->next;
1884 __free_token(top_if);
1885 return 1;
1888 static int handle_warning(struct stream *stream, struct token **line, struct token *token)
1890 warning(token->pos, "%s", show_token_sequence(token->next, 0));
1891 return 1;
1894 static int handle_error(struct stream *stream, struct token **line, struct token *token)
1896 sparse_error(token->pos, "%s", show_token_sequence(token->next, 0));
1897 return 1;
1900 static int handle_nostdinc(struct stream *stream, struct token **line, struct token *token)
1903 * Do we have any non-system includes?
1904 * Clear them out if so..
1906 *sys_includepath = NULL;
1907 return 1;
1910 static inline void update_inc_ptrs(const char ***where)
1913 if (*where <= dirafter_includepath) {
1914 dirafter_includepath++;
1915 /* If this was the entry that we prepend, don't
1916 * rise the lower entries, even if they are at
1917 * the same level. */
1918 if (where == &dirafter_includepath)
1919 return;
1921 if (*where <= sys_includepath) {
1922 sys_includepath++;
1923 if (where == &sys_includepath)
1924 return;
1926 if (*where <= isys_includepath) {
1927 isys_includepath++;
1928 if (where == &isys_includepath)
1929 return;
1932 /* angle_includepath is actually never updated, since we
1933 * don't suppport -iquote rught now. May change some day. */
1934 if (*where <= angle_includepath) {
1935 angle_includepath++;
1936 if (where == &angle_includepath)
1937 return;
1941 /* Add a path before 'where' and update the pointers associated with the
1942 * includepath array */
1943 static void add_path_entry(struct token *token, const char *path,
1944 const char ***where)
1946 const char **dst;
1947 const char *next;
1949 /* Need one free entry.. */
1950 if (includepath[INCLUDEPATHS-2])
1951 error_die(token->pos, "too many include path entries");
1953 /* check that this is not a duplicate */
1954 dst = includepath;
1955 while (*dst) {
1956 if (strcmp(*dst, path) == 0)
1957 return;
1958 dst++;
1960 next = path;
1961 dst = *where;
1963 update_inc_ptrs(where);
1966 * Move them all up starting at dst,
1967 * insert the new entry..
1969 do {
1970 const char *tmp = *dst;
1971 *dst = next;
1972 next = tmp;
1973 dst++;
1974 } while (next);
1977 static int handle_add_include(struct stream *stream, struct token **line, struct token *token)
1979 for (;;) {
1980 token = token->next;
1981 if (eof_token(token))
1982 return 1;
1983 if (token_type(token) != TOKEN_STRING) {
1984 warning(token->pos, "expected path string");
1985 return 1;
1987 add_path_entry(token, token->string->data, &isys_includepath);
1991 static int handle_add_isystem(struct stream *stream, struct token **line, struct token *token)
1993 for (;;) {
1994 token = token->next;
1995 if (eof_token(token))
1996 return 1;
1997 if (token_type(token) != TOKEN_STRING) {
1998 sparse_error(token->pos, "expected path string");
1999 return 1;
2001 add_path_entry(token, token->string->data, &sys_includepath);
2005 static int handle_add_system(struct stream *stream, struct token **line, struct token *token)
2007 for (;;) {
2008 token = token->next;
2009 if (eof_token(token))
2010 return 1;
2011 if (token_type(token) != TOKEN_STRING) {
2012 sparse_error(token->pos, "expected path string");
2013 return 1;
2015 add_path_entry(token, token->string->data, &dirafter_includepath);
2019 /* Add to end on includepath list - no pointer updates */
2020 static void add_dirafter_entry(struct token *token, const char *path)
2022 const char **dst = includepath;
2024 /* Need one free entry.. */
2025 if (includepath[INCLUDEPATHS-2])
2026 error_die(token->pos, "too many include path entries");
2028 /* Add to the end */
2029 while (*dst)
2030 dst++;
2031 *dst = path;
2032 dst++;
2033 *dst = NULL;
2036 static int handle_add_dirafter(struct stream *stream, struct token **line, struct token *token)
2038 for (;;) {
2039 token = token->next;
2040 if (eof_token(token))
2041 return 1;
2042 if (token_type(token) != TOKEN_STRING) {
2043 sparse_error(token->pos, "expected path string");
2044 return 1;
2046 add_dirafter_entry(token, token->string->data);
2050 static int handle_split_include(struct stream *stream, struct token **line, struct token *token)
2053 * -I-
2054 * From info gcc:
2055 * Split the include path. Any directories specified with `-I'
2056 * options before `-I-' are searched only for headers requested with
2057 * `#include "FILE"'; they are not searched for `#include <FILE>'.
2058 * If additional directories are specified with `-I' options after
2059 * the `-I-', those directories are searched for all `#include'
2060 * directives.
2061 * In addition, `-I-' inhibits the use of the directory of the current
2062 * file directory as the first search directory for `#include "FILE"'.
2064 quote_includepath = includepath+1;
2065 angle_includepath = sys_includepath;
2066 return 1;
2070 * We replace "#pragma xxx" with "__pragma__" in the token
2071 * stream. Just as an example.
2073 * We'll just #define that away for now, but the theory here
2074 * is that we can use this to insert arbitrary token sequences
2075 * to turn the pragmas into internal front-end sequences for
2076 * when we actually start caring about them.
2078 * So eventually this will turn into some kind of extended
2079 * __attribute__() like thing, except called __pragma__(xxx).
2081 static int handle_pragma(struct stream *stream, struct token **line, struct token *token)
2083 struct token *next = *line;
2085 if (match_ident(token->next, &once_ident) && eof_token(token->next->next)) {
2086 stream->once = 1;
2087 return 1;
2089 token->ident = &pragma_ident;
2090 token->pos.newline = 1;
2091 token->pos.whitespace = 1;
2092 token->pos.pos = 1;
2093 *line = token;
2094 token->next = next;
2095 return 0;
2099 * We ignore #line for now.
2101 static int handle_line(struct stream *stream, struct token **line, struct token *token)
2103 return 1;
2106 static int handle_ident(struct stream *stream, struct token **line, struct token *token)
2108 return 1;
2111 static int handle_nondirective(struct stream *stream, struct token **line, struct token *token)
2113 sparse_error(token->pos, "unrecognized preprocessor line '%s'", show_token_sequence(token, 0));
2114 return 1;
2117 static bool expand_has_attribute(struct token *token, struct arg *args)
2119 struct token *arg = args[0].expanded;
2120 struct symbol *sym;
2122 if (token_type(arg) != TOKEN_IDENT) {
2123 sparse_error(arg->pos, "identifier expected");
2124 return false;
2127 sym = lookup_symbol(arg->ident, NS_KEYWORD);
2128 replace_with_bool(token, sym && sym->op && sym->op->attribute);
2129 return true;
2132 static bool expand_has_builtin(struct token *token, struct arg *args)
2134 struct token *arg = args[0].expanded;
2135 struct symbol *sym;
2137 if (token_type(arg) != TOKEN_IDENT) {
2138 sparse_error(arg->pos, "identifier expected");
2139 return false;
2142 sym = lookup_symbol(arg->ident, NS_SYMBOL);
2143 replace_with_bool(token, sym && sym->builtin);
2144 return true;
2147 static bool expand_has_extension(struct token *token, struct arg *args)
2149 struct token *arg = args[0].expanded;
2150 struct ident *ident;
2151 bool val = false;
2153 if (token_type(arg) != TOKEN_IDENT) {
2154 sparse_error(arg->pos, "identifier expected");
2155 return false;
2158 ident = arg->ident;
2159 if (ident == &c_alignas_ident)
2160 val = true;
2161 else if (ident == &c_alignof_ident)
2162 val = true;
2163 else if (ident == &c_generic_selections_ident)
2164 val = true;
2165 else if (ident == &c_static_assert_ident)
2166 val = true;
2168 replace_with_bool(token, val);
2169 return 1;
2172 static bool expand_has_feature(struct token *token, struct arg *args)
2174 struct token *arg = args[0].expanded;
2175 struct ident *ident;
2176 bool val = false;
2178 if (token_type(arg) != TOKEN_IDENT) {
2179 sparse_error(arg->pos, "identifier expected");
2180 return false;
2183 ident = arg->ident;
2184 if (standard >= STANDARD_C11) {
2185 if (ident == &c_alignas_ident)
2186 val = true;
2187 else if (ident == &c_alignof_ident)
2188 val = true;
2189 else if (ident == &c_generic_selections_ident)
2190 val = true;
2191 else if (ident == &c_static_assert_ident)
2192 val = true;
2195 replace_with_bool(token, val);
2196 return 1;
2199 static void create_arglist(struct symbol *sym, int count)
2201 struct token *token;
2202 struct token **next;
2204 if (!count)
2205 return;
2207 token = __alloc_token(0);
2208 token_type(token) = TOKEN_ARG_COUNT;
2209 token->count.normal = count;
2210 sym->arglist = token;
2211 next = &token->next;
2213 while (count--) {
2214 struct token *id, *uses;
2215 id = __alloc_token(0);
2216 token_type(id) = TOKEN_IDENT;
2217 uses = __alloc_token(0);
2218 token_type(uses) = TOKEN_ARG_COUNT;
2219 uses->count.normal = 1;
2221 *next = id;
2222 id->next = uses;
2223 next = &uses->next;
2225 *next = &eof_token_entry;
2228 static void init_preprocessor(void)
2230 int i;
2231 int stream = init_stream(NULL, "preprocessor", -1, includepath);
2232 static struct {
2233 const char *name;
2234 int (*handler)(struct stream *, struct token **, struct token *);
2235 } normal[] = {
2236 { "define", handle_define },
2237 { "weak_define", handle_weak_define },
2238 { "strong_define", handle_strong_define },
2239 { "undef", handle_undef },
2240 { "strong_undef", handle_strong_undef },
2241 { "warning", handle_warning },
2242 { "error", handle_error },
2243 { "include", handle_include },
2244 { "include_next", handle_include_next },
2245 { "pragma", handle_pragma },
2246 { "line", handle_line },
2247 { "ident", handle_ident },
2249 // our internal preprocessor tokens
2250 { "nostdinc", handle_nostdinc },
2251 { "add_include", handle_add_include },
2252 { "add_isystem", handle_add_isystem },
2253 { "add_system", handle_add_system },
2254 { "add_dirafter", handle_add_dirafter },
2255 { "split_include", handle_split_include },
2256 { "argv_include", handle_argv_include },
2257 }, special[] = {
2258 { "ifdef", handle_ifdef },
2259 { "ifndef", handle_ifndef },
2260 { "else", handle_else },
2261 { "endif", handle_endif },
2262 { "if", handle_if },
2263 { "elif", handle_elif },
2265 static struct {
2266 const char *name;
2267 void (*expand_simple)(struct token *);
2268 bool (*expand)(struct token *, struct arg *args);
2269 } dynamic[] = {
2270 { "__LINE__", expand_line },
2271 { "__FILE__", expand_file },
2272 { "__BASE_FILE__", expand_basefile },
2273 { "__DATE__", expand_date },
2274 { "__TIME__", expand_time },
2275 { "__COUNTER__", expand_counter },
2276 { "__INCLUDE_LEVEL__", expand_include_level },
2277 { "__has_attribute", NULL, expand_has_attribute },
2278 { "__has_builtin", NULL, expand_has_builtin },
2279 { "__has_extension", NULL, expand_has_extension },
2280 { "__has_feature", NULL, expand_has_feature },
2283 for (i = 0; i < ARRAY_SIZE(normal); i++) {
2284 struct symbol *sym;
2285 sym = create_symbol(stream, normal[i].name, SYM_PREPROCESSOR, NS_PREPROCESSOR);
2286 sym->handler = normal[i].handler;
2287 sym->normal = 1;
2289 for (i = 0; i < ARRAY_SIZE(special); i++) {
2290 struct symbol *sym;
2291 sym = create_symbol(stream, special[i].name, SYM_PREPROCESSOR, NS_PREPROCESSOR);
2292 sym->handler = special[i].handler;
2293 sym->normal = 0;
2295 for (i = 0; i < ARRAY_SIZE(dynamic); i++) {
2296 struct symbol *sym;
2297 sym = create_symbol(stream, dynamic[i].name, SYM_NODE, NS_MACRO);
2298 sym->expand_simple = dynamic[i].expand_simple;
2299 if ((sym->expand = dynamic[i].expand) != NULL)
2300 create_arglist(sym, 1);
2303 counter_macro = 0;
2306 static void handle_preprocessor_line(struct stream *stream, struct token **line, struct token *start)
2308 int (*handler)(struct stream *, struct token **, struct token *);
2309 struct token *token = start->next;
2310 int is_normal = 1;
2311 int is_cond = 0; // is one of {is,ifdef,ifndef,elif,else,endif}
2313 if (eof_token(token))
2314 return;
2316 if (token_type(token) == TOKEN_IDENT) {
2317 struct symbol *sym = lookup_symbol(token->ident, NS_PREPROCESSOR);
2318 if (sym) {
2319 handler = sym->handler;
2320 is_normal = sym->normal;
2321 is_cond = !sym->normal;
2322 } else {
2323 handler = handle_nondirective;
2325 } else if (token_type(token) == TOKEN_NUMBER) {
2326 handler = handle_line;
2327 } else {
2328 handler = handle_nondirective;
2331 if (is_normal) {
2332 dirty_stream(stream);
2333 if (false_nesting)
2334 goto out;
2337 if (expanding) {
2338 if (!is_cond || Wpedantic)
2339 warning(start->pos, "directive in macro's argument list");
2341 if (!handler(stream, line, token)) /* all set */
2342 return;
2344 out:
2345 free_preprocessor_line(token);
2348 static void preprocessor_line(struct stream *stream, struct token **line)
2350 struct token *start = *line, *next;
2351 struct token **tp = &start->next;
2353 for (;;) {
2354 next = *tp;
2355 if (next->pos.newline)
2356 break;
2357 tp = &next->next;
2359 *line = next;
2360 *tp = &eof_token_entry;
2361 handle_preprocessor_line(stream, line, start);
2364 static void do_preprocess(struct token **list)
2366 struct token *next;
2368 while (!eof_token(next = scan_next(list))) {
2369 struct stream *stream = input_streams + next->pos.stream;
2371 if (next->pos.newline && match_op(next, '#')) {
2372 if (!next->pos.noexpand) {
2373 preprocessor_line(stream, list);
2374 __free_token(next); /* Free the '#' token */
2375 continue;
2379 switch (token_type(next)) {
2380 case TOKEN_STREAMEND:
2381 if (stream->top_if) {
2382 nesting_error(stream);
2383 sparse_error(stream->top_if->pos, "unterminated preprocessor conditional");
2384 stream->top_if = NULL;
2385 false_nesting = 0;
2387 if (!stream->dirty)
2388 stream->constant = CONSTANT_FILE_YES;
2389 *list = next->next;
2390 include_level--;
2391 continue;
2392 case TOKEN_STREAMBEGIN:
2393 *list = next->next;
2394 include_level++;
2395 continue;
2397 default:
2398 dirty_stream(stream);
2399 if (false_nesting) {
2400 *list = next->next;
2401 __free_token(next);
2402 continue;
2405 if (token_type(next) != TOKEN_IDENT ||
2406 expand_one_symbol(list))
2407 list = &next->next;
2412 void init_include_path(void)
2414 char path[256];
2415 char os[32];
2416 int error;
2417 struct utsname name;
2419 error = uname(&name);
2420 if (error)
2421 return;
2423 if (strcmp(name.sysname, "Linux") != 0)
2424 return;
2425 strcpy(os, "linux-gnu");
2427 snprintf(path, sizeof(path), "/usr/include/%s-%s/",
2428 name.machine, os);
2429 add_pre_buffer("#add_system \"%s/\"\n", path);
2432 struct token * preprocess(struct token *token)
2434 preprocessing = 1;
2435 init_preprocessor();
2436 do_preprocess(&token);
2438 // Drop all expressions from preprocessing, they're not used any more.
2439 // This is not true when we have multiple files, though ;/
2440 // clear_expression_alloc();
2441 preprocessing = 0;
2443 return token;
2446 static int is_VA_ARGS_token(struct token *token)
2448 return (token_type(token) == TOKEN_IDENT) &&
2449 (token->ident == &__VA_ARGS___ident);
2452 static void dump_macro(struct symbol *sym)
2454 int nargs = sym->arglist ? sym->arglist->count.normal : 0;
2455 struct token *args[nargs];
2456 struct token *token;
2458 printf("#define %s", show_ident(sym->ident));
2459 token = sym->arglist;
2460 if (token) {
2461 const char *sep = "";
2462 int narg = 0;
2463 putchar('(');
2464 for (; !eof_token(token); token = token->next) {
2465 if (token_type(token) == TOKEN_ARG_COUNT)
2466 continue;
2467 if (is_VA_ARGS_token(token))
2468 printf("%s...", sep);
2469 else
2470 printf("%s%s", sep, show_token(token));
2471 args[narg++] = token;
2472 sep = ",";
2474 putchar(')');
2477 token = sym->expansion;
2478 while (token_type(token) != TOKEN_UNTAINT) {
2479 struct token *next = token->next;
2480 if (token->pos.whitespace)
2481 putchar(' ');
2482 switch (token_type(token)) {
2483 case TOKEN_CONCAT:
2484 printf("##");
2485 break;
2486 case TOKEN_STR_ARGUMENT:
2487 printf("#");
2488 /* fall-through */
2489 case TOKEN_QUOTED_ARGUMENT:
2490 case TOKEN_MACRO_ARGUMENT:
2491 token = args[token->argnum];
2492 /* fall-through */
2493 default:
2494 printf("%s", show_token(token));
2496 token = next;
2498 putchar('\n');
2501 void dump_macro_definitions(void)
2503 struct ident *name;
2505 FOR_EACH_PTR(macros, name) {
2506 struct symbol *sym = lookup_macro(name);
2507 if (sym)
2508 dump_macro(sym);
2509 } END_FOR_EACH_PTR(name);