- make only one function from previously four pieces - use parse_pp_string() for the normal cases "..." and <...> - use the sanity check for computed include as end-condition too. - use 's1' instead of 'tcc_state' when possible 117 insertions(+), 165 deletions(-), less 48 lines
Unified · Split
| @@ -891,6 +891,7 @@ ST_FUNC int set_idnum(int c, int val) · 890 unmodified lines | |||
| 891 | 891 | ||
| 892 | static inline void skip_spaces(void) | 892 | static inline void skip_spaces(void) |
| 893 | { | 893 | { |
| 894 | ch = file->buf_ptr[0]; | ||
| 894 | while (isidnum_table[ch - CH_EOF] & IS_SPC) | 895 | while (isidnum_table[ch - CH_EOF] & IS_SPC) |
| 895 | cinp(); | 896 | cinp(); |
| 896 | } | 897 | } |
| @@ -1495,94 +1496,113 @@ static void maybe_run_test(TCCState *s) · 598 unmodified lines | |||
| 1495 | define_push(tok, MACRO_OBJ, NULL, NULL); | 1496 | define_push(tok, MACRO_OBJ, NULL, NULL); |
| 1496 | } | 1497 | } |
| 1497 | 1498 | ||
| 1498 | static int parse_include(char *buf, size_t size_buf, int last) | 1499 | static CachedInclude * |
| 1500 | search_cached_include(TCCState *s1, const char *filename, int add); | ||
| 1501 | |||
| 1502 | static int parse_include(TCCState *s1, int do_next, int test) | ||
| 1499 | { | 1503 | { |
| 1500 | int c; | 1504 | int c, i; |
| 1505 | CString cs; | ||
| 1506 | char name[1024], buf[1024], *p; | ||
| 1507 | CachedInclude *e; | ||
| 1501 | 1508 | ||
| 1502 | skip_spaces(); | 1509 | cstr_new(&cs); |
| 1503 | if (ch == '<') { | 1510 | skip_spaces(), c = ch; |
| 1504 | c = '>'; | 1511 | if (c == '<' || c == '\"') { |
| 1505 | goto read_name; | 1512 | file->buf_ptr = parse_pp_string(file->buf_ptr, c == '<' ? '>' : c, &cs); |
| 1506 | } else if (ch == '\"') { | 1513 | next_nomacro(); |
| 1507 | char *q; | 1514 | } else { |
| 1515 | /* computed #include : concatenate tokens until result is one of | ||
| 1516 | the two accepted forms. Don't convert pp-tokens to tokens here. */ | ||
| 1517 | parse_flags = PARSE_FLAG_PREPROCESS | ||
| 1518 | | PARSE_FLAG_LINEFEED | ||
| 1519 | | (parse_flags & PARSE_FLAG_ASM_FILE); | ||
| 1520 | for (;;) { | ||
| 1521 | next(); | ||
| 1522 | p = cs.data, i = cs.size - 1; | ||
| 1523 | if (i > 0 | ||
| 1524 | && ((p[0] == '"' && p[i] == '"') | ||
| 1525 | || (p[0] == '<' && p[i] == '>'))) | ||
| 1526 | break; | ||
| 1527 | if (tok == TOK_LINEFEED) | ||
| 1528 | tcc_error("'#include' expects \"FILENAME\" or <FILENAME>"); | ||
| 1529 | cstr_cat(&cs, get_tok_str(tok, &tokc), -1); | ||
| 1530 | } | ||
| 1531 | c = p[0]; | ||
| 1532 | /* remove '<>|""' */ | ||
| 1533 | memmove(p, p + 1, cs.size -= 2); | ||
| 1534 | } | ||
| 1535 | cstr_ccat(&cs, '\0'); | ||
| 1536 | pstrcpy(name, sizeof name, cs.data); | ||
| 1537 | cstr_free(&cs); | ||
| 1508 | 1538 | ||
| 1509 | c = ch; | 1539 | i = do_next ? file->include_next_index : -1; |
| 1510 | read_name: | 1540 | for (;;) { |
| 1511 | inp(); | 1541 | ++i; |
| 1512 | q = buf; | 1542 | if (i == 0) { |
| 1513 | while (ch != c && ch != '\n' && ch != CH_EOF) { | 1543 | /* check absolute include path */ |
| 1514 | if ((q - buf) < size_buf - 1) | 1544 | if (!IS_ABSPATH(name)) |
| 1515 | *q++ = ch; | 1545 | continue; |
| 1516 | if (ch == '\\') { | 1546 | buf[0] = '\0'; |
| 1517 | if (handle_stray_noerror() == 0) | 1547 | } else if (i == 1) { |
| 1518 | --q; | 1548 | /* search in file's dir if "header.h" */ |
| 1519 | } else | 1549 | if (c != '\"') |
| 1520 | inp(); | 1550 | continue; |
| 1551 | p = file->true_filename; | ||
| 1552 | pstrncpy(buf, p, tcc_basename(p) - p); | ||
| 1553 | } else { | ||
| 1554 | int j = i - 2, k = j - s1->nb_include_paths; | ||
| 1555 | if (k < 0) | ||
| 1556 | p = s1->include_paths[j]; | ||
| 1557 | else if (k < s1->nb_sysinclude_paths) | ||
| 1558 | p = s1->sysinclude_paths[k]; | ||
| 1559 | else if (test) | ||
| 1560 | return 0; | ||
| 1561 | else | ||
| 1562 | tcc_error("include file '%s' not found", name); | ||
| 1563 | pstrcpy(buf, sizeof buf, p); | ||
| 1564 | pstrcat(buf, sizeof buf, "/"); | ||
| 1521 | } | 1565 | } |
| 1522 | if (ch != c) | 1566 | pstrcat(buf, sizeof buf, name); |
| 1523 | goto error; | 1567 | e = search_cached_include(s1, buf, 0); |
| 1524 | *q = '\0'; | 1568 | if (e && (define_find(e->ifndef_macro) || e->once == pp_once)) { |
| 1525 | minp(); | 1569 | /* no need to parse the include because the 'ifndef macro' |
| 1526 | #if 0 | 1570 | is defined (or had #pragma once) */ |
| 1527 | /* eat all spaces and comments after include */ | 1571 | #ifdef INC_DEBUG |
| 1528 | /* XXX: slightly incorrect */ | 1572 | printf("%s: skipping cached %s\n", file->filename, buf); |
| 1529 | while (ch1 != '\n' && ch1 != CH_EOF) | ||
| 1530 | inp(); | ||
| 1531 | #endif | 1573 | #endif |
| 1532 | } else { | 1574 | return 1; |
| 1533 | int len; | 1575 | } |
| 1534 | /* computed #include : concatenate everything up to linefeed, | 1576 | if (tcc_open(s1, buf) >= 0) |
| 1535 | the result must be one of the two accepted forms. | 1577 | break; |
| 1536 | Don't convert pp-tokens to tokens here. */ | ||
| 1537 | parse_flags = (PARSE_FLAG_PREPROCESS | ||
| 1538 | | PARSE_FLAG_LINEFEED | ||
| 1539 | | (parse_flags & PARSE_FLAG_ASM_FILE)); | ||
| 1540 | next(); | ||
| 1541 | buf[0] = '\0'; | ||
| 1542 | while (tok != TOK_LINEFEED && tok != last) { | ||
| 1543 | pstrcat(buf, size_buf, get_tok_str(tok, &tokc)); | ||
| 1544 | next(); | ||
| 1545 | } | ||
| 1546 | len = strlen(buf); | ||
| 1547 | if (tok == last) | ||
| 1548 | unget_tok(0); | ||
| 1549 | /* check syntax and remove '<>|""' */ | ||
| 1550 | if ((len < 2 || ((buf[0] != '"' || buf[len-1] != '"') && | ||
| 1551 | (buf[0] != '<' || buf[len-1] != '>')))) | ||
| 1552 | error: | ||
| 1553 | tcc_error("'#include' expects \"FILENAME\" or <FILENAME>"); | ||
| 1554 | c = buf[len-1]; | ||
| 1555 | memmove(buf, buf + 1, len - 2); | ||
| 1556 | buf[len - 2] = '\0'; | ||
| 1557 | } | 1578 | } |
| 1558 | return c; | ||
| 1559 | } | ||
| 1560 | 1579 | ||
| 1561 | static int get_include_file(TCCState *s1, int i, int c, | 1580 | if (test) { |
| 1562 | char *buf, char *buf1, size_t size_buf1) | 1581 | tcc_close(); |
| 1563 | { | ||
| 1564 | const char *path; | ||
| 1565 | |||
| 1566 | if (i == 0) { | ||
| 1567 | /* check absolute include path */ | ||
| 1568 | if (!IS_ABSPATH(buf)) | ||
| 1569 | return -1; | ||
| 1570 | buf1[0] = 0; | ||
| 1571 | } else if (i == 1) { | ||
| 1572 | /* search in file's dir if "header.h" */ | ||
| 1573 | if (c != '\"') | ||
| 1574 | return -1; | ||
| 1575 | path = file->true_filename; | ||
| 1576 | pstrncpy(buf1, path, tcc_basename(path) - path); | ||
| 1577 | } else { | 1582 | } else { |
| 1578 | /* search in all the include paths */ | 1583 | if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) |
| 1579 | int j = i - 2, k = j - s1->nb_include_paths; | 1584 | tcc_error("#include recursion too deep"); |
| 1580 | path = k < 0 ? s1->include_paths[j] : s1->sysinclude_paths[k]; | 1585 | /* push previous file on stack */ |
| 1581 | pstrcpy(buf1, size_buf1, path); | 1586 | *s1->include_stack_ptr++ = file->prev; |
| 1582 | pstrcat(buf1, size_buf1, "/"); | 1587 | file->include_next_index = i; |
| 1588 | #ifdef INC_DEBUG | ||
| 1589 | printf("%s: including %s\n", file->prev->filename, file->filename); | ||
| 1590 | #endif | ||
| 1591 | /* update target deps */ | ||
| 1592 | if (s1->gen_deps) { | ||
| 1593 | BufferedFile *bf = file; | ||
| 1594 | while (i == 1 && (bf = bf->prev)) | ||
| 1595 | i = bf->include_next_index; | ||
| 1596 | /* skip system include files */ | ||
| 1597 | if (s1->include_sys_deps || i - 2 < s1->nb_include_paths) | ||
| 1598 | dynarray_add(&s1->target_deps, &s1->nb_target_deps, | ||
| 1599 | tcc_strdup(buf)); | ||
| 1600 | } | ||
| 1601 | /* add include file debug info */ | ||
| 1602 | tcc_debug_bincl(s1); | ||
| 1603 | tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL; | ||
| 1583 | } | 1604 | } |
| 1584 | pstrcat(buf1, size_buf1, buf); | 1605 | return 1; |
| 1585 | return 0; | ||
| 1586 | } | 1606 | } |
| 1587 | 1607 | ||
| 1588 | /* eval an expression for #if/#elif */ | 1608 | /* eval an expression for #if/#elif */ |
| @@ -1601,15 +1621,15 @@ static int expr_preprocess(TCCState *s1) · 12 unmodified lines | |||
| 1601 | t = tok; | 1621 | t = tok; |
| 1602 | if (t == '(') | 1622 | if (t == '(') |
| 1603 | next_nomacro(); | 1623 | next_nomacro(); |
| 1604 | if (tok == TOK___HAS_INCLUDE || tok == TOK___HAS_INCLUDE_NEXT) | 1624 | if (tok < TOK_IDENT) |
| 1605 | c = 1; | 1625 | expect("identifier"); |
| 1606 | else { | 1626 | if (s1->run_test) |
| 1607 | if (tok < TOK_IDENT) | 1627 | maybe_run_test(s1); |
| 1608 | expect("identifier"); | 1628 | c = 0; |
| 1609 | if (tcc_state->run_test) | 1629 | if (define_find(tok) |
| 1610 | maybe_run_test(tcc_state); | 1630 | || tok == TOK___HAS_INCLUDE |
| 1611 | c = define_find(tok) != 0; | 1631 | || tok == TOK___HAS_INCLUDE_NEXT) |
| 1612 | } | 1632 | c = 1; |
| 1613 | if (t == '(') { | 1633 | if (t == '(') { |
| 1614 | next_nomacro(); | 1634 | next_nomacro(); |
| 1615 | if (tok != ')') | 1635 | if (tok != ')') |
| @@ -1619,32 +1639,15 @@ static int expr_preprocess(TCCState *s1) · 3 unmodified lines | |||
| 1619 | tokc.i = c; | 1639 | tokc.i = c; |
| 1620 | } else if (tok == TOK___HAS_INCLUDE || | 1640 | } else if (tok == TOK___HAS_INCLUDE || |
| 1621 | tok == TOK___HAS_INCLUDE_NEXT) { | 1641 | tok == TOK___HAS_INCLUDE_NEXT) { |
| 1622 | int c, n, i, fd, save_tok = tok; | 1642 | t = tok; |
| 1623 | char buf[1024]; | ||
| 1624 | |||
| 1625 | next_nomacro(); | 1643 | next_nomacro(); |
| 1626 | if (tok != '(') | 1644 | if (tok != '(') |
| 1627 | expect("("); | 1645 | expect("("); |
| 1628 | ch = file->buf_ptr[0]; | 1646 | c = parse_include(s1, t - TOK___HAS_INCLUDE, 1); |
| 1629 | c = parse_include(buf, sizeof(buf), ')'); | ||
| 1630 | next_nomacro(); | ||
| 1631 | if (tok != ')') | 1647 | if (tok != ')') |
| 1632 | expect("')'"); | 1648 | expect("')'"); |
| 1633 | tok = TOK_CINT; | 1649 | tok = TOK_CINT; |
| 1634 | tokc.i = 0; | 1650 | tokc.i = c; |
| 1635 | i = save_tok == TOK___HAS_INCLUDE_NEXT ? file->include_next_index + 1 : 0; | ||
| 1636 | n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths; | ||
| 1637 | for (; i < n; i++) { | ||
| 1638 | char buf1[sizeof file->filename]; | ||
| 1639 | |||
| 1640 | if (get_include_file(s1, i, c, buf, buf1, sizeof(buf1))) | ||
| 1641 | continue; | ||
| 1642 | if ((fd = open(buf1, O_RDONLY | O_BINARY)) >= 0) { | ||
| 1643 | close(fd); | ||
| 1644 | tokc.i = 1; | ||
| 1645 | break; | ||
| 1646 | } | ||
| 1647 | } | ||
| 1648 | } else if (tok >= TOK_IDENT) { | 1651 | } else if (tok >= TOK_IDENT) { |
| 1649 | /* if undefined macro, replace with zero, check for func-like */ | 1652 | /* if undefined macro, replace with zero, check for func-like */ |
| 1650 | t = tok; | 1653 | t = tok; |
| @@ -1922,7 +1925,7 @@ pragma_err: · 271 unmodified lines | |||
| 1922 | ST_FUNC void preprocess(int is_bof) | 1925 | ST_FUNC void preprocess(int is_bof) |
| 1923 | { | 1926 | { |
| 1924 | TCCState *s1 = tcc_state; | 1927 | TCCState *s1 = tcc_state; |
| 1925 | int i, c, n, saved_parse_flags; | 1928 | int c, n, saved_parse_flags; |
| 1926 | char buf[1024], *q; | 1929 | char buf[1024], *q; |
| 1927 | Sym *s; | 1930 | Sym *s; |
| 1928 | 1931 | ||
| @@ -1954,57 +1957,7 @@ ST_FUNC void preprocess(int is_bof) · 25 unmodified lines | |||
| 1954 | break; | 1957 | break; |
| 1955 | case TOK_INCLUDE: | 1958 | case TOK_INCLUDE: |
| 1956 | case TOK_INCLUDE_NEXT: | 1959 | case TOK_INCLUDE_NEXT: |
| 1957 | ch = file->buf_ptr[0]; | 1960 | parse_include(s1, tok - TOK_INCLUDE, 0); |
| 1958 | /* XXX: incorrect if comments : use next_nomacro with a special mode */ | ||
| 1959 | |||
| 1960 | c = parse_include(buf, sizeof(buf), 0); | ||
| 1961 | |||
| 1962 | if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) | ||
| 1963 | tcc_error("#include recursion too deep"); | ||
| 1964 | i = tok == TOK_INCLUDE_NEXT ? file->include_next_index + 1 : 0; | ||
| 1965 | n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths; | ||
| 1966 | for (; i < n; ++i) { | ||
| 1967 | char buf1[sizeof file->filename]; | ||
| 1968 | CachedInclude *e; | ||
| 1969 | |||
| 1970 | if (get_include_file(s1, i, c, buf, buf1, sizeof(buf1))) | ||
| 1971 | continue; | ||
| 1972 | e = search_cached_include(s1, buf1, 0); | ||
| 1973 | if (e && (define_find(e->ifndef_macro) || e->once == pp_once)) { | ||
| 1974 | /* no need to parse the include because the 'ifndef macro' | ||
| 1975 | is defined (or had #pragma once) */ | ||
| 1976 | #ifdef INC_DEBUG | ||
| 1977 | printf("%s: skipping cached %s\n", file->filename, buf1); | ||
| 1978 | #endif | ||
| 1979 | goto include_done; | ||
| 1980 | } | ||
| 1981 | |||
| 1982 | if (tcc_open(s1, buf1) < 0) | ||
| 1983 | continue; | ||
| 1984 | /* push previous file on stack */ | ||
| 1985 | *s1->include_stack_ptr++ = file->prev; | ||
| 1986 | file->include_next_index = i; | ||
| 1987 | #ifdef INC_DEBUG | ||
| 1988 | printf("%s: including %s\n", file->prev->filename, file->filename); | ||
| 1989 | #endif | ||
| 1990 | /* update target deps */ | ||
| 1991 | if (s1->gen_deps) { | ||
| 1992 | BufferedFile *bf = file; | ||
| 1993 | while (i == 1 && (bf = bf->prev)) | ||
| 1994 | i = bf->include_next_index; | ||
| 1995 | /* skip system include files */ | ||
| 1996 | if (s1->include_sys_deps || n - i > s1->nb_sysinclude_paths) | ||
| 1997 | dynarray_add(&s1->target_deps, &s1->nb_target_deps, | ||
| 1998 | tcc_strdup(buf1)); | ||
| 1999 | } | ||
| 2000 | /* add include file debug info */ | ||
| 2001 | tcc_debug_bincl(tcc_state); | ||
| 2002 | tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL; | ||
| 2003 | ch = file->buf_ptr[0]; | ||
| 2004 | goto the_end; | ||
| 2005 | } | ||
| 2006 | tcc_error("include file '%s' not found", buf); | ||
| 2007 | include_done: | ||
| 2008 | break; | 1961 | break; |
| 2009 | case TOK_IFNDEF: | 1962 | case TOK_IFNDEF: |
| 2010 | c = 1; | 1963 | c = 1; |
| @@ -2026,10 +1979,10 @@ include_done: · 15 unmodified lines | |||
| 2026 | file->ifndef_macro = tok; | 1979 | file->ifndef_macro = tok; |
| 2027 | } | 1980 | } |
| 2028 | } | 1981 | } |
| 2029 | if (tok == TOK___HAS_INCLUDE || tok == TOK___HAS_INCLUDE_NEXT) | 1982 | if (define_find(tok) |
| 2030 | c = 1 ^ c; | 1983 | || tok == TOK___HAS_INCLUDE |
| 2031 | else | 1984 | || tok == TOK___HAS_INCLUDE_NEXT) |
| 2032 | c = (define_find(tok) != 0) ^ c; | 1985 | c ^= 1; |
| 2033 | do_if: | 1986 | do_if: |
| 2034 | if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE) | 1987 | if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE) |
| 2035 | tcc_error("memory full (ifdef)"); | 1988 | tcc_error("memory full (ifdef)"); |
| @@ -2120,7 +2073,6 @@ include_done: · 84 unmodified lines | |||
| 2120 | case TOK_ERROR: | 2073 | case TOK_ERROR: |
| 2121 | case TOK_WARNING: | 2074 | case TOK_WARNING: |
| 2122 | c = tok; | 2075 | c = tok; |
| 2123 | ch = file->buf_ptr[0]; | ||
| 2124 | skip_spaces(); | 2076 | skip_spaces(); |
| 2125 | q = buf; | 2077 | q = buf; |
| 2126 | while (ch != '\n' && ch != CH_EOF) { | 2078 | while (ch != '\n' && ch != CH_EOF) { |