comparison directive.c @ 64:f50b4ea6cbfe

Prune single-line comments from (most) directive lines. Also, don't pass the string length to the directive processing functions, as half of them weren't honoring it. Instead, ensure that the directive line is terminated at the place the directive processing functions should stop looking at it.
author David A. Holland
date Sun, 31 Mar 2013 02:04:56 -0400
parents 90c6052410ce
children f8507e5ed84c
comparison
equal deleted inserted replaced
63:5e24746d8335 64:f50b4ea6cbfe
55 //////////////////////////////////////////////////////////// 55 ////////////////////////////////////////////////////////////
56 // common parsing bits 56 // common parsing bits
57 57
58 static 58 static
59 void 59 void
60 uncomment(char *buf)
61 {
62 char *s, *t, *u = NULL;
63 bool incomment = false;
64
65 for (s = t = buf; *s; s++) {
66 if (incomment) {
67 if (s[0] == '*' && s[1] == '/') {
68 s++;
69 incomment = false;
70 }
71 } else {
72 if (s[0] == '/' && s[1] == '*') {
73 incomment = true;
74 } else {
75 if (t != s) {
76 *t = *s;
77 }
78 if (!strchr(ws, *t)) {
79 u = t;
80 }
81 t++;
82 }
83 }
84 }
85 if (u) {
86 /* end string after last non-whitespace char */
87 u[1] = '\0';
88 } else {
89 *t = '\0';
90 }
91 }
92
93 static
94 void
60 oneword(const char *what, struct place *p2, char *line) 95 oneword(const char *what, struct place *p2, char *line)
61 { 96 {
62 size_t pos; 97 size_t pos;
63 98
64 pos = strcspn(line, ws); 99 pos = strcspn(line, ws);
117 ifstate_destroy(is); 152 ifstate_destroy(is);
118 } 153 }
119 154
120 static 155 static
121 void 156 void
122 d_if(struct place *p, struct place *p2, char *line, size_t len) 157 d_if(struct place *p, struct place *p2, char *line)
123 { 158 {
124 char *expr; 159 char *expr;
125 bool val; 160 bool val;
126 struct place p3 = *p2; 161 struct place p3 = *p2;
127 162
128 expr = macroexpand(p2, line, len, true); 163 uncomment(line);
164 expr = macroexpand(p2, line, strlen(line), true);
129 val = eval(&p3, expr); 165 val = eval(&p3, expr);
130 ifstate_push(p, val); 166 ifstate_push(p, val);
131 dostrfree(expr); 167 dostrfree(expr);
132 } 168 }
133 169
134 static 170 static
135 void 171 void
136 d_ifdef(struct place *p, struct place *p2, char *line, size_t len) 172 d_ifdef(struct place *p, struct place *p2, char *line)
137 { 173 {
174 uncomment(line);
138 oneword("#ifdef", p2, line); 175 oneword("#ifdef", p2, line);
139 ifstate_push(p, macro_isdefined(line)); 176 ifstate_push(p, macro_isdefined(line));
140 } 177 }
141 178
142 static 179 static
143 void 180 void
144 d_ifndef(struct place *p, struct place *p2, char *line, size_t len) 181 d_ifndef(struct place *p, struct place *p2, char *line)
145 { 182 {
183 uncomment(line);
146 oneword("#ifndef", p2, line); 184 oneword("#ifndef", p2, line);
147 ifstate_push(p, !macro_isdefined(line)); 185 ifstate_push(p, !macro_isdefined(line));
148 } 186 }
149 187
150 static 188 static
151 void 189 void
152 d_elif(struct place *p, struct place *p2, char *line, size_t len) 190 d_elif(struct place *p, struct place *p2, char *line)
153 { 191 {
154 char *expr; 192 char *expr;
155 struct place p3 = *p2; 193 struct place p3 = *p2;
156 194
157 if (ifstate->seenelse) { 195 if (ifstate->seenelse) {
160 } 198 }
161 199
162 if (ifstate->evertrue) { 200 if (ifstate->evertrue) {
163 ifstate->curtrue = false; 201 ifstate->curtrue = false;
164 } else { 202 } else {
165 expr = macroexpand(p2, line, len, true); 203 uncomment(line);
204 expr = macroexpand(p2, line, strlen(line), true);
166 ifstate->curtrue = eval(&p3, expr); 205 ifstate->curtrue = eval(&p3, expr);
167 ifstate->evertrue = ifstate->curtrue; 206 ifstate->evertrue = ifstate->curtrue;
168 dostrfree(expr); 207 dostrfree(expr);
169 } 208 }
170 } 209 }
171 210
172 static 211 static
173 void 212 void
174 d_else(struct place *p, struct place *p2, char *line, size_t len) 213 d_else(struct place *p, struct place *p2, char *line)
175 { 214 {
176 if (ifstate->seenelse) { 215 if (ifstate->seenelse) {
177 complain(p, "Multiple #else directives in one conditional"); 216 complain(p, "Multiple #else directives in one conditional");
178 complain_fail(); 217 complain_fail();
179 } 218 }
183 ifstate->seenelse = true; 222 ifstate->seenelse = true;
184 } 223 }
185 224
186 static 225 static
187 void 226 void
188 d_endif(struct place *p, struct place *p2, char *line, size_t len) 227 d_endif(struct place *p, struct place *p2, char *line)
189 { 228 {
190 if (ifstate->prev == NULL) { 229 if (ifstate->prev == NULL) {
191 complain(p, "Unmatched #endif"); 230 complain(p, "Unmatched #endif");
192 complain_fail(); 231 complain_fail();
193 } else { 232 } else {
198 //////////////////////////////////////////////////////////// 237 ////////////////////////////////////////////////////////////
199 // macros 238 // macros
200 239
201 static 240 static
202 void 241 void
203 d_define(struct place *p, struct place *p2, char *line, size_t len) 242 d_define(struct place *p, struct place *p2, char *line)
204 { 243 {
205 size_t pos, argpos; 244 size_t pos, argpos;
206 struct place p3, p4; 245 struct place p3, p4;
207 246
208 /* 247 /*
261 } 300 }
262 } 301 }
263 302
264 static 303 static
265 void 304 void
266 d_undef(struct place *p, struct place *p2, char *line, size_t len) 305 d_undef(struct place *p, struct place *p2, char *line)
267 { 306 {
307 uncomment(line);
268 oneword("#undef", p2, line); 308 oneword("#undef", p2, line);
269 macro_undef(line); 309 macro_undef(line);
270 } 310 }
271 311
272 //////////////////////////////////////////////////////////// 312 ////////////////////////////////////////////////////////////
273 // includes 313 // includes
274 314
275 static 315 static
276 bool 316 bool
277 tryinclude(struct place *p, char *line, size_t len) 317 tryinclude(struct place *p, char *line)
278 { 318 {
319 size_t len;
320
321 len = strlen(line);
279 if (len > 2 && line[0] == '"' && line[len-1] == '"') { 322 if (len > 2 && line[0] == '"' && line[len-1] == '"') {
280 line[len-1] = '\0'; 323 line[len-1] = '\0';
281 file_readquote(p, line+1); 324 file_readquote(p, line+1);
282 line[len-1] = '"'; 325 line[len-1] = '"';
283 return true; 326 return true;
291 return false; 334 return false;
292 } 335 }
293 336
294 static 337 static
295 void 338 void
296 d_include(struct place *p, struct place *p2, char *line, size_t len) 339 d_include(struct place *p, struct place *p2, char *line)
297 { 340 {
298 char *text; 341 char *text;
299 342
300 if (tryinclude(p, line, len)) { 343 uncomment(line);
344 if (tryinclude(p, line)) {
301 return; 345 return;
302 } 346 }
303 text = macroexpand(p2, line, len, false); 347 text = macroexpand(p2, line, strlen(line), false);
304 if (tryinclude(p, text, strlen(text))) { 348 if (tryinclude(p, text)) {
305 dostrfree(text); 349 dostrfree(text);
306 return; 350 return;
307 } 351 }
308 dostrfree(text); 352 dostrfree(text);
309 complain(p, "Illegal #include directive"); 353 complain(p, "Illegal #include directive");
310 complain_fail(); 354 complain_fail();
311 } 355 }
312 356
313 static 357 static
314 void 358 void
315 d_line(struct place *p, struct place *p2, char *line, size_t len) 359 d_line(struct place *p, struct place *p2, char *line)
316 { 360 {
317 /* XXX */ 361 /* XXX */
318 complain(p, "Sorry, no #line yet"); 362 complain(p, "Sorry, no #line yet");
319 } 363 }
320 364
321 //////////////////////////////////////////////////////////// 365 ////////////////////////////////////////////////////////////
322 // messages 366 // messages
323 367
324 static 368 static
325 void 369 void
326 d_warning(struct place *p, struct place *p2, char *line, size_t len) 370 d_warning(struct place *p, struct place *p2, char *line)
327 { 371 {
328 char *msg; 372 char *msg;
329 373
330 msg = macroexpand(p2, line, len, false); 374 msg = macroexpand(p2, line, strlen(line), false);
331 complain(p, "#warning: %s", msg); 375 complain(p, "#warning: %s", msg);
332 if (mode.werror) { 376 if (mode.werror) {
333 complain_fail(); 377 complain_fail();
334 } 378 }
335 dostrfree(msg); 379 dostrfree(msg);
336 } 380 }
337 381
338 static 382 static
339 void 383 void
340 d_error(struct place *p, struct place *p2, char *line, size_t len) 384 d_error(struct place *p, struct place *p2, char *line)
341 { 385 {
342 char *msg; 386 char *msg;
343 387
344 msg = macroexpand(p2, line, len, false); 388 msg = macroexpand(p2, line, strlen(line), false);
345 complain(p, "#error: %s", msg); 389 complain(p, "#error: %s", msg);
346 complain_fail(); 390 complain_fail();
347 dostrfree(msg); 391 dostrfree(msg);
348 } 392 }
349 393
350 //////////////////////////////////////////////////////////// 394 ////////////////////////////////////////////////////////////
351 // other 395 // other
352 396
353 static 397 static
354 void 398 void
355 d_pragma(struct place *p, struct place *p2, char *line, size_t len) 399 d_pragma(struct place *p, struct place *p2, char *line)
356 { 400 {
357 complain(p, "#pragma %s", line); 401 complain(p, "#pragma %s", line);
358 complain_fail(); 402 complain_fail();
359 } 403 }
360 404
362 // directive table 406 // directive table
363 407
364 static const struct { 408 static const struct {
365 const char *name; 409 const char *name;
366 bool ifskip; 410 bool ifskip;
367 void (*func)(struct place *, struct place *, char *line, size_t len); 411 void (*func)(struct place *, struct place *, char *line);
368 } directives[] = { 412 } directives[] = {
369 { "define", true, d_define }, 413 { "define", true, d_define },
370 { "elif", false, d_elif }, 414 { "elif", false, d_elif },
371 { "else", false, d_else }, 415 { "else", false, d_else },
372 { "endif", false, d_endif }, 416 { "endif", false, d_endif },
382 }; 426 };
383 static const unsigned numdirectives = HOWMANY(directives); 427 static const unsigned numdirectives = HOWMANY(directives);
384 428
385 static 429 static
386 void 430 void
387 directive_gotdirective(struct place *p, char *line, size_t linelen) 431 directive_gotdirective(struct place *p, char *line)
388 { 432 {
389 struct place p2; 433 struct place p2;
390 size_t len, skip; 434 size_t len, skip;
391 unsigned i; 435 unsigned i;
392 436
399 return; 443 return;
400 } 444 }
401 skip = len + strspn(line+len, ws); 445 skip = len + strspn(line+len, ws);
402 p2.column += skip; 446 p2.column += skip;
403 line += skip; 447 line += skip;
404 linelen -= skip; 448
405 linelen = notrailingws(line, linelen); 449 len = strlen(line);
406 directives[i].func(p, &p2, line, linelen); 450 len = notrailingws(line, len);
451 if (len < strlen(line)) {
452 line[len] = '\0';
453 }
454 directives[i].func(p, &p2, line);
407 return; 455 return;
408 } 456 }
409 } 457 }
410 skip = strcspn(line, ws); 458 skip = strcspn(line, ws);
411 complain(p, "Unknown directive #%.*s", (int)skip, line); 459 complain(p, "Unknown directive #%.*s", (int)skip, line);
524 } 572 }
525 573
526 /* check if we have a directive line */ 574 /* check if we have a directive line */
527 skip = strspn(line + acomm, ws); 575 skip = strspn(line + acomm, ws);
528 if (acomm == 0 && line[skip] == '#') { 576 if (acomm == 0 && line[skip] == '#') {
577 char ch;
578
529 skip = skip + 1 + strspn(line + skip + 1, ws); 579 skip = skip + 1 + strspn(line + skip + 1, ws);
530 assert(skip <= text); 580 assert(skip <= text);
531 p->column += skip; 581 p->column += skip;
532 directive_gotdirective(p, line+skip, text-skip); 582 assert(line[len] == '\0');
583 /* ensure null termination for directives */
584 ch = line[text];
585 if (ch != '\0') {
586 line[text] = '\0';
587 }
588 directive_gotdirective(p, line+skip /*, length = text-skip */);
589 line[text] = ch;
533 p->column += text-skip; 590 p->column += text-skip;
534 } else if (ifstate->curtrue) { 591 } else if (ifstate->curtrue) {
535 macro_sendline(p, line + acomm, text); 592 macro_sendline(p, line + acomm, text);
536 p->column += text; 593 p->column += text;
537 } 594 }