11 #define CPP_DEBUG 0 /* LOTS of junk to stderr. */
14 * This file comprises the 'guts' of a C preprocessor.
16 * Functions exported from this file:
17 * gettok() Returns the next token from the source
18 * curword contains the text of the token
21 * curword Contains the text of the last token parsed.
22 * curfile Currently open primary file
23 * c_fname Name of file being parsed
24 * c_lineno Current line number in file being parsed.
26 * alltok Control flag for the kind of tokens you want (C or generic)
27 * dialect Control flag to change the preprocessor for Ansi C.
30 * #asm -> asm("...") translation.
31 * ?: in #if expressions
32 * Complete #line directive.
33 * \n in "\n" in a stringized argument.
34 * Comments in stringized arguments should be deleted.
36 * Poss: Seperate current directory for #include from errors (#line).
37 * (For editors that hunt down source files)
38 * Poss: C99 Variable macro args.
47 char curword
[WORDSIZE
];
56 typedef long int_type
; /* Used for preprocessor expressions */
58 typedef int int_type
; /* Used for preprocessor expressions */
60 static int curtok
= 0; /* Used for preprocessor expressions */
62 static int fi_count
= 0;
63 static FILE * saved_files
[MAX_INCLUDE
];
64 static char * saved_fname
[MAX_INCLUDE
];
65 static int saved_lines
[MAX_INCLUDE
];
67 static char * def_ptr
= 0;
68 static char * def_start
= 0;
69 static struct define_item
* def_ref
= 0;
71 static int def_count
=0;
72 static char * saved_def
[MAX_DEFINE
];
73 static char * saved_start
[MAX_DEFINE
];
74 static long saved_unputc
[MAX_DEFINE
];
75 static struct define_item
* saved_ref
[MAX_DEFINE
];
77 static long unputc
= 0;
79 static int last_char
= '\n';
80 static int in_preproc
= 0;
81 static int dont_subst
= 0;
82 static int quoted_str
= 0;
84 static int if_count
= 0;
85 static int if_false
= 0;
86 static int if_has_else
= 0;
87 static int if_hidden
= 0;
88 static unsigned int if_stack
= 0;
96 static int chget
P((void));
97 static int chget_raw
P((void));
98 static void unchget
P((int));
99 static int gettok_nosub
P((void));
100 static int get_onetok
P((int));
101 static int pgetc
P((void));
102 static int do_preproc
P((void));
103 static int do_proc_copy_hashline
P((void));
104 static int do_proc_if
P((int));
105 static void do_proc_include
P((void));
106 static void do_proc_define
P((void));
107 static void do_proc_undef
P((void));
108 static void do_proc_else
P((void));
109 static void do_proc_endif
P((void));
110 static void do_proc_tail
P((void));
111 static int get_if_expression
P((void));
112 static int_type get_expression
P((int));
113 static int_type get_exp_value
P((void));
114 static void gen_substrings
P((char *, char *, int, int));
115 static char * insert_substrings
P((char *, struct arg_store
*, int));
124 /* Tokenised C-Preprocessing */
128 ch
= get_onetok(KEEP_SPACE
);
130 ch
= get_onetok(SKIP_SPACE
);
132 if( ch
== '"' || ch
== '\'' )
137 struct token_trans
*p
= is_ckey(curword
, strlen(curword
)) ;
142 if (ch
== '\n') continue;
146 /* Special for quoted strings */
149 if( ch
== EOF
) return ch
;
154 if( ch
== quoted_str
) {
157 if (dialect
== DI_ANSI
) {
158 /* Found a terminator '"' check for ansi continuation */
159 while( (ch
= pgetc()) <= ' ' && ch
!= EOF
) ;
160 if( ch
== '"' ) continue;
175 unchget(ch
); /* Make sure error line is right */
180 ch
= get_onetok(KEEP_SPACE
);
189 { int rv
; dont_subst
++; rv
=get_onetok(SKIP_SPACE
); dont_subst
--; return rv
; }
203 /* First skip whitespace, if the arg says so then we need to keep it */
204 while( (ch
= pgetc()) == ' ' || ch
== '\t' )
206 if (keep
== KEEP_SPACE
) {
207 if( p
< curword
+ WORDSIZE
-1 ) {
208 *p
++ = ch
; /* Clip to WORDSIZE */
214 if( ch
> 0xFF ) return ch
;
215 if( p
!= curword
) { unchget(ch
); return TK_WSPACE
; }
216 if( ch
== '\n') return ch
;
217 if( ch
== EOF
) return ch
;
218 if( ch
>= 0 && ch
< ' ' ) goto Try_again
;
224 case 0: if( (ch
>= 'A' && ch
<= 'Z')
225 || (ch
>= 'a' && ch
<= 'z')
226 || ch
== '_' || ch
== '$' )
230 else if(ch
>= '1' && ch
<= '9')
235 case 1: if( (ch
>= '0' && ch
<= '9')
236 || (ch
>= 'A' && ch
<= 'Z')
237 || (ch
>= 'a' && ch
<= 'z')
238 || ch
== '_' || ch
== '$' )
242 case 2: if( ch
>= '0' && ch
<= '7')
244 else if( ch
== 'x' || ch
== 'X' )
249 case 3: if( ch
>= '0' && ch
<= '7')
253 case 4: if( (ch
>= '0' && ch
<= '9')
254 || (ch
>= 'A' && ch
<= 'F')
255 || (ch
>= 'a' && ch
<= 'f') )
260 case 6: if( ch
>= '0' && ch
<= '9')
262 else if( ch
== '.' && state
!= 6 )
264 else if( ch
== 'e' || ch
== 'E' )
269 case 7: if( ch
== '+' || ch
== '-' )
273 case 8: if( ch
>= '0' && ch
<= '9')
278 if( cc
< WORDSIZE
-1 ) *p
++ = ch
; /* Clip to WORDSIZE */
281 if (ch
== SYN
) ch
= chget();
289 if( ch
== 'u' || ch
== 'U' )
291 if( cc
< WORDSIZE
-1 ) *p
++ = ch
; /* Clip to WORDSIZE */
295 if( ch
== 'l' || ch
== 'L' )
297 if( cc
< WORDSIZE
-1 ) *p
++ = ch
; /* Clip to WORDSIZE */
310 struct define_item
* ptr
;
313 && (ptr
= read_entry(0, curword
)) != 0
317 if ( def_count
>= MAX_DEFINE
) {
318 cwarn("Preprocessor recursion overflow");
320 } else if( ptr
->arg_count
>= 0 )
322 /* An open bracket must follow the word */
324 while ((ch
= chget()) == ' ' || ch
== '\t' ) ch1
= ch
;
327 if (ch1
) unchget(ch1
);
331 /* We have arguments to process so lets do so. */
332 gen_substrings(ptr
->name
, ptr
->value
, ptr
->arg_count
, ptr
->varargs
);
334 /* Don't mark macros with arguments as in use, it's very
335 * difficult to say what the correct result would be so
336 * I'm letting the error happen. Also if I do block
337 * recursion then it'll also block 'pseudo' recursion
338 * where the arguments have a call to this macro.
344 else if (ptr
->value
[0])
346 /* Simple direct substitution; note the shortcut (above) for
347 * macros that are defined as null */
348 saved_ref
[def_count
] = def_ref
;
349 saved_def
[def_count
] = def_ptr
;
350 saved_start
[def_count
] = def_start
;
351 saved_unputc
[def_count
] = unputc
;
355 def_ptr
= ptr
->value
;
364 /* Quoted char for preprocessor expressions */
365 if(in_preproc
&& ch
== '\'' )
367 *p
++ = ch
; ch
= chget();
370 if( cc
< WORDSIZE
-1 ) *p
++ = ch
; /* Clip to WORDSIZE */
372 if( ch
== '\'' || ch
== '\n' ) break;
377 if( cc
< WORDSIZE
-1 ) *p
++ = ch
; /* Clip to WORDSIZE */
385 /* Collect and translate \xyx strings, (should probably translate these
386 * all to some standard form (eg \ooo plus \N )
388 * ___________________________________________________________________
389 * | new-line NL (LF) \n| audible alert BEL \a |
390 * | horizontal tab HT \t| question mark ? \? |
391 * | vertical tab VT \v| double quote " \" |
392 * | backspace BS \b| octal escape ooo \ooo|
393 * | carriage return CR \r| hexadecimal escape hh \xhh|
394 * | formfeed FF \f| backslash \ \\ |
395 * | single quote ' \'| |
396 * |_______________________________|_________________________________|
403 *p
++ = ch
; ch
= chget();
404 if (ch
>= '0' && ch
<= '7' ) {
406 if (ch
>= '0' && ch
<= '7' ) {
407 *p
++ = ch
; ch
= chget();
411 } else if (ch
== 'x' || ch
== 'X') {
412 *p
++ = ch
; ch
= chget();
414 if ( (ch
>= '0' && ch
<= '9' ) ||
415 (ch
>= 'A' && ch
<= 'F' ) ||
416 (ch
>= 'a' && ch
<= 'f' ) ) {
417 *p
++ = ch
; ch
= chget();
421 } else if (ch
== '?') {
423 } else if (ch
!= '\n' && ch
!= EOF
) {
431 /* Possible composite tokens */
432 if( ch
> ' ' && ch
<= '~' )
434 struct token_trans
*p
;
437 for(state
=1; ; state
++)
439 curword
[state
] = ch
= chget();
440 if( !(p
=is_ctok(curword
, state
+1)) )
443 curword
[state
] = '\0';
459 if ((ch
= chget()) == EOF
) return ch
;
461 if( !in_preproc
&& last_char
== '\n' && ch
== '#' )
466 if(if_false
|| ch
== 0) continue;
471 if( last_char
!= '\n' || (ch
!= ' ' && ch
!= '\t') )
474 /* Remove comments ... */
476 { if(if_false
&& !in_preproc
) continue; return ch
; }
477 ch1
= chget(); /* Allow "/\\\n*" as comment start too!? */
479 if( ch1
== '/' ) /* Double slash style comments */
481 do { ch
= chget(); } while(ch
!= '\n' && ch
!= EOF
);
482 return ch
; /* Keep the return. */
488 if(if_false
&& !in_preproc
) continue;
497 if( ch
== EOF
) return EOF
;
498 if( ch
== '/' ) break;
502 if (dialect
== DI_ANSI
)
503 return ' '; /* If comments become " " */
504 else return SYN
; /* Comments become nulls, but we need a
505 * marker so I can do token concat properly. */
509 /* This function handles the first and second translation phases of Ansi-C */
518 if (ch1
== '\n') continue;
522 /* Ansi trigraphs -- Ewww, it needs lots of 'unchget' space too. */
523 if (dialect
== DI_ANSI
&& ch
== '?') {
528 static char trig1
[] = "()<>/!'-=";
529 static char trig2
[] = "[]{}\\|^~#";
532 s
= strchr(trig1
, ch1
);
534 unchget(trig2
[s
-trig1
]); /* Unchget so that ??/ can be used as */
535 continue; /* a real backslash at EOL. */
551 fprintf(stderr
, "\b", ch
);
553 if(ch
== 0) return; /* Hummm */
554 if(ch
== EOF
) ch
=EOT
; /* EOF is pushed back as a normal character. */
557 if(unputc
&0xFF000000)
558 cerror("Internal character pushback stack overflow");
559 else unputc
= (unputc
<<8) + (ch
);
560 if( ch
== '\n' ) c_lineno
--;
568 static int last_def
= 0;
569 static int last_fi
= 0;
570 if (last_fi
!= fi_count
) fprintf(stderr
, "<INC%d>", fi_count
);
571 if (last_def
!= def_count
) fprintf(stderr
, "<DEF%d>", def_count
);
572 last_def
= def_count
; last_fi
= fi_count
;
575 if (ch
== EOF
) fprintf(stderr
, "<EOF>"); else fprintf(stderr
, "%c", ch
);
577 if (last_def
!= def_count
) fprintf(stderr
, "<DEF%d>", def_count
);
578 if (last_fi
!= fi_count
) fprintf(stderr
, "<INC%d>", fi_count
);
579 last_def
= def_count
; last_fi
= fi_count
;
593 if((unputc
&0xFF)==EOT
&& in_preproc
) return '\n';
594 ch
=(unputc
&0xFF); unputc
>>=8;
595 if( ch
== EOT
) ch
= EOF
;
596 if( ch
== '\n' ) c_lineno
++;
602 ch
= *def_ptr
++; if(ch
) return (unsigned char)ch
;
603 if( def_start
) free(def_start
);
604 if( def_ref
) def_ref
->in_use
= 0;
607 def_ref
= saved_ref
[def_count
];
608 def_ptr
= saved_def
[def_count
];
609 def_start
= saved_start
[def_count
];
610 unputc
= saved_unputc
[def_count
];
615 if( ch
== EOF
&& fi_count
!= 0)
619 curfile
= saved_files
[fi_count
];
620 if(c_fname
) free(c_fname
);
621 c_fname
= saved_fname
[fi_count
];
622 c_lineno
= saved_lines
[fi_count
];
623 ch
= '\n'; /* Ensure end of line on end of file */
625 else if( ch
== '\n' ) c_lineno
++;
627 /* Treat all control characters, except the standard whitespace
628 * characters of TAB and NL as completely invisible.
630 if( ch
>= 0 && ch
< ' ' && ch
!='\n' && ch
!='\t' && ch
!=EOF
) continue;
632 if( ch
== EOF
) { unchget(ch
); return '\n'; } /* Ensure EOL before EOF */
633 return (unsigned char)ch
;
642 if( (val
=get_onetok(SKIP_SPACE
)) == TK_WORD
)
644 if( strcmp(curword
, "ifdef") == 0 )
646 else if( strcmp(curword
, "ifndef") == 0 )
648 else if( strcmp(curword
, "if") == 0 )
650 else if( strcmp(curword
, "elif") == 0 )
652 else if( strcmp(curword
, "else") == 0 )
654 else if( strcmp(curword
, "endif") == 0 )
660 if( strcmp(curword
, "include") == 0 )
662 else if( strcmp(curword
, "define") == 0 )
664 else if( strcmp(curword
, "undef") == 0 )
666 else if( strcmp(curword
, "error") == 0 ) {
667 strcpy(curword
, "#error");
668 do_proc_copy_hashline(); pgetc();
670 } else if( strcmp(curword
, "warning") == 0 ) {
671 strcpy(curword
, "#warning");
672 do_proc_copy_hashline(); pgetc();
674 } else if( strcmp(curword
, "pragma") == 0 ) {
675 do_proc_copy_hashline(); pgetc();
676 /* Ignore #pragma ? */
677 } else if( strcmp(curword
, "line") == 0 ) {
678 do_proc_copy_hashline(); pgetc();
679 /* Ignore #line for now. */
680 } else if( strcmp(curword
, "asm") == 0 ) {
682 return do_proc_copy_hashline();
683 } else if( strcmp(curword
, "endasm") == 0 ) {
685 return do_proc_copy_hashline();
694 if(!if_false
) cerror("Unknown preprocessor directive");
695 while( val
!= '\n' ) val
= pgetc();
698 *curword
= 0; /* Just in case */
703 do_proc_copy_hashline()
707 off
= strlen(curword
);
709 while( (ch
=pgetc()) != '\n' )
711 if( off
< WORDSIZE
) curword
[off
++] = ch
;
713 if( off
== WORDSIZE
)
715 cerror("Preprocessor directive too long");
716 curword
[WORDSIZE
-1] = '\0';
732 ch
= get_onetok(SKIP_SPACE
);
733 if( ch
== '<' || ch
== '"' )
735 if( ch
== '"' ) ch1
= ch
; else ch1
= '>';
737 while(p
< curword
+WORDSIZE
-1)
740 if( ch
== '\n' ) break;
746 do { ch1
= pgetc(); } while(ch1
== ' ' || ch1
== '\t');
750 saved_files
[fi_count
] = curfile
;
751 saved_fname
[fi_count
] = c_fname
;
752 saved_lines
[fi_count
] = c_lineno
;
754 fd
= open_include(p
, "r", (ch
=='"'));
759 cerror("Cannot open include file");
766 cerror("Bad #include command");
767 while(ch
!= '\n') ch
= pgetc();
775 struct define_item
* ptr
, * old_value
= 0;
779 if( (ch
=gettok_nosub()) == TK_WORD
)
781 strcpy(name
, curword
);
782 ptr
= read_entry(0, name
);
785 set_entry(0, name
, (void*)0); /* Unset var */
787 /* Eeeek! This shouldn't happen; so just let it leak. */
788 cwarn("macro redefined while it was in use!?");
794 for(ch
=ch1
=pgetc(); ch
== ' ' || ch
== '\t' ; ch
=pgetc()) ;
797 ptr
= malloc(sizeof(struct define_item
) + WORDSIZE
);
798 if(ptr
==0) cfatal("Preprocessor out of memory");
799 ptr
->value
[cc
=0] = '\0';
801 /* Add in arguments */
808 if( ptr
->arg_count
==0 && ch
== ')' ) break;
811 if( cc
+strlen(curword
)+4 >= len
)
814 ptr
= (struct define_item
*) realloc(ptr
, sizeof(struct define_item
) + len
);
815 if(ptr
==0) cfatal("Preprocessor out of memory");
817 if( cc
+strlen(curword
) < len
)
819 strcpy(ptr
->value
+cc
, curword
);
821 strcpy(ptr
->value
+cc
, ",");
825 if( ch
== TK_ELLIPSIS
) {
828 if (ch
== ',') ch
= '*'; /* Force error if not ')' */
830 if( ch
== ')' ) break;
831 if( ch
== ',' ) continue;
834 cerror("Bad #define command");
836 while(ch
!= '\n') ch
= pgetc();
837 set_entry(0, name
, (void*)old_value
); /* Return var to old. */
840 while((ch
=pgetc())==' ' || ch
=='\t');
842 else ptr
->arg_count
= -1;
844 /* And the substitution string */
850 ptr
= (struct define_item
*) realloc(ptr
, sizeof(struct define_item
) + len
);
851 if(ptr
==0) cfatal("Preprocessor out of memory");
853 ptr
->value
[cc
++] = ch
;
857 ptr
->value
[cc
++] = ' ';/* Byte of lookahead for recursive macros */
858 ptr
->value
[cc
++] = '\0';
862 fprintf(stderr
, "\n### Define '%s' as null\n", name
);
863 else if (ptr
->arg_count
<0)
864 fprintf(stderr
, "\n### Define '%s' as '%s'\n",
867 fprintf(stderr
, "\n### Define '%s' as %d args '%s'\n",
868 name
, ptr
->arg_count
, ptr
->value
);
871 /* Clip to correct size and save */
872 ptr
= (struct define_item
*) realloc(ptr
, sizeof(struct define_item
) + cc
);
873 ptr
->name
= set_entry(0, name
, ptr
);
878 if (strcmp(old_value
->value
, ptr
->value
) != 0)
879 cwarn("#define redefined macro");
883 else cerror("Bad #define command");
884 while(ch
!= '\n') ch
= pgetc();
891 struct define_item
* ptr
;
892 if( (ch
=gettok_nosub()) == TK_WORD
)
894 ptr
= read_entry(0, curword
);
897 set_entry(0, curword
, (void*)0); /* Unset var */
899 /* Eeeek! This shouldn't happen; so just let it leak. */
900 cwarn("macro undefined while it was in use!?");
908 cerror("Bad #undef command");
909 while(ch
!= '\n') ch
= pgetc();
918 if(if_false
&& if_hidden
)
920 if( type
!= 3 ) if_hidden
++;
928 cerror("#elif without matching #if");
932 cerror("#elif following #else for one #if");
933 if( if_has_else
|| if_false
!= 1 )
936 while(ch
!= '\n') ch
= pgetc();
945 if( type
!= 3 ) if_hidden
++;
954 if_stack
|= if_has_else
;
959 ch
= get_if_expression();
968 if_false
= (read_entry(0, curword
) == 0);
969 if(type
== 1) if_false
= !if_false
;
973 cerror("Bad #if command");
975 while(ch
!= '\n') ch
= pgetc();
988 cerror("#else without matching #if");
990 if_false
= (if_false
^1);
992 cerror("Multiple #else's for one #if");
1006 cerror("Unmatched #endif");
1011 if_has_else
= (if_stack
&1);
1022 while((ch
= pgetc()) != '\n') if(ch
> ' ')
1024 if (!if_false
&& flg
)
1025 cwarn("Unexpected text following preprocessor command");
1033 int value
= get_expression(0);
1042 get_expression(prio
)
1049 curtok
= get_onetok(SKIP_SPACE
);
1050 lvalue
= get_exp_value();
1056 case '*': case '/': case '%':
1057 if (prio
>= 10) return lvalue
;
1060 if (prio
>= 9) return lvalue
;
1062 case TK_RIGHT_OP
: case TK_LEFT_OP
:
1063 if (prio
>= 8) return lvalue
;
1065 case '<': case '>': case TK_LE_OP
: case TK_GE_OP
:
1066 if (prio
>= 7) return lvalue
;
1068 case TK_EQ_OP
: case TK_NE_OP
:
1069 if (prio
>= 6) return lvalue
;
1072 if (prio
>= 5) return lvalue
;
1075 if (prio
>= 4) return lvalue
;
1078 if (prio
>= 3) return lvalue
;
1081 if (prio
>= 2) return lvalue
;
1084 if (prio
>= 1) return lvalue
;
1090 rvalue
= get_expression(10);
1094 rvalue
= get_expression(10);
1099 rvalue
= get_expression(10);
1104 rvalue
= get_expression(9);
1108 rvalue
= get_expression(9);
1112 rvalue
= get_expression(8);
1116 rvalue
= get_expression(8);
1120 rvalue
= get_expression(7);
1121 lvalue
= (lvalue
< rvalue
);
1124 rvalue
= get_expression(7);
1125 lvalue
= (lvalue
> rvalue
);
1128 rvalue
= get_expression(7);
1129 lvalue
= (lvalue
<= rvalue
);
1132 rvalue
= get_expression(7);
1133 lvalue
= (lvalue
>= rvalue
);
1136 rvalue
= get_expression(6);
1137 lvalue
= (lvalue
== rvalue
);
1140 rvalue
= get_expression(6);
1141 lvalue
= (lvalue
!= rvalue
);
1144 rvalue
= get_expression(5);
1145 lvalue
= (lvalue
& rvalue
);
1148 rvalue
= get_expression(4);
1149 lvalue
= (lvalue
^ rvalue
);
1152 rvalue
= get_expression(3);
1153 lvalue
= (lvalue
| rvalue
);
1156 rvalue
= get_expression(2);
1157 lvalue
= (lvalue
&& rvalue
);
1160 rvalue
= get_expression(1);
1161 lvalue
= (lvalue
|| rvalue
);
1164 case '?': /* XXX: To add */
1170 while(prio
== 0 && !no_op
);
1181 if (curtok
== '!') {
1182 curtok
= get_onetok(SKIP_SPACE
);
1183 return !get_exp_value();
1185 if (curtok
== '~') {
1186 curtok
= get_onetok(SKIP_SPACE
);
1187 return ~get_exp_value();
1190 while (curtok
== '+' || curtok
== '-') {
1191 if (curtok
== '-') sign
= -sign
;
1192 curtok
= get_onetok(SKIP_SPACE
);
1195 if (curtok
== TK_NUM
) {
1196 value
= strtoul(curword
, (void*)0, 0);
1197 curtok
= get_onetok(SKIP_SPACE
);
1198 } else if (curtok
== TK_QUOT
) {
1200 if (value
== '\\') {
1201 if (curword
[2] >= '0' && curword
[2] <= '7') {
1202 value
= curword
[2] - '0';
1203 if (curword
[3] >= '0' && curword
[3] <= '7') {
1204 value
= (value
<<3) + curword
[3] - '0';
1205 if (curword
[4] >= '0' && curword
[4] <= '7') {
1206 value
= (value
<<3) + curword
[4] - '0';
1209 } else switch(curword
[2]) {
1210 case 'n': value
= '\n'; break;
1211 case 'f': value
= '\f'; break;
1212 case 't': value
= '\t'; break;
1213 default: value
= curword
[2]; break;
1217 value
= (char) value
; /* Fix range */
1219 value
= (signed char) value
;
1221 value
= (unsigned char) value
;
1223 curtok
= get_onetok(SKIP_SPACE
);
1224 } else if (curtok
== TK_WORD
) {
1226 if (strcmp("defined", curword
) == 0) {
1227 curtok
= gettok_nosub();
1228 if (curtok
== '(' && gettok_nosub() != TK_WORD
)
1229 cerror("'defined' keyword requires argument");
1231 value
= (read_entry(0, curword
) != 0);
1232 if (curtok
== '(' && gettok_nosub() != ')')
1233 cerror("'defined' keyword requires closing ')'");
1235 curtok
= get_onetok(SKIP_SPACE
);
1239 curtok
= get_onetok(SKIP_SPACE
);
1241 } else if (curtok
== '(') {
1242 value
= get_expression(0);
1244 curtok
= get_onetok(SKIP_SPACE
);
1247 cerror("Expected ')'");
1251 return sign
<0 ? -value
: value
;
1255 gen_substrings(macname
, data_str
, arg_count
, is_vararg
)
1261 char * mac_text
= 0;
1262 struct arg_store
*arg_list
;
1263 int ac
, ch
, cc
, len
;
1265 int paren_count
= 0;
1268 int commas_found
= 0;
1271 arg_list
= malloc(sizeof(struct arg_store
) * arg_count
);
1272 memset(arg_list
, 0, sizeof(struct arg_store
) * arg_count
);
1274 for(ac
=0; *data_str
&& ac
< arg_count
; data_str
++) {
1275 if( *data_str
== ',' ) { ac
++; continue; }
1277 if (arg_list
[ac
].name
== 0) cc
= len
= 0;
1281 arg_list
[ac
].name
= realloc(arg_list
[ac
].name
, len
);
1283 arg_list
[ac
].name
[cc
++] = *data_str
;
1284 arg_list
[ac
].name
[cc
] = '\0';
1288 if ((ch
= chget()) == EOF
) break;
1291 } else if (in_quote
) {
1292 if ( ch
== quote_char
) in_quote
= 0;
1293 if ( ch
== '\\') in_quote
= 2;
1295 if ( ch
== '(' ) paren_count
++;
1296 if ( ch
== '"' || ch
== '\'' ) { in_quote
= 1; quote_char
= ch
; }
1297 if (paren_count
== 0 && ch
== ',' ) {
1299 if (commas_found
< arg_count
)
1303 if (paren_count
== 0) break;
1308 /* Too many args, deal with, or ignore, the rest. */
1309 if (commas_found
>= arg_count
) {
1310 if(arg_count
== 0) continue;
1315 if (arg_list
[ac
].value
== 0) {
1317 arg_list
[ac
].in_define
= def_count
;
1322 arg_list
[ac
].value
= realloc(arg_list
[ac
].value
, len
);
1326 if (ch
== '\n' && cc
>0 && arg_list
[ac
].value
[cc
-1] == '\n' ) {
1331 arg_list
[ac
].value
[cc
++] = ch
;
1332 arg_list
[ac
].value
[cc
] = '\0';
1335 if (commas_found
|| args_found
) args_found
= commas_found
+1;
1337 if( arg_count
== 0 && args_found
!= 0 )
1338 cerror("Arguments given to macro without them.");
1339 else if( !is_vararg
&& arg_count
!= args_found
)
1340 cwarn("Incorrect number of macro arguments");
1342 mac_text
= insert_substrings(data_str
, arg_list
, arg_count
);
1345 * At this point 'mac_text' contains the full expansion of the macro.
1347 * So we could scan this for calls to this macro and if we find one
1348 * that _exactly_ matches this call (including arguments) then we mark
1349 * this call's in_use flag.
1351 * OTOH, it would probably be best to throw away this expansion and
1352 * pretend we never noticed this macro expansion in the first place.
1354 * Still this is mostly academic as the error trapping works and
1355 * recursive macros _with_arguments_ are both rare and unpredictable.
1359 for (ac
=0; ac
<arg_count
; ac
++) {
1360 if (arg_list
[ac
].name
) free(arg_list
[ac
].name
);
1361 if (arg_list
[ac
].value
) free(arg_list
[ac
].value
);
1366 saved_ref
[def_count
] = def_ref
;
1367 saved_def
[def_count
] = def_ptr
;
1368 saved_start
[def_count
] = def_start
;
1369 saved_unputc
[def_count
] = unputc
;
1373 def_start
= mac_text
;
1376 fprintf(stderr
, "\n### <DEF%d='%s'>\n", def_count
, mac_text
);
1381 insert_substrings(data_str
, arg_list
, arg_count
)
1383 struct arg_store
*arg_list
;
1393 int ansi_stringize
= 0;
1396 fprintf(stderr
, "\n### Macro substitution in '%s'\n", data_str
);
1397 for (ac
=0; ac
<arg_count
; ac
++) {
1398 fprintf(stderr
, "### Argument %d (%s) = '%s'\n",
1399 ac
+1, arg_list
[ac
].name
, arg_list
[ac
].value
);
1403 rv
= malloc(4); *rv
= '\0'; len
= 4;
1408 if (dialect
== DI_ANSI
) {
1411 else if (in_quote
) {
1412 if (*data_str
== quote_char
) in_quote
= 0;
1413 if (*data_str
== '\\') in_quote
= 2;
1415 if (*data_str
== '"' || *data_str
== '\'')
1416 { in_quote
= 1; quote_char
= *data_str
; }
1420 if (!in_quote
) for(;;) {
1422 if( (ch
>= '0' && ch
<= '9')
1423 || (ch
>= 'A' && ch
<= 'Z')
1424 || (ch
>= 'a' && ch
<= 'z')
1425 || ch
== '_' || ch
== '$' )
1432 /* Ansi Stringize and concat */
1433 if (*data_str
== '#' && dialect
!= DI_KNR
) {
1434 if (data_str
[1] == '#') {
1435 while(cc
>0 && (rv
[cc
-1] == ' ' || rv
[cc
-1] == '\t'))
1438 while(*data_str
== ' ' || *data_str
== '\t')
1440 if (*data_str
== '\0') { /* Hummm */
1442 cerror("'##' operator at end of macro");
1451 if (ansi_stringize
) {
1453 cerror("'#' operator should be followed by a macro argument name");
1456 /* Other characters ... */
1457 if (cc
+2 > len
) { len
+= 20; rv
= realloc(rv
, len
); }
1458 rv
[cc
++] = *data_str
++;
1461 *p
= '\0'; s
= curword
;
1462 for (ac
=0; ac
<arg_count
; ac
++) {
1463 if (*curword
== arg_list
[ac
].name
[0] &&
1464 strcmp(curword
, arg_list
[ac
].name
) == 0)
1466 s
= arg_list
[ac
].value
;
1467 if (!s
) s
= ""; else
1469 /* Ansi stringize operation, this is very messy! */
1470 if (ansi_stringize
) {
1471 if (arg_list
[ac
].in_define
) {
1472 struct define_item
* ptr
;
1473 if ((ptr
= read_entry(0, s
)) &&
1474 ptr
->arg_count
== -1) {
1480 while(*s
== ' ' || *s
== '\t') s
++;
1482 if (cc
+4 > len
) { len
+= 20; rv
= realloc(rv
, len
); }
1483 if (*s
== '"') rv
[cc
++] = '\\';
1486 while(cc
>0 && (rv
[cc
-1] == ' ' || rv
[cc
-1] == '\t'))
1499 if (ansi_stringize
) {
1501 cerror("'#' operator should be followed by a macro argument name");
1504 if (cc
+2+strlen(s
) > len
) { len
+= strlen(s
)+20; rv
= realloc(rv
, len
); }