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 | ST_FUNC void tcc_mormalize_inc_dirs(TCCState *s) | 1557 | ST_FUNC void tcc_mormalize_inc_dirs(TCCState *s) |
| 1514 | { | 1558 | { |
| 1515 | /* check a preprocessor include dirs and remove not | 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 | - for each duplicate path keep just the first one | 1561 | - for each duplicate path keep just the first one |
| 1518 | - remove each include_path that exists in sysinclude_paths | 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 | 1564 | file_info_t sysinc_stats[50]; // we don't use VLA in tcc code |
| 1521 | struct stat inc_stats[50]; | 1565 | file_info_t inc_stats[50]; |
| 1522 | int num_sysinc = s->nb_sysinclude_paths; | 1566 | int num_sysinc = s->nb_sysinclude_paths; |
| 1523 | int num_inc = s->nb_include_paths; | 1567 | int num_inc = s->nb_include_paths; |
| 1524 | char** pp; | 1568 | char** pp; |
| @@ -1532,28 +1576,28 @@ ST_FUNC void tcc_mormalize_inc_dirs(TCCState *s) · 7 unmodified lines | |||
| 1532 | 1576 | ||
| 1533 | pp = s->sysinclude_paths; | 1577 | pp = s->sysinclude_paths; |
| 1534 | for (i=0; i < num_sysinc; i++) { | 1578 | for (i=0; i < num_sysinc; i++) { |
| 1535 | struct stat *st = &sysinc_stats [i]; | 1579 | file_info_t *st = &sysinc_stats [i]; |
| 1536 | r = stat( pp [i], st); | 1580 | r = get_file_info( pp [i], st); |
| 1537 | if (r || !S_ISDIR(st->st_mode)) { | 1581 | if (r || !is_dir(st)) { |
| 1538 | tcc_free( pp[i] ); | 1582 | tcc_free( pp[i] ); |
| 1539 | pp[i] = 0; | 1583 | pp[i] = 0; |
| 1540 | } | 1584 | } |
| 1541 | } | 1585 | } |
| 1542 | pp = s->include_paths; | 1586 | pp = s->include_paths; |
| 1543 | for (i=0; i < num_inc; i++) { | 1587 | for (i=0; i < num_inc; i++) { |
| 1544 | struct stat *st = &inc_stats [i]; | 1588 | file_info_t *st = &inc_stats [i]; |
| 1545 | r = stat( pp [i], st); | 1589 | r = get_file_info( pp [i], st); |
| 1546 | if (r || !S_ISDIR(st->st_mode)) { | 1590 | if (r || !is_dir(st)) { |
| 1547 | tcc_free( pp[i] ); | 1591 | tcc_free( pp[i] ); |
| 1548 | pp[i] = 0; | 1592 | pp[i] = 0; |
| 1549 | } | 1593 | } |
| 1550 | } | 1594 | } |
| 1551 | 1595 | ||
| 1552 | for (i=0; i < num_inc; i++) { | 1596 | for (i=0; i < num_inc; i++) { |
| 1553 | struct stat *st1 = &inc_stats [i]; | 1597 | file_info_t *st1 = &inc_stats [i]; |
| 1554 | for (j=i+1; j < num_inc; j++) { | 1598 | for (j=i+1; j < num_inc; j++) { |
| 1555 | struct stat *st2 = &inc_stats [j]; | 1599 | file_info_t *st2 = &inc_stats [j]; |
| 1556 | if ((st1->st_dev == st2->st_dev) && (st1->st_ino == st2->st_ino)) { | 1600 | if (is_same_file(st1, st2)) { |
| 1557 | pp = &s->include_paths[j]; | 1601 | pp = &s->include_paths[j]; |
| 1558 | if (*pp) { | 1602 | if (*pp) { |
| 1559 | tcc_free( *pp ); | 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 | for (j=0; i < num_sysinc; i++) { | 1608 | for (j=0; i < num_sysinc; i++) { |
| 1565 | struct stat *st2 = &sysinc_stats [j]; | 1609 | file_info_t *st2 = &sysinc_stats [j]; |
| 1566 | if ((st1->st_dev == st2->st_dev) && (st1->st_ino == st2->st_ino)) { | 1610 | if (is_same_file(st1, st2)) { |
| 1567 | pp = &s->include_paths[i]; | 1611 | pp = &s->include_paths[i]; |
| 1568 | if (*pp) { | 1612 | if (*pp) { |
| 1569 | tcc_free( *pp ); | 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 | for (i=0; i < num_sysinc; i++) { | 1619 | for (i=0; i < num_sysinc; i++) { |
| 1576 | struct stat *st1 = &sysinc_stats [i]; | 1620 | file_info_t *st1 = &sysinc_stats [i]; |
| 1577 | for (j=i+1; j < num_sysinc; j++) { | 1621 | for (j=i+1; j < num_sysinc; j++) { |
| 1578 | struct stat *st2 = &sysinc_stats [j]; | 1622 | file_info_t *st2 = &sysinc_stats [j]; |
| 1579 | if ((st1->st_dev == st2->st_dev) && (st1->st_ino == st2->st_ino)) { | 1623 | if (is_same_file(st1, st2)) { |
| 1580 | pp = &s->sysinclude_paths[j]; | 1624 | pp = &s->sysinclude_paths[j]; |
| 1581 | if (*pp) { | 1625 | if (*pp) { |
| 1582 | tcc_free( *pp ); | 1626 | tcc_free( *pp ); |