Mercurial > ~dholland > hg > tradcpp > index.cgi
comparison directive.c @ 165:cc6d6f27d6ee
Fix Joerg's #line code.
(avoid redundant whitespace grinding, don't use atoi, be simpler and
tidier, etc.)
author | David A. Holland |
---|---|
date | Fri, 12 Jun 2015 01:30:13 -0400 (2015-06-12) |
parents | f14f5352956c |
children | 6ff17ab68b16 |
comparison
equal
deleted
inserted
replaced
164:f14f5352956c | 165:cc6d6f27d6ee |
---|---|
29 | 29 |
30 #include <assert.h> | 30 #include <assert.h> |
31 #include <stdbool.h> | 31 #include <stdbool.h> |
32 #include <stdlib.h> | 32 #include <stdlib.h> |
33 #include <string.h> | 33 #include <string.h> |
34 #include <errno.h> | |
34 | 35 |
35 #include "utils.h" | 36 #include "utils.h" |
36 #include "mode.h" | 37 #include "mode.h" |
37 #include "place.h" | 38 #include "place.h" |
38 #include "files.h" | 39 #include "files.h" |
415 void | 416 void |
416 d_line(struct lineplace *lp, struct place *p2, char *line) | 417 d_line(struct lineplace *lp, struct place *p2, char *line) |
417 { | 418 { |
418 char *text; | 419 char *text; |
419 size_t oldlen; | 420 size_t oldlen; |
420 const char *token, *start_lineno, *start_filename; | 421 unsigned long val; |
421 size_t len_lineno, len_filename; | 422 char *moretext; |
423 size_t moretextlen; | |
424 char *filename; | |
422 | 425 |
423 text = macroexpand(p2, line, strlen(line), true); | 426 text = macroexpand(p2, line, strlen(line), true); |
424 | 427 |
425 oldlen = strlen(text); | 428 oldlen = strlen(text); |
426 uncomment(text); | 429 uncomment(text); |
427 /* trim to fit, so the malloc debugging won't complain */ | 430 /* trim to fit, so the malloc debugging won't complain */ |
428 text = dorealloc(text, oldlen + 1, strlen(text) + 1); | 431 text = dorealloc(text, oldlen + 1, strlen(text) + 1); |
429 | 432 |
430 token = text; | 433 /* |
431 token += strspn(token, ws); | 434 * What we should have here: either 1234 "file.c", |
432 start_lineno = token; | 435 * or just 1234. |
433 len_lineno = strspn(token, digits); | 436 */ |
434 if (len_lineno == 0) { | 437 |
435 goto illegal_line; | 438 errno = 0; |
436 } | 439 val = strtoul(text, &moretext, 10); |
437 token += len_lineno; | 440 if (errno) { |
438 token += strspn(ws, token); | 441 complain(&lp->current, "No line number in #line directive"); |
439 if (*token == '"') { | 442 goto fail; |
440 ++token; | 443 } |
441 start_filename = token; | 444 #if UINT_MAX < ULONG_MAX |
442 len_filename = strcspn(token, "\""); | 445 if (val > UINT_MAX) { |
443 token += len_filename; | 446 complain(&lp->current, |
444 if (*token != '"' || len_filename == 0) { | 447 "Line number in #line directive too large"); |
445 goto illegal_line; | 448 goto fail; |
446 } | 449 } |
447 ++token; | 450 #endif |
448 token += strspn(token, ws); | 451 moretext += strspn(moretext, ws); |
449 if (*token != '\0') { | 452 moretextlen = strlen(moretext); |
450 goto illegal_line; | 453 lp->current.column += (moretext - text); |
451 } | 454 |
452 } else { | 455 if (moretextlen > 2 && |
453 len_filename = 0; | 456 moretext[0] == '"' && moretext[moretextlen-1] == '"') { |
454 token += strspn(token, ws); | 457 filename = dostrndup(moretext+1, moretextlen-2); |
455 if (*token != '\0') { | |
456 goto illegal_line; | |
457 } | |
458 } | |
459 lp->nextline.line = atoi(start_lineno); | |
460 if (len_filename) { | |
461 char *filename = dostrndup(start_filename, len_filename); | |
462 place_setfile(&lp->nextline, filename); | 458 place_setfile(&lp->nextline, filename); |
463 dostrfree(filename); | 459 dostrfree(filename); |
464 } | 460 } |
461 else if (moretextlen > 0) { | |
462 complain(&lp->current, | |
463 "Invalid file name in #line directive"); | |
464 goto fail; | |
465 } | |
466 | |
467 lp->nextline.line = val; | |
465 dostrfree(text); | 468 dostrfree(text); |
466 return; | 469 return; |
467 | 470 |
468 illegal_line: | 471 fail: |
469 complain(&lp->current, "Illegal #line directive"); | 472 complain(&lp->current, "Before macro expansion: #line %s", line); |
470 complain(&lp->current, "Before macro expansion: #include %s", line); | 473 complain(&lp->current, "After macro expansion: #line %s", text); |
471 complain(&lp->current, "After macro expansion: #include %s", text); | 474 complain_fail(); |
472 dostrfree(text); | 475 dostrfree(text); |
473 } | 476 } |
474 | 477 |
475 //////////////////////////////////////////////////////////// | 478 //////////////////////////////////////////////////////////// |
476 // messages | 479 // messages |