Use native Windows API via wrapper with stat-like API.
Unified · Split
| @@ -1510,6 +1510,50 @@ LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val) · 1509 unmodified lines | ||
| 1510 | 1510 | } |
| 1511 | 1511 | |
| 1512 | 1512 | |
| 1513 | +#ifndef _WIN32 | |
| 1514 | +typedef struct stat file_info_t; | |
| 1515 | +#else | |
| 1516 | +typedef BY_HANDLE_FILE_INFORMATION file_info_t; | |
| 1517 | +#endif | |
| 1518 | + | |
| 1519 | +int get_file_info(const char *fname, file_info_t *out_info) | |
| 1520 | +{ | |
| 1521 | +#ifndef _WIN32 | |
| 1522 | + return stat(fname, out_info); | |
| 1523 | +#else | |
| 1524 | + int rv = 1; | |
| 1525 | + HANDLE h = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, | |
| 1526 | + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, NULL); | |
| 1527 | + if (h == INVALID_HANDLE_VALUE) | |
| 1528 | + return rv; | |
| 1529 | + | |
| 1530 | + rv = !GetFileInformationByHandle(h, out_info); | |
| 1531 | + CloseHandle(h); | |
| 1532 | + return rv; | |
| 1533 | +#endif | |
| 1534 | +} | |
| 1535 | + | |
| 1536 | +int is_dir(file_info_t *info) | |
| 1537 | +{ | |
| 1538 | +#ifndef _WIN32 | |
| 1539 | + return S_ISDIR(info->st_mode); | |
| 1540 | +#else | |
| 1541 | + return info->dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY; | |
| 1542 | +#endif | |
| 1543 | +} | |
| 1544 | + | |
| 1545 | +int is_same_file(const file_info_t *fi1, const file_info_t *fi2) | |
| 1546 | +{ | |
| 1547 | +#ifndef _WIN32 | |
| 1548 | + return fi1->st_dev == fi2->st_dev && | |
| 1549 | + fi1->st_ino == fi2->st_ino; | |
| 1550 | +#else | |
| 1551 | + return fi1->dwVolumeSerialNumber == fi2->dwVolumeSerialNumber && | |
| 1552 | + fi1->nFileIndexHigh == fi2->nFileIndexHigh && | |
| 1553 | + fi1->nFileIndexLow == fi2->nFileIndexLow; | |
| 1554 | +#endif | |
| 1555 | +} | |
| 1556 | + | |
| 1513 | 1557 | ST_FUNC void tcc_mormalize_inc_dirs(TCCState *s) |
| 1514 | 1558 | { |
| 1515 | 1559 | /* check a preprocessor include dirs and remove not |
| @@ -1517,8 +1561,8 @@ ST_FUNC void tcc_mormalize_inc_dirs(TCCState *s) · 1 unmodified line | ||
| 1517 | 1561 | - for each duplicate path keep just the first one |
| 1518 | 1562 | - remove each include_path that exists in sysinclude_paths |
| 1519 | 1563 | */ |
| 1520 | − struct stat sysinc_stats[50]; // we don't use VLA in tcc code | |
| 1521 | − struct stat inc_stats[50]; | |
| 1564 | + file_info_t sysinc_stats[50]; // we don't use VLA in tcc code | |
| 1565 | + file_info_t inc_stats[50]; | |
| 1522 | 1566 | int num_sysinc = s->nb_sysinclude_paths; |
| 1523 | 1567 | int num_inc = s->nb_include_paths; |
| 1524 | 1568 | char** pp; |
| @@ -1532,28 +1576,28 @@ ST_FUNC void tcc_mormalize_inc_dirs(TCCState *s) · 7 unmodified lines | ||
| 1532 | 1576 | |
| 1533 | 1577 | pp = s->sysinclude_paths; |
| 1534 | 1578 | for (i=0; i < num_sysinc; i++) { |
| 1535 | − struct stat *st = &sysinc_stats [i]; | |
| 1536 | − r = stat( pp [i], st); | |
| 1537 | − if (r || !S_ISDIR(st->st_mode)) { | |
| 1579 | + file_info_t *st = &sysinc_stats [i]; | |
| 1580 | + r = get_file_info( pp [i], st); | |
| 1581 | + if (r || !is_dir(st)) { | |
| 1538 | 1582 | tcc_free( pp[i] ); |
| 1539 | 1583 | pp[i] = 0; |
| 1540 | 1584 | } |
| 1541 | 1585 | } |
| 1542 | 1586 | pp = s->include_paths; |
| 1543 | 1587 | for (i=0; i < num_inc; i++) { |
| 1544 | − struct stat *st = &inc_stats [i]; | |
| 1545 | − r = stat( pp [i], st); | |
| 1546 | − if (r || !S_ISDIR(st->st_mode)) { | |
| 1588 | + file_info_t *st = &inc_stats [i]; | |
| 1589 | + r = get_file_info( pp [i], st); | |
| 1590 | + if (r || !is_dir(st)) { | |
| 1547 | 1591 | tcc_free( pp[i] ); |
| 1548 | 1592 | pp[i] = 0; |
| 1549 | 1593 | } |
| 1550 | 1594 | } |
| 1551 | 1595 | |
| 1552 | 1596 | for (i=0; i < num_inc; i++) { |
| 1553 | − struct stat *st1 = &inc_stats [i]; | |
| 1597 | + file_info_t *st1 = &inc_stats [i]; | |
| 1554 | 1598 | for (j=i+1; j < num_inc; j++) { |
| 1555 | − struct stat *st2 = &inc_stats [j]; | |
| 1556 | − if ((st1->st_dev == st2->st_dev) && (st1->st_ino == st2->st_ino)) { | |
| 1599 | + file_info_t *st2 = &inc_stats [j]; | |
| 1600 | + if (is_same_file(st1, st2)) { | |
| 1557 | 1601 | pp = &s->include_paths[j]; |
| 1558 | 1602 | if (*pp) { |
| 1559 | 1603 | tcc_free( *pp ); |
| @@ -1562,8 +1606,8 @@ ST_FUNC void tcc_mormalize_inc_dirs(TCCState *s) · 2 unmodified lines | ||
| 1562 | 1606 | } |
| 1563 | 1607 | } |
| 1564 | 1608 | for (j=0; i < num_sysinc; i++) { |
| 1565 | − struct stat *st2 = &sysinc_stats [j]; | |
| 1566 | − if ((st1->st_dev == st2->st_dev) && (st1->st_ino == st2->st_ino)) { | |
| 1609 | + file_info_t *st2 = &sysinc_stats [j]; | |
| 1610 | + if (is_same_file(st1, st2)) { | |
| 1567 | 1611 | pp = &s->include_paths[i]; |
| 1568 | 1612 | if (*pp) { |
| 1569 | 1613 | tcc_free( *pp ); |
| @@ -1573,10 +1617,10 @@ ST_FUNC void tcc_mormalize_inc_dirs(TCCState *s) · 3 unmodified lines | ||
| 1573 | 1617 | } |
| 1574 | 1618 | } |
| 1575 | 1619 | for (i=0; i < num_sysinc; i++) { |
| 1576 | − struct stat *st1 = &sysinc_stats [i]; | |
| 1620 | + file_info_t *st1 = &sysinc_stats [i]; | |
| 1577 | 1621 | for (j=i+1; j < num_sysinc; j++) { |
| 1578 | − struct stat *st2 = &sysinc_stats [j]; | |
| 1579 | − if ((st1->st_dev == st2->st_dev) && (st1->st_ino == st2->st_ino)) { | |
| 1622 | + file_info_t *st2 = &sysinc_stats [j]; | |
| 1623 | + if (is_same_file(st1, st2)) { | |
| 1580 | 1624 | pp = &s->sysinclude_paths[j]; |
| 1581 | 1625 | if (*pp) { |
| 1582 | 1626 | tcc_free( *pp ); |