History

tcc -E: preserve spaces, alternative solution

/* test case */ #define STR(x) #x #define MKSTR(x) STR(x) MKSTR(-A-) MKSTR(+ B +) tcc -E: expected result: "-A-" "+ B +"

grischka committed 17 years ago

Commit 0f0ed4a1 parent 90697c41 file · +73 −43Browse files

Unified · Split

tcc.c+73−43
@@ -336,7 +336,6 @@ typedef struct CachedInclude { · 335 unmodified lines
336336 /* parser */
337337 static struct BufferedFile *file;
338338 static int ch, tok;
339−static CString tok_spaces; /* spaces before current token */
340339 static CValue tokc;
341340 static CString tokcstr; /* current parsed string, if any */
342341 /* additional informations about token */
@@ -357,6 +356,7 @@ static int parse_flags; · 14 unmodified lines
357356 token. line feed is also
358357 returned at eof */
359358 #define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
359+#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */
360360
361361 static Section *text_section, *data_section, *bss_section; /* predefined sections */
362362 static Section *cur_text_section; /* current section where function code is
@@ -797,6 +797,7 @@ static char *tcc_fileextension (const char *p); · 434 unmodified lines
797797
798798 static void next(void);
799799 static void next_nomacro(void);
800+static void next_nomacro_spc(void);
800801 static void parse_expr_type(CType *type);
801802 static void expr_type(CType *type);
802803 static void unary_type(CType *type);
@@ -2290,6 +2291,17 @@ static inline void skip_spaces(void) · 1487 unmodified lines
22902291 cinp();
22912292 }
22922293
2294+static inline int check_space(int t, int *spc)
2295+{
2296+ if (is_space(t)) {
2297+ if (*spc)
2298+ return 1;
2299+ *spc = 1;
2300+ } else
2301+ *spc = 0;
2302+ return 0;
2303+}
2304+
22932305 /* parse a string without interpreting escapes */
22942306 static uint8_t *parse_pp_string(uint8_t *p,
22952307 int sep, CString *str)
@@ -2822,13 +2834,14 @@ static void tok_print(int *str) · 526 unmodified lines
28222834 int t;
28232835 CValue cval;
28242836
2837+ printf("<");
28252838 while (1) {
28262839 TOK_GET(t, str, cval);
28272840 if (!t)
28282841 break;
2829− printf(" %s", get_tok_str(t, &cval));
2842+ printf("%s", get_tok_str(t, &cval));
28302843 }
2831− printf("\n");
2844+ printf(">\n");
28322845 }
28332846 #endif
28342847
@@ -2836,7 +2849,7 @@ static void tok_print(int *str) · 1 unmodified line
28362849 static void parse_define(void)
28372850 {
28382851 Sym *s, *first, **ps;
2839− int v, t, varg, is_vaargs, c;
2852+ int v, t, varg, is_vaargs, spc;
28402853 TokenString str;
28412854
28422855 v = tok;
@@ -2846,11 +2859,8 @@ static void parse_define(void) · 3 unmodified lines
28462859 first = NULL;
28472860 t = MACRO_OBJ;
28482861 /* '(' must be just after macro definition for MACRO_FUNC */
2849− c = file->buf_ptr[0];
2850− if (c == '\\')
2851− c = handle_stray1(file->buf_ptr);
2852− if (c == '(') {
2853− next_nomacro();
2862+ next_nomacro_spc();
2863+ if (tok == '(') {
28542864 next_nomacro();
28552865 ps = &first;
28562866 while (tok != ')') {
@@ -2873,15 +2883,30 @@ static void parse_define(void) · 16 unmodified lines
28732883 break;
28742884 next_nomacro();
28752885 }
2886+ if (tok == ')')
2887+ next_nomacro_spc();
28762888 t = MACRO_FUNC;
28772889 }
28782890 tok_str_new(&str);
2879− next_nomacro();
2891+ spc = 2;
28802892 /* EOF testing necessary for '-D' handling */
28812893 while (tok != TOK_LINEFEED && tok != TOK_EOF) {
2894+ /* remove spaces around ## and after '#' */
2895+ if (TOK_TWOSHARPS == tok) {
2896+ if (1 == spc)
2897+ --str.len;
2898+ spc = 2;
2899+ } else if ('#' == tok) {
2900+ spc = 2;
2901+ } else if (check_space(tok, &spc)) {
2902+ goto skip;
2903+ }
28822904 tok_str_add2(&str, tok, &tokc);
2883− next_nomacro();
2905+ skip:
2906+ next_nomacro_spc();
28842907 }
2908+ if (spc == 1)
2909+ --str.len; /* remove trailing space */
28852910 tok_str_add(&str, 0);
28862911 #ifdef PP_DEBUG
28872912 printf("define %s %d: ", get_tok_str(v, NULL), t);
@@ -3703,20 +3728,20 @@ static inline void next_nomacro1(void) · 815 unmodified lines
37033728 uint8_t *p, *p1;
37043729 unsigned int h;
37053730
3706− cstr_reset(&tok_spaces);
37073731 p = file->buf_ptr;
37083732 redo_no_start:
37093733 c = *p;
37103734 switch(c) {
37113735 case ' ':
37123736 case '\t':
3737+ tok = c;
3738+ p++;
3739+ goto keep_tok_flags;
37133740 case '\f':
37143741 case '\v':
37153742 case '\r':
3716− cstr_ccat(&tok_spaces, c);
37173743 p++;
37183744 goto redo_no_start;
3719−
37203745 case '\\':
37213746 /* first look if it is in fact an end of buffer */
37223747 if (p >= file->buf_end) {
@@ -4121,7 +4146,7 @@ keep_tok_flags: · 398 unmodified lines
41214146
41224147 /* return next token without macro substitution. Can read input from
41234148 macro_ptr buffer */
4124−static void next_nomacro(void)
4149+static void next_nomacro_spc(void)
41254150 {
41264151 if (macro_ptr) {
41274152 redo:
@@ -4138,10 +4163,17 @@ static void next_nomacro(void) · 10 unmodified lines
41384163 }
41394164 }
41404165
4166+static void next_nomacro(void)
4167+{
4168+ do {
4169+ next_nomacro_spc();
4170+ } while (is_space(tok));
4171+}
4172+
41414173 /* substitute args in macro_str and return allocated string */
41424174 static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
41434175 {
4144− int *st, last_tok, t, notfirst;
4176+ int *st, last_tok, t, spc;
41454177 Sym *s;
41464178 CValue cval;
41474179 TokenString str;
@@ -4162,16 +4194,13 @@ static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args) · 14 unmodified lines
41624194 if (s) {
41634195 cstr_new(&cstr);
41644196 st = (int *)s->c;
4165− notfirst = 0;
4197+ spc = 0;
41664198 while (*st) {
4167− if (notfirst)
4168− cstr_ccat(&cstr, ' ');
41694199 TOK_GET(t, st, cval);
4170− cstr_cat(&cstr, get_tok_str(t, &cval));
4171−#ifndef PP_NOSPACES
4172− notfirst = 1;
4173−#endif
4200+ if (!check_space(t, &spc))
4201+ cstr_cat(&cstr, get_tok_str(t, &cval));
41744202 }
4203+ cstr.size -= spc;
41754204 cstr_ccat(&cstr, '\0');
41764205 #ifdef PP_DEBUG
41774206 printf("stringize: %s\n", (char *)cstr.data);
@@ -4246,7 +4275,7 @@ static int macro_subst_tok(TokenString *tok_str, · 68 unmodified lines
42464275 Sym **nested_list, Sym *s, struct macro_level **can_read_stream)
42474276 {
42484277 Sym *args, *sa, *sa1;
4249− int mstr_allocated, parlevel, *mstr, t, t1;
4278+ int mstr_allocated, parlevel, *mstr, t, t1, *p, spc;
42504279 TokenString str;
42514280 char *cstrval;
42524281 CValue cval;
@@ -4294,7 +4323,9 @@ static int macro_subst_tok(TokenString *tok_str, · 41 unmodified lines
42944323 next token. XXX: find better solution */
42954324 redo:
42964325 if (macro_ptr) {
4297− t = *macro_ptr;
4326+ p = macro_ptr;
4327+ while (is_space(t = *p) || TOK_LINEFEED == t)
4328+ ++p;
42984329 if (t == 0 && can_read_stream) {
42994330 /* end of macro stream: we must look at the token
43004331 after in the file */
@@ -4332,7 +4363,7 @@ static int macro_subst_tok(TokenString *tok_str, · 31 unmodified lines
43324363 error("macro '%s' used with too many args",
43334364 get_tok_str(s->v, 0));
43344365 tok_str_new(&str);
4335− parlevel = 0;
4366+ parlevel = spc = 0;
43364367 /* NOTE: non zero sa->t indicates VA_ARGS */
43374368 while ((parlevel > 0 ||
43384369 (tok != ')' &&
@@ -4342,10 +4373,13 @@ static int macro_subst_tok(TokenString *tok_str, · 3 unmodified lines
43424373 parlevel++;
43434374 else if (tok == ')')
43444375 parlevel--;
4345− if (tok != TOK_LINEFEED)
4376+ if (tok == TOK_LINEFEED)
4377+ tok = ' ';
4378+ if (!check_space(tok, &spc))
43464379 tok_str_add2(&str, tok, &tokc);
4347− next_nomacro();
4380+ next_nomacro_spc();
43484381 }
4382+ str.len -= spc;
43494383 tok_str_add(&str, 0);
43504384 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (long)str.str);
43514385 sa = sa->next;
@@ -4535,7 +4569,7 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 183 unmodified lines
45354569 Sym *s;
45364570 int *macro_str1;
45374571 const int *ptr;
4538− int t, ret;
4572+ int t, ret, spc;
45394573 CValue cval;
45404574 struct macro_level ml;
45414575
@@ -4544,6 +4578,7 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 2 unmodified lines
45444578 macro_str1 = macro_twosharps(ptr);
45454579 if (macro_str1)
45464580 ptr = macro_str1;
4581+ spc = 0;
45474582 while (1) {
45484583 /* NOTE: ptr == NULL can only happen if tokens are read from
45494584 file stream due to a macro function call */
@@ -4571,7 +4606,8 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 21 unmodified lines
45714606 goto no_subst;
45724607 } else {
45734608 no_subst:
4574− tok_str_add2(tok_str, t, &cval);
4609+ if (!check_space(t, &spc))
4610+ tok_str_add2(tok_str, t, &cval);
45754611 }
45764612 }
45774613 if (macro_str1)
@@ -4586,7 +4622,10 @@ static void next(void) · 8 unmodified lines
45864622 struct macro_level *ml;
45874623
45884624 redo:
4589− next_nomacro();
4625+ if (parse_flags & PARSE_FLAG_SPACES)
4626+ next_nomacro_spc();
4627+ else
4628+ next_nomacro();
45904629 if (!macro_ptr) {
45914630 /* if not reading from macro substituted string, then try
45924631 to substitute macros */
@@ -9873,10 +9912,6 @@ static int tcc_compile(TCCState *s1) · 5280 unmodified lines
98739912 }
98749913
98759914 /* Preprocess the current file */
9876−/* XXX: add line and file infos,
9877− * XXX: add options to preserve spaces (partly done, only spaces in macro are
9878− * not preserved)
9879− */
98809915 static int tcc_preprocess(TCCState *s1)
98819916 {
98829917 Sym *define_start;
@@ -9886,11 +9921,9 @@ static int tcc_preprocess(TCCState *s1) · 3 unmodified lines
98869921 preprocess_init(s1);
98879922 define_start = define_stack;
98889923 ch = file->buf_ptr[0];
9889−
98909924 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
9891− parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS |
9892− PARSE_FLAG_LINEFEED;
9893−
9925+ parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS |
9926+ PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES;
98949927 token_seen = 0;
98959928 line_ref = 0;
98969929 file_ref = NULL;
@@ -9904,9 +9937,7 @@ static int tcc_preprocess(TCCState *s1) · 7 unmodified lines
99049937 continue;
99059938 ++line_ref;
99069939 token_seen = 0;
9907− } else if (token_seen) {
9908− fwrite(tok_spaces.data, tok_spaces.size, 1, s1->outfile);
9909− } else {
9940+ } else if (!token_seen) {
99109941 int d = file->line_num - line_ref;
99119942 if (file != file_ref || d < 0 || d >= 8)
99129943 fprintf(s1->outfile, "# %d \"%s\"\n", file->line_num, file->filename);
@@ -10455,7 +10486,6 @@ static void tcc_cleanup(void) · 542 unmodified lines
1045510486 dynarray_reset(&sym_pools, &nb_sym_pools);
1045610487 /* string buffer */
1045710488 cstr_free(&tokcstr);
10458− cstr_free(&tok_spaces);
1045910489 /* reset symbol stack */
1046010490 sym_free_first = NULL;
1046110491 /* cleanup from error/setjmp */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t