2 * Do C preprocessing, based on a token list gathered by
5 * This may not be the smartest preprocessor on the planet.
7 * Copyright (C) 2003 Linus Torvalds, all rights reserved.
23 #include "expression.h"
26 static int true_nesting
= 0;
27 static int false_nesting
= 0;
28 static struct token
*unmatched_if
= NULL
;
29 static int elif_ignore
[MAXNEST
];
30 #define if_nesting (true_nesting + false_nesting)
33 * This is stupid - the tokenizer already guarantees unique
34 * identifiers, so we should just compare identifier pointers
36 static int match_string_ident(struct ident
*ident
, const char *str
)
38 return !str
[ident
->len
] && !memcmp(str
, ident
->name
, ident
->len
);
41 static struct token
*alloc_token(struct token
*dup
)
43 struct token
*token
= __alloc_token(0);
45 token
->stream
= dup
->stream
;
46 token
->line
= dup
->line
;
47 token
->pos
= dup
->pos
;
48 token
->whitespace
= 1;
52 static const char *show_token_sequence(struct token
*token
);
54 /* Head is one-before-list, and last is one-past-list */
55 static struct token
*for_each_ident(struct token
*head
, struct token
*(*action
)(struct token
*head
, struct token
*))
58 struct token
*next
= head
->next
;
60 /* Did we hit the end of the current expansion? */
64 if (next
->type
== TOKEN_IDENT
)
65 next
= action(head
, next
);
72 static struct token
*is_defined(struct token
*head
, struct token
*token
, struct token
*next
)
74 char *string
[] = { "0", "1" };
75 char *defined
= string
[lookup_symbol(token
->ident
, NS_PREPROCESSOR
) != NULL
];
76 struct token
*newtoken
= alloc_token(token
);
78 newtoken
->type
= TOKEN_INTEGER
;
79 newtoken
->integer
= defined
;
80 newtoken
->next
= next
;
81 head
->next
= newtoken
;
86 struct token
*defined_one_symbol(struct token
*head
, struct token
*next
)
88 if (match_string_ident(next
->ident
, "defined")) {
89 struct token
*token
= next
->next
;
90 struct token
*past
= token
->next
;
92 if (match_op(token
, '(')) {
95 if (!match_op(past
, ')'))
99 if (token
->type
== TOKEN_IDENT
)
100 return is_defined(head
, token
, past
);
105 static struct token
*expand_defined(struct token
*head
)
107 return for_each_ident(head
, defined_one_symbol
);
110 /* Expand symbol 'sym' between 'head->next' and 'head->next->next' */
111 static struct token
*expand(struct token
*, struct symbol
*);
113 struct token
*expand_one_symbol(struct token
*head
, struct token
*token
)
115 struct symbol
*sym
= lookup_symbol(token
->ident
, NS_PREPROCESSOR
);
116 if (sym
&& !sym
->busy
) {
117 if (sym
->arglist
&& !match_op(token
->next
, '('))
119 return expand(head
, sym
);
124 static struct token
*expand_list(struct token
*head
)
126 return for_each_ident(head
, expand_one_symbol
);
129 static struct token
*find_argument_end(struct token
*start
)
133 while (!eof_token(start
)) {
134 struct token
*next
= start
->next
;
135 if (match_op(next
, '('))
137 else if (match_op(next
, ')')) {
139 start
->next
= &eof_token_entry
;
142 } else if (!nesting
&& match_op(next
, ','))
143 next
->special
= SPECIAL_ARG_SEPARATOR
;
149 static struct token
*dup_token(struct token
*token
, struct token
*pos
, int newline
)
151 struct token
*alloc
= alloc_token(pos
);
152 alloc
->type
= token
->type
;
153 alloc
->line
= pos
->line
;
154 alloc
->newline
= newline
;
155 alloc
->integer
= token
->integer
;
159 static void insert(struct token
*token
, struct token
*prev
)
161 token
->next
= prev
->next
;
165 static struct token
* replace(struct token
*token
, struct token
*prev
, struct token
*list
)
167 int newline
= token
->newline
;
169 prev
->next
= token
->next
;
170 while (!eof_token(list
) && !match_op(list
, SPECIAL_ARG_SEPARATOR
)) {
171 struct token
*newtok
= dup_token(list
, token
, newline
);
173 insert(newtok
, prev
);
180 static struct token
*get_argument(int nr
, struct token
*args
)
184 while (!eof_token(args
)) {
185 if (match_op(args
, SPECIAL_ARG_SEPARATOR
))
194 static struct token
*stringify(struct token
*token
, struct token
*arg
)
196 const char *s
= show_token_sequence(arg
);
197 int size
= strlen(s
)+1;
198 struct token
*newtoken
= alloc_token(token
);
199 struct string
*string
= __alloc_string(size
);
201 newtoken
->newline
= token
->newline
;
202 memcpy(string
->data
, s
, size
);
203 string
->length
= size
;
204 newtoken
->type
= TOKEN_STRING
;
205 newtoken
->string
= string
;
206 newtoken
->next
= &eof_token_entry
;
210 static int arg_number(struct token
*arglist
, struct ident
*ident
)
214 while (!eof_token(arglist
)) {
215 if (arglist
->ident
== ident
)
218 arglist
= arglist
->next
;
223 static struct token empty_arg_token
= { .type
= TOKEN_EOF
};
225 static struct token
*expand_one_arg(struct token
*head
, struct token
*token
,
226 struct token
*arglist
, struct token
*arguments
)
228 int nr
= arg_number(arglist
, token
->ident
);
229 struct token
*orig_head
= head
;
232 struct token
*arg
= get_argument(nr
, arguments
);
233 struct token
*last
= token
->next
;
234 token
->next
= &eof_token_entry
;
237 * Special case for gcc 'x ## arg' semantics: if 'arg' is empty
238 * then the 'x' goes away too.
240 if (match_op(head
, SPECIAL_HASHHASH
) && eof_token(arg
)) {
241 arg
= &empty_arg_token
;
242 empty_arg_token
.next
= &eof_token_entry
;
245 head
= replace(token
, head
, arg
);
246 if (!match_op(orig_head
, SPECIAL_HASHHASH
) && !match_op(last
, SPECIAL_HASHHASH
) && !match_op(orig_head
, '#'))
247 head
= expand_list(orig_head
);
254 static void expand_arguments(struct token
*token
, struct token
*head
,
255 struct token
*arguments
, struct token
*arglist
)
258 struct token
*next
= head
->next
;
260 /* Did we hit the end of the current expansion? */
264 if (match_op(next
, '#')) {
265 struct token
*nextnext
= next
->next
;
266 int nr
= arg_number(arglist
, nextnext
->ident
);
267 if (nextnext
!= head
&& nr
>= 0 && nextnext
->type
== TOKEN_IDENT
) {
268 struct token
*newtoken
= stringify(nextnext
, get_argument(nr
, arguments
));
269 replace(nextnext
, head
, newtoken
);
272 warn(next
, "'#' operation is not followed by argument name");
275 if (next
->type
== TOKEN_IDENT
)
276 next
= expand_one_arg(head
, next
, arglist
, arguments
);
283 * Possibly valid combinations:
284 * - anything + 'empty_arg_token' is empty.
285 * - ident + ident - combine (==ident)
286 * - ident + number - combine (==ident)
287 * - number + number - combine (==number)
288 * - number + ident - combine (==number)
289 * - string + string - leave as is, C will combine them anyway
290 * others cause an error and leave the two tokens as separate tokens.
292 static struct token
*hashhash(struct token
*head
, struct token
*first
, struct token
*second
)
294 static char buffer
[512], *p
;
295 struct token
*newtoken
;
296 static const char *src
;
299 first
->next
= second
;
302 * Special case for gcc 'x ## arg' semantics: if 'arg' is empty
303 * then the 'x' goes away too.
305 * See expand_one_arg.
307 if (second
->type
== TOKEN_EOF
) {
308 head
->next
= second
->next
;
313 switch (first
->type
) {
315 len
= strlen(first
->integer
);
316 src
= first
->integer
;
319 len
= first
->ident
->len
;
320 src
= first
->ident
->name
;
328 switch (second
->type
) {
330 len
= strlen(second
->integer
);
331 src
= second
->integer
;
334 len
= second
->ident
->len
;
335 src
= second
->ident
->name
;
344 newtoken
= alloc_token(first
);
345 head
->next
= newtoken
;
346 newtoken
->type
= first
->type
;
347 switch (newtoken
->type
) {
349 newtoken
->ident
= built_in_ident(buffer
);
352 newtoken
->integer
= __alloc_bytes(p
- buffer
);
353 memcpy(newtoken
->integer
, buffer
, p
- buffer
);
359 static void retokenize(struct token
*head
)
361 struct token
* next
= head
->next
;
362 struct token
* nextnext
= next
->next
;
363 struct token
* nextnextnext
= nextnext
->next
;
365 if (eof_token(next
) || eof_token(nextnext
))
369 if (eof_token(nextnextnext
))
372 if (match_op(nextnext
, SPECIAL_HASHHASH
)) {
373 struct token
*newtoken
= hashhash(head
, next
, nextnextnext
);
376 nextnext
= nextnextnext
->next
;
377 nextnextnext
= nextnext
->next
;
379 newtoken
->next
= nextnext
;
380 if (!eof_token(nextnext
))
387 nextnext
= nextnext
->next
;
388 nextnextnext
= nextnextnext
->next
;
392 static struct token
*expand(struct token
*head
, struct symbol
*sym
)
394 struct token
*arguments
, *token
, *last
;
402 arguments
= last
->next
;
403 last
= find_argument_end(last
);
405 token
->next
= &eof_token_entry
;
407 /* Replace the token with the token expansion */
408 replace(token
, head
, sym
->expansion
);
410 /* Then, replace all the arguments with their expansions */
412 expand_arguments(token
, head
, arguments
, sym
->arglist
);
414 /* Re-tokenize the sequence if any ## token exists.. */
417 /* Finally, expand the expansion itself .. */
418 head
= expand_list(head
);
420 /* Put the rest of the stuff in place again */
426 static const char *token_name_sequence(struct token
*token
, int endop
, struct token
*start
)
429 static char buffer
[256];
433 while (!eof_token(token
) && !match_op(token
, endop
)) {
435 const char *val
= token
->string
->data
;
436 if (token
->type
!= TOKEN_STRING
)
437 val
= show_token(token
);
439 memcpy(ptr
, val
, len
);
444 if (endop
&& !match_op(token
, endop
))
445 warn(start
, "expected '>' at end of filename");
449 static void do_include(struct token
*head
, struct token
*token
, const char *filename
)
451 int endlen
= strlen(filename
) + 1;
452 char **pptr
= includepath
, *path
;
454 while ((path
= *pptr
++) != NULL
) {
455 int fd
, len
= strlen(path
);
456 static char fullname
[PATH_MAX
];
458 memcpy(fullname
, path
, len
);
459 memcpy(fullname
+len
, filename
, endlen
);
460 fd
= open(fullname
, O_RDONLY
);
462 char * streamname
= __alloc_bytes(len
+ endlen
);
463 memcpy(streamname
, fullname
, len
+ endlen
);
464 head
->next
= tokenize(streamname
, fd
, head
->next
);
469 warn(token
, "unable to open '%s'", filename
);
472 static int handle_include(struct stream
*stream
, struct token
*head
, struct token
*token
)
474 const char *filename
;
478 if (stream
->constant
== -1)
479 stream
->constant
= 0;
484 if (!match_op(next
, '<')) {
490 filename
= token_name_sequence(token
, expect
, token
);
491 do_include(head
, token
, filename
);
495 static int token_list_different(struct token
*list1
, struct token
*list2
)
500 if (!list1
|| !list2
)
502 if (list1
->type
!= list2
->type
)
510 static int handle_define(struct stream
*stream
, struct token
*head
, struct token
*token
)
512 struct token
*arglist
, *expansion
;
513 struct token
*left
= token
->next
;
517 if (left
->type
!= TOKEN_IDENT
) {
518 warn(head
, "expected identifier to 'define'");
526 expansion
= left
->next
;
527 if (!expansion
->whitespace
&& match_op(expansion
, '(')) {
529 while (!eof_token(expansion
)) {
530 struct token
*next
= expansion
->next
;
531 if (match_op(next
, ')')) {
532 // Terminate the arglist
533 expansion
->next
= &eof_token_entry
;
534 expansion
= next
->next
;
537 if (match_op(next
, ','))
538 expansion
->next
= next
->next
;
541 arglist
= arglist
->next
;
544 sym
= lookup_symbol(name
, NS_PREPROCESSOR
);
546 if (token_list_different(sym
->expansion
, expansion
) ||
547 token_list_different(sym
->arglist
, arglist
)) {
548 warn(left
, "preprocessor token redefined");
549 warn(sym
->token
, "this was the original definition");
553 sym
= alloc_symbol(left
, SYM_NONE
);
554 bind_symbol(sym
, name
, NS_PREPROCESSOR
);
556 sym
->expansion
= expansion
;
557 sym
->arglist
= arglist
;
561 static int handle_undef(struct stream
*stream
, struct token
*head
, struct token
*token
)
563 struct token
*left
= token
->next
;
566 if (left
->type
!= TOKEN_IDENT
) {
567 warn(head
, "expected identifier to 'undef'");
572 sym
= &left
->ident
->symbols
;
574 struct symbol
*t
= *sym
;
575 if (t
->namespace == NS_PREPROCESSOR
) {
584 static int preprocessor_if(struct token
*token
, int true)
587 unmatched_if
= token
;
588 elif_ignore
[if_nesting
] = false_nesting
|| true;
589 if (false_nesting
|| !true) {
597 static int token_defined(struct token
*token
)
599 if (token
->type
== TOKEN_IDENT
)
600 return lookup_symbol(token
->ident
, NS_PREPROCESSOR
) != NULL
;
602 warn(token
, "expected identifier for #if[n]def");
606 static int handle_ifdef(struct stream
*stream
, struct token
*head
, struct token
*token
)
608 return preprocessor_if(token
, token_defined(token
->next
));
611 static int handle_ifndef(struct stream
*stream
, struct token
*head
, struct token
*token
)
613 struct token
*next
= token
->next
;
614 if (stream
->constant
== -1) {
616 if (next
->type
== TOKEN_IDENT
) {
617 if (!stream
->protect
|| stream
->protect
== next
->ident
) {
619 stream
->protect
= next
->ident
;
620 stream
->nesting
= if_nesting
+1;
623 stream
->constant
= newconstant
;
625 return preprocessor_if(token
, !token_defined(next
));
628 static int expression_value(struct token
*head
)
630 struct expression
*expr
;
634 expand_defined(head
);
636 token
= constant_expression(head
->next
, &expr
);
637 if (!eof_token(token
))
638 warn(token
, "garbage at end: %s", show_token_sequence(token
));
639 value
= get_expression_value(expr
);
643 static int handle_if(struct stream
*stream
, struct token
*head
, struct token
*token
)
647 value
= expression_value(token
);
648 return preprocessor_if(token
, value
);
651 static int handle_elif(struct stream
* stream
, struct token
*head
, struct token
*token
)
653 if (stream
->nesting
== if_nesting
)
654 stream
->constant
= 0;
656 /* If this whole if-thing is if'ed out, an elif cannot help */
657 if (elif_ignore
[if_nesting
-1])
659 if (expression_value(token
)) {
662 elif_ignore
[if_nesting
-1] = 1;
671 warn(token
, "unmatched '#elif'");
675 static int handle_else(struct stream
*stream
, struct token
*head
, struct token
*token
)
677 if (stream
->nesting
== if_nesting
)
678 stream
->constant
= 0;
680 /* If this whole if-thing is if'ed out, an else cannot help */
681 if (elif_ignore
[if_nesting
-1])
685 elif_ignore
[if_nesting
-1] = 1;
693 warn(token
, "unmatched #else");
697 static int handle_endif(struct stream
*stream
, struct token
*head
, struct token
*token
)
699 if (stream
->constant
== -2 && stream
->nesting
== if_nesting
)
700 stream
->constant
= -1;
710 warn(token
, "unmatched #endif");
714 static const char *show_token_sequence(struct token
*token
)
716 static char buffer
[256];
722 while (!eof_token(token
) && !match_op(token
, SPECIAL_ARG_SEPARATOR
)) {
723 const char *val
= show_token(token
);
724 int len
= strlen(val
);
727 memcpy(ptr
, val
, len
);
730 whitespace
= token
->whitespace
;
736 static int handle_warning(struct stream
*stream
, struct token
*head
, struct token
*token
)
740 warn(token
, "%s", show_token_sequence(token
->next
));
744 static int handle_error(struct stream
*stream
, struct token
*head
, struct token
*token
)
748 error(token
, "%s", show_token_sequence(token
->next
));
752 static int handle_preprocessor_command(struct stream
*stream
, struct token
*head
, struct ident
*ident
, struct token
*token
)
757 int (*handler
)(struct stream
*, struct token
*, struct token
*);
759 { "define", handle_define
},
760 { "undef", handle_undef
},
761 { "ifdef", handle_ifdef
},
762 { "ifndef", handle_ifndef
},
763 { "else", handle_else
},
764 { "endif", handle_endif
},
766 { "elif", handle_elif
},
767 { "warning", handle_warning
},
768 { "error", handle_error
},
769 { "include", handle_include
},
772 for (i
= 0; i
< (sizeof (handlers
) / sizeof (handlers
[0])); i
++) {
773 if (match_string_ident(ident
, handlers
[i
].name
))
774 return handlers
[i
].handler(stream
, head
, token
);
779 static void handle_preprocessor_line(struct stream
*stream
, struct token
* head
, struct token
*token
)
784 if (token
->type
== TOKEN_IDENT
)
785 if (handle_preprocessor_command(stream
, head
, token
->ident
, token
))
787 warn(token
, "unrecognized preprocessor line '%s'", show_token_sequence(token
));
790 static void preprocessor_line(struct stream
*stream
, struct token
* head
)
792 struct token
*start
= head
->next
, *next
;
793 struct token
**tp
= &start
->next
;
802 *tp
= &eof_token_entry
;
803 handle_preprocessor_line(stream
, head
, start
->next
);
806 static void do_preprocess(struct token
*head
)
809 struct token
*next
= head
->next
;
810 struct stream
*stream
= input_streams
+ next
->stream
;
812 if (next
->newline
&& match_op(next
, '#')) {
813 preprocessor_line(stream
, head
);
818 head
->next
= next
->next
;
822 switch (next
->type
) {
823 case TOKEN_STREAMEND
:
824 if (stream
->constant
== -1 && stream
->protect
) {
825 stream
->constant
= 1;
828 case TOKEN_STREAMBEGIN
:
829 head
->next
= next
->next
;
833 next
= expand_one_symbol(head
, next
);
837 * Any token expansion (even if it ended up being an
838 * empty expansion) in this stream implies it can't
841 stream
->constant
= 0;
845 } while (!eof_token(head
));
848 struct token
* preprocess(struct token
*token
)
850 struct token header
= { 0, };
853 do_preprocess(&header
);
855 warn(unmatched_if
, "unmatched preprocessor conditional");
857 // Drop all expressions from pre-processing, they're not used any more.
858 clear_expression_alloc();