Fri Apr 2 09:45:55 2021 UTC ()
lint: extract filename ID counter into separate function

No functional change.


(rillig)
diff -r1.38 -r1.39 src/usr.bin/xlint/lint1/mem1.c

cvs diff -r1.38 -r1.39 src/usr.bin/xlint/lint1/mem1.c (switch to unified diff)

--- src/usr.bin/xlint/lint1/mem1.c 2021/04/02 09:39:25 1.38
+++ src/usr.bin/xlint/lint1/mem1.c 2021/04/02 09:45:55 1.39
@@ -1,386 +1,392 @@ @@ -1,386 +1,392 @@
1/* $NetBSD: mem1.c,v 1.38 2021/04/02 09:39:25 rillig Exp $ */ 1/* $NetBSD: mem1.c,v 1.39 2021/04/02 09:45:55 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by Jochen Pohl for 17 * This product includes software developed by Jochen Pohl for
18 * The NetBSD Project. 18 * The NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products 19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission. 20 * derived from this software without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) && !defined(lint) 39#if defined(__RCSID) && !defined(lint)
40__RCSID("$NetBSD: mem1.c,v 1.38 2021/04/02 09:39:25 rillig Exp $"); 40__RCSID("$NetBSD: mem1.c,v 1.39 2021/04/02 09:45:55 rillig Exp $");
41#endif 41#endif
42 42
43#include <sys/types.h> 43#include <sys/types.h>
44#include <sys/param.h> 44#include <sys/param.h>
45#include <stdlib.h> 45#include <stdlib.h>
46#include <string.h> 46#include <string.h>
47#include <unistd.h> 47#include <unistd.h>
48 48
49#include "lint1.h" 49#include "lint1.h"
50 50
51/* 51/*
52 * Filenames allocated by record_filename are shared. 52 * Filenames allocated by record_filename are shared.
53 */ 53 */
54struct filename { 54struct filename {
55 char *fn_name; 55 char *fn_name;
56 size_t fn_len; 56 size_t fn_len;
57 int fn_id; 57 int fn_id;
58 struct filename *fn_next; 58 struct filename *fn_next;
59}; 59};
60 60
61static struct filename *filenames; /* null-terminated array */ 61static struct filename *filenames; /* null-terminated array */
62 62
63/* Find the given filename, or return NULL. */ 63/* Find the given filename, or return NULL. */
64static const struct filename * 64static const struct filename *
65search_filename(const char *s, size_t len) 65search_filename(const char *s, size_t len)
66{ 66{
67 const struct filename *fn; 67 const struct filename *fn;
68 68
69 for (fn = filenames; fn != NULL; fn = fn->fn_next) { 69 for (fn = filenames; fn != NULL; fn = fn->fn_next) {
70 if (fn->fn_len == len && memcmp(fn->fn_name, s, len) == 0) 70 if (fn->fn_len == len && memcmp(fn->fn_name, s, len) == 0)
71 break; 71 break;
72 } 72 }
73 return fn; 73 return fn;
74} 74}
75 75
76struct filename_replacement { 76struct filename_replacement {
77 char *orig; 77 char *orig;
78 size_t orig_len; 78 size_t orig_len;
79 char *repl; 79 char *repl;
80 struct filename_replacement *next; 80 struct filename_replacement *next;
81}; 81};
82 82
83static struct filename_replacement *filename_replacements; 83static struct filename_replacement *filename_replacements;
84 84
85void 85void
86add_directory_replacement(char *arg) 86add_directory_replacement(char *arg)
87{ 87{
88 struct filename_replacement *r = xmalloc(sizeof *r); 88 struct filename_replacement *r = xmalloc(sizeof *r);
89 89
90 char *sep = strchr(arg, '='); 90 char *sep = strchr(arg, '=');
91 if (sep == NULL) 91 if (sep == NULL)
92 err(1, "Bad replacement directory spec `%s'", arg); 92 err(1, "Bad replacement directory spec `%s'", arg);
93 *sep = '\0'; 93 *sep = '\0';
94 94
95 r->orig = arg; 95 r->orig = arg;
96 r->orig_len = sep - arg; 96 r->orig_len = sep - arg;
97 r->repl = sep + 1; 97 r->repl = sep + 1;
98 r->next = filename_replacements; 98 r->next = filename_replacements;
99 filename_replacements = r; 99 filename_replacements = r;
100} 100}
101 101
102const char * 102const char *
103transform_filename(const char *name, size_t len) 103transform_filename(const char *name, size_t len)
104{ 104{
105 static char buf[MAXPATHLEN]; 105 static char buf[MAXPATHLEN];
106 const struct filename_replacement *r; 106 const struct filename_replacement *r;
107 107
108 for (r = filename_replacements; r != NULL; r = r->next) 108 for (r = filename_replacements; r != NULL; r = r->next)
109 if (r->orig_len < len && 109 if (r->orig_len < len &&
110 memcmp(name, r->orig, r->orig_len) == 0) 110 memcmp(name, r->orig, r->orig_len) == 0)
111 break; 111 break;
112 if (r == NULL) 112 if (r == NULL)
113 return name; 113 return name;
114 snprintf(buf, sizeof buf, "%s%s", r->repl, name + r->orig_len); 114 snprintf(buf, sizeof buf, "%s%s", r->repl, name + r->orig_len);
115 return buf; 115 return buf;
116} 116}
117 117
 118static int
 119next_filename_id(void)
 120{
 121 static int next_id = 0;
 122
 123 return next_id++;
 124}
 125
