| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: dir.c,v 1.111 2020/08/26 22:55:46 rillig Exp $ */ | | 1 | /* $NetBSD: dir.c,v 1.112 2020/08/27 06:28:44 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. | | 4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Adam de Boor. | | 8 | * Adam de Boor. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -60,34 +60,34 @@ | | | @@ -60,34 +60,34 @@ |
60 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 60 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
61 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 61 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
62 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 62 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
63 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 63 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
64 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 64 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
65 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 65 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
66 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 66 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
67 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 67 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
68 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 68 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
69 | * SUCH DAMAGE. | | 69 | * SUCH DAMAGE. |
70 | */ | | 70 | */ |
71 | | | 71 | |
72 | #ifndef MAKE_NATIVE | | 72 | #ifndef MAKE_NATIVE |
73 | static char rcsid[] = "$NetBSD: dir.c,v 1.111 2020/08/26 22:55:46 rillig Exp $"; | | 73 | static char rcsid[] = "$NetBSD: dir.c,v 1.112 2020/08/27 06:28:44 rillig Exp $"; |
74 | #else | | 74 | #else |
75 | #include <sys/cdefs.h> | | 75 | #include <sys/cdefs.h> |
76 | #ifndef lint | | 76 | #ifndef lint |
77 | #if 0 | | 77 | #if 0 |
78 | static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94"; | | 78 | static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94"; |
79 | #else | | 79 | #else |
80 | __RCSID("$NetBSD: dir.c,v 1.111 2020/08/26 22:55:46 rillig Exp $"); | | 80 | __RCSID("$NetBSD: dir.c,v 1.112 2020/08/27 06:28:44 rillig Exp $"); |
81 | #endif | | 81 | #endif |
82 | #endif /* not lint */ | | 82 | #endif /* not lint */ |
83 | #endif | | 83 | #endif |
84 | | | 84 | |
85 | /*- | | 85 | /*- |
86 | * dir.c -- | | 86 | * dir.c -- |
87 | * Directory searching using wildcards and/or normal names... | | 87 | * Directory searching using wildcards and/or normal names... |
88 | * Used both for source wildcarding in the Makefile and for finding | | 88 | * Used both for source wildcarding in the Makefile and for finding |
89 | * implicit sources. | | 89 | * implicit sources. |
90 | * | | 90 | * |
91 | * The interface for this module is: | | 91 | * The interface for this module is: |
92 | * Dir_Init Initialize the module. | | 92 | * Dir_Init Initialize the module. |
93 | * | | 93 | * |
| @@ -785,33 +785,32 @@ DirExpandCurly(const char *word, const c | | | @@ -785,33 +785,32 @@ DirExpandCurly(const char *word, const c |
785 | * Results: | | 785 | * Results: |
786 | * None. | | 786 | * None. |
787 | * | | 787 | * |
788 | * Side Effects: | | 788 | * Side Effects: |
789 | * Things are added to the expansions list. | | 789 | * Things are added to the expansions list. |
790 | * | | 790 | * |
791 | *----------------------------------------------------------------------- | | 791 | *----------------------------------------------------------------------- |
792 | */ | | 792 | */ |
793 | static void | | 793 | static void |
794 | DirExpandInt(const char *word, Lst path, Lst expansions) | | 794 | DirExpandInt(const char *word, Lst path, Lst expansions) |
795 | { | | 795 | { |
796 | LstNode ln; /* Current node */ | | 796 | LstNode ln; /* Current node */ |
797 | | | 797 | |
798 | if (Lst_Open(path) == SUCCESS) { | | 798 | Lst_OpenS(path); |
799 | while ((ln = Lst_NextS(path)) != NULL) { | | 799 | while ((ln = Lst_NextS(path)) != NULL) { |
800 | Path *p = Lst_DatumS(ln); | | 800 | Path *p = Lst_DatumS(ln); |
801 | DirMatchFiles(word, p, expansions); | | 801 | DirMatchFiles(word, p, expansions); |
802 | } | | | |
803 | Lst_CloseS(path); | | | |
804 | } | | 802 | } |
| | | 803 | Lst_CloseS(path); |
805 | } | | 804 | } |
806 | | | 805 | |
807 | /* Print a word in the list of expansions. | | 806 | /* Print a word in the list of expansions. |
808 | * Callback for Dir_Expand when DEBUG(DIR), via Lst_ForEach. */ | | 807 | * Callback for Dir_Expand when DEBUG(DIR), via Lst_ForEach. */ |
809 | static int | | 808 | static int |
810 | DirPrintWord(void *word, void *dummy MAKE_ATTR_UNUSED) | | 809 | DirPrintWord(void *word, void *dummy MAKE_ATTR_UNUSED) |
811 | { | | 810 | { |
812 | fprintf(debug_file, "%s ", (char *)word); | | 811 | fprintf(debug_file, "%s ", (char *)word); |
813 | | | 812 | |
814 | return 0; | | 813 | return 0; |
815 | } | | 814 | } |
816 | | | 815 | |
817 | /*- | | 816 | /*- |
| @@ -830,26 +829,29 @@ DirPrintWord(void *word, void *dummy MAK | | | @@ -830,26 +829,29 @@ DirPrintWord(void *word, void *dummy MAK |
830 | * A list of words consisting of the files which exist along the search | | 829 | * A list of words consisting of the files which exist along the search |
831 | * path matching the given pattern. | | 830 | * path matching the given pattern. |
832 | * | | 831 | * |
833 | * Side Effects: | | 832 | * Side Effects: |
834 | * Directories may be opened. Who knows? | | 833 | * Directories may be opened. Who knows? |
835 | * Undefined behavior if the word is really in read-only memory. | | 834 | * Undefined behavior if the word is really in read-only memory. |
836 | *----------------------------------------------------------------------- | | 835 | *----------------------------------------------------------------------- |
837 | */ | | 836 | */ |
838 | void | | 837 | void |
839 | Dir_Expand(const char *word, Lst path, Lst expansions) | | 838 | Dir_Expand(const char *word, Lst path, Lst expansions) |
840 | { | | 839 | { |
841 | const char *cp; | | 840 | const char *cp; |
842 | | | 841 | |
| | | 842 | assert(path != NULL); |
| | | 843 | assert(expansions != NULL); |
| | | 844 | |
843 | DIR_DEBUG1("Expanding \"%s\"... ", word); | | 845 | DIR_DEBUG1("Expanding \"%s\"... ", word); |
844 | | | 846 | |
845 | cp = strchr(word, '{'); | | 847 | cp = strchr(word, '{'); |
846 | if (cp) { | | 848 | if (cp) { |
847 | DirExpandCurly(word, cp, path, expansions); | | 849 | DirExpandCurly(word, cp, path, expansions); |
848 | } else { | | 850 | } else { |
849 | cp = strchr(word, '/'); | | 851 | cp = strchr(word, '/'); |
850 | if (cp) { | | 852 | if (cp) { |
851 | /* | | 853 | /* |
852 | * The thing has a directory component -- find the first wildcard | | 854 | * The thing has a directory component -- find the first wildcard |
853 | * in the string. | | 855 | * in the string. |
854 | */ | | 856 | */ |
855 | for (cp = word; *cp; cp++) { | | 857 | for (cp = word; *cp; cp++) { |
| @@ -1118,32 +1120,33 @@ Dir_FindFile(const char *name, Lst path) | | | @@ -1118,32 +1120,33 @@ Dir_FindFile(const char *name, Lst path) |
1118 | * slash in it (the name, I mean) | | 1120 | * slash in it (the name, I mean) |
1119 | */ | | 1121 | */ |
1120 | cp = strrchr(name, '/'); | | 1122 | cp = strrchr(name, '/'); |
1121 | if (cp) { | | 1123 | if (cp) { |
1122 | hasSlash = TRUE; | | 1124 | hasSlash = TRUE; |
1123 | cp += 1; | | 1125 | cp += 1; |
1124 | } else { | | 1126 | } else { |
1125 | hasSlash = FALSE; | | 1127 | hasSlash = FALSE; |
1126 | cp = name; | | 1128 | cp = name; |
1127 | } | | 1129 | } |
1128 | | | 1130 | |
1129 | DIR_DEBUG1("Searching for %s ...", name); | | 1131 | DIR_DEBUG1("Searching for %s ...", name); |
1130 | | | 1132 | |
1131 | if (Lst_Open(path) == FAILURE) { | | 1133 | if (path == NULL) { |
1132 | DIR_DEBUG0("couldn't open path, file not found\n"); | | 1134 | DIR_DEBUG0("couldn't open path, file not found\n"); |
1133 | misses += 1; | | 1135 | misses += 1; |
1134 | return NULL; | | 1136 | return NULL; |
1135 | } | | 1137 | } |
1136 | | | 1138 | |
| | | 1139 | Lst_OpenS(path); |
1137 | if ((ln = Lst_First(path)) != NULL) { | | 1140 | if ((ln = Lst_First(path)) != NULL) { |
1138 | p = Lst_DatumS(ln); | | 1141 | p = Lst_DatumS(ln); |
1139 | if (p == dotLast) { | | 1142 | if (p == dotLast) { |
1140 | hasLastDot = TRUE; | | 1143 | hasLastDot = TRUE; |
1141 | DIR_DEBUG0("[dot last]..."); | | 1144 | DIR_DEBUG0("[dot last]..."); |
1142 | } | | 1145 | } |
1143 | } | | 1146 | } |
1144 | DIR_DEBUG0("\n"); | | 1147 | DIR_DEBUG0("\n"); |
1145 | | | 1148 | |
1146 | /* | | 1149 | /* |
1147 | * If there's no leading directory components or if the leading | | 1150 | * If there's no leading directory components or if the leading |
1148 | * directory component is exactly `./', consult the cached contents | | 1151 | * directory component is exactly `./', consult the cached contents |
1149 | * of each of the directories on the search path. | | 1152 | * of each of the directories on the search path. |
| @@ -1650,27 +1653,28 @@ Dir_CopyDir(void *p) | | | @@ -1650,27 +1653,28 @@ Dir_CopyDir(void *p) |
1650 | * | | 1653 | * |
1651 | * Side Effects: | | 1654 | * Side Effects: |
1652 | * None | | 1655 | * None |
1653 | *----------------------------------------------------------------------- | | 1656 | *----------------------------------------------------------------------- |
1654 | */ | | 1657 | */ |
1655 | char * | | 1658 | char * |
1656 | Dir_MakeFlags(const char *flag, Lst path) | | 1659 | Dir_MakeFlags(const char *flag, Lst path) |
1657 | { | | 1660 | { |
1658 | Buffer buf; | | 1661 | Buffer buf; |
1659 | LstNode ln; /* the node of the current directory */ | | 1662 | LstNode ln; /* the node of the current directory */ |
1660 | | | 1663 | |
1661 | Buf_Init(&buf, 0); | | 1664 | Buf_Init(&buf, 0); |
1662 | | | 1665 | |
1663 | if (Lst_Open(path) == SUCCESS) { | | 1666 | if (path != NULL) { |
| | | 1667 | Lst_OpenS(path); |
1664 | while ((ln = Lst_NextS(path)) != NULL) { | | 1668 | while ((ln = Lst_NextS(path)) != NULL) { |
1665 | Path *p = Lst_DatumS(ln); | | 1669 | Path *p = Lst_DatumS(ln); |
1666 | Buf_AddStr(&buf, " "); | | 1670 | Buf_AddStr(&buf, " "); |
1667 | Buf_AddStr(&buf, flag); | | 1671 | Buf_AddStr(&buf, flag); |
1668 | Buf_AddStr(&buf, p->name); | | 1672 | Buf_AddStr(&buf, p->name); |
1669 | } | | 1673 | } |
1670 | Lst_CloseS(path); | | 1674 | Lst_CloseS(path); |
1671 | } | | 1675 | } |
1672 | | | 1676 | |
1673 | return Buf_Destroy(&buf, FALSE); | | 1677 | return Buf_Destroy(&buf, FALSE); |
1674 | } | | 1678 | } |
1675 | | | 1679 | |
1676 | /*- | | 1680 | /*- |
| @@ -1770,42 +1774,41 @@ Dir_Concat(Lst path1, Lst path2) | | | @@ -1770,42 +1774,41 @@ Dir_Concat(Lst path1, Lst path2) |
1770 | } | | 1774 | } |
1771 | | | 1775 | |
1772 | static int | | 1776 | static int |
1773 | percentage(int num, int den) | | 1777 | percentage(int num, int den) |
1774 | { | | 1778 | { |
1775 | return den != 0 ? num * 100 / den : 0; | | 1779 | return den != 0 ? num * 100 / den : 0; |
1776 | } | | 1780 | } |
1777 | | | 1781 | |
1778 | /********** DEBUG INFO **********/ | | 1782 | /********** DEBUG INFO **********/ |
1779 | void | | 1783 | void |
1780 | Dir_PrintDirectories(void) | | 1784 | Dir_PrintDirectories(void) |
1781 | { | | 1785 | { |
1782 | LstNode ln; | | 1786 | LstNode ln; |
1783 | Path *p; | | | |
1784 | | | 1787 | |
1785 | fprintf(debug_file, "#*** Directory Cache:\n"); | | 1788 | fprintf(debug_file, "#*** Directory Cache:\n"); |
1786 | fprintf(debug_file, | | 1789 | fprintf(debug_file, |
1787 | "# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n", | | 1790 | "# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n", |
1788 | hits, misses, nearmisses, bigmisses, | | 1791 | hits, misses, nearmisses, bigmisses, |
1789 | percentage(hits, hits + bigmisses + nearmisses)); | | 1792 | percentage(hits, hits + bigmisses + nearmisses)); |
1790 | fprintf(debug_file, "# %-20s referenced\thits\n", "directory"); | | 1793 | fprintf(debug_file, "# %-20s referenced\thits\n", "directory"); |
1791 | if (Lst_Open(openDirectories) == SUCCESS) { | | 1794 | |
1792 | while ((ln = Lst_NextS(openDirectories)) != NULL) { | | 1795 | Lst_OpenS(openDirectories); |
1793 | p = Lst_DatumS(ln); | | 1796 | while ((ln = Lst_NextS(openDirectories)) != NULL) { |
1794 | fprintf(debug_file, "# %-20s %10d\t%4d\n", p->name, p->refCount, | | 1797 | Path *p = Lst_DatumS(ln); |
1795 | p->hits); | | 1798 | fprintf(debug_file, "# %-20s %10d\t%4d\n", p->name, p->refCount, |
1796 | } | | 1799 | p->hits); |
1797 | Lst_CloseS(openDirectories); | | | |
1798 | } | | 1800 | } |
| | | 1801 | Lst_CloseS(openDirectories); |
1799 | } | | 1802 | } |
1800 | | | 1803 | |
1801 | static int | | 1804 | static int |
1802 | DirPrintDir(void *p, void *dummy MAKE_ATTR_UNUSED) | | 1805 | DirPrintDir(void *p, void *dummy MAKE_ATTR_UNUSED) |
1803 | { | | 1806 | { |
1804 | fprintf(debug_file, "%s ", ((Path *)p)->name); | | 1807 | fprintf(debug_file, "%s ", ((Path *)p)->name); |
1805 | return 0; | | 1808 | return 0; |
1806 | } | | 1809 | } |
1807 | | | 1810 | |
1808 | void | | 1811 | void |
1809 | Dir_PrintPath(Lst path) | | 1812 | Dir_PrintPath(Lst path) |
1810 | { | | 1813 | { |
1811 | Lst_ForEach(path, DirPrintDir, NULL); | | 1814 | Lst_ForEach(path, DirPrintDir, NULL); |