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 */);