Add -dh for DEBUG_HASH Allow tracking of max chain length, to see how well the hash tables are working. Pull the actual hash operation into a marco so it can be easily changed - for experimenting. The current hash, is pretty good. Reviewed by: christosdiff -r1.22 -r1.23 src/usr.bin/make/hash.c
(sjg)
--- src/usr.bin/make/hash.c 2020/07/03 17:03:09 1.22
+++ src/usr.bin/make/hash.c 2020/07/18 21:37:38 1.23
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: hash.c,v 1.22 2020/07/03 17:03:09 rillig Exp $ */ | 1 | /* $NetBSD: hash.c,v 1.23 2020/07/18 21:37:38 sjg 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: hash.c,v 1.22 2020/07/03 17:03:09 rillig Exp $"; | 73 | static char rcsid[] = "$NetBSD: hash.c,v 1.23 2020/07/18 21:37:38 sjg 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[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93"; | 78 | static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93"; | |
79 | #else | 79 | #else | |
80 | __RCSID("$NetBSD: hash.c,v 1.22 2020/07/03 17:03:09 rillig Exp $"); | 80 | __RCSID("$NetBSD: hash.c,v 1.23 2020/07/18 21:37:38 sjg Exp $"); | |
81 | #endif | 81 | #endif | |
82 | #endif /* not lint */ | 82 | #endif /* not lint */ | |
83 | #endif | 83 | #endif | |
84 | 84 | |||
85 | /* hash.c -- | 85 | /* hash.c -- | |
86 | * | 86 | * | |
87 | * This module contains routines to manipulate a hash table. | 87 | * This module contains routines to manipulate a hash table. | |
88 | * See hash.h for a definition of the structure of the hash | 88 | * See hash.h for a definition of the structure of the hash | |
89 | * table. Hash tables grow automatically as the amount of | 89 | * table. Hash tables grow automatically as the amount of | |
90 | * information increases. | 90 | * information increases. | |
91 | */ | 91 | */ | |
92 | #include "sprite.h" | 92 | #include "sprite.h" | |
93 | #include "make.h" | 93 | #include "make.h" | |
@@ -97,26 +97,34 @@ __RCSID("$NetBSD: hash.c,v 1.22 2020/07/ | @@ -97,26 +97,34 @@ __RCSID("$NetBSD: hash.c,v 1.22 2020/07/ | |||
97 | * Forward references to local procedures that are used before they're | 97 | * Forward references to local procedures that are used before they're | |
98 | * defined: | 98 | * defined: | |
99 | */ | 99 | */ | |
100 | 100 | |||
101 | static void RebuildTable(Hash_Table *); | 101 | static void RebuildTable(Hash_Table *); | |
102 | 102 | |||
103 | /* | 103 | /* | |
104 | * The following defines the ratio of # entries to # buckets | 104 | * The following defines the ratio of # entries to # buckets | |
105 | * at which we rebuild the table to make it larger. | 105 | * at which we rebuild the table to make it larger. | |
106 | */ | 106 | */ | |
107 | 107 | |||
108 | #define rebuildLimit 3 | 108 | #define rebuildLimit 3 | |
109 | 109 | |||
110 | /* The hash function(s) */ | |||
111 | /* This one matches Gosling's emacs */ | |||
112 | #define HASH(h, key, p) do { \ | |||
113 | for (h = 0, p = key; *p;) \ | |||
114 | h = (h << 5) - h + *p++; \ | |||
115 | } while (0) | |||
116 | ||||
117 | ||||
110 | /* | 118 | /* | |
111 | *--------------------------------------------------------- | 119 | *--------------------------------------------------------- | |
112 | * | 120 | * | |
113 | * Hash_InitTable -- | 121 | * Hash_InitTable -- | |
114 | * | 122 | * | |
115 | * This routine just sets up the hash table. | 123 | * This routine just sets up the hash table. | |
116 | * | 124 | * | |
117 | * Input: | 125 | * Input: | |
118 | * t Structure to to hold table. | 126 | * t Structure to to hold table. | |
119 | * numBuckets How many buckets to create for starters. This | 127 | * numBuckets How many buckets to create for starters. This | |
120 | * number is rounded up to a power of two. If | 128 | * number is rounded up to a power of two. If | |
121 | * <= 0, a reasonable default is chosen. The | 129 | * <= 0, a reasonable default is chosen. The | |
122 | * table will grow in size later as needed. | 130 | * table will grow in size later as needed. | |
@@ -136,26 +144,27 @@ Hash_InitTable(Hash_Table *t, int numBuc | @@ -136,26 +144,27 @@ Hash_InitTable(Hash_Table *t, int numBuc | |||
136 | int i; | 144 | int i; | |
137 | struct Hash_Entry **hp; | 145 | struct Hash_Entry **hp; | |
138 | 146 | |||
139 | /* | 147 | /* | |
140 | * Round up the size to a power of two. | 148 | * Round up the size to a power of two. | |
141 | */ | 149 | */ | |
142 | if (numBuckets <= 0) | 150 | if (numBuckets <= 0) | |
143 | i = 16; | 151 | i = 16; | |
144 | else { | 152 | else { | |
145 | for (i = 2; i < numBuckets; i <<= 1) | 153 | for (i = 2; i < numBuckets; i <<= 1) | |
146 | continue; | 154 | continue; | |
147 | } | 155 | } | |
148 | t->numEntries = 0; | 156 | t->numEntries = 0; | |
157 | t->maxlen = 0; | |||
149 | t->size = i; | 158 | t->size = i; | |
150 | t->mask = i - 1; | 159 | t->mask = i - 1; | |
151 | t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i); | 160 | t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i); | |
152 | while (--i >= 0) | 161 | while (--i >= 0) | |
153 | *hp++ = NULL; | 162 | *hp++ = NULL; | |
154 | } | 163 | } | |
155 | 164 | |||
156 | /* | 165 | /* | |
157 | *--------------------------------------------------------- | 166 | *--------------------------------------------------------- | |
158 | * | 167 | * | |
159 | * Hash_DeleteTable -- | 168 | * Hash_DeleteTable -- | |
160 | * | 169 | * | |
161 | * This routine removes everything from a hash table | 170 | * This routine removes everything from a hash table | |
@@ -210,37 +219,45 @@ Hash_DeleteTable(Hash_Table *t) | @@ -210,37 +219,45 @@ Hash_DeleteTable(Hash_Table *t) | |||
210 | * | 219 | * | |
211 | * Side Effects: | 220 | * Side Effects: | |
212 | * None. | 221 | * None. | |
213 | * | 222 | * | |
214 | *--------------------------------------------------------- | 223 | *--------------------------------------------------------- | |
215 | */ | 224 | */ | |
216 | 225 | |||
217 | Hash_Entry * | 226 | Hash_Entry * | |
218 | Hash_FindEntry(Hash_Table *t, const char *key) | 227 | Hash_FindEntry(Hash_Table *t, const char *key) | |
219 | { | 228 | { | |
220 | Hash_Entry *e; | 229 | Hash_Entry *e; | |
221 | unsigned h; | 230 | unsigned h; | |
222 | const char *p; | 231 | const char *p; | |
232 | int chainlen; | |||
223 | 233 | |||
224 | if (t == NULL || t->bucketPtr == NULL) { | 234 | if (t == NULL || t->bucketPtr == NULL) { | |
225 | return NULL; | 235 | return NULL; | |
226 | } | 236 | } | |
227 | for (h = 0, p = key; *p;) | 237 | HASH(h, key, p); | |
228 | h = (h << 5) - h + *p++; | |||
229 | p = key; | 238 | p = key; | |
230 | for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) | 239 | if (DEBUG(HASH)) | |
231 | if (e->namehash == h && strcmp(e->name, p) == 0) | 240 | fprintf(debug_file, "%s: %p h=%x key=%s\n", __func__, | |
232 | return e; | 241 | t, h, key); | |
233 | return NULL; | 242 | chainlen = 0; | |
243 | for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) { | |||
244 | chainlen++; | |||
245 | if (e->namehash == h && strcmp(e->name, p) == 0) | |||
246 | break; | |||
247 | } | |||
248 | if (chainlen > t->maxlen) | |||
249 | t->maxlen = chainlen; | |||
250 | return e; | |||
234 | } | 251 | } | |
235 | 252 | |||
236 | /* | 253 | /* | |
237 | *--------------------------------------------------------- | 254 | *--------------------------------------------------------- | |
238 | * | 255 | * | |
239 | * Hash_CreateEntry -- | 256 | * Hash_CreateEntry -- | |
240 | * | 257 | * | |
241 | * Searches a hash table for an entry corresponding to | 258 | * Searches a hash table for an entry corresponding to | |
242 | * key. If no entry is found, then one is created. | 259 | * key. If no entry is found, then one is created. | |
243 | * | 260 | * | |
244 | * Input: | 261 | * Input: | |
245 | * t Hash table to search. | 262 | * t Hash table to search. | |
246 | * key A hash key. | 263 | * key A hash key. | |
@@ -255,43 +272,52 @@ Hash_FindEntry(Hash_Table *t, const char | @@ -255,43 +272,52 @@ Hash_FindEntry(Hash_Table *t, const char | |||
255 | * | 272 | * | |
256 | * Side Effects: | 273 | * Side Effects: | |
257 | * Memory may be allocated, and the hash buckets may be modified. | 274 | * Memory may be allocated, and the hash buckets may be modified. | |
258 | *--------------------------------------------------------- | 275 | *--------------------------------------------------------- | |
259 | */ | 276 | */ | |
260 | 277 | |||
261 | Hash_Entry * | 278 | Hash_Entry * | |
262 | Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr) | 279 | Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr) | |
263 | { | 280 | { | |
264 | Hash_Entry *e; | 281 | Hash_Entry *e; | |
265 | unsigned h; | 282 | unsigned h; | |
266 | const char *p; | 283 | const char *p; | |
267 | int keylen; | 284 | int keylen; | |
285 | int chainlen; | |||
268 | struct Hash_Entry **hp; | 286 | struct Hash_Entry **hp; | |
269 | 287 | |||
270 | /* | 288 | /* | |
271 | * Hash the key. As a side effect, save the length (strlen) of the | 289 | * Hash the key. As a side effect, save the length (strlen) of the | |
272 | * key in case we need to create the entry. | 290 | * key in case we need to create the entry. | |
273 | */ | 291 | */ | |
274 | for (h = 0, p = key; *p;) | 292 | HASH(h, key, p); | |
275 | h = (h << 5) - h + *p++; | |||
276 | keylen = p - key; | 293 | keylen = p - key; | |
277 | p = key; | 294 | p = key; | |
295 | if (DEBUG(HASH)) | |||
296 | fprintf(debug_file, "%s: %p h=%x key=%s\n", __func__, | |||
297 | t, h, key); | |||
298 | chainlen = 0; | |||
278 | for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) { | 299 | for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) { | |
300 | chainlen++; | |||
279 | if (e->namehash == h && strcmp(e->name, p) == 0) { | 301 | if (e->namehash == h && strcmp(e->name, p) == 0) { | |
280 | if (newPtr != NULL) | 302 | if (newPtr != NULL) | |
281 | *newPtr = FALSE; | 303 | *newPtr = FALSE; | |
282 | return e; | 304 | break; | |
283 | } | 305 | } | |
284 | } | 306 | } | |
307 | if (chainlen > t->maxlen) | |||
308 | t->maxlen = chainlen; | |||
309 | if (e) | |||
310 | return e; | |||
285 | 311 | |||
286 | /* | 312 | /* | |
287 | * The desired entry isn't there. Before allocating a new entry, | 313 | * The desired entry isn't there. Before allocating a new entry, | |
288 | * expand the table if necessary (and this changes the resulting | 314 | * expand the table if necessary (and this changes the resulting | |
289 | * bucket chain). | 315 | * bucket chain). | |
290 | */ | 316 | */ | |
291 | if (t->numEntries >= rebuildLimit * t->size) | 317 | if (t->numEntries >= rebuildLimit * t->size) | |
292 | RebuildTable(t); | 318 | RebuildTable(t); | |
293 | e = bmake_malloc(sizeof(*e) + keylen); | 319 | e = bmake_malloc(sizeof(*e) + keylen); | |
294 | hp = &t->bucketPtr[h & t->mask]; | 320 | hp = &t->bucketPtr[h & t->mask]; | |
295 | e->next = *hp; | 321 | e->next = *hp; | |
296 | *hp = e; | 322 | *hp = e; | |
297 | Hash_SetValue(e, NULL); | 323 | Hash_SetValue(e, NULL); | |
@@ -453,25 +479,29 @@ RebuildTable(Hash_Table *t) | @@ -453,25 +479,29 @@ RebuildTable(Hash_Table *t) | |||
453 | t->mask = mask = i - 1; | 479 | t->mask = mask = i - 1; | |
454 | t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i); | 480 | t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i); | |
455 | while (--i >= 0) | 481 | while (--i >= 0) | |
456 | *hp++ = NULL; | 482 | *hp++ = NULL; | |
457 | for (hp = oldhp, i = oldsize; --i >= 0;) { | 483 | for (hp = oldhp, i = oldsize; --i >= 0;) { | |
458 | for (e = *hp++; e != NULL; e = next) { | 484 | for (e = *hp++; e != NULL; e = next) { | |
459 | next = e->next; | 485 | next = e->next; | |
460 | xp = &t->bucketPtr[e->namehash & mask]; | 486 | xp = &t->bucketPtr[e->namehash & mask]; | |
461 | e->next = *xp; | 487 | e->next = *xp; | |
462 | *xp = e; | 488 | *xp = e; | |
463 | } | 489 | } | |
464 | } | 490 | } | |
465 | free(oldhp); | 491 | free(oldhp); | |
492 | if (DEBUG(HASH)) | |||
493 | fprintf(debug_file, "%s: %p size=%d entries=%d maxlen=%d\n", | |||
494 | __func__, t, t->size, t->numEntries, t->maxlen); | |||
495 | t->maxlen = 0; | |||
466 | } | 496 | } | |
467 | 497 | |||
468 | void Hash_ForEach(Hash_Table *t, void (*action)(void *, void *), void *data) | 498 | void Hash_ForEach(Hash_Table *t, void (*action)(void *, void *), void *data) | |
469 | { | 499 | { | |
470 | Hash_Search search; | 500 | Hash_Search search; | |
471 | Hash_Entry *e; | 501 | Hash_Entry *e; | |
472 | 502 | |||
473 | for (e = Hash_EnumFirst(t, &search); | 503 | for (e = Hash_EnumFirst(t, &search); | |
474 | e != NULL; | 504 | e != NULL; | |
475 | e = Hash_EnumNext(&search)) | 505 | e = Hash_EnumNext(&search)) | |
476 | action(Hash_GetValue(e), data); | 506 | action(Hash_GetValue(e), data); | |
477 | } | 507 | } |
--- src/usr.bin/make/hash.h 2020/07/03 17:03:09 1.13
+++ src/usr.bin/make/hash.h 2020/07/18 21:37:38 1.14
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: hash.h,v 1.13 2020/07/03 17:03:09 rillig Exp $ */ | 1 | /* $NetBSD: hash.h,v 1.14 2020/07/18 21:37:38 sjg 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 | * | 5 | * | |
6 | * This code is derived from software contributed to Berkeley by | 6 | * This code is derived from software contributed to Berkeley by | |
7 | * Adam de Boor. | 7 | * Adam de Boor. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
@@ -90,26 +90,27 @@ typedef struct Hash_Entry { | @@ -90,26 +90,27 @@ typedef struct Hash_Entry { | |||
90 | * entries associated with the same | 90 | * entries associated with the same | |
91 | * bucket. */ | 91 | * bucket. */ | |
92 | void *clientPtr; /* Arbitrary pointer */ | 92 | void *clientPtr; /* Arbitrary pointer */ | |
93 | unsigned namehash; /* hash value of key */ | 93 | unsigned namehash; /* hash value of key */ | |
94 | char name[1]; /* key string */ | 94 | char name[1]; /* key string */ | |
95 | } Hash_Entry; | 95 | } Hash_Entry; | |
96 | 96 | |||
97 | typedef struct Hash_Table { | 97 | typedef struct Hash_Table { | |
98 | struct Hash_Entry **bucketPtr;/* Pointers to Hash_Entry, one | 98 | struct Hash_Entry **bucketPtr;/* Pointers to Hash_Entry, one | |
99 | * for each bucket in the table. */ | 99 | * for each bucket in the table. */ | |
100 | int size; /* Actual size of array. */ | 100 | int size; /* Actual size of array. */ | |
101 | int numEntries; /* Number of entries in the table. */ | 101 | int numEntries; /* Number of entries in the table. */ | |
102 | int mask; /* Used to select bits for hashing. */ | 102 | int mask; /* Used to select bits for hashing. */ | |
103 | int maxlen; /* max length of chain detected */ | |||
103 | } Hash_Table; | 104 | } Hash_Table; | |
104 | 105 | |||
105 | /* | 106 | /* | |
106 | * The following structure is used by the searching routines | 107 | * The following structure is used by the searching routines | |
107 | * to record where we are in the search. | 108 | * to record where we are in the search. | |
108 | */ | 109 | */ | |
109 | 110 | |||
110 | typedef struct Hash_Search { | 111 | typedef struct Hash_Search { | |
111 | Hash_Table *tablePtr; /* Table being searched. */ | 112 | Hash_Table *tablePtr; /* Table being searched. */ | |
112 | int nextIndex; /* Next bucket to check (after current). */ | 113 | int nextIndex; /* Next bucket to check (after current). */ | |
113 | Hash_Entry *hashEntryPtr; /* Next entry to check in current bucket. */ | 114 | Hash_Entry *hashEntryPtr; /* Next entry to check in current bucket. */ | |
114 | } Hash_Search; | 115 | } Hash_Search; | |
115 | 116 |
--- src/usr.bin/make/main.c 2020/07/03 08:13:23 1.279
+++ src/usr.bin/make/main.c 2020/07/18 21:37:38 1.280
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $ */ | 1 | /* $NetBSD: main.c,v 1.280 2020/07/18 21:37:38 sjg Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1988, 1989, 1990, 1993 | 4 | * Copyright (c) 1988, 1989, 1990, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. 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. | |
@@ -59,39 +59,39 @@ | @@ -59,39 +59,39 @@ | |||
59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 59 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 60 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 61 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 62 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 63 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 64 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 65 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 66 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 67 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
68 | * SUCH DAMAGE. | 68 | * SUCH DAMAGE. | |
69 | */ | 69 | */ | |
70 | 70 | |||
71 | #ifndef MAKE_NATIVE | 71 | #ifndef MAKE_NATIVE | |
72 | static char rcsid[] = "$NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $"; | 72 | static char rcsid[] = "$NetBSD: main.c,v 1.280 2020/07/18 21:37:38 sjg Exp $"; | |
73 | #else | 73 | #else | |
74 | #include <sys/cdefs.h> | 74 | #include <sys/cdefs.h> | |
75 | #ifndef lint | 75 | #ifndef lint | |
76 | __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\ | 76 | __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\ | |
77 | The Regents of the University of California. All rights reserved."); | 77 | The Regents of the University of California. All rights reserved."); | |
78 | #endif /* not lint */ | 78 | #endif /* not lint */ | |
79 | 79 | |||
80 | #ifndef lint | 80 | #ifndef lint | |
81 | #if 0 | 81 | #if 0 | |
82 | static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94"; | 82 | static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94"; | |
83 | #else | 83 | #else | |
84 | __RCSID("$NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $"); | 84 | __RCSID("$NetBSD: main.c,v 1.280 2020/07/18 21:37:38 sjg Exp $"); | |
85 | #endif | 85 | #endif | |
86 | #endif /* not lint */ | 86 | #endif /* not lint */ | |
87 | #endif | 87 | #endif | |
88 | 88 | |||
89 | /*- | 89 | /*- | |
90 | * main.c -- | 90 | * main.c -- | |
91 | * The main file for this entire program. Exit routines etc | 91 | * The main file for this entire program. Exit routines etc | |
92 | * reside here. | 92 | * reside here. | |
93 | * | 93 | * | |
94 | * Utility functions defined in this file: | 94 | * Utility functions defined in this file: | |
95 | * Main_ParseArgLine Takes a line of arguments, breaks them and | 95 | * Main_ParseArgLine Takes a line of arguments, breaks them and | |
96 | * treats them as if they were given when first | 96 | * treats them as if they were given when first | |
97 | * invoked. Used by the parse module to implement | 97 | * invoked. Used by the parse module to implement | |
@@ -268,26 +268,29 @@ parse_debug_options(const char *argvalue | @@ -268,26 +268,29 @@ parse_debug_options(const char *argvalue | |||
268 | if (modules[1] == '1') { | 268 | if (modules[1] == '1') { | |
269 | debug |= DEBUG_GRAPH1; | 269 | debug |= DEBUG_GRAPH1; | |
270 | ++modules; | 270 | ++modules; | |
271 | } | 271 | } | |
272 | else if (modules[1] == '2') { | 272 | else if (modules[1] == '2') { | |
273 | debug |= DEBUG_GRAPH2; | 273 | debug |= DEBUG_GRAPH2; | |
274 | ++modules; | 274 | ++modules; | |
275 | } | 275 | } | |
276 | else if (modules[1] == '3') { | 276 | else if (modules[1] == '3') { | |
277 | debug |= DEBUG_GRAPH3; | 277 | debug |= DEBUG_GRAPH3; | |
278 | ++modules; | 278 | ++modules; | |
279 | } | 279 | } | |
280 | break; | 280 | break; | |
281 | case 'h': | |||
282 | debug |= DEBUG_HASH; | |||
283 | break; | |||
281 | case 'j': | 284 | case 'j': | |
282 | debug |= DEBUG_JOB; | 285 | debug |= DEBUG_JOB; | |
283 | break; | 286 | break; | |
284 | case 'l': | 287 | case 'l': | |
285 | debug |= DEBUG_LOUD; | 288 | debug |= DEBUG_LOUD; | |
286 | break; | 289 | break; | |
287 | case 'M': | 290 | case 'M': | |
288 | debug |= DEBUG_META; | 291 | debug |= DEBUG_META; | |
289 | break; | 292 | break; | |
290 | case 'm': | 293 | case 'm': | |
291 | debug |= DEBUG_MAKE; | 294 | debug |= DEBUG_MAKE; | |
292 | break; | 295 | break; | |
293 | case 'n': | 296 | case 'n': |
--- src/usr.bin/make/make.1 2020/06/06 20:28:42 1.282
+++ src/usr.bin/make/make.1 2020/07/18 21:37:38 1.283
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | .\" $NetBSD: make.1,v 1.282 2020/06/06 20:28:42 wiz Exp $ | 1 | .\" $NetBSD: make.1,v 1.283 2020/07/18 21:37:38 sjg Exp $ | |
2 | .\" | 2 | .\" | |
3 | .\" Copyright (c) 1990, 1993 | 3 | .\" Copyright (c) 1990, 1993 | |
4 | .\" The Regents of the University of California. All rights reserved. | 4 | .\" The Regents of the University of California. All rights reserved. | |
5 | .\" | 5 | .\" | |
6 | .\" Redistribution and use in source and binary forms, with or without | 6 | .\" Redistribution and use in source and binary forms, with or without | |
7 | .\" modification, are permitted provided that the following conditions | 7 | .\" modification, are permitted provided that the following conditions | |
8 | .\" are met: | 8 | .\" are met: | |
9 | .\" 1. Redistributions of source code must retain the above copyright | 9 | .\" 1. Redistributions of source code must retain the above copyright | |
10 | .\" notice, this list of conditions and the following disclaimer. | 10 | .\" notice, this list of conditions and the following disclaimer. | |
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright | |
12 | .\" notice, this list of conditions and the following disclaimer in the | 12 | .\" notice, this list of conditions and the following disclaimer in the | |
13 | .\" documentation and/or other materials provided with the distribution. | 13 | .\" documentation and/or other materials provided with the distribution. | |
14 | .\" 3. Neither the name of the University nor the names of its contributors | 14 | .\" 3. Neither the name of the University nor the names of its contributors | |
@@ -19,27 +19,27 @@ | @@ -19,27 +19,27 @@ | |||
19 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 19 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
20 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 20 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
21 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 21 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
22 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 22 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
23 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 23 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
24 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 24 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
25 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 25 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
26 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 26 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
28 | .\" SUCH DAMAGE. | 28 | .\" SUCH DAMAGE. | |
29 | .\" | 29 | .\" | |
30 | .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 | 30 | .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 | |
31 | .\" | 31 | .\" | |
32 | .Dd June 5, 2020 | 32 | .Dd July 18, 2020 | |
33 | .Dt MAKE 1 | 33 | .Dt MAKE 1 | |
34 | .Os | 34 | .Os | |
35 | .Sh NAME | 35 | .Sh NAME | |
36 | .Nm make | 36 | .Nm make | |
37 | .Nd maintain program dependencies | 37 | .Nd maintain program dependencies | |
38 | .Sh SYNOPSIS | 38 | .Sh SYNOPSIS | |
39 | .Nm | 39 | .Nm | |
40 | .Op Fl BeikNnqrstWwX | 40 | .Op Fl BeikNnqrstWwX | |
41 | .Op Fl C Ar directory | 41 | .Op Fl C Ar directory | |
42 | .Op Fl D Ar variable | 42 | .Op Fl D Ar variable | |
43 | .Op Fl d Ar flags | 43 | .Op Fl d Ar flags | |
44 | .Op Fl f Ar makefile | 44 | .Op Fl f Ar makefile | |
45 | .Op Fl I Ar directory | 45 | .Op Fl I Ar directory | |
@@ -156,26 +156,28 @@ If the file name ends | @@ -156,26 +156,28 @@ If the file name ends | |||
156 | .Ql .%d | 156 | .Ql .%d | |
157 | then the | 157 | then the | |
158 | .Ql %d | 158 | .Ql %d | |
159 | is replaced by the pid. | 159 | is replaced by the pid. | |
160 | .It Ar f | 160 | .It Ar f | |
161 | Print debugging information about loop evaluation. | 161 | Print debugging information about loop evaluation. | |
162 | .It Ar "g1" | 162 | .It Ar "g1" | |
163 | Print the input graph before making anything. | 163 | Print the input graph before making anything. | |
164 | .It Ar "g2" | 164 | .It Ar "g2" | |
165 | Print the input graph after making everything, or before exiting | 165 | Print the input graph after making everything, or before exiting | |
166 | on error. | 166 | on error. | |
167 | .It Ar "g3" | 167 | .It Ar "g3" | |
168 | Print the input graph before exiting on error. | 168 | Print the input graph before exiting on error. | |
169 | .It Ar h | |||
170 | Print debugging information about hash table operations. | |||
169 | .It Ar j | 171 | .It Ar j | |
170 | Print debugging information about running multiple shells. | 172 | Print debugging information about running multiple shells. | |
171 | .It Ar l | 173 | .It Ar l | |
172 | Print commands in Makefiles regardless of whether or not they are prefixed by | 174 | Print commands in Makefiles regardless of whether or not they are prefixed by | |
173 | .Ql @ | 175 | .Ql @ | |
174 | or other "quiet" flags. | 176 | or other "quiet" flags. | |
175 | Also known as "loud" behavior. | 177 | Also known as "loud" behavior. | |
176 | .It Ar M | 178 | .It Ar M | |
177 | Print debugging information about "meta" mode decisions about targets. | 179 | Print debugging information about "meta" mode decisions about targets. | |
178 | .It Ar m | 180 | .It Ar m | |
179 | Print debugging information about making targets, including modification | 181 | Print debugging information about making targets, including modification | |
180 | dates. | 182 | dates. | |
181 | .It Ar n | 183 | .It Ar n |
--- src/usr.bin/make/make.h 2020/07/02 15:14:38 1.109
+++ src/usr.bin/make/make.h 2020/07/18 21:37:38 1.110
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: make.h,v 1.109 2020/07/02 15:14:38 rillig Exp $ */ | 1 | /* $NetBSD: make.h,v 1.110 2020/07/18 21:37:38 sjg Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1988, 1989, 1990, 1993 | 4 | * Copyright (c) 1988, 1989, 1990, 1993 | |
5 | * The Regents of the University of California. All rights reserved. | 5 | * The Regents of the University of California. 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. | |
@@ -455,26 +455,27 @@ extern int debug; | @@ -455,26 +455,27 @@ extern int debug; | |||
455 | #define DEBUG_DIR 0x00004 | 455 | #define DEBUG_DIR 0x00004 | |
456 | #define DEBUG_GRAPH1 0x00008 | 456 | #define DEBUG_GRAPH1 0x00008 | |
457 | #define DEBUG_GRAPH2 0x00010 | 457 | #define DEBUG_GRAPH2 0x00010 | |
458 | #define DEBUG_JOB 0x00020 | 458 | #define DEBUG_JOB 0x00020 | |
459 | #define DEBUG_MAKE 0x00040 | 459 | #define DEBUG_MAKE 0x00040 | |
460 | #define DEBUG_SUFF 0x00080 | 460 | #define DEBUG_SUFF 0x00080 | |
461 | #define DEBUG_TARG 0x00100 | 461 | #define DEBUG_TARG 0x00100 | |
462 | #define DEBUG_VAR 0x00200 | 462 | #define DEBUG_VAR 0x00200 | |
463 | #define DEBUG_FOR 0x00400 | 463 | #define DEBUG_FOR 0x00400 | |
464 | #define DEBUG_SHELL 0x00800 | 464 | #define DEBUG_SHELL 0x00800 | |
465 | #define DEBUG_ERROR 0x01000 | 465 | #define DEBUG_ERROR 0x01000 | |
466 | #define DEBUG_LOUD 0x02000 | 466 | #define DEBUG_LOUD 0x02000 | |
467 | #define DEBUG_META 0x04000 | 467 | #define DEBUG_META 0x04000 | |
468 | #define DEBUG_HASH 0x08000 | |||
468 | 469 | |||
469 | #define DEBUG_GRAPH3 0x10000 | 470 | #define DEBUG_GRAPH3 0x10000 | |
470 | #define DEBUG_SCRIPT 0x20000 | 471 | #define DEBUG_SCRIPT 0x20000 | |
471 | #define DEBUG_PARSE 0x40000 | 472 | #define DEBUG_PARSE 0x40000 | |
472 | #define DEBUG_CWD 0x80000 | 473 | #define DEBUG_CWD 0x80000 | |
473 | 474 | |||
474 | #define CONCAT(a,b) a##b | 475 | #define CONCAT(a,b) a##b | |
475 | 476 | |||
476 | #define DEBUG(module) (debug & CONCAT(DEBUG_,module)) | 477 | #define DEBUG(module) (debug & CONCAT(DEBUG_,module)) | |
477 | 478 | |||
478 | #include "nonints.h" | 479 | #include "nonints.h" | |
479 | 480 | |||
480 | int Make_TimeStamp(GNode *, GNode *); | 481 | int Make_TimeStamp(GNode *, GNode *); |