# HG changeset patch # User Joerg Sonnenberger # Date 1364707189 -7200 # Node ID 737ffe27b4bdefdbcf8b5366dd47b84f2ae6fefd # Parent 8a204d1533980e8c4aae983a87fb5eb5cc73d513# Parent a3dd0db23b0c1007ae43b7f0f004173515b472db Merge diff -r a3dd0db23b0c -r 737ffe27b4bd directive.c --- a/directive.c Sun Mar 31 06:45:44 2013 +0200 +++ b/directive.c Sun Mar 31 07:19:49 2013 +0200 @@ -39,6 +39,7 @@ #include "directive.h" #include "macro.h" #include "eval.h" +#include "output.h" struct ifstate { struct ifstate *prev; @@ -49,6 +50,7 @@ }; static struct ifstate *ifstate; +static bool in_multiline_comment; //////////////////////////////////////////////////////////// // common parsing bits @@ -408,23 +410,138 @@ complain_fail(); } +/* + * If desired, warn about a nested comment. The comment begins at + * offset POS from the place P. + */ +static +void +warn_nestcomment(const struct place *p, size_t pos) +{ + struct place p2; + + if (warns.nestcomment) { + p2 = *p; + p2.column += pos; + complain(p, "Warning: %c%c within comment", + '/', '*'); + if (mode.werror) { + complain_failed(); + } + } +} + +/* + * Check for comment delimiters in LINE. If a multi-line comment is + * continuing or ending, set ACOMM to its length. If a multi-line + * comment is starting, set BCOMM to its length. Set TEXT to the + * length of text that is not commented out, or that contains comments + * that both begin and end on this line. ACOMM + TEXT + BCOMM == LEN. + * + * Updates in_multiline_comment to the appropriate state for after + * this line is handled. + */ +static +size_t +directive_scancomments(const struct place *p, char *line, size_t len, + size_t *acomm, size_t *text, size_t *bcomm) +{ + size_t pos; + size_t first_commentend; + size_t last_commentstart; + bool incomment; + + first_commentend = len; + last_commentstart = len; + incomment = in_multiline_comment; + for (pos = 0; pos+1 < len; pos++) { + if (line[pos] == '/' && line[pos+1] == '*') { + if (incomment) { + warn_nestcomment(p, pos); + } else { + incomment = true; + last_commentstart = pos; + } + } else if (line[pos] == '*' && line[pos+1] == '/') { + if (incomment) { + incomment = false; + if (first_commentend == len) { + first_commentend = pos; + } + last_commentstart = len; + } else { + /* stray end-comment; should we care? */ + } + } + } + + if (in_multiline_comment && first_commentend < last_commentstart) { + /* multiline comment ends */ + /* first_commentend points to the star, adjust */ + *acomm = first_commentend + 2; + *text = len - *acomm; + } else if (in_multiline_comment) { + /* comment did not end, so another one cannot have started */ + assert(last_commentstart == len); + *acomm = len; + *text = 0; + } else { + *acomm = 0; + *text = len; + } + + *bcomm = len - last_commentstart; + *text -= *bcomm; + + in_multiline_comment = incomment; + return len; +} + void directive_gotline(struct place *p, char *line, size_t len) { + size_t acomm; /* length of comment ending on this line */ + size_t text; /* length of non-multi-line-comment text */ + size_t bcomm; /* length of comment beginning on this line */ size_t skip; + directive_scancomments(p, line, len, &acomm, &text, &bcomm); + + if (acomm > 0) { + if (mode.output_retain_comments && ifstate->curtrue) { + /* + * Do not expand the comment; send it straight + * to the output. This will cause it to appear + * first if we're partway through collecting a + * macro argument. Too bad. This isn't a + * standard mode anyway. + */ + output(p, line, acomm); + } + p->column += acomm; + } + /* check if we have a directive line */ - skip = strspn(line, ws); - if (line[skip] == '#') { + skip = strspn(line + acomm, ws); + if (acomm == 0 && line[skip] == '#') { skip = skip + 1 + strspn(line + skip + 1, ws); + assert(skip <= text); p->column += skip; - directive_gotdirective(p, line+skip, len-skip); + directive_gotdirective(p, line+skip, text-skip); + p->column += text-skip; } else if (ifstate->curtrue) { - macro_sendline(p, line, len); + macro_sendline(p, line + acomm, text); + p->column += text; + } + + if (bcomm > 0) { + if (mode.output_retain_comments && ifstate->curtrue) { + output(p, line + acomm + text, bcomm); + } + p->column += bcomm; } } - void directive_goteof(struct place *p) { diff -r a3dd0db23b0c -r 737ffe27b4bd tests/Makefile --- a/tests/Makefile Sun Mar 31 06:45:44 2013 +0200 +++ b/tests/Makefile Sun Mar 31 07:19:49 2013 +0200 @@ -11,7 +11,8 @@ TRADCPP_OBJDIR!= ${MAKE} -C .. -V .OBJDIR TRADCPP= ${TRADCPP_OBJDIR}/tradcpp -TESTS=t01 t02 t03 t04 t05 t06 t07 t08 t09 t10 t11 t12 t13 t14 t15 t16 +TESTS=t01 t02 t03 t04 t05 t06 t07 t08 t09 t10 t11 t12 t13 t14 t15 t16 \ + t17 t18 t19 .for T in $(TESTS) run-tests: $(T).diff diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t07.good --- a/tests/t07.good Sun Mar 31 06:45:44 2013 +0200 +++ b/tests/t07.good Sun Mar 31 07:19:49 2013 +0200 @@ -1,1 +1,3 @@ + + diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t09.good --- a/tests/t09.good Sun Mar 31 06:45:44 2013 +0200 +++ b/tests/t09.good Sun Mar 31 07:19:49 2013 +0200 @@ -1,1 +1,3 @@ - fnord + + + diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t13.c --- a/tests/t13.c Sun Mar 31 06:45:44 2013 +0200 +++ b/tests/t13.c Sun Mar 31 07:19:49 2013 +0200 @@ -1,11 +1,4 @@ -#define a() x -a() -a () -#define b(p) p -x/**/b(1)/**/x -x/**/b (1)/**/x -x/**/b()/**/x -#define c(p,q) p/**/q -x/**/c(1,2)/**/x -x/**/c(1)/**/x -x/**/c()/**/x +/* +#define FOO BAR +*/ +FOO diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t13.good --- a/tests/t13.good Sun Mar 31 06:45:44 2013 +0200 +++ b/tests/t13.good Sun Mar 31 07:19:49 2013 +0200 @@ -1,11 +1,4 @@ -x -x -x1x -x1x -xx -x12x -t13.c:10:1: Wrong number of arguments for macro c; found 1, expected 2 -x1x -t13.c:11:1: Wrong number of arguments for macro c; found 0, expected 2 -xx -FAILED + + + +FOO diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t14.c --- a/tests/t14.c Sun Mar 31 06:45:44 2013 +0200 +++ b/tests/t14.c Sun Mar 31 07:19:49 2013 +0200 @@ -1,2 +1,4 @@ -#define file "subdir/test.h" -#include file +/* +#define FOO BAR */ +FOO +FOO diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t14.good --- a/tests/t14.good Sun Mar 31 06:45:44 2013 +0200 +++ b/tests/t14.good Sun Mar 31 07:19:49 2013 +0200 @@ -1,1 +1,4 @@ -hello + + +FOO +FOO diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t15.c --- a/tests/t15.c Sun Mar 31 06:45:44 2013 +0200 +++ b/tests/t15.c Sun Mar 31 07:19:49 2013 +0200 @@ -1,2 +1,3 @@ -#if FOO /* ignore me */ -#endif +#define FOO /* BAR */ BAZ +FOO +FOO diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t15.good --- a/tests/t15.good Sun Mar 31 06:45:44 2013 +0200 +++ b/tests/t15.good Sun Mar 31 07:19:49 2013 +0200 @@ -0,0 +1,2 @@ + BAZ + BAZ diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t17.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/t17.c Sun Mar 31 07:19:49 2013 +0200 @@ -0,0 +1,11 @@ +#define a() x +a() +a () +#define b(p) p +x/**/b(1)/**/x +x/**/b (1)/**/x +x/**/b()/**/x +#define c(p,q) p/**/q +x/**/c(1,2)/**/x +x/**/c(1)/**/x +x/**/c()/**/x diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t17.good --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/t17.good Sun Mar 31 07:19:49 2013 +0200 @@ -0,0 +1,11 @@ +x +x +x1x +x1x +xx +x12x +t17.c:10:1: Wrong number of arguments for macro c; found 1, expected 2 +x1x +t17.c:11:1: Wrong number of arguments for macro c; found 0, expected 2 +xx +FAILED diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t18.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/t18.c Sun Mar 31 07:19:49 2013 +0200 @@ -0,0 +1,2 @@ +#define file "subdir/test.h" +#include file diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t18.good --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/t18.good Sun Mar 31 07:19:49 2013 +0200 @@ -0,0 +1,1 @@ +hello diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t19.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/t19.c Sun Mar 31 07:19:49 2013 +0200 @@ -0,0 +1,2 @@ +#if FOO /* ignore me */ +#endif diff -r a3dd0db23b0c -r 737ffe27b4bd tests/t19.good --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/t19.good Sun Mar 31 07:19:49 2013 +0200 @@ -0,0 +1,2 @@ + +