Mercurial > ~dholland > hg > tradcpp > index.cgi
comparison directive.c @ 178:0d5b9651b240
Merge Joerg's changes into upstream.
(now that they've been thrashed out a bit, include CHANGES entries, etc.)
author | David A. Holland |
---|---|
date | Fri, 12 Jun 2015 03:05:49 -0400 |
parents | a2f047301c15 |
children | 4c3375895c6e |
comparison
equal
deleted
inserted
replaced
156:e8f7ae63844f | 178:0d5b9651b240 |
---|---|
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 <limits.h> | |
35 #include <errno.h> | |
34 | 36 |
35 #include "utils.h" | 37 #include "utils.h" |
36 #include "mode.h" | 38 #include "mode.h" |
37 #include "place.h" | 39 #include "place.h" |
38 #include "files.h" | 40 #include "files.h" |
413 | 415 |
414 static | 416 static |
415 void | 417 void |
416 d_line(struct lineplace *lp, struct place *p2, char *line) | 418 d_line(struct lineplace *lp, struct place *p2, char *line) |
417 { | 419 { |
418 (void)p2; | 420 char *text; |
419 (void)line; | 421 size_t oldlen; |
420 | 422 unsigned long val; |
421 /* XXX */ | 423 char *moretext; |
422 complain(&lp->current, "Sorry, no #line yet"); | 424 size_t moretextlen; |
425 char *filename; | |
426 | |
427 text = macroexpand(p2, line, strlen(line), true); | |
428 | |
429 oldlen = strlen(text); | |
430 uncomment(text); | |
431 /* trim to fit, so the malloc debugging won't complain */ | |
432 text = dorealloc(text, oldlen + 1, strlen(text) + 1); | |
433 | |
434 /* | |
435 * What we should have here: either 1234 "file.c", | |
436 * or just 1234. | |
437 */ | |
438 | |
439 errno = 0; | |
440 val = strtoul(text, &moretext, 10); | |
441 if (errno) { | |
442 complain(&lp->current, "No line number in #line directive"); | |
443 goto fail; | |
444 } | |
445 #if UINT_MAX < ULONG_MAX | |
446 if (val > UINT_MAX) { | |
447 complain(&lp->current, | |
448 "Line number in #line directive too large"); | |
449 goto fail; | |
450 } | |
451 #endif | |
452 moretext += strspn(moretext, ws); | |
453 moretextlen = strlen(moretext); | |
454 lp->current.column += (moretext - text); | |
455 | |
456 if (moretextlen > 2 && | |
457 moretext[0] == '"' && moretext[moretextlen-1] == '"') { | |
458 filename = dostrndup(moretext+1, moretextlen-2); | |
459 place_changefile(&lp->nextline, filename); | |
460 dostrfree(filename); | |
461 } | |
462 else if (moretextlen > 0) { | |
463 complain(&lp->current, | |
464 "Invalid file name in #line directive"); | |
465 goto fail; | |
466 } | |
467 | |
468 lp->nextline.line = val; | |
469 dostrfree(text); | |
470 return; | |
471 | |
472 fail: | |
473 complain(&lp->current, "Before macro expansion: #line %s", line); | |
474 complain(&lp->current, "After macro expansion: #line %s", text); | |
475 complain_fail(); | |
476 dostrfree(text); | |
423 } | 477 } |
424 | 478 |
425 //////////////////////////////////////////////////////////// | 479 //////////////////////////////////////////////////////////// |
426 // messages | 480 // messages |
427 | 481 |
582 if (warns.nestcomment) { | 636 if (warns.nestcomment) { |
583 directive_scancomments(lp, line, len); | 637 directive_scancomments(lp, line, len); |
584 } | 638 } |
585 | 639 |
586 /* check if we have a directive line (# exactly in column 0) */ | 640 /* check if we have a directive line (# exactly in column 0) */ |
587 if (line[0] == '#') { | 641 if (len > 0 && line[0] == '#') { |
588 skip = 1 + strspn(line + 1, ws); | 642 skip = 1 + strspn(line + 1, ws); |
589 assert(skip <= len); | 643 assert(skip <= len); |
590 lp->current.column += skip; | 644 lp->current.column += skip; |
591 assert(line[len] == '\0'); | 645 assert(line[len] == '\0'); |
592 directive_gotdirective(lp, line+skip /*, length = len-skip */); | 646 directive_gotdirective(lp, line+skip /*, length = len-skip */); |