aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdmund Grimley Evans <Edmund.Grimley.Evans@gmail.com>2016-05-04 21:37:11 +0100
committerEdmund Grimley Evans <Edmund.Grimley.Evans@gmail.com>2016-05-09 19:27:31 +0100
commitf5f82abc99424c4ece836000934fcf57a867c635 (patch)
tree2e70deb54bcac302987e7a20f124041c34c00f51
parent75243f744c60e588ee68c1a47f1ce691a36c07a7 (diff)
downloadtinycc-f5f82abc99424c4ece836000934fcf57a867c635.tar.gz
tinycc-f5f82abc99424c4ece836000934fcf57a867c635.tar.bz2
Insert spaces between certain tokens when tcc is invoked with -E.
Insert a space when it is required to prevent mistokenisation of the output, and also in a few cases where it is not strictly required, imitating GCC's behaviour.
-rw-r--r--TODO2
-rw-r--r--tccpp.c54
-rw-r--r--tests/pp/15.c5
-rw-r--r--tests/pp/15.expect20
4 files changed, 78 insertions, 3 deletions
diff --git a/TODO b/TODO
index bc7fb8b..e6e5b07 100644
--- a/TODO
+++ b/TODO
@@ -31,7 +31,6 @@ Bugs:
- make libtcc fully reentrant (except for the compilation stage itself).
- struct/union/enum definitions in nested scopes (see also Debian bug #770657)
- __STDC_IEC_559__: float f(void) { static float x = 0.0 / 0.0; return x; }
-- preprocessor: #define Y(x) Z(x) {newline} #define X Y {newline} X(X(1))
Portability:
@@ -94,7 +93,6 @@ Not critical:
- handle void (__attribute__() *ptr)()
- VLAs are implemented in a way that is not compatible with signals:
http://lists.gnu.org/archive/html/tinycc-devel/2015-11/msg00018.html
-- output with -E should include spaces: #define n 0xe {newline} n+1
Fixed (probably):
diff --git a/tccpp.c b/tccpp.c
index c5b0192..718401d 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -3644,12 +3644,61 @@ static void pp_debug_builtins(TCCState *s1)
define_print(s1, v);
}
+static int need_space(int prev_tok, int tok, const char *tokstr)
+{
+ const char *sp_chars = "";
+ if ((prev_tok >= TOK_IDENT || prev_tok == TOK_PPNUM) &&
+ (tok >= TOK_IDENT || tok == TOK_PPNUM))
+ return 1;
+ switch (prev_tok) {
+ case '+':
+ sp_chars = "+=";
+ break;
+ case '-':
+ sp_chars = "-=>";
+ break;
+ case '*':
+ case '/':
+ case '%':
+ case '^':
+ case '=':
+ case '!':
+ case TOK_A_SHL:
+ case TOK_A_SAR:
+ sp_chars = "=";
+ break;
+ case '&':
+ sp_chars = "&=";
+ break;
+ case '|':
+ sp_chars = "|=";
+ break;
+ case '<':
+ sp_chars = "<=";
+ break;
+ case '>':
+ sp_chars = ">=";
+ break;
+ case '.':
+ sp_chars = ".";
+ break;
+ case '#':
+ sp_chars = "#";
+ break;
+ case TOK_PPNUM:
+ sp_chars = "+-";
+ break;
+ }
+ return !!strchr(sp_chars, tokstr[0]);
+}
+
/* Preprocess the current file */
ST_FUNC int tcc_preprocess(TCCState *s1)
{
BufferedFile **iptr;
int token_seen, spcs, level;
Sym *define_start;
+ const char *tokstr;
preprocess_init(s1);
ch = file->buf_ptr[0];
@@ -3707,9 +3756,12 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
++file->line_ref;
}
+ tokstr = get_tok_str(tok, &tokc);
+ if (!spcs && need_space(token_seen, tok, tokstr))
+ ++spcs;
while (spcs)
fputs(" ", s1->ppfp), --spcs;
- fputs(get_tok_str(tok, &tokc), s1->ppfp);
+ fputs(tokstr, s1->ppfp);
token_seen = tok;
}
diff --git a/tests/pp/15.c b/tests/pp/15.c
index 28a12bd..dc2b8d1 100644
--- a/tests/pp/15.c
+++ b/tests/pp/15.c
@@ -19,3 +19,8 @@ return A + B;
#define B1 C1+2
#define C1 A1+3
return A1 + B1;
+
+#define i() x
+#define n() 1
+i()i()n()n()i()
+i()+i()-n()+n()-
diff --git a/tests/pp/15.expect b/tests/pp/15.expect
index 7ccee4a..d3d3dd5 100644
--- a/tests/pp/15.expect
+++ b/tests/pp/15.expect
@@ -1,6 +1,26 @@
+
+
Z(1)
Z(Z(1))
Z(Z(Z(Z(Z(1)))))
+
+
+
return A + B;
+
+
+
+
+
+
return A+1 + B+1;
+
+
+
+
return A1+3 +2 +1 + B1+1 +3 +2;
+
+
+
+x x 1 1 x
+x+x-1 +1 -