118/* 126/*
119 * Return a copy of the filename s with unlimited lifetime. 127 * Return a copy of the filename s with unlimited lifetime.
120 * If the filename is new, write it to the output file. 128 * If the filename is new, write it to the output file.
121 */ 129 */
122const char * 130const char *
123record_filename(const char *s, size_t slen) 131record_filename(const char *s, size_t slen)
124{ 132{
125 const struct filename *existing_fn; 133 const struct filename *existing_fn;
126 struct filename *fn; 134 struct filename *fn;
127 135
128 static int nxt_id = 0; 
129 
130 if (s == NULL) 136 if (s == NULL)
131 return NULL; 137 return NULL;
132 138
133 if ((existing_fn = search_filename(s, slen)) != NULL) 139 if ((existing_fn = search_filename(s, slen)) != NULL)
134 return existing_fn->fn_name; 140 return existing_fn->fn_name;
135 141
136 fn = xmalloc(sizeof(*fn)); 142 fn = xmalloc(sizeof(*fn));
137 /* Do not use strdup() because s is not NUL-terminated.*/ 143 /* Do not use strdup() because s is not NUL-terminated.*/
138 fn->fn_name = xmalloc(slen + 1); 144 fn->fn_name = xmalloc(slen + 1);
139 (void)memcpy(fn->fn_name, s, slen); 145 (void)memcpy(fn->fn_name, s, slen);
140 fn->fn_name[slen] = '\0'; 146 fn->fn_name[slen] = '\0';
141 fn->fn_len = slen; 147 fn->fn_len = slen;
142 fn->fn_id = nxt_id++; 148 fn->fn_id = next_filename_id();
143 fn->fn_next = filenames; 149 fn->fn_next = filenames;
144 filenames = fn; 150 filenames = fn;
145 151
146 /* Write the ID of this filename to the output file. */ 152 /* Write the ID of this filename to the output file. */
147 outclr(); 153 outclr();
148 outint(fn->fn_id); 154 outint(fn->fn_id);
149 outchar('s'); 155 outchar('s');
150 outstrg(transform_filename(fn->fn_name, fn->fn_len)); 156 outstrg(transform_filename(fn->fn_name, fn->fn_len));
151 157
152 return fn->fn_name; 158 return fn->fn_name;
153} 159}
154 160
155/* Get the ID of a filename. */ 161/* Get the ID of a filename. */
156int 162int
157get_filename_id(const char *s) 163get_filename_id(const char *s)
158{ 164{
159 const struct filename *fn; 165 const struct filename *fn;
160 166
161 if (s == NULL || (fn = search_filename(s, strlen(s))) == NULL) 167 if (s == NULL || (fn = search_filename(s, strlen(s))) == NULL)
162 return -1; 168 return -1;
163 return fn->fn_id; 169 return fn->fn_id;
164} 170}
165 171
166/* 172/*
167 * Memory for declarations and other things which must be available 173 * Memory for declarations and other things which must be available
168 * until the end of a block (or the end of the translation unit) 174 * until the end of a block (or the end of the translation unit)
169 * are associated with the level (mem_block_level) of the block (or with 0). 175 * are associated with the level (mem_block_level) of the block (or with 0).
170 * Because this memory is allocated in large blocks associated with 176 * Because this memory is allocated in large blocks associated with
171 * a given level it can be freed easily at the end of a block. 177 * a given level it can be freed easily at the end of a block.
172 */ 178 */
173#define ML_INC ((size_t)32) /* Increment for length of *mblks */ 179#define ML_INC ((size_t)32) /* Increment for length of *mblks */
174 180
175typedef struct memory_block { 181typedef struct memory_block {
176 void *blk; /* beginning of memory block */ 182 void *blk; /* beginning of memory block */
177 void *ffree; /* first free byte */ 183 void *ffree; /* first free byte */
178 size_t nfree; /* # of free bytes */ 184 size_t nfree; /* # of free bytes */
179 size_t size; /* total size of memory block */ 185 size_t size; /* total size of memory block */
180 struct memory_block *nxt; /* next block */ 186 struct memory_block *nxt; /* next block */
181} memory_block; 187} memory_block;
182 188
183/* 189/*
184 * Array of pointers to lists of memory blocks. mem_block_level is used as 190 * Array of pointers to lists of memory blocks. mem_block_level is used as
185 * index into this array. 191 * index into this array.
186 */ 192 */
187static memory_block **mblks; 193static memory_block **mblks;
188 194
189/* number of elements in *mblks */ 195/* number of elements in *mblks */
190static size_t nmblks; 196static size_t nmblks;
191 197
192/* free list for memory blocks */ 198/* free list for memory blocks */
193static memory_block *frmblks; 199static memory_block *frmblks;
194 200
195/* length of new allocated memory blocks */ 201/* length of new allocated memory blocks */
196static size_t mblklen; 202static size_t mblklen;
197 203
198static void *xgetblk(memory_block **, size_t); 204static void *xgetblk(memory_block **, size_t);
199static void xfreeblk(memory_block **); 205static void xfreeblk(memory_block **);
200static memory_block *xnewblk(void); 206static memory_block *xnewblk(void);
201 207
202static memory_block * 208static memory_block *
203xnewblk(void) 209xnewblk(void)
204{ 210{
205 memory_block *mb = xmalloc(sizeof *mb); 211 memory_block *mb = xmalloc(sizeof *mb);
206 212
207 /* use mmap instead of malloc to avoid malloc's size overhead */ 213 /* use mmap instead of malloc to avoid malloc's size overhead */
208 mb->blk = xmapalloc(mblklen); 214 mb->blk = xmapalloc(mblklen);
209 mb->size = mblklen; 215 mb->size = mblklen;
210 216
211 return mb; 217 return mb;
212} 218}
213 219
214/* Allocate new memory, initialized with zero. */ 220/* Allocate new memory, initialized with zero. */
215static void * 221static void *
216xgetblk(memory_block **mbp, size_t s) 222xgetblk(memory_block **mbp, size_t s)
217{ 223{
218 memory_block *mb; 224 memory_block *mb;
219 void *p; 225 void *p;
220 size_t t = 0; 226 size_t t = 0;
221 227
222 /* 228 /*
223 * If the first block of the list has not enough free space, 229 * If the first block of the list has not enough free space,
224 * or there is no first block, get a new block. The new block 230 * or there is no first block, get a new block. The new block
225 * is taken from the free list or, if there is no block on the 231 * is taken from the free list or, if there is no block on the
226 * free list, is allocated using xnewblk(). 232 * free list, is allocated using xnewblk().
227 * 233 *
228 * If a new block is allocated it is initialized with zero. 234 * If a new block is allocated it is initialized with zero.
229 * Blocks taken from the free list are zero'd in xfreeblk(). 235 * Blocks taken from the free list are zero'd in xfreeblk().
230 */ 236 */
231 237
232 s = WORST_ALIGN(s); 238 s = WORST_ALIGN(s);
233 if ((mb = *mbp) == NULL || mb->nfree < s) { 239 if ((mb = *mbp) == NULL || mb->nfree < s) {
234 if ((mb = frmblks) == NULL || mb->size < s) { 240 if ((mb = frmblks) == NULL || mb->size < s) {
235 if (s > mblklen) { 241 if (s > mblklen) {
236 t = mblklen; 242 t = mblklen;
237 mblklen = s; 243 mblklen = s;
238 } 244 }
239 mb = xnewblk(); 245 mb = xnewblk();
240#ifndef BLKDEBUG 246#ifndef BLKDEBUG
241 (void)memset(mb->blk, 0, mb->size); 247 (void)memset(mb->blk, 0, mb->size);
242#endif 248#endif
243 if (t > 0) 249 if (t > 0)
244 mblklen = t; 250 mblklen = t;
245 } else { 251 } else {
246 frmblks = mb->nxt; 252 frmblks = mb->nxt;
247 } 253 }
248 mb->ffree = mb->blk; 254 mb->ffree = mb->blk;
249 mb->nfree = mb->size; 255 mb->nfree = mb->size;
250 mb->nxt = *mbp; 256 mb->nxt = *mbp;
251 *mbp = mb; 257 *mbp = mb;
252 } 258 }
253 p = mb->ffree; 259 p = mb->ffree;
254 mb->ffree = (char *)mb->ffree + s; 260 mb->ffree = (char *)mb->ffree + s;
255 mb->nfree -= s; 261 mb->nfree -= s;
256#ifdef BLKDEBUG 262#ifdef BLKDEBUG
257 (void)memset(p, 0, s); 263 (void)memset(p, 0, s);
258#endif 264#endif
259 return p; 265 return p;
260} 266}
261 267
262/* 268/*
263 * Move all blocks from list *fmbp to free list. For each block, set all 269 * Move all blocks from list *fmbp to free list. For each block, set all
264 * used memory to zero. 270 * used memory to zero.
265 */ 271 */
266static void 272static void
267xfreeblk(memory_block **fmbp) 273xfreeblk(memory_block **fmbp)
268{ 274{
269 memory_block *mb; 275 memory_block *mb;
270 276
271 while ((mb = *fmbp) != NULL) { 277 while ((mb = *fmbp) != NULL) {
272 *fmbp = mb->nxt; 278 *fmbp = mb->nxt;
273 mb->nxt = frmblks; 279 mb->nxt = frmblks;
274 frmblks = mb; 280 frmblks = mb;
275 (void)memset(mb->blk, ZERO, mb->size - mb->nfree); 281 (void)memset(mb->blk, ZERO, mb->size - mb->nfree);
276 } 282 }
277} 283}
278 284
279void 285void
280initmem(void) 286initmem(void)
281{ 287{
282 int pgsz; 288 int pgsz;
283 289
284 pgsz = getpagesize(); 290 pgsz = getpagesize();
285 mblklen = ((MBLKSIZ + pgsz - 1) / pgsz) * pgsz; 291 mblklen = ((MBLKSIZ + pgsz - 1) / pgsz) * pgsz;
286 292
287 mblks = xcalloc(nmblks = ML_INC, sizeof *mblks); 293 mblks = xcalloc(nmblks = ML_INC, sizeof *mblks);
288} 294}
289 295
290 296
291/* Allocate memory associated with level l. */ 297/* Allocate memory associated with level l. */
292void * 298void *
293getlblk(size_t l, size_t s) 299getlblk(size_t l, size_t s)
294{ 300{
295 301
296 while (l >= nmblks) { 302 while (l >= nmblks) {
297 mblks = xrealloc(mblks, (nmblks + ML_INC) * sizeof *mblks); 303 mblks = xrealloc(mblks, (nmblks + ML_INC) * sizeof *mblks);
298 (void)memset(&mblks[nmblks], 0, ML_INC * sizeof *mblks); 304 (void)memset(&mblks[nmblks], 0, ML_INC * sizeof *mblks);
299 nmblks += ML_INC; 305 nmblks += ML_INC;
300 } 306 }
301 return xgetblk(&mblks[l], s); 307 return xgetblk(&mblks[l], s);
302} 308}
303 309
304void * 310void *
305getblk(size_t s) 311getblk(size_t s)
306{ 312{
307 313
308 return getlblk(mem_block_level, s); 314 return getlblk(mem_block_level, s);
309} 315}
310 316
311/* Free all memory associated with level l. */ 317/* Free all memory associated with level l. */
312void 318void
313freelblk(int l) 319freelblk(int l)
314{ 320{
315 321
316 xfreeblk(&mblks[l]); 322 xfreeblk(&mblks[l]);
317} 323}
318 324
319void 325void
320freeblk(void) 326freeblk(void)
321{ 327{
322 328
323 freelblk(mem_block_level); 329 freelblk(mem_block_level);
324} 330}
325 331
326static memory_block *tmblk; 332static memory_block *tmblk;
327 333
328/* 334/*
329 * Return zero-initialized memory that is freed at the end of the current 335 * Return zero-initialized memory that is freed at the end of the current
330 * expression. 336 * expression.
331 */ 337 */
332void * 338void *
333tgetblk(size_t s) 339tgetblk(size_t s)
334{ 340{
335 341
336 return xgetblk(&tmblk, s); 342 return xgetblk(&tmblk, s);
337} 343}
338 344
339/* Return a freshly allocated tree node. */ 345/* Return a freshly allocated tree node. */
340tnode_t * 346tnode_t *
341getnode(void) 347getnode(void)
342{ 348{
343 tnode_t *tn = tgetblk(sizeof *tn); 349 tnode_t *tn = tgetblk(sizeof *tn);
344 tn->tn_from_system_header = in_system_header; 350 tn->tn_from_system_header = in_system_header;
345 return tn; 351 return tn;
346} 352}
347 353
348/* Free all memory which is allocated by the current expression. */ 354/* Free all memory which is allocated by the current expression. */
349void 355void
350tfreeblk(void) 356tfreeblk(void)
351{ 357{
352 358
353 xfreeblk(&tmblk); 359 xfreeblk(&tmblk);
354} 360}
355 361
356/* 362/*
357 * Save the memory which is used by the current expression. This memory 363 * Save the memory which is used by the current expression. This memory
358 * is not freed by the next tfreeblk() call. The pointer returned can be 364 * is not freed by the next tfreeblk() call. The pointer returned can be
359 * used to restore the memory. 365 * used to restore the memory.
360 */ 366 */
361memory_block * 367memory_block *
362tsave(void) 368tsave(void)
363{ 369{
364 memory_block *tmem; 370 memory_block *tmem;
365 371
366 tmem = tmblk; 372 tmem = tmblk;
367 tmblk = NULL; 373 tmblk = NULL;
368 return tmem; 374 return tmem;
369} 375}
370 376
371/* 377/*
372 * Free all memory used for the current expression and the memory used 378 * Free all memory used for the current expression and the memory used
373 * be a previous expression and saved by tsave(). The next call to 379 * be a previous expression and saved by tsave(). The next call to
374 * tfreeblk() frees the restored memory. 380 * tfreeblk() frees the restored memory.
375 */ 381 */
376void 382void
377trestor(memory_block *tmem) 383trestor(memory_block *tmem)
378{ 384{
379 385
380 tfreeblk(); 386 tfreeblk();
381 if (tmblk != NULL) { 387 if (tmblk != NULL) {
382 free(tmblk->blk); 388 free(tmblk->blk);
383 free(tmblk); 389 free(tmblk);
384 } 390 }
385 tmblk = tmem; 391 tmblk = tmem;
386} 392}