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
336/* parser */336/* parser */
337static struct BufferedFile *file;337static struct BufferedFile *file;
338static int ch, tok;338static int ch, tok;
339static CString tok_spaces; /* spaces before current token */
340static CValue tokc;339static CValue tokc;
341static CString tokcstr; /* current parsed string, if any */340static CString tokcstr; /* current parsed string, if any */
342/* additional informations about token */341/* additional informations about token */
@@ -357,6 +356,7 @@ static int parse_flags; · 14 unmodified lines
357 token. line feed is also356 token. line feed is also
358 returned at eof */357 returned at eof */
359#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */358#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
359#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */
360 360
361static Section *text_section, *data_section, *bss_section; /* predefined sections */361static Section *text_section, *data_section, *bss_section; /* predefined sections */
362static Section *cur_text_section; /* current section where function code is362static Section *cur_text_section; /* current section where function code is
@@ -797,6 +797,7 @@ static char *tcc_fileextension (const char *p); · 434 unmodified lines
797 797
798static void next(void);798static void next(void);
799static void next_nomacro(void);799static void next_nomacro(void);
800static void next_nomacro_spc(void);
800static void parse_expr_type(CType *type);801static void parse_expr_type(CType *type);
801static void expr_type(CType *type);802static void expr_type(CType *type);
802static void unary_type(CType *type);803static void unary_type(CType *type);
@@ -2290,6 +2291,17 @@ static inline void skip_spaces(void) · 1487 unmodified lines
2290 cinp();2291 cinp();
2291}2292}
2292 2293
2294static 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
2293/* parse a string without interpreting escapes */2305/* parse a string without interpreting escapes */
2294static uint8_t *parse_pp_string(uint8_t *p,2306static uint8_t *parse_pp_string(uint8_t *p,
2295 int sep, CString *str)2307 int sep, CString *str)
@@ -2822,13 +2834,14 @@ static void tok_print(int *str) · 526 unmodified lines
2822 int t;2834 int t;
2823 CValue cval;2835 CValue cval;
2824 2836
2837 printf("<");
2825 while (1) {2838 while (1) {
2826 TOK_GET(t, str, cval);2839 TOK_GET(t, str, cval);
2827 if (!t)2840 if (!t)
2828 break;2841 break;
2829 printf(" %s", get_tok_str(t, &cval));2842 printf("%s", get_tok_str(t, &cval));
2830 }2843 }
2831 printf("\n");2844 printf(">\n");
2832}2845}
2833#endif2846#endif
2834 2847
@@ -2836,7 +2849,7 @@ static void tok_print(int *str) · 1 unmodified line
2836static void parse_define(void)2849static void parse_define(void)
2837{2850{
2838 Sym *s, *first, **ps;2851 Sym *s, *first, **ps;
2839 int v, t, varg, is_vaargs, c;2852 int v, t, varg, is_vaargs, spc;
2840 TokenString str;2853 TokenString str;
2841 2854
2842 v = tok;2855 v = tok;
@@ -2846,11 +2859,8 @@ static void parse_define(void) · 3 unmodified lines
2846 first = NULL;2859 first = NULL;
2847 t = MACRO_OBJ;2860 t = MACRO_OBJ;
2848 /* '(' must be just after macro definition for MACRO_FUNC */2861 /* '(' must be just after macro definition for MACRO_FUNC */
2849 c = file->buf_ptr[0];2862 next_nomacro_spc();
2850 if (c == '\\')2863 if (tok == '(') {
2851 c = handle_stray1(file->buf_ptr);
2852 if (c == '(') {
2853 next_nomacro();
2854 next_nomacro();2864 next_nomacro();
2855 ps = &first;2865 ps = &first;
2856 while (tok != ')') {2866 while (tok != ')') {
@@ -2873,15 +2883,30 @@ static void parse_define(void) · 16 unmodified lines
2873 break;2883 break;
2874 next_nomacro();2884 next_nomacro();
2875 }2885 }
2886 if (tok == ')')
2887 next_nomacro_spc();
2876 t = MACRO_FUNC;2888 t = MACRO_FUNC;
2877 }2889 }
2878 tok_str_new(&str);2890 tok_str_new(&str);
2879 next_nomacro();2891 spc = 2;
2880 /* EOF testing necessary for '-D' handling */2892 /* EOF testing necessary for '-D' handling */
2881 while (tok != TOK_LINEFEED && tok != TOK_EOF) {2893 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 }
2882 tok_str_add2(&str, tok, &tokc);2904 tok_str_add2(&str, tok, &tokc);
2883 next_nomacro();2905 skip:
2906 next_nomacro_spc();
2884 }2907 }
2908 if (spc == 1)
2909 --str.len; /* remove trailing space */
2885 tok_str_add(&str, 0);2910 tok_str_add(&str, 0);
2886#ifdef PP_DEBUG2911#ifdef PP_DEBUG
2887 printf("define %s %d: ", get_tok_str(v, NULL), t);2912 printf("define %s %d: ", get_tok_str(v, NULL), t);
@@ -3703,20 +3728,20 @@ static inline void next_nomacro1(void) · 815 unmodified lines
3703 uint8_t *p, *p1;3728 uint8_t *p, *p1;
3704 unsigned int h;3729 unsigned int h;
3705 3730
3706 cstr_reset(&tok_spaces);
3707 p = file->buf_ptr;3731 p = file->buf_ptr;
3708 redo_no_start:3732 redo_no_start:
3709 c = *p;3733 c = *p;
3710 switch(c) {3734 switch(c) {
3711 case ' ':3735 case ' ':
3712 case '\t':3736 case '\t':
3737 tok = c;
3738 p++;
3739 goto keep_tok_flags;
3713 case '\f':3740 case '\f':
3714 case '\v':3741 case '\v':
3715 case '\r':3742 case '\r':
3716 cstr_ccat(&tok_spaces, c);
3717 p++;3743 p++;
3718 goto redo_no_start;3744 goto redo_no_start;
3719
3720 case '\\':3745 case '\\':
3721 /* first look if it is in fact an end of buffer */3746 /* first look if it is in fact an end of buffer */
3722 if (p >= file->buf_end) {3747 if (p >= file->buf_end) {
@@ -4121,7 +4146,7 @@ keep_tok_flags: · 398 unmodified lines
4121 4146
4122/* return next token without macro substitution. Can read input from4147/* return next token without macro substitution. Can read input from
4123 macro_ptr buffer */4148 macro_ptr buffer */
4124static void next_nomacro(void)4149static void next_nomacro_spc(void)
4125{4150{
4126 if (macro_ptr) {4151 if (macro_ptr) {
4127 redo:4152 redo:
@@ -4138,10 +4163,17 @@ static void next_nomacro(void) · 10 unmodified lines
4138 }4163 }
4139}4164}
4140 4165
4166static void next_nomacro(void)
4167{
4168 do {
4169 next_nomacro_spc();
4170 } while (is_space(tok));
4171}
4172
4141/* substitute args in macro_str and return allocated string */4173/* substitute args in macro_str and return allocated string */
4142static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)4174static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
4143{4175{
4144 int *st, last_tok, t, notfirst;4176 int *st, last_tok, t, spc;
4145 Sym *s;4177 Sym *s;
4146 CValue cval;4178 CValue cval;
4147 TokenString str;4179 TokenString str;
@@ -4162,16 +4194,13 @@ static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args) · 14 unmodified lines
4162 if (s) {4194 if (s) {
4163 cstr_new(&cstr);4195 cstr_new(&cstr);
4164 st = (int *)s->c;4196 st = (int *)s->c;
4165 notfirst = 0;4197 spc = 0;
4166 while (*st) {4198 while (*st) {
4167 if (notfirst)
4168 cstr_ccat(&cstr, ' ');
4169 TOK_GET(t, st, cval);4199 TOK_GET(t, st, cval);
4170 cstr_cat(&cstr, get_tok_str(t, &cval));4200 if (!check_space(t, &spc))
4171#ifndef PP_NOSPACES4201 cstr_cat(&cstr, get_tok_str(t, &cval));
4172 notfirst = 1;
4173#endif
4174 }4202 }
4203 cstr.size -= spc;
4175 cstr_ccat(&cstr, '\0');4204 cstr_ccat(&cstr, '\0');
4176#ifdef PP_DEBUG4205#ifdef PP_DEBUG
4177 printf("stringize: %s\n", (char *)cstr.data);4206 printf("stringize: %s\n", (char *)cstr.data);
@@ -4246,7 +4275,7 @@ static int macro_subst_tok(TokenString *tok_str, · 68 unmodified lines
4246 Sym **nested_list, Sym *s, struct macro_level **can_read_stream)4275 Sym **nested_list, Sym *s, struct macro_level **can_read_stream)
4247{4276{
4248 Sym *args, *sa, *sa1;4277 Sym *args, *sa, *sa1;
4249 int mstr_allocated, parlevel, *mstr, t, t1;4278 int mstr_allocated, parlevel, *mstr, t, t1, *p, spc;
4250 TokenString str;4279 TokenString str;
4251 char *cstrval;4280 char *cstrval;
4252 CValue cval;4281 CValue cval;
@@ -4294,7 +4323,9 @@ static int macro_subst_tok(TokenString *tok_str, · 41 unmodified lines
4294 next token. XXX: find better solution */4323 next token. XXX: find better solution */
4295 redo:4324 redo:
4296 if (macro_ptr) {4325 if (macro_ptr) {
4297 t = *macro_ptr;4326 p = macro_ptr;
4327 while (is_space(t = *p) || TOK_LINEFEED == t)
4328 ++p;
4298 if (t == 0 && can_read_stream) {4329 if (t == 0 && can_read_stream) {
4299 /* end of macro stream: we must look at the token4330 /* end of macro stream: we must look at the token
4300 after in the file */4331 after in the file */
@@ -4332,7 +4363,7 @@ static int macro_subst_tok(TokenString *tok_str, · 31 unmodified lines
4332 error("macro '%s' used with too many args",4363 error("macro '%s' used with too many args",
4333 get_tok_str(s->v, 0));4364 get_tok_str(s->v, 0));
4334 tok_str_new(&str);4365 tok_str_new(&str);
4335 parlevel = 0;4366 parlevel = spc = 0;
4336 /* NOTE: non zero sa->t indicates VA_ARGS */4367 /* NOTE: non zero sa->t indicates VA_ARGS */
4337 while ((parlevel > 0 || 4368 while ((parlevel > 0 ||
4338 (tok != ')' && 4369 (tok != ')' &&
@@ -4342,10 +4373,13 @@ static int macro_subst_tok(TokenString *tok_str, · 3 unmodified lines
4342 parlevel++;4373 parlevel++;
4343 else if (tok == ')')4374 else if (tok == ')')
4344 parlevel--;4375 parlevel--;
4345 if (tok != TOK_LINEFEED)4376 if (tok == TOK_LINEFEED)
4377 tok = ' ';
4378 if (!check_space(tok, &spc))
4346 tok_str_add2(&str, tok, &tokc);4379 tok_str_add2(&str, tok, &tokc);
4347 next_nomacro();4380 next_nomacro_spc();
4348 }4381 }
4382 str.len -= spc;
4349 tok_str_add(&str, 0);4383 tok_str_add(&str, 0);
4350 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (long)str.str);4384 sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, (long)str.str);
4351 sa = sa->next;4385 sa = sa->next;
@@ -4535,7 +4569,7 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 183 unmodified lines
4535 Sym *s;4569 Sym *s;
4536 int *macro_str1;4570 int *macro_str1;
4537 const int *ptr;4571 const int *ptr;
4538 int t, ret;4572 int t, ret, spc;
4539 CValue cval;4573 CValue cval;
4540 struct macro_level ml;4574 struct macro_level ml;
4541 4575
@@ -4544,6 +4578,7 @@ static void macro_subst(TokenString *tok_str, Sym **nested_list, · 2 unmodified lines
4544 macro_str1 = macro_twosharps(ptr);4578 macro_str1 = macro_twosharps(ptr);
4545 if (macro_str1) 4579 if (macro_str1)
4546 ptr = macro_str1;4580 ptr = macro_str1;
4581 spc = 0;
4547 while (1) {4582 while (1) {
4548 /* NOTE: ptr == NULL can only happen if tokens are read from4583 /* NOTE: ptr == NULL can only happen if tokens are read from
4549 file stream due to a macro function call */4584 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
4571 goto no_subst;4606 goto no_subst;
4572 } else {4607 } else {
4573 no_subst:4608 no_subst:
4574 tok_str_add2(tok_str, t, &cval);4609 if (!check_space(t, &spc))
4610 tok_str_add2(tok_str, t, &cval);
4575 }4611 }
4576 }4612 }
4577 if (macro_str1)4613 if (macro_str1)
@@ -4586,7 +4622,10 @@ static void next(void) · 8 unmodified lines
4586 struct macro_level *ml;4622 struct macro_level *ml;
4587 4623
4588 redo:4624 redo:
4589 next_nomacro();4625 if (parse_flags & PARSE_FLAG_SPACES)
4626 next_nomacro_spc();
4627 else
4628 next_nomacro();
4590 if (!macro_ptr) {4629 if (!macro_ptr) {
4591 /* if not reading from macro substituted string, then try4630 /* if not reading from macro substituted string, then try
4592 to substitute macros */4631 to substitute macros */
@@ -9873,10 +9912,6 @@ static int tcc_compile(TCCState *s1) · 5280 unmodified lines
9873}9912}
9874 9913
9875/* Preprocess the current file */9914/* 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 */
9880static int tcc_preprocess(TCCState *s1)9915static int tcc_preprocess(TCCState *s1)
9881{9916{
9882 Sym *define_start;9917 Sym *define_start;
@@ -9886,11 +9921,9 @@ static int tcc_preprocess(TCCState *s1) · 3 unmodified lines
9886 preprocess_init(s1);9921 preprocess_init(s1);
9887 define_start = define_stack;9922 define_start = define_stack;
9888 ch = file->buf_ptr[0];9923 ch = file->buf_ptr[0];
9889
9890 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;9924 tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
9891 parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS | 9925 parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS |
9892 PARSE_FLAG_LINEFEED;9926 PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES;
9893
9894 token_seen = 0;9927 token_seen = 0;
9895 line_ref = 0;9928 line_ref = 0;
9896 file_ref = NULL;9929 file_ref = NULL;
@@ -9904,9 +9937,7 @@ static int tcc_preprocess(TCCState *s1) · 7 unmodified lines
9904 continue;9937 continue;
9905 ++line_ref;9938 ++line_ref;
9906 token_seen = 0;9939 token_seen = 0;
9907 } else if (token_seen) {9940 } else if (!token_seen) {
9908 fwrite(tok_spaces.data, tok_spaces.size, 1, s1->outfile);
9909 } else {
9910 int d = file->line_num - line_ref;9941 int d = file->line_num - line_ref;
9911 if (file != file_ref || d < 0 || d >= 8)9942 if (file != file_ref || d < 0 || d >= 8)
9912 fprintf(s1->outfile, "# %d \"%s\"\n", file->line_num, file->filename);9943 fprintf(s1->outfile, "# %d \"%s\"\n", file->line_num, file->filename);
@@ -10455,7 +10486,6 @@ static void tcc_cleanup(void) · 542 unmodified lines
10455 dynarray_reset(&sym_pools, &nb_sym_pools);10486 dynarray_reset(&sym_pools, &nb_sym_pools);
10456 /* string buffer */10487 /* string buffer */
10457 cstr_free(&tokcstr);10488 cstr_free(&tokcstr);
10458 cstr_free(&tok_spaces);
10459 /* reset symbol stack */10489 /* reset symbol stack */
10460 sym_free_first = NULL;10490 sym_free_first = NULL;
10461 /* cleanup from error/setjmp */10491 /* 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