Mercurial > ~dholland > hg > tradcpp > index.cgi
comparison directive.c @ 77:123168887da8
Clean out old not-really-working nested comment handling.
author | David A. Holland |
---|---|
date | Mon, 10 Jun 2013 20:12:37 -0400 |
parents | b1d0f10e8d36 |
children | 27c9aafcaca1 |
comparison
equal
deleted
inserted
replaced
76:7dba4436cff9 | 77:123168887da8 |
---|---|
48 bool evertrue; | 48 bool evertrue; |
49 bool seenelse; | 49 bool seenelse; |
50 }; | 50 }; |
51 | 51 |
52 static struct ifstate *ifstate; | 52 static struct ifstate *ifstate; |
53 static bool in_multiline_comment; | |
54 | 53 |
55 //////////////////////////////////////////////////////////// | 54 //////////////////////////////////////////////////////////// |
56 // common parsing bits | 55 // common parsing bits |
57 | 56 |
58 static | 57 static |
466 complain(p, "Unknown directive #%.*s", (int)skip, line); | 465 complain(p, "Unknown directive #%.*s", (int)skip, line); |
467 complain_fail(); | 466 complain_fail(); |
468 } | 467 } |
469 | 468 |
470 /* | 469 /* |
471 * If desired, warn about a nested comment. The comment begins at | 470 * Check for nested comment delimiters in LINE. |
472 * offset POS from the place P. | |
473 */ | 471 */ |
474 static | 472 static |
475 void | 473 size_t |
476 warn_nestcomment(const struct place *p, size_t pos) | 474 directive_scancomments(const struct place *p, char *line, size_t len) |
477 { | 475 { |
476 size_t pos; | |
477 bool incomment; | |
478 struct place p2; | 478 struct place p2; |
479 | 479 |
480 if (warns.nestcomment) { | 480 p2 = *p; |
481 p2 = *p; | 481 incomment = 0; |
482 p2.column += pos; | |
483 complain(p, "Warning: %c%c within comment", | |
484 '/', '*'); | |
485 if (mode.werror) { | |
486 complain_failed(); | |
487 } | |
488 } | |
489 } | |
490 | |
491 /* | |
492 * Check for comment delimiters in LINE. If a multi-line comment is | |
493 * continuing or ending, set ACOMM to its length. If a multi-line | |
494 * comment is starting, set BCOMM to its length. Set TEXT to the | |
495 * length of text that is not commented out, or that contains comments | |
496 * that both begin and end on this line. ACOMM + TEXT + BCOMM == LEN. | |
497 * | |
498 * Updates in_multiline_comment to the appropriate state for after | |
499 * this line is handled. | |
500 */ | |
501 static | |
502 size_t | |
503 directive_scancomments(const struct place *p, char *line, size_t len, | |
504 size_t *acomm, size_t *text, size_t *bcomm) | |
505 { | |
506 size_t pos; | |
507 size_t first_commentend; | |
508 size_t last_commentstart; | |
509 bool incomment; | |
510 | |
511 first_commentend = len; | |
512 last_commentstart = len; | |
513 incomment = in_multiline_comment; | |
514 for (pos = 0; pos+1 < len; pos++) { | 482 for (pos = 0; pos+1 < len; pos++) { |
515 if (line[pos] == '/' && line[pos+1] == '*') { | 483 if (line[pos] == '/' && line[pos+1] == '*') { |
516 if (incomment) { | 484 if (incomment) { |
517 warn_nestcomment(p, pos); | 485 complain(&p2, "Warning: %c%c within comment", |
486 '/', '*'); | |
487 if (mode.werror) { | |
488 complain_failed(); | |
489 } | |
518 } else { | 490 } else { |
519 incomment = true; | 491 incomment = true; |
520 last_commentstart = pos; | |
521 } | 492 } |
522 } else if (line[pos] == '*' && line[pos+1] == '/') { | 493 } else if (line[pos] == '*' && line[pos+1] == '/') { |
523 if (incomment) { | 494 if (incomment) { |
524 incomment = false; | 495 incomment = false; |
525 if (first_commentend == len) { | |
526 first_commentend = pos; | |
527 } | |
528 last_commentstart = len; | |
529 } else { | 496 } else { |
530 /* stray end-comment; should we care? */ | 497 /* stray end-comment; should we care? */ |
531 } | 498 } |
532 } | 499 } |
533 } | 500 if (line[pos] == '\n') { |
534 | 501 p2.line++; |
535 if (in_multiline_comment && first_commentend < last_commentstart) { | 502 p2.column = 0; |
536 /* multiline comment ends */ | 503 } else { |
537 /* first_commentend points to the star, adjust */ | 504 p2.column++; |
538 *acomm = first_commentend + 2; | 505 } |
539 *text = len - *acomm; | 506 } |
540 } else if (in_multiline_comment) { | 507 |
541 /* comment did not end, so another one cannot have started */ | 508 /* multiline comments are supposed to arrive in a single buffer */ |
542 assert(last_commentstart == len); | 509 assert(!incomment); |
543 *acomm = len; | |
544 *text = 0; | |
545 } else { | |
546 *acomm = 0; | |
547 *text = len; | |
548 } | |
549 | |
550 *bcomm = len - last_commentstart; | |
551 *text -= *bcomm; | |
552 | |
553 in_multiline_comment = incomment; | |
554 return len; | 510 return len; |
555 } | 511 } |
556 | 512 |
557 void | 513 void |
558 directive_gotline(struct place *p, char *line, size_t len) | 514 directive_gotline(struct place *p, char *line, size_t len) |
559 { | 515 { |
560 size_t acomm; /* length of comment ending on this line */ | |
561 size_t text; /* length of non-multi-line-comment text */ | |
562 size_t bcomm; /* length of comment beginning on this line */ | |
563 size_t skip; | 516 size_t skip; |
564 | 517 |
565 directive_scancomments(p, line, len, &acomm, &text, &bcomm); | 518 if (warns.nestcomment) { |
566 | 519 directive_scancomments(p, line, len); |
567 if (acomm > 0) { | |
568 if (mode.output_retain_comments && ifstate->curtrue) { | |
569 /* | |
570 * Do not expand the comment; send it straight | |
571 * to the output. This will cause it to appear | |
572 * first if we're partway through collecting a | |
573 * macro argument. Too bad. This isn't a | |
574 * standard mode anyway. | |
575 */ | |
576 output(p, line, acomm); | |
577 } | |
578 p->column += acomm; | |
579 } | 520 } |
580 | 521 |
581 /* check if we have a directive line (# exactly in column 0) */ | 522 /* check if we have a directive line (# exactly in column 0) */ |
582 if (acomm == 0 && line[0] == '#') { | 523 if (line[0] == '#') { |
583 char ch; | |
584 | |
585 skip = 1 + strspn(line + 1, ws); | 524 skip = 1 + strspn(line + 1, ws); |
586 assert(skip <= text); | 525 assert(skip <= len); |
587 p->column += skip; | 526 p->column += skip; |
588 assert(line[len] == '\0'); | 527 assert(line[len] == '\0'); |
589 /* ensure null termination for directives */ | 528 directive_gotdirective(p, line+skip /*, length = len-skip */); |
590 ch = line[text]; | 529 p->column += len-skip; |
591 if (ch != '\0') { | |
592 line[text] = '\0'; | |
593 } | |
594 directive_gotdirective(p, line+skip /*, length = text-skip */); | |
595 line[text] = ch; | |
596 p->column += text-skip; | |
597 } else if (ifstate->curtrue) { | 530 } else if (ifstate->curtrue) { |
598 macro_sendline(p, line + acomm, text); | 531 macro_sendline(p, line, len); |
599 p->column += text; | 532 p->column += len; |
600 } | |
601 | |
602 if (bcomm > 0) { | |
603 if (mode.output_retain_comments && ifstate->curtrue) { | |
604 output(p, line + acomm + text, bcomm); | |
605 } | |
606 p->column += bcomm; | |
607 } | 533 } |
608 } | 534 } |
609 | 535 |
610 void | 536 void |
611 directive_goteof(struct place *p) | 537 directive_goteof(struct place *p) |