| @@ -1500,96 +1500,6 @@ LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val) · 1499 unmodified lines |
| 1500 | return 0; | 1500 | return 0; |
| 1501 | } | 1501 | } |
| 1502 | | 1502 | |
| 1503 | | | |
| 1504 | /* Windows stat* ( https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx ): | | |
| 1505 | * - st_gid, st_ino, st_uid: only valid on "unix" file systems (not FAT, NTFS, etc) | | |
| 1506 | * - st_atime, st_ctime: not valid on FAT, valid on NTFS. | | |
| 1507 | * - Other fields should be reasonably compatible (and S_ISDIR should work). | | |
| 1508 | * | | |
| 1509 | * BY_HANDLE_FILE_INFORMATION ( https://msdn.microsoft.com/en-us/library/windows/desktop/aa363788%28v=vs.85%29.aspx ): | | |
| 1510 | * - File index (combined nFileIndexHigh and nFileIndexLow) _may_ change when the file is opened. | | |
| 1511 | * - But on NTFS: it's guaranteed to be the same value until the file is deleted. | | |
| 1512 | * - On windows server 2012 there's a 128b file id, and the 64b one via | | |
| 1513 | * nFileIndex* is not guaranteed to be unique. | | |
| 1514 | * | | |
| 1515 | * - MS Docs suggest to that volume number with the file index could be used to | | |
| 1516 | * check if two handles refer to the same file. | | |
| 1517 | */ | | |
| 1518 | #ifndef _WIN32 | | |
| 1519 | typedef struct stat file_info_t; | | |
| 1520 | #else | | |
| 1521 | typedef BY_HANDLE_FILE_INFORMATION file_info_t; | | |
| 1522 | #endif | | |
| 1523 | | | |
| 1524 | static int get_file_info(const char *fname, file_info_t *out_info) | | |
| 1525 | { | | |
| 1526 | #ifndef _WIN32 | | |
| 1527 | return stat(fname, out_info); | | |
| 1528 | #else | | |
| 1529 | int rv = 1; | | |
| 1530 | HANDLE h = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, | | |
| 1531 | FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, NULL); | | |
| 1532 | | | |
| 1533 | if (h != INVALID_HANDLE_VALUE) { | | |
| 1534 | rv = !GetFileInformationByHandle(h, out_info); | | |
| 1535 | CloseHandle(h); | | |
| 1536 | } | | |
| 1537 | return rv; | | |
| 1538 | #endif | | |
| 1539 | } | | |
| 1540 | | | |
| 1541 | static int is_dir(file_info_t *info) | | |
| 1542 | { | | |
| 1543 | #ifndef _WIN32 | | |
| 1544 | return S_ISDIR(info->st_mode); | | |
| 1545 | #else | | |
| 1546 | return (info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == | | |
| 1547 | FILE_ATTRIBUTE_DIRECTORY; | | |
| 1548 | #endif | | |
| 1549 | } | | |
| 1550 | | | |
| 1551 | static int is_same_file(const file_info_t *fi1, const file_info_t *fi2) | | |
| 1552 | { | | |
| 1553 | #ifndef _WIN32 | | |
| 1554 | return fi1->st_dev == fi2->st_dev && | | |
| 1555 | fi1->st_ino == fi2->st_ino; | | |
| 1556 | #else | | |
| 1557 | return fi1->dwVolumeSerialNumber == fi2->dwVolumeSerialNumber && | | |
| 1558 | fi1->nFileIndexHigh == fi2->nFileIndexHigh && | | |
| 1559 | fi1->nFileIndexLow == fi2->nFileIndexLow; | | |
| 1560 | #endif | | |
| 1561 | } | | |
| 1562 | | | |
| 1563 | static void | | |
| 1564 | tcc_normalize_inc_dirs_aux(file_info_t *stats, size_t *pnum, char **path) | | |
| 1565 | { | | |
| 1566 | size_t i, num = *pnum; | | |
| 1567 | if (get_file_info(*path, &stats[num]) || !is_dir(&stats[num])) | | |
| 1568 | goto remove; | | |
| 1569 | for (i = 0; i < num; i++) | | |
| 1570 | if (is_same_file(&stats[i], &stats[num])) | | |
| 1571 | goto remove; | | |
| 1572 | *pnum = num + 1; | | |
| 1573 | return; | | |
| 1574 | remove: | | |
| 1575 | tcc_free(*path); | | |
| 1576 | *path = 0; | | |
| 1577 | } | | |
| 1578 | | | |
| 1579 | /* Remove non-existent and duplicate directories from include paths. */ | | |
| 1580 | ST_FUNC void tcc_normalize_inc_dirs(TCCState *s) | | |
| 1581 | { | | |
| 1582 | file_info_t *stats = | | |
| 1583 | tcc_malloc(((size_t)s->nb_sysinclude_paths + s->nb_include_paths) * | | |
| 1584 | sizeof(*stats)); | | |
| 1585 | size_t i, num = 0; | | |
| 1586 | for (i = 0; i < s->nb_sysinclude_paths; i++) | | |
| 1587 | tcc_normalize_inc_dirs_aux(stats, &num, &s->sysinclude_paths[i]); | | |
| 1588 | for (i = 0; i < s->nb_include_paths; i++) | | |
| 1589 | tcc_normalize_inc_dirs_aux(stats, &num, &s->include_paths[i]); | | |
| 1590 | tcc_free(stats); | | |
| 1591 | } | | |
| 1592 | | | |
| 1593 | LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) | 1503 | LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) |
| 1594 | { | 1504 | { |
| 1595 | s->output_type = output_type; | 1505 | s->output_type = output_type; |
| @@ -1643,8 +1553,6 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) · 47 unmodified lines |
| 1643 | tcc_add_crt(s, "crti.o"); | 1553 | tcc_add_crt(s, "crti.o"); |
| 1644 | } | 1554 | } |
| 1645 | #endif | 1555 | #endif |
| 1646 | if (s->normalize_inc_dirs) | | |
| 1647 | tcc_normalize_inc_dirs(s); | | |
| 1648 | return 0; | 1556 | return 0; |
| 1649 | } | 1557 | } |
| 1650 | | 1558 | |
| @@ -1729,7 +1637,6 @@ static const FlagDef flag_defs[] = { · 78 unmodified lines |
| 1729 | { offsetof(TCCState, ms_extensions), 0, "ms-extensions" }, | 1637 | { offsetof(TCCState, ms_extensions), 0, "ms-extensions" }, |
| 1730 | { offsetof(TCCState, old_struct_init_code), 0, "old-struct-init-code" }, | 1638 | { offsetof(TCCState, old_struct_init_code), 0, "old-struct-init-code" }, |
| 1731 | { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" }, | 1639 | { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" }, |
| 1732 | { offsetof(TCCState, normalize_inc_dirs), 0, "normalize-inc-dirs" }, | | |
| 1733 | }; | 1640 | }; |
| 1734 | | 1641 | |
| 1735 | /* set/reset a flag */ | 1642 | /* set/reset a flag */ |