12 #define MAXDEFS (1 << 10)
13 #define MACROLEN (1 << 10)
14 #define MAXARGS (1 << 5)
19 char args
[MAXARGS
][NAMELEN
];
25 #define MAXBUFS (1 << 3)
34 static void buf_new(void)
37 bufs
[nbufs
- 1].cur
= cur
;
38 bufs
[nbufs
- 1].len
= len
;
43 buf
= bufs
[nbufs
- 1].buf
;
46 static void buf_pop(void)
50 cur
= bufs
[nbufs
- 1].cur
;
51 len
= bufs
[nbufs
- 1].len
;
52 buf
= bufs
[nbufs
- 1].buf
;
56 static void include(int fd
)
60 while ((n
= read(fd
, buf
+ len
, BUFSIZE
- len
)) > 0)
69 static void jumpws(void)
71 while (cur
< len
&& isspace(buf
[cur
]))
75 static void read_word(char *dst
)
78 while (cur
< len
&& isalnum(buf
[cur
]) || buf
[cur
] == '_')
83 static void read_tilleol(char *dst
)
85 while (cur
< len
&& buf
[cur
] != '\n')
93 static char *putstr(char *d
, char *s
)
101 #define MAXLOCS (1 << 10)
103 static char *locs
[MAXLOCS
] = {"/usr/include"};
104 static int nlocs
= 1;
106 void cpp_addpath(char *s
)
111 static int include_find(char *name
, int std
)
115 for (i
= std
? nlocs
- 1 : nlocs
; i
>= 0; i
--) {
120 s
= putstr(s
, locs
[i
]);
124 fd
= open(path
, O_RDONLY
);
131 static void jumpstr(void)
133 if (buf
[cur
] == '\'') {
134 while (cur
< len
&& buf
[++cur
] != '\'')
135 if (buf
[cur
] == '\\')
140 if (buf
[cur
] == '"') {
141 while (cur
< len
&& buf
[++cur
] != '"')
142 if (buf
[cur
] == '\\')
149 static void jumpcomment(void)
151 while (++cur
< len
) {
152 if (buf
[cur
] == '*' && buf
[cur
+ 1] == '/') {
159 static void readarg(char *s
)
163 while (cur
< len
&& (depth
|| buf
[cur
] != ',' && buf
[cur
] != ')')) {
182 if (buf
[cur
] == '/' && buf
[cur
+ 1] == '*')
188 memcpy(s
, buf
+ beg
, cur
- beg
);
192 static int macro_find(char *name
)
195 for (i
= 0; i
< nmacros
; i
++)
196 if (!strcmp(name
, macros
[i
].name
))
201 static int macro_new(char *name
)
204 for (i
= 0; i
< nmacros
; i
++) {
205 if (!strcmp(name
, macros
[i
].name
))
207 if (!*macros
[i
].name
) {
208 strcpy(macros
[i
].name
, name
);
212 strcpy(macros
[nmacros
++].name
, name
);
216 static void macro_define(void)
221 d
= ¯os
[macro_new(name
)];
223 if (buf
[cur
++] == '(') {
225 while (cur
< len
&& buf
[cur
] != ')') {
226 readarg(d
->args
[d
->nargs
++]);
235 read_tilleol(d
->def
);
238 static void jumpifs(int jumpelse
)
242 if (buf
[cur
] == '#') {
246 if (!strcmp("else", cmd
))
247 if (!depth
&& !jumpelse
)
249 if (!strcmp("endif", cmd
))
254 if (!strcmp("ifdef", cmd
) || !strcmp("ifndef", cmd
))
257 if (buf
[cur
] == '/' && buf
[cur
+ 1] == '*') {
261 if (buf
[cur
] == '\'' || buf
[cur
] == '"') {
269 static void cpp_cmd(void)
274 if (!strcmp("define", cmd
)) {
278 if (!strcmp("undef", cmd
)) {
282 idx
= macro_find(name
);
284 strcpy(macros
[idx
].name
, "");
287 if (!strcmp("ifdef", cmd
) || !strcmp("ifndef", cmd
)) {
289 int not = cmd
[2] == 'n';
291 if (!not && macro_find(name
) < 0 || not && macro_find(name
) >= 0)
295 if (!strcmp("else", cmd
)) {
299 if (!strcmp("endif", cmd
))
301 if (!strcmp("include", cmd
)) {
307 e
= strchr(buf
+ cur
+ 1, buf
[cur
] == '"' ? '"' : '>');
308 memcpy(file
, s
, e
- s
);
311 fd
= include_find(file
, *e
== '>');
320 static int macro_arg(struct macro
*m
, char *arg
)
323 for (i
= 0; i
< m
->nargs
; i
++)
324 if (!strcmp(arg
, m
->args
[i
]))
329 static void macro_expand(void)
332 char args
[MAXARGS
][MACROLEN
];
339 m
= ¯os
[macro_find(name
)];
343 len
= strlen(m
->def
);
346 if (buf
[cur
] == '(') {
349 while (cur
< len
&& buf
[cur
] != ')') {
350 readarg(args
[nargs
++]);
362 len
= strlen(m
->def
);
365 if (buf
[cur
] == '/' && buf
[cur
+ 1] == '*') {
369 if (strchr("'\"", buf
[cur
])) {
373 if (isalpha(buf
[cur
]) || buf
[cur
] == '_') {
377 if ((arg
= macro_arg(m
, word
)) != -1) {
378 int len
= cur
- beg
- strlen(word
);
379 char *argstr
= arg
> nargs
? "" : args
[arg
];
380 int arglen
= strlen(argstr
);
381 memcpy(dst
+ dstlen
, buf
+ beg
, len
);
383 memcpy(dst
+ dstlen
, argstr
, arglen
);
391 memcpy(dst
+ dstlen
, buf
+ beg
, len
- beg
);
399 void cpp_define(char *name
, char *def
)
412 static int definedword
;
414 int cpp_read(char *s
)
427 if (buf
[cur
] == '#') {
434 if (buf
[cur
] == '/' && buf
[cur
+ 1] == '*') {
438 if (buf
[cur
] == '\'' || buf
[cur
] == '"') {
442 if (isalpha(buf
[cur
]) || buf
[cur
] == '_') {
445 if (macro_find(word
) != -1) {
454 memcpy(s
, buf
+ old
, cur
- old
);