| @@ -49,6 +49,9 @@ static char token_buf[STRING_MAX_SIZE + 1]; · 48 unmodified lines |
| 49 | static CString cstr_buf; | 49 | static CString cstr_buf; |
| 50 | static TokenString tokstr_buf; | 50 | static TokenString tokstr_buf; |
| 51 | static unsigned char isidnum_table[256 - CH_EOF]; | 51 | static unsigned char isidnum_table[256 - CH_EOF]; |
| | 52 | static int pp_debug_tok, pp_debug_symv; |
| | 53 | static void tok_print(const char *msg, const int *str); |
| | 54 | |
| 52 | /* isidnum_table flags: */ | 55 | /* isidnum_table flags: */ |
| 53 | #define IS_SPC 1 | 56 | #define IS_SPC 1 |
| 54 | #define IS_ID 2 | 57 | #define IS_ID 2 |
| @@ -129,6 +132,21 @@ ST_FUNC void end_macro(void) · 74 unmodified lines |
| 129 | } | 132 | } |
| 130 | } | 133 | } |
| 131 | | 134 | |
| | 135 | ST_FUNC char *trimfront(char *p) |
| | 136 | { |
| | 137 | while (*p && (unsigned char)*p <= ' ') |
| | 138 | ++p; |
| | 139 | return p; |
| | 140 | } |
| | 141 | |
| | 142 | ST_FUNC char *trimback(char *a, char *e) |
| | 143 | { |
| | 144 | while (e > a && (unsigned char)e[-1] <= ' ') |
| | 145 | --e; |
| | 146 | *e = 0;; |
| | 147 | return a; |
| | 148 | } |
| | 149 | |
| 132 | /* ------------------------------------------------------------------------- */ | 150 | /* ------------------------------------------------------------------------- */ |
| 133 | /* Custom allocator for tiny objects */ | 151 | /* Custom allocator for tiny objects */ |
| 134 | | 152 | |
| @@ -675,80 +693,12 @@ ST_FUNC void minp(void) · 540 unmodified lines |
| 675 | handle_stray(); | 693 | handle_stray(); |
| 676 | } | 694 | } |
| 677 | | 695 | |
| 678 | static void pp_line(TCCState *s1, BufferedFile *f, int level) | | |
| 679 | { | | |
| 680 | if (s1->ppfp) { | | |
| 681 | int d = f->line_num - f->line_ref; | | |
| 682 | if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_NONE | | |
| 683 | || (level == 0 && f->line_ref && d < 8)) { | | |
| 684 | while (d > 0) | | |
| 685 | fputs("\n", s1->ppfp), --d; | | |
| 686 | } else if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_STD) { | | |
| 687 | fprintf(s1->ppfp, "#line %d \"%s\"\n", f->line_num, f->filename); | | |
| 688 | } else { | | |
| 689 | fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename, | | |
| 690 | level > 0 ? " 1" : level < 0 ? " 2" : ""); | | |
| 691 | } | | |
| 692 | } | | |
| 693 | f->line_ref = f->line_num; | | |
| 694 | } | | |
| 695 | | | |
| 696 | static uint8_t *parse_print_comment(uint8_t *p, int is_line_comment) | | |
| 697 | { | | |
| 698 | int c, star_count; | | |
| 699 | FILE *ppfp = tcc_state->ppfp; | | |
| 700 | | | |
| 701 | if ((file->line_num - file->line_ref) > 0) { | | |
| 702 | fputc('\n', ppfp); | | |
| 703 | file->line_ref++; | | |
| 704 | pp_line(tcc_state, file, 0); | | |
| 705 | } | | |
| 706 | if (is_line_comment) | | |
| 707 | fputs("//", ppfp); else | | |
| 708 | fputs("/*", ppfp); | | |
| 709 | | | |
| 710 | star_count = 0; | | |
| 711 | for(;;) { | | |
| 712 | c = *p; | | |
| 713 | if (c == '\\') { | | |
| 714 | file->buf_ptr = p; | | |
| 715 | c = handle_eob(); | | |
| 716 | p = file->buf_ptr; | | |
| 717 | } | | |
| 718 | if (c == CH_EOF) { | | |
| 719 | if (is_line_comment) break; | | |
| 720 | tcc_error("unexpected end of file in comment"); | | |
| 721 | } | | |
| 722 | if (c == '*') | | |
| 723 | star_count++; | | |
| 724 | else { | | |
| 725 | if ((c == '/') && star_count && !is_line_comment) | | |
| 726 | break; | | |
| 727 | star_count = 0; | | |
| 728 | if (c == '\n') { | | |
| 729 | if (is_line_comment) break; | | |
| 730 | file->line_num++; | | |
| 731 | } | | |
| 732 | } | | |
| 733 | fputc(c, ppfp); | | |
| 734 | p++; | | |
| 735 | } | | |
| 736 | if (!is_line_comment) { | | |
| 737 | fputc('/', ppfp); | | |
| 738 | p++; | | |
| 739 | file->line_ref = file->line_num; | | |
| 740 | } | | |
| 741 | return p; | | |
| 742 | } | | |
| 743 | | | |
| 744 | /* single line C++ comments */ | 696 | /* single line C++ comments */ |
| 745 | static uint8_t *parse_line_comment(uint8_t *p, int skip) | 697 | static uint8_t *parse_line_comment(uint8_t *p) |
| 746 | { | 698 | { |
| 747 | int c; | 699 | int c; |
| 748 | | 700 | |
| 749 | p++; | 701 | p++; |
| 750 | if (tcc_state->option_C && !skip) | | |
| 751 | return parse_print_comment(p, 1); | | |
| 752 | for(;;) { | 702 | for(;;) { |
| 753 | c = *p; | 703 | c = *p; |
| 754 | redo: | 704 | redo: |
| @@ -781,13 +731,11 @@ static uint8_t *parse_line_comment(uint8_t *p, int skip) · 26 unmodified lines |
| 781 | } | 731 | } |
| 782 | | 732 | |
| 783 | /* C comments */ | 733 | /* C comments */ |
| 784 | ST_FUNC uint8_t *parse_comment(uint8_t *p, int skip) | 734 | ST_FUNC uint8_t *parse_comment(uint8_t *p) |
| 785 | { | 735 | { |
| 786 | int c; | 736 | int c; |
| 787 | | 737 | |
| 788 | p++; | 738 | p++; |
| 789 | if (tcc_state->option_C && !skip) | | |
| 790 | return parse_print_comment(p, 0); | | |
| 791 | for(;;) { | 739 | for(;;) { |
| 792 | /* fast skip loop */ | 740 | /* fast skip loop */ |
| 793 | for(;;) { | 741 | for(;;) { |
| @@ -994,9 +942,9 @@ redo_start: · 200 unmodified lines |
| 994 | minp(); | 942 | minp(); |
| 995 | p = file->buf_ptr; | 943 | p = file->buf_ptr; |
| 996 | if (ch == '*') { | 944 | if (ch == '*') { |
| 997 | p = parse_comment(p,1); | 945 | p = parse_comment(p); |
| 998 | } else if (ch == '/') { | 946 | } else if (ch == '/') { |
| 999 | p = parse_line_comment(p,1); | 947 | p = parse_line_comment(p); |
| 1000 | } | 948 | } |
| 1001 | break; | 949 | break; |
| 1002 | case '#': | 950 | case '#': |
| @@ -1017,9 +965,9 @@ redo_start: · 14 unmodified lines |
| 1017 | else if (tok == TOK_LINEFEED) | 965 | else if (tok == TOK_LINEFEED) |
| 1018 | goto redo_start; | 966 | goto redo_start; |
| 1019 | else if (parse_flags & PARSE_FLAG_ASM_FILE) | 967 | else if (parse_flags & PARSE_FLAG_ASM_FILE) |
| 1020 | p = parse_line_comment(p,0); | 968 | p = parse_line_comment(p); |
| 1021 | } else if (parse_flags & PARSE_FLAG_ASM_FILE) | 969 | } else if (parse_flags & PARSE_FLAG_ASM_FILE) |
| 1022 | p = parse_line_comment(p,0); | 970 | p = parse_line_comment(p); |
| 1023 | break; | 971 | break; |
| 1024 | _default: | 972 | _default: |
| 1025 | default: | 973 | default: |
| @@ -1287,6 +1235,10 @@ static int macro_is_equal(const int *a, const int *b) · 261 unmodified lines |
| 1287 | { | 1235 | { |
| 1288 | CValue cv; | 1236 | CValue cv; |
| 1289 | int t; | 1237 | int t; |
| | 1238 | |
| | 1239 | if (!a || !b) |
| | 1240 | return 1; |
| | 1241 | |
| 1290 | while (*a && *b) { | 1242 | while (*a && *b) { |
| 1291 | /* first time preallocate static cstr_buf, next time only reset position to start */ | 1243 | /* first time preallocate static cstr_buf, next time only reset position to start */ |
| 1292 | cstr_reset(&cstr_buf); | 1244 | cstr_reset(&cstr_buf); |
| @@ -1299,106 +1251,25 @@ static int macro_is_equal(const int *a, const int *b) · 6 unmodified lines |
| 1299 | return !(*a || *b); | 1251 | return !(*a || *b); |
| 1300 | } | 1252 | } |
| 1301 | | 1253 | |
| 1302 | static void tok_print(const char *msg, const int *str) | | |
| 1303 | { | | |
| 1304 | FILE *pr = tcc_state->dffp; | | |
| 1305 | int t; | | |
| 1306 | CValue cval; | | |
| 1307 | | | |
| 1308 | fprintf(pr, "%s ", msg); | | |
| 1309 | while (str) { | | |
| 1310 | TOK_GET(&t, &str, &cval); | | |
| 1311 | if (!t) | | |
| 1312 | break; | | |
| 1313 | fprintf(pr,"%s", get_tok_str(t, &cval)); | | |
| 1314 | } | | |
| 1315 | fprintf(pr, "\n"); | | |
| 1316 | } | | |
| 1317 | | | |
| 1318 | static int define_print_prepared(Sym *s) | | |
| 1319 | { | | |
| 1320 | if (!s || !tcc_state->dffp || tcc_state->dflag == 0) | | |
| 1321 | return 0; | | |
| 1322 | | | |
| 1323 | if (s->v < TOK_IDENT || s->v >= tok_ident) | | |
| 1324 | return 0; | | |
| 1325 | | | |
| 1326 | if (file && tcc_state->dflag == 'D') { | | |
| 1327 | file->line_num--; | | |
| 1328 | pp_line(tcc_state, file, 0); | | |
| 1329 | file->line_ref = ++file->line_num; | | |
| 1330 | } | | |
| 1331 | return 1; | | |
| 1332 | } | | |
| 1333 | | | |
| 1334 | static void define_print(int v) | | |
| 1335 | { | | |
| 1336 | FILE *pr = tcc_state->dffp; | | |
| 1337 | Sym *s, *a; | | |
| 1338 | | | |
| 1339 | s = define_find(v); | | |
| 1340 | if (define_print_prepared(s) == 0) | | |
| 1341 | return; | | |
| 1342 | | | |
| 1343 | fprintf(pr, "// #define %s", get_tok_str(v, NULL)); | | |
| 1344 | if (s->type.t == MACRO_FUNC) { | | |
| 1345 | a = s->next; | | |
| 1346 | fprintf(pr,"("); | | |
| 1347 | if (a) | | |
| 1348 | for (;;) { | | |
| 1349 | fprintf(pr,"%s", get_tok_str(a->v & ~SYM_FIELD, NULL)); | | |
| 1350 | if (!(a = a->next)) | | |
| 1351 | break; | | |
| 1352 | fprintf(pr,","); | | |
| 1353 | } | | |
| 1354 | fprintf(pr,")"); | | |
| 1355 | } | | |
| 1356 | tok_print("", s->d); | | |
| 1357 | } | | |
| 1358 | | | |
| 1359 | static void undef_print(int v) | | |
| 1360 | { | | |
| 1361 | FILE *pr = tcc_state->dffp; | | |
| 1362 | Sym *s; | | |
| 1363 | | | |
| 1364 | s = define_find(v); | | |
| 1365 | if (define_print_prepared(s) == 0) | | |
| 1366 | return; | | |
| 1367 | | | |
| 1368 | fprintf(pr, "// #undef %s\n", get_tok_str(s->v, NULL)); | | |
| 1369 | } | | |
| 1370 | | | |
| 1371 | ST_FUNC void print_defines(void) | | |
| 1372 | { | | |
| 1373 | Sym *top = define_stack; | | |
| 1374 | while (top) { | | |
| 1375 | define_print(top->v); | | |
| 1376 | top = top->prev; | | |
| 1377 | } | | |
| 1378 | } | | |
| 1379 | | | |
| 1380 | /* defines handling */ | 1254 | /* defines handling */ |
| 1381 | ST_INLN void define_push(int v, int macro_type, TokenString *str, Sym *first_arg) | 1255 | ST_INLN void define_push(int v, int macro_type, TokenString *str, Sym *first_arg) |
| 1382 | { | 1256 | { |
| 1383 | Sym *s; | 1257 | Sym *s, *o; |
| 1384 | | | |
| 1385 | if (str) { | | |
| 1386 | s = define_find(v); | | |
| 1387 | if (s && !macro_is_equal(s->d, str->str)) | | |
| 1388 | tcc_warning("%s redefined", get_tok_str(v, NULL)); | | |
| 1389 | } | | |
| 1390 | | 1258 | |
| | 1259 | o = define_find(v); |
| 1391 | s = sym_push2(&define_stack, v, macro_type, 0); | 1260 | s = sym_push2(&define_stack, v, macro_type, 0); |
| 1392 | s->d = str ? tok_str_dup(str) : NULL; | 1261 | s->d = str ? tok_str_dup(str) : NULL; |
| 1393 | s->next = first_arg; | 1262 | s->next = first_arg; |
| 1394 | table_ident[v - TOK_IDENT]->sym_define = s; | 1263 | table_ident[v - TOK_IDENT]->sym_define = s; |
| | 1264 | |
| | 1265 | if (o && !macro_is_equal(o->d, s->d)) |
| | 1266 | tcc_warning("%s redefined", get_tok_str(v, NULL)); |
| 1395 | } | 1267 | } |
| 1396 | | 1268 | |
| 1397 | /* undefined a define symbol. Its name is just set to zero */ | 1269 | /* undefined a define symbol. Its name is just set to zero */ |
| 1398 | ST_FUNC void define_undef(Sym *s) | 1270 | ST_FUNC void define_undef(Sym *s) |
| 1399 | { | 1271 | { |
| 1400 | int v = s->v; | 1272 | int v = s->v; |
| 1401 | undef_print(v); | | |
| 1402 | if (v >= TOK_IDENT && v < tok_ident) | 1273 | if (v >= TOK_IDENT && v < tok_ident) |
| 1403 | table_ident[v - TOK_IDENT]->sym_define = NULL; | 1274 | table_ident[v - TOK_IDENT]->sym_define = NULL; |
| 1404 | } | 1275 | } |
| @@ -1602,7 +1473,6 @@ ST_FUNC void parse_define(void) · 197 unmodified lines |
| 1602 | bad_twosharp: | 1473 | bad_twosharp: |
| 1603 | tcc_error("'##' cannot appear at either end of macro"); | 1474 | tcc_error("'##' cannot appear at either end of macro"); |
| 1604 | define_push(v, t, &tokstr_buf, first); | 1475 | define_push(v, t, &tokstr_buf, first); |
| 1605 | define_print(v); | | |
| 1606 | } | 1476 | } |
| 1607 | | 1477 | |
| 1608 | static inline int hash_cached_include(const char *filename) | 1478 | static inline int hash_cached_include(const char *filename) |
| @@ -1688,6 +1558,7 @@ static void pragma_parse(TCCState *s1) · 79 unmodified lines |
| 1688 | table_ident[v - TOK_IDENT]->sym_define = s->d ? s : NULL; | 1558 | table_ident[v - TOK_IDENT]->sym_define = s->d ? s : NULL; |
| 1689 | else | 1559 | else |
| 1690 | tcc_warning("unbalanced #pragma pop_macro"); | 1560 | tcc_warning("unbalanced #pragma pop_macro"); |
| | 1561 | pp_debug_tok = t, pp_debug_symv = v; |
| 1691 | | 1562 | |
| 1692 | } else if (tok == TOK_once) { | 1563 | } else if (tok == TOK_once) { |
| 1693 | char buf1[sizeof(file->filename) + sizeof(ONCE_PREFIX)]; | 1564 | char buf1[sizeof(file->filename) + sizeof(ONCE_PREFIX)]; |
| @@ -1788,11 +1659,15 @@ ST_FUNC void preprocess(int is_bof) · 94 unmodified lines |
| 1788 | redo: | 1659 | redo: |
| 1789 | switch(tok) { | 1660 | switch(tok) { |
| 1790 | case TOK_DEFINE: | 1661 | case TOK_DEFINE: |
| | 1662 | pp_debug_tok = tok; |
| 1791 | next_nomacro(); | 1663 | next_nomacro(); |
| | 1664 | pp_debug_symv = tok; |
| 1792 | parse_define(); | 1665 | parse_define(); |
| 1793 | break; | 1666 | break; |
| 1794 | case TOK_UNDEF: | 1667 | case TOK_UNDEF: |
| | 1668 | pp_debug_tok = tok; |
| 1795 | next_nomacro(); | 1669 | next_nomacro(); |
| | 1670 | pp_debug_symv = tok; |
| 1796 | s = define_find(tok); | 1671 | s = define_find(tok); |
| 1797 | /* undefine symbol by putting an invalid name */ | 1672 | /* undefine symbol by putting an invalid name */ |
| 1798 | if (s) | 1673 | if (s) |
| @@ -2059,7 +1934,7 @@ _line_num: · 260 unmodified lines |
| 2059 | goto ignore; | 1934 | goto ignore; |
| 2060 | tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc)); | 1935 | tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc)); |
| 2061 | ignore: | 1936 | ignore: |
| 2062 | file->buf_ptr = parse_line_comment(file->buf_ptr,0); | 1937 | file->buf_ptr = parse_line_comment(file->buf_ptr); |
| 2063 | goto the_end; | 1938 | goto the_end; |
| 2064 | } | 1939 | } |
| 2065 | /* ignore other preprocess commands or #! for C scripts */ | 1940 | /* ignore other preprocess commands or #! for C scripts */ |
| @@ -2655,7 +2530,7 @@ maybe_newline: · 589 unmodified lines |
| 2655 | tok = TOK_TWOSHARPS; | 2530 | tok = TOK_TWOSHARPS; |
| 2656 | } else { | 2531 | } else { |
| 2657 | if (parse_flags & PARSE_FLAG_ASM_FILE) { | 2532 | if (parse_flags & PARSE_FLAG_ASM_FILE) { |
| 2658 | p = parse_line_comment(p - 1,0); | 2533 | p = parse_line_comment(p - 1); |
| 2659 | goto redo_no_start; | 2534 | goto redo_no_start; |
| 2660 | } else { | 2535 | } else { |
| 2661 | tok = '#'; | 2536 | tok = '#'; |
| @@ -2918,17 +2793,13 @@ maybe_newline: · 256 unmodified lines |
| 2918 | case '/': | 2793 | case '/': |
| 2919 | PEEKC(c, p); | 2794 | PEEKC(c, p); |
| 2920 | if (c == '*') { | 2795 | if (c == '*') { |
| 2921 | p = parse_comment(p,0); | 2796 | p = parse_comment(p); |
| 2922 | /* comments replaced by a blank */ | 2797 | /* comments replaced by a blank */ |
| 2923 | tok = ' '; | 2798 | tok = ' '; |
| 2924 | if (tcc_state->option_C) | | |
| 2925 | goto redo_no_start; | | |
| 2926 | goto keep_tok_flags; | 2799 | goto keep_tok_flags; |
| 2927 | } else if (c == '/') { | 2800 | } else if (c == '/') { |
| 2928 | p = parse_line_comment(p,0); | 2801 | p = parse_line_comment(p); |
| 2929 | tok = ' '; | 2802 | tok = ' '; |
| 2930 | if (tcc_state->option_C) | | |
| 2931 | goto redo_no_start; | | |
| 2932 | goto keep_tok_flags; | 2803 | goto keep_tok_flags; |
| 2933 | } else if (c == '=') { | 2804 | } else if (c == '=') { |
| 2934 | p++; | 2805 | p++; |
| @@ -3150,10 +3021,10 @@ static int next_argstream(Sym **nested_list, int can_read_stream, TokenString *w · 215 unmodified lines |
| 3150 | uint8_t *p = file->buf_ptr; | 3021 | uint8_t *p = file->buf_ptr; |
| 3151 | PEEKC(c, p); | 3022 | PEEKC(c, p); |
| 3152 | if (c == '*') { | 3023 | if (c == '*') { |
| 3153 | p = parse_comment(p,0); | 3024 | p = parse_comment(p); |
| 3154 | file->buf_ptr = p - 1; | 3025 | file->buf_ptr = p - 1; |
| 3155 | } else if (c == '/') { | 3026 | } else if (c == '/') { |
| 3156 | p = parse_line_comment(p,0); | 3027 | p = parse_line_comment(p); |
| 3157 | file->buf_ptr = p - 1; | 3028 | file->buf_ptr = p - 1; |
| 3158 | } else | 3029 | } else |
| 3159 | break; | 3030 | break; |
| @@ -3570,8 +3441,6 @@ ST_INLN void unget_tok(int last_tok) · 410 unmodified lines |
| 3570 | tok = last_tok; | 3441 | tok = last_tok; |
| 3571 | } | 3442 | } |
| 3572 | | 3443 | |
| 3573 | /* better than nothing, but needs extension to handle '-E' option | | |
| 3574 | correctly too */ | | |
| 3575 | ST_FUNC void preprocess_init(TCCState *s1) | 3444 | ST_FUNC void preprocess_init(TCCState *s1) |
| 3576 | { | 3445 | { |
| 3577 | s1->include_stack_ptr = s1->include_stack; | 3446 | s1->include_stack_ptr = s1->include_stack; |
| @@ -3585,8 +3454,7 @@ ST_FUNC void preprocess_init(TCCState *s1) · 7 unmodified lines |
| 3585 | s1->pack_stack_ptr = s1->pack_stack; | 3454 | s1->pack_stack_ptr = s1->pack_stack; |
| 3586 | | 3455 | |
| 3587 | isidnum_table['$' - CH_EOF] = | 3456 | isidnum_table['$' - CH_EOF] = |
| 3588 | tcc_state->dollars_in_identifiers ? IS_ID : 0; | 3457 | s1->dollars_in_identifiers ? IS_ID : 0; |
| 3589 | | | |
| 3590 | isidnum_table['.' - CH_EOF] = | 3458 | isidnum_table['.' - CH_EOF] = |
| 3591 | (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0; | 3459 | (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0; |
| 3592 | } | 3460 | } |
| @@ -3665,11 +3533,122 @@ ST_FUNC void preprocess_delete(void) · 72 unmodified lines |
| 3665 | cstr_alloc = NULL; | 3533 | cstr_alloc = NULL; |
| 3666 | } | 3534 | } |
| 3667 | | 3535 | |
| | 3536 | /* ------------------------------------------------------------------------- */ |
| | 3537 | /* tcc -E [-P[1]] [-dD} support */ |
| | 3538 | |
| | 3539 | static void tok_print(const char *msg, const int *str) |
| | 3540 | { |
| | 3541 | FILE *fp; |
| | 3542 | int t; |
| | 3543 | CValue cval; |
| | 3544 | |
| | 3545 | fp = tcc_state->ppfp; |
| | 3546 | if (!fp || !tcc_state->dflag) |
| | 3547 | fp = stdout; |
| | 3548 | |
| | 3549 | fprintf(fp, "%s ", msg); |
| | 3550 | while (str) { |
| | 3551 | TOK_GET(&t, &str, &cval); |
| | 3552 | if (!t) |
| | 3553 | break; |
| | 3554 | fprintf(fp,"%s", get_tok_str(t, &cval)); |
| | 3555 | } |
| | 3556 | fprintf(fp, "\n"); |
| | 3557 | } |
| | 3558 | |
| | 3559 | static void pp_line(TCCState *s1, BufferedFile *f, int level) |
| | 3560 | { |
| | 3561 | int d = f->line_num - f->line_ref; |
| | 3562 | |
| | 3563 | if (s1->dflag & 4) |
| | 3564 | return; |
| | 3565 | |
| | 3566 | if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_NONE) { |
| | 3567 | if (level == 0 && f->line_ref && d) { |
| | 3568 | d = 1; |
| | 3569 | goto simple; |
| | 3570 | } |
| | 3571 | } else if (level == 0 && f->line_ref && d < 8) { |
| | 3572 | simple: |
| | 3573 | while (d > 0) |
| | 3574 | fputs("\n", s1->ppfp), --d; |
| | 3575 | } else if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_STD) { |
| | 3576 | fprintf(s1->ppfp, "#line %d \"%s\"\n", f->line_num, f->filename); |
| | 3577 | } else { |
| | 3578 | fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename, |
| | 3579 | level > 0 ? " 1" : level < 0 ? " 2" : ""); |
| | 3580 | } |
| | 3581 | f->line_ref = f->line_num; |
| | 3582 | } |
| | 3583 | |
| | 3584 | static void define_print(TCCState *s1, int v) |
| | 3585 | { |
| | 3586 | FILE *fp; |
| | 3587 | Sym *s; |
| | 3588 | |
| | 3589 | s = define_find(v); |
| | 3590 | if (NULL == s || NULL == s->d) |
| | 3591 | return; |
| | 3592 | |
| | 3593 | fp = s1->ppfp; |
| | 3594 | fprintf(fp, "#define %s", get_tok_str(v, NULL)); |
| | 3595 | if (s->type.t == MACRO_FUNC) { |
| | 3596 | Sym *a = s->next; |
| | 3597 | fprintf(fp,"("); |
| | 3598 | if (a) |
| | 3599 | for (;;) { |
| | 3600 | fprintf(fp,"%s", get_tok_str(a->v & ~SYM_FIELD, NULL)); |
| | 3601 | if (!(a = a->next)) |
| | 3602 | break; |
| | 3603 | fprintf(fp,","); |
| | 3604 | } |
| | 3605 | fprintf(fp,")"); |
| | 3606 | } |
| | 3607 | tok_print("", s->d); |
| | 3608 | } |
| | 3609 | |
| | 3610 | static void pp_debug_defines(TCCState *s1) |
| | 3611 | { |
| | 3612 | int v, t; |
| | 3613 | const char *vs; |
| | 3614 | FILE *fp; |
| | 3615 | |
| | 3616 | t = pp_debug_tok; |
| | 3617 | if (t == 0) |
| | 3618 | return; |
| | 3619 | |
| | 3620 | file->line_num--; |
| | 3621 | pp_line(s1, file, 0); |
| | 3622 | file->line_ref = ++file->line_num; |
| | 3623 | |
| | 3624 | fp = s1->ppfp; |
| | 3625 | v = pp_debug_symv; |
| | 3626 | vs = get_tok_str(v, NULL); |
| | 3627 | if (t == TOK_DEFINE) { |
| | 3628 | define_print(s1, v); |
| | 3629 | } else if (t == TOK_UNDEF) { |
| | 3630 | fprintf(fp, "#undef %s\n", vs); |
| | 3631 | } else if (t == TOK_push_macro) { |
| | 3632 | fprintf(fp, "#pragma push_macro(\"%s\")\n", vs); |
| | 3633 | } else if (t == TOK_pop_macro) { |
| | 3634 | fprintf(fp, "#pragma pop_macro(\"%s\")\n", vs); |
| | 3635 | } |
| | 3636 | pp_debug_tok = 0; |
| | 3637 | } |
| | 3638 | |
| | 3639 | static void pp_debug_builtins(TCCState *s1) |
| | 3640 | { |
| | 3641 | int v; |
| | 3642 | for (v = TOK_IDENT; v < tok_ident; ++v) |
| | 3643 | define_print(s1, v); |
| | 3644 | } |
| | 3645 | |
| 3668 | /* Preprocess the current file */ | 3646 | /* Preprocess the current file */ |
| 3669 | ST_FUNC int tcc_preprocess(TCCState *s1) | 3647 | ST_FUNC int tcc_preprocess(TCCState *s1) |
| 3670 | { | 3648 | { |
| 3671 | BufferedFile **iptr; | 3649 | BufferedFile **iptr; |
| 3672 | int token_seen, spcs, level; | 3650 | int token_seen, spcs, level; |
| | 3651 | Sym *define_start; |
| 3673 | | 3652 | |
| 3674 | preprocess_init(s1); | 3653 | preprocess_init(s1); |
| 3675 | ch = file->buf_ptr[0]; | 3654 | ch = file->buf_ptr[0]; |
| @@ -3680,12 +3659,19 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 4 unmodified lines |
| 3680 | | PARSE_FLAG_SPACES | 3659 | | PARSE_FLAG_SPACES |
| 3681 | | PARSE_FLAG_ACCEPT_STRAYS | 3660 | | PARSE_FLAG_ACCEPT_STRAYS |
| 3682 | ; | 3661 | ; |
| | 3662 | define_start = define_stack; |
| 3683 | | 3663 | |
| 3684 | #ifdef PP_BENCH | 3664 | #ifdef PP_BENCH |
| | 3665 | /* for PP benchmarks */ |
| 3685 | do next(); while (tok != TOK_EOF); return 0; | 3666 | do next(); while (tok != TOK_EOF); return 0; |
| 3686 | #endif | 3667 | #endif |
| 3687 | | 3668 | |
| 3688 | token_seen = spcs = 0; | 3669 | if (s1->dflag & 1) { |
| | 3670 | pp_debug_builtins(s1); |
| | 3671 | s1->dflag &= ~1; |
| | 3672 | } |
| | 3673 | |
| | 3674 | token_seen = TOK_LINEFEED, spcs = 0; |
| 3689 | pp_line(s1, file, 0); | 3675 | pp_line(s1, file, 0); |
| 3690 | | 3676 | |
| 3691 | for (;;) { | 3677 | for (;;) { |
| @@ -3700,7 +3686,13 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 8 unmodified lines |
| 3700 | pp_line(s1, file, level); | 3686 | pp_line(s1, file, level); |
| 3701 | } | 3687 | } |
| 3702 | | 3688 | |
| 3703 | if (0 == token_seen) { | 3689 | if (s1->dflag) { |
| | 3690 | pp_debug_defines(s1); |
| | 3691 | if (s1->dflag & 4) |
| | 3692 | continue; |
| | 3693 | } |
| | 3694 | |
| | 3695 | if (token_seen == TOK_LINEFEED) { |
| 3704 | if (tok == ' ') { | 3696 | if (tok == ' ') { |
| 3705 | ++spcs; | 3697 | ++spcs; |
| 3706 | continue; | 3698 | continue; |
| @@ -3710,33 +3702,19 @@ ST_FUNC int tcc_preprocess(TCCState *s1) · 3 unmodified lines |
| 3710 | continue; | 3702 | continue; |
| 3711 | } | 3703 | } |
| 3712 | pp_line(s1, file, 0); | 3704 | pp_line(s1, file, 0); |
| 3713 | while (s1->ppfp && spcs > 0) | | |
| 3714 | fputs(" ", s1->ppfp), --spcs; | | |
| 3715 | spcs = 0; | | |
| 3716 | token_seen = 1; | | |
| 3717 | | | |
| 3718 | } else if (tok == TOK_LINEFEED) { | 3705 | } else if (tok == TOK_LINEFEED) { |
| 3719 | ++file->line_ref; | 3706 | ++file->line_ref; |
| 3720 | token_seen = 0; | | |
| 3721 | } | 3707 | } |
| 3722 | if (s1->ppfp) | | |
| 3723 | fputs(get_tok_str(tok, &tokc), s1->ppfp); | | |
| 3724 | } | | |
| 3725 | | 3708 | |
| 3726 | return 0; | 3709 | while (spcs) |
| 3727 | } | 3710 | fputs(" ", s1->ppfp), --spcs; |
| | 3711 | fputs(get_tok_str(tok, &tokc), s1->ppfp); |
| 3728 | | 3712 | |
| 3729 | ST_FUNC char *trimfront(char *p) | 3713 | token_seen = tok; |
| 3730 | { | 3714 | } |
| 3731 | while (*p && (unsigned char)*p <= ' ') | 3715 | /* reset define stack, but keep -D and built-ins */ |
| 3732 | ++p; | 3716 | free_defines(define_start); |
| 3733 | return p; | 3717 | return 0; |
| 3734 | } | 3718 | } |
| 3735 | | 3719 | |
| 3736 | ST_FUNC char *trimback(char *a, char *e) | 3720 | /* ------------------------------------------------------------------------- */ |
| 3737 | { | | |
| 3738 | while (e > a && (unsigned char)e[-1] <= ' ') | | |
| 3739 | --e; | | |
| 3740 | *e = 0;; | | |
| 3741 | return a; | | |
| 3742 | } | | |