12 #define MAXDEFS (1 << 10)
13 #define MACROLEN (1 << 10)
14 #define MAXARGS (1 << 5)
19 char args
[MAXARGS
][NAMELEN
];
25 #define MAXBUFS (1 << 5)
34 static void buf_new(void)
37 bufs
[nbufs
- 1].cur
= cur
;
38 bufs
[nbufs
- 1].len
= len
;
41 die("nomem: MAXBUFS reached!\n");
45 buf
= bufs
[nbufs
- 1].buf
;
48 static void buf_pop(void)
52 cur
= bufs
[nbufs
- 1].cur
;
53 len
= bufs
[nbufs
- 1].len
;
54 buf
= bufs
[nbufs
- 1].buf
;
58 static void include(int fd
)
62 while ((n
= read(fd
, buf
+ len
, BUFSIZE
- len
)) > 0)
68 cpp_define("__STDC__", "");
69 cpp_define("__x86_64__", "");
70 cpp_define("__linux__", "");
74 static void jumpws(void)
76 while (cur
< len
&& isspace(buf
[cur
]))
80 static void read_word(char *dst
)
83 while (cur
< len
&& (isalnum(buf
[cur
]) || buf
[cur
] == '_'))
88 static void jumpcomment(void)
91 if (buf
[cur
] == '*' && buf
[cur
+ 1] == '/') {
98 static void read_tilleol(char *dst
)
100 while (cur
< len
&& isspace(buf
[cur
]) && buf
[cur
] != '\n')
102 while (cur
< len
&& buf
[cur
] != '\n') {
103 if (buf
[cur
] == '\\')
105 else if (buf
[cur
] == '/' && buf
[cur
+ 1] == '*')
113 static char *putstr(char *d
, char *s
)
121 #define MAXLOCS (1 << 10)
123 static char *locs
[MAXLOCS
] = {"/usr/include"};
124 static int nlocs
= 1;
126 void cpp_addpath(char *s
)
131 static int include_find(char *name
, int std
)
135 for (i
= std
? nlocs
- 1 : nlocs
; i
>= 0; i
--) {
140 s
= putstr(s
, locs
[i
]);
144 fd
= open(path
, O_RDONLY
);
151 static void jumpstr(void)
153 if (buf
[cur
] == '\'') {
154 while (cur
< len
&& buf
[++cur
] != '\'')
155 if (buf
[cur
] == '\\')
160 if (buf
[cur
] == '"') {
161 while (cur
< len
&& buf
[++cur
] != '"')
162 if (buf
[cur
] == '\\')
169 static void readarg(char *s
)
173 while (cur
< len
&& (depth
|| buf
[cur
] != ',' && buf
[cur
] != ')')) {
192 if (buf
[cur
] == '/' && buf
[cur
+ 1] == '*')
198 memcpy(s
, buf
+ beg
, cur
- beg
);
202 static int macro_find(char *name
)
205 for (i
= 0; i
< nmacros
; i
++)
206 if (!strcmp(name
, macros
[i
].name
))
211 static int macro_new(char *name
)
214 for (i
= 0; i
< nmacros
; i
++) {
215 if (!strcmp(name
, macros
[i
].name
))
217 if (!*macros
[i
].name
) {
218 strcpy(macros
[i
].name
, name
);
222 if (nmacros
>= MAXDEFS
)
223 die("nomem: MAXDEFS reached!\n");
224 strcpy(macros
[nmacros
++].name
, name
);
228 static void macro_define(void)
233 d
= ¯os
[macro_new(name
)];
235 if (buf
[cur
] == '(') {
238 while (cur
< len
&& buf
[cur
] != ')') {
239 readarg(d
->args
[d
->nargs
++]);
241 if (buf
[cur
++] != ',')
247 read_tilleol(d
->def
);
250 int cpp_read(char *buf
);
252 static char ebuf
[BUFSIZE
];
257 static long evalexpr(void);
259 static int cpp_eval(void)
263 char evalbuf
[BUFSIZE
];
264 read_tilleol(evalbuf
);
266 strcpy(buf
, evalbuf
);
267 len
= strlen(evalbuf
);
272 while (bufid
< nbufs
|| cur
< len
)
273 elen
+= cpp_read(ebuf
+ elen
);
280 static void jumpifs(int jumpelse
)
284 if (buf
[cur
] == '#') {
288 if (!strcmp("else", cmd
))
289 if (!depth
&& !jumpelse
)
291 if (!strcmp("elif", cmd
))
292 if (!depth
&& !jumpelse
&& cpp_eval())
294 if (!strcmp("endif", cmd
)) {
300 if (!strcmp("ifdef", cmd
) || !strcmp("ifndef", cmd
) ||
305 if (buf
[cur
] == '/' && buf
[cur
+ 1] == '*') {
309 if (buf
[cur
] == '\'' || buf
[cur
] == '"') {
317 static void cpp_cmd(void)
322 if (!strcmp("define", cmd
)) {
326 if (!strcmp("undef", cmd
)) {
330 idx
= macro_find(name
);
332 strcpy(macros
[idx
].name
, "");
335 if (!strcmp("ifdef", cmd
) || !strcmp("ifndef", cmd
) ||
336 !strcmp("if", cmd
)) {
340 int not = cmd
[2] == 'n';
342 matched
= not ? macro_find(name
) < 0 :
343 macro_find(name
) >= 0;
345 matched
= cpp_eval();
351 if (!strcmp("else", cmd
) || !strcmp("elif", cmd
)) {
355 if (!strcmp("endif", cmd
))
357 if (!strcmp("include", cmd
)) {
363 e
= strchr(buf
+ cur
+ 1, buf
[cur
] == '"' ? '"' : '>');
364 memcpy(file
, s
, e
- s
);
367 fd
= include_find(file
, *e
== '>');
376 static int macro_arg(struct macro
*m
, char *arg
)
379 for (i
= 0; i
< m
->nargs
; i
++)
380 if (!strcmp(arg
, m
->args
[i
]))
385 static void macro_expand(void)
388 char args
[MAXARGS
][MACROLEN
];
395 m
= ¯os
[macro_find(name
)];
399 len
= strlen(m
->def
);
403 if (buf
[cur
] == '(') {
406 while (cur
< len
&& buf
[cur
] != ')') {
407 readarg(args
[nargs
++]);
419 len
= strlen(m
->def
);
422 if (buf
[cur
] == '/' && buf
[cur
+ 1] == '*') {
426 if (strchr("'\"", buf
[cur
])) {
430 if (isalpha(buf
[cur
]) || buf
[cur
] == '_') {
434 if ((arg
= macro_arg(m
, word
)) != -1) {
435 int len
= cur
- beg
- strlen(word
);
436 char *argstr
= arg
> nargs
? "" : args
[arg
];
437 int arglen
= strlen(argstr
);
438 memcpy(dst
+ dstlen
, buf
+ beg
, len
);
440 memcpy(dst
+ dstlen
, argstr
, arglen
);
448 memcpy(dst
+ dstlen
, buf
+ beg
, len
- beg
);
456 void cpp_define(char *name
, char *def
)
469 static int definedword
;
471 int cpp_read(char *s
)
484 if (buf
[cur
] == '#') {
491 if (buf
[cur
] == '/' && buf
[cur
+ 1] == '*') {
495 if (buf
[cur
] == '\'' || buf
[cur
] == '"') {
499 if (isalpha(buf
[cur
]) || buf
[cur
] == '_') {
502 if (macro_find(word
) != -1) {
507 if (cppeval
&& !strcmp("defined", word
)) {
510 if (buf
[cur
] == '(') {
524 memcpy(s
, buf
+ old
, cur
- old
);
529 /* preprocessor constant expression evaluation */
531 static char etok
[NAMELEN
];
534 static char *tok2
[] = {
535 "<<", ">>", "&&", "||", "==", "!=", "<=", ">="
538 static int eval_tok(void)
542 while (ecur
< elen
) {
543 while (ecur
< elen
&& isspace(ebuf
[ecur
]))
545 if (ebuf
[ecur
] == '/' && ebuf
[ecur
+ 1] == '*') {
546 while (ecur
< elen
&& (ebuf
[ecur
- 2] != '*' ||
547 ebuf
[ecur
- 1] != '/'))
555 if (isalpha(ebuf
[ecur
]) || ebuf
[ecur
] == '_') {
556 while (isalnum(ebuf
[ecur
]) || ebuf
[ecur
] == '_')
561 if (isdigit(ebuf
[ecur
])) {
562 while (isdigit(ebuf
[ecur
]))
564 while (tolower(ebuf
[ecur
]) == 'u' || tolower(ebuf
[ecur
]) == 'l')
568 for (i
= 0; i
< ARRAY_SIZE(tok2
); i
++)
569 if (TOK2(tok2
[i
]) == TOK2(ebuf
+ ecur
)) {
570 int ret
= TOK2(tok2
[i
]);
577 static int eval_see(void)
584 static int eval_get(void)
594 static long eval_num(void)
599 static int eval_jmp(int tok
)
601 if (eval_see() == tok
) {
608 static void eval_expect(int tok
)
613 static char *eval_id(void)
618 static long evalcexpr(void);
620 static long evalatom(void)
622 if (!eval_jmp(TOK_NUM
))
624 if (!eval_jmp(TOK_NAME
)) {
625 int parens
= !eval_jmp('(');
627 eval_expect(TOK_NAME
);
628 ret
= macro_find(eval_id()) >= 0;
633 if (!eval_jmp('(')) {
634 long ret
= evalcexpr();
641 static long evalpre(void)
652 static long evalmul(void)
654 long ret
= evalpre();
656 if (!eval_jmp('*')) {
660 if (!eval_jmp('/')) {
664 if (!eval_jmp('%')) {
673 static long evaladd(void)
675 long ret
= evalmul();
677 if (!eval_jmp('+')) {
681 if (!eval_jmp('-')) {
690 static long evalshift(void)
692 long ret
= evaladd();
694 if (!eval_jmp(TOK2("<<"))) {
698 if (!eval_jmp(TOK2(">>"))) {
707 static long evalcmp(void)
709 long ret
= evalshift();
711 if (!eval_jmp('<')) {
712 ret
= ret
< evalshift();
715 if (!eval_jmp('>')) {
716 ret
= ret
> evalshift();
719 if (!eval_jmp(TOK2("<="))) {
720 ret
= ret
<= evalshift();
723 if (!eval_jmp(TOK2(">="))) {
724 ret
= ret
>= evalshift();
732 static long evaleq(void)
734 long ret
= evalcmp();
736 if (!eval_jmp(TOK2("=="))) {
737 ret
= ret
== evalcmp();
740 if (!eval_jmp(TOK2("!="))) {
741 ret
= ret
!= evalcmp();
749 static long evalbitand(void)
752 while (!eval_jmp('&'))
757 static long evalxor(void)
759 long ret
= evalbitand();
760 while (!eval_jmp('^'))
765 static long evalbitor(void)
767 long ret
= evalxor();
768 while (!eval_jmp('|'))
773 static long evaland(void)
775 long ret
= evalbitor();
776 while (!eval_jmp(TOK2("&&")))
777 ret
= ret
&& evalbitor();
781 static long evalor(void)
783 long ret
= evaland();
784 while (!eval_jmp(TOK2("||")))
785 ret
= ret
|| evaland();
789 static long evalcexpr(void)
796 while (eval_get() != ':')
801 static long evalexpr(void)