]> andersk Git - splint.git/blame - src/fileTable.c
Committed my changes (but there are several splintme errors currently).
[splint.git] / src / fileTable.c
CommitLineData
616915dd 1/*
11db3170 2** Splint - annotation-assisted static program checker
77d37419 3** Copyright (C) 1994-2002 University of Virginia,
616915dd 4** Massachusetts Institute of Technology
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** This program is distributed in the hope that it will be useful, but
12** WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14** General Public License for more details.
15**
16** The GNU General Public License is available from http://www.gnu.org/ or
17** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18** MA 02111-1307, USA.
19**
155af98d 20** For information on splint: info@splint.org
21** To report a bug: splint-bug@splint.org
11db3170 22** For more information: http://www.splint.org
616915dd 23*/
24/*
25** fileTable.c
26**
27** replaces filenamemap.c
28** based (loosely) on typeTable.c
29**
30** entries in the fileTable are:
31**
32** name - name of the file
33** type - kind of file (a temp file to be deleted?)
34** link - derived from this file
35**
36*/
37/*
38 * Herbert 04/1997:
39 * - Added conditional stuff (macros OS2 and MSDOS) to make names of temporary
40 * files under Windows or OS/2 not larger than 8+3 characters to avoid
41 * trouble with FAT file systems or Novell Netware volumes.
42 * - Added include of new header file portab.h containing OS dependent stuff.
43 * - Changed occurance of '/' as path delimiter to a macro.
44 * - Added conditional stuff (#define and #include) for IBM's compiler.
45 */
46
d5047b91 47# include <sys/types.h>
48# include <sys/stat.h>
49# include <fcntl.h>
1b8ae690 50# include "splintMacros.nf"
616915dd 51# include "llbasic.h"
52# include "osd.h"
53# include "llmain.h"
54# include "portab.h"
d5047b91 55
616915dd 56# if defined(__IBMC__) && defined(OS2)
57# include <process.h>
36250f22 58# include <io.h>
616915dd 59# define getpid _getpid
36250f22 60# define S_IRUSR S_IREAD
61# define S_IWUSR S_IWRITE
62# define S_IXUSR S_IEXEC
616915dd 63# endif
64
65/*@access fileId*/
66
80489f0a 67static void
68fileTable_addOpen (fileTable p_ft, /*@observer@*/ FILE *p_f, /*@only@*/ cstring p_fname)
69 /*@modifies p_ft@*/ ;
70
616915dd 71static bool fileTable_inRange (fileTable ft, fileId fid) /*@*/
72{
73 return (fileTable_isDefined (ft) && (fid >= 0) && (fid < ft->nentries));
74}
75
76static fileId fileTable_internAddEntry (fileTable p_ft, /*@only@*/ ftentry p_e)
77 /*@modifies p_ft@*/ ;
28bf4b0b 78static /*@only@*/ cstring makeTempName (cstring p_dir, cstring p_pre, cstring p_suf);
616915dd 79
80static /*@only@*/ cstring
81fileType_unparse (fileType ft)
82{
83 switch (ft)
84 {
85 case FILE_NORMAL: return cstring_makeLiteral ("normal");
86 case FILE_NODELETE: return cstring_makeLiteral ("normal");
87 case FILE_LSLTEMP: return cstring_makeLiteral ("ltemp");
88 case FILE_HEADER: return cstring_makeLiteral ("header");
28bf4b0b 89 case FILE_XH: return cstring_makeLiteral ("xh");
616915dd 90 case FILE_MACROS: return cstring_makeLiteral ("macros");
28bf4b0b 91 case FILE_METASTATE: return cstring_makeLiteral ("metastate");
616915dd 92 }
93
94 BADEXIT;
95}
96
97static int
98fileTable_getIndex (fileTable ft, cstring s)
99{
53a89507 100 int res;
101 cstring abspath;
616915dd 102 if (ft == NULL) return NOT_FOUND;
53a89507 103 abspath = osd_absolutePath (cstring_undefined, s);
2cecdaff 104
105 if (context_getFlag (FLG_CASEINSENSITIVEFILENAMES))
106 {
107 abspath = cstring_downcase (abspath);
108 }
109
f2b6724f 110 DPRINTF (("Absolute path: %s: %s", s, abspath));
53a89507 111 res = cstringTable_lookup (ft->htable, abspath);
112 cstring_free (abspath);
113 return res;
616915dd 114}
115
4dd72714 116static cstring ftentry_unparse (fileTable ft, ftentry fte)
117{
118 if (fileId_isValid (fte->fder))
119 {
abd7f895 120 llassert (fileTable_isDefined (ft));
121
4dd72714 122 return message ("%s %q %d (%s)",
123 fte->fname,
124 fileType_unparse (fte->ftype),
125 fte->fder,
126 ft->elements[fte->fder]->fname);
127 }
128 else
129 {
130 return message ("%s %q", fte->fname,
131 fileType_unparse (fte->ftype));
132 }
133}
134
616915dd 135/*@only@*/ cstring
136fileTable_unparse (fileTable ft)
137{
138 cstring s = cstring_undefined;
139 int i;
140
141 if (fileTable_isUndefined (ft))
142 {
143 return (cstring_makeLiteral ("<fileTable undefined>"));
144 }
145
146 for (i = 0; i < ft->nentries; i++)
147 {
4dd72714 148 s = message ("%s\n[%d] %q", s, i, ftentry_unparse (ft, ft->elements[i]));
149 }
616915dd 150
151 return s;
152}
153
154void fileTable_printTemps (fileTable ft)
155{
156 if (fileTable_isDefined (ft))
157 {
158 int i;
159
160 for (i = 0; i < ft->nentries; i++)
161 {
162 if (ft->elements[i]->ftemp)
163 {
164 if (fileId_isValid (ft->elements[i]->fder))
165 {
166 fprintf (stderr, " %s:1\n\t%s:1\n",
167 cstring_toCharsSafe (ft->elements[ft->elements[i]->fder]->fname),
168 cstring_toCharsSafe (ft->elements[i]->fname));
169 }
170 else
171 {
172 fprintf (stderr, "[no file]\n\t%s:1\n",
173 cstring_toCharsSafe (ft->elements[i]->fname));
174 }
175 }
176 }
177 }
178}
179
180/*
181** loads in fileTable from fileTable_dump
182*/
183
184static /*@notnull@*/ ftentry
185ftentry_create (/*@keep@*/ cstring tn, bool temp, fileType typ, fileId der)
186{
187 ftentry t = (ftentry) dmalloc (sizeof (*t));
188
189 if (cstring_isUndefined (tn))
190 {
191 llbug (cstring_makeLiteral ("Undefined filename!"));
192 }
193
194 t->fname = tn;
616915dd 195 t->basename = cstring_undefined;
196 t->ftemp = temp;
197 t->ftype = typ;
198 t->fder = der;
199
200 /* Don't set these until the basename is needed. */
201 t->fsystem = FALSE;
202 t->fspecial = FALSE;
203
204 return t;
205}
206
207static void
208ftentry_free (/*@only@*/ ftentry t)
209{
210 cstring_free (t->fname);
211 cstring_free (t->basename);
212 sfree (t);
213}
214
215/*@only@*/ /*@notnull@*/ fileTable
216fileTable_create ()
217{
218 fileTable ft = (fileTable) dmalloc (sizeof (*ft));
219
220 ft->nentries = 0;
221 ft->nspace = FTBASESIZE;
222 ft->elements = (ftentry *) dmalloc (FTBASESIZE * sizeof (*ft->elements));
28bf4b0b 223 ft->htable = cstringTable_create (FTHASHSIZE);
dfd82dce 224
225 ft->nopen = 0;
226 ft->nopenspace = FTBASESIZE;
227 ft->openelements = (foentry *) dmalloc (FTBASESIZE * sizeof (*ft->openelements));
6fcd0b1e 228
616915dd 229 return (ft);
230}
231
232static void
233fileTable_grow (fileTable ft)
234{
235 int i;
236 ftentry *newent;
237
238 llassert (fileTable_isDefined (ft));
239
240 ft->nspace = FTBASESIZE;
241
242 newent = (ftentry *) dmalloc ((ft->nentries + ft->nspace) * sizeof (*newent));
243
244 for (i = 0; i < ft->nentries; i++)
245 {
246 newent[i] = ft->elements[i];
247 }
248
249 sfree (ft->elements);
250 ft->elements = newent;
251}
252
dfd82dce 253static void
254fileTable_growOpen (fileTable ft)
255{
256 int i;
257 foentry *newent;
258
259 llassert (fileTable_isDefined (ft));
260
261 ft->nopenspace = FTBASESIZE;
262
263 newent = (foentry *) dmalloc ((ft->nopen + ft->nopenspace) * sizeof (*newent));
264
265 for (i = 0; i < ft->nopen; i++)
266 {
267 newent[i] = ft->openelements[i];
268 }
269
270 sfree (ft->openelements);
271 ft->openelements = newent;
272}
273
616915dd 274static fileId
275fileTable_internAddEntry (fileTable ft, /*@only@*/ ftentry e)
276{
277 llassert (fileTable_isDefined (ft));
278
279 if (ft->nspace <= 0)
280 fileTable_grow (ft);
281
282 ft->nspace--;
283
f2b6724f 284 DPRINTF (("Adding: %s", e->fname));
2cecdaff 285
286 if (context_getFlag (FLG_CASEINSENSITIVEFILENAMES))
287 {
288 cstring sd = cstring_downcase (e->fname);
289 cstringTable_insert (ft->htable, sd, ft->nentries);
2cecdaff 290 }
291 else
292 {
6fcd0b1e 293 cstringTable_insert (ft->htable, cstring_copy (e->fname), ft->nentries);
2cecdaff 294 }
295
6fcd0b1e 296 /* evans 2002-07-12:
297 Before, there was no cstring_copy above, and e->fname was free'd in the if branch.
298 Splint should have caught this, and produced a warning for this assignment.
299 Why not?
300 */
616915dd 301 ft->elements[ft->nentries] = e;
302
303 ft->nentries++;
304 return (ft->nentries - 1);
305}
306
307void fileTable_noDelete (fileTable ft, cstring name)
308{
309 fileId fid = fileTable_lookup (ft, name);
310
4dd72714 311 if (fileId_isValid (fid))
312 {
313 llassert (fileTable_isDefined (ft));
314 ft->elements[fid]->ftype = FILE_NODELETE;
315 }
316 else
317 {
318 DPRINTF (("Invalid no delete: %s", name));
319 }
616915dd 320}
321
322static fileId
53a89507 323fileTable_addFilePrim (fileTable ft, /*@temp@*/ cstring name,
616915dd 324 bool temp, fileType typ, fileId der)
325 /*@modifies ft@*/
326{
53a89507 327 cstring absname = osd_absolutePath (NULL, name);
328 int tindex = fileTable_getIndex (ft, absname);
4dd72714 329
140c27a8 330 /*@i534 fprintf (stderr, "Got abs path: %s", absname); */
616915dd 331 llassert (ft != fileTable_undefined);
332
333 if (tindex != NOT_FOUND)
334 {
53a89507 335 llcontbug (message ("fileTable_addFilePrim: duplicate entry: %q", absname));
616915dd 336 return tindex;
337 }
338 else
339 {
53a89507 340 ftentry e = ftentry_create (absname, temp, typ, der);
616915dd 341
342 if (der == fileId_invalid)
343 {
344 llassert (cstring_isUndefined (e->basename));
345
53a89507 346 e->basename = fileLib_removePathFree (fileLib_removeAnyExtension (absname));
347 e->fsystem = context_isSystemDir (absname);
52e90c0f 348
349 /*
350 ** evans 2002-03-15: change suggested by Jim Zelenka
351 ** support relative paths for system directories
352 */
353
354 if (!e->fsystem)
355 {
356 e->fsystem = context_isSystemDir (name);
357 }
358
53a89507 359 e->fspecial = context_isSpecialFile (absname);
616915dd 360
361 if (e->fspecial)
362 {
53a89507 363 cstring srcname = cstring_concatFree1 (fileLib_removeAnyExtension (absname),
28bf4b0b 364 C_EXTENSION);
616915dd 365 fileId fid = fileTable_lookup (ft, srcname);
616915dd 366 cstring_free (srcname);
367
368 if (fileId_isValid (fid))
369 {
370 fileId derid = ft->elements[fid]->fder;
371
372 ft->elements[fid]->fspecial = TRUE;
373
374 if (fileId_isValid (derid))
375 {
376 ft->elements[derid]->fspecial = TRUE;
377 }
378 }
379 }
380 }
381 else
382 {
383 ftentry de = ft->elements[der];
384
385 llassert (cstring_isUndefined (e->basename));
386 e->basename = cstring_copy (de->basename);
387 e->fsystem = de->fsystem;
388 e->fspecial = de->fspecial;
389 }
390
391 return (fileTable_internAddEntry (ft, e));
392 }
393}
394
395fileId
396fileTable_addFile (fileTable ft, cstring name)
397{
53a89507 398 return (fileTable_addFilePrim (ft, name, FALSE, FILE_NORMAL, fileId_invalid));
616915dd 399}
400
401fileId
402fileTable_addFileOnly (fileTable ft, /*@only@*/ cstring name)
403{
53a89507 404 fileId res = fileTable_addFilePrim (ft, name, FALSE, FILE_NORMAL, fileId_invalid);
405 cstring_free (name);
406 return res;
616915dd 407}
408
409fileId
410fileTable_addHeaderFile (fileTable ft, cstring name)
411{
28bf4b0b 412 fileId res;
53a89507 413 res = fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid);
28bf4b0b 414 return res;
415
616915dd 416}
417
80489f0a 418void
419fileTable_addStreamFile (fileTable ft, FILE *fstream, cstring name)
420{
421 fileTable_addOpen (ft, fstream, cstring_copy (name));
422}
423
616915dd 424bool
425fileTable_isHeader (fileTable ft, fileId fid)
426{
427 if (fileId_isInvalid (fid))
428 {
429 return FALSE;
430 }
431
432 llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
433 return (ft->elements[fid]->ftype == FILE_HEADER);
434}
435
436bool
437fileTable_isSystemFile (fileTable ft, fileId fid)
438{
439 if (fileId_isInvalid (fid))
440 {
441 return FALSE;
442 }
443
444 llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
445 return (ft->elements[fid]->fsystem);
446}
447
28bf4b0b 448bool
449fileTable_isXHFile (fileTable ft, fileId fid)
450{
451 if (fileId_isInvalid (fid))
452 {
453 return FALSE;
454 }
455
ccf0a4a8 456 if (!(fileTable_isDefined (ft) && fileTable_inRange (ft, fid)))
457 {
458 llcontbug (message ("Bad file table or id: %s %d", bool_unparse (fileTable_isDefined (ft)), fid));
459 return FALSE;
460 }
461 else
462 {
463 return (ft->elements[fid]->ftype == FILE_XH);
464 }
28bf4b0b 465}
466
616915dd 467bool
468fileTable_isSpecialFile (fileTable ft, fileId fid)
469{
470 if (fileId_isInvalid (fid))
471 {
472 return FALSE;
473 }
ccf0a4a8 474
616915dd 475 llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
476 return (ft->elements[fid]->fspecial);
477}
478
479fileId
480fileTable_addLibraryFile (fileTable ft, cstring name)
481{
53a89507 482 return (fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid));
616915dd 483}
484
28bf4b0b 485fileId
486fileTable_addXHFile (fileTable ft, cstring name)
487{
53a89507 488 return (fileTable_addFilePrim (ft, name, FALSE, FILE_XH, fileId_invalid));
28bf4b0b 489}
490
616915dd 491fileId
492fileTable_addImportFile (fileTable ft, cstring name)
493{
53a89507 494 return (fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid));
616915dd 495}
496
497fileId
498fileTable_addLCLFile (fileTable ft, cstring name)
499{
53a89507 500 return (fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid));
616915dd 501}
616915dd 502
616915dd 503static int tmpcounter = 0;
616915dd 504
505fileId
506fileTable_addMacrosFile (fileTable ft)
507{
28bf4b0b 508 cstring newname =
509 makeTempName (context_tmpdir (), cstring_makeLiteralTemp ("lmx"),
510 cstring_makeLiteralTemp (".llm"));
53a89507 511 fileId res = fileTable_addFilePrim (ft, newname, TRUE, FILE_MACROS, fileId_invalid);
512 cstring_free (newname);
513 return res;
616915dd 514}
515
28bf4b0b 516fileId
517fileTable_addMetastateFile (fileTable ft, cstring name)
518{
53a89507 519 return (fileTable_addFilePrim (ft, name, FALSE, FILE_METASTATE, fileId_invalid));
28bf4b0b 520}
521
616915dd 522fileId
523fileTable_addCTempFile (fileTable ft, fileId fid)
524{
28bf4b0b 525 cstring newname =
526 makeTempName (context_tmpdir (), cstring_makeLiteralTemp ("cl"),
527 C_EXTENSION);
53a89507 528 fileId res;
616915dd 529
4dd72714 530 DPRINTF (("tmp dir: %s", context_tmpdir ()));
531 DPRINTF (("new name: %s", newname));
532
616915dd 533 llassert (fileTable_isDefined (ft));
534
535 if (!fileId_isValid (ft->elements[fid]->fder))
536 {
28bf4b0b 537 if (fileTable_isXHFile (ft, fid))
538 {
53a89507 539 res = fileTable_addFilePrim (ft, newname, TRUE, FILE_XH, fid);
28bf4b0b 540 }
541 else
542 {
53a89507 543 res = fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL, fid);
28bf4b0b 544 }
616915dd 545 }
546 else
547 {
28bf4b0b 548 if (fileTable_isXHFile (ft, fid))
549 {
53a89507 550 res = fileTable_addFilePrim (ft, newname, TRUE, FILE_XH,
551 ft->elements[fid]->fder);
28bf4b0b 552 }
553 else
554 {
53a89507 555 res = fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL,
556 ft->elements[fid]->fder);
28bf4b0b 557 }
616915dd 558 }
53a89507 559
4dd72714 560 DPRINTF (("Added file: %s", fileTable_fileName (res)));
53a89507 561 cstring_free (newname);
562 return res;
616915dd 563}
564
616915dd 565fileId
566fileTable_addltemp (fileTable ft)
567{
28bf4b0b 568 cstring newname = makeTempName (context_tmpdir (),
569 cstring_makeLiteralTemp ("ls"),
570 cstring_makeLiteralTemp (".lsl"));
616915dd 571 fileId ret;
572
28bf4b0b 573 if (cstring_hasNonAlphaNumBar (newname))
616915dd 574 {
575 char *lastpath = (char *)NULL;
576
577 if (tmpcounter == 0)
578 {
579 lldiagmsg
580 (message
581 ("Operating system generates tmp filename containing invalid charater: %s",
28bf4b0b 582 newname));
616915dd 583 lldiagmsg (cstring_makeLiteral
584 ("Try cleaning up the tmp directory. Attempting to continue."));
585 }
586
28bf4b0b 587 /*@access cstring@*/
588 llassert (cstring_isDefined (newname));
616915dd 589 lastpath = strrchr (newname, CONNECTCHAR); /* get the directory */
590 llassert (lastpath != NULL);
591 *lastpath = '\0';
592
28bf4b0b 593 newname = message ("%q%hlsl%d.lsl",
594 newname,
595 CONNECTCHAR,
596 tmpcounter);
597 /*@noaccess cstring@*/
616915dd 598 tmpcounter++;
599 }
600
601 /*
602 ** this is kind of yucky...need to make the result of cstring_fromChars
603 ** refer to the same storage as its argument. Of course, this loses,
604 ** since cstring is abstract. Should make it an only?
605 */
606
53a89507 607 ret = fileTable_addFilePrim (ft, newname, TRUE, FILE_LSLTEMP, fileId_invalid);
28bf4b0b 608 cstring_free (newname);
616915dd 609 return (ret);
610}
616915dd 611
612bool
613fileTable_exists (fileTable ft, cstring s)
614{
615 int tindex = fileTable_getIndex (ft, s);
616
617 if (tindex == NOT_FOUND)
f2b6724f 618 {
619 DPRINTF (("Not found: %s", s));
620 return FALSE;
621 }
616915dd 622 else
f2b6724f 623 {
624 return TRUE;
625 }
616915dd 626}
627
628fileId
629fileTable_lookup (fileTable ft, cstring s)
630{
631 int tindex = fileTable_getIndex (ft, s);
632
633 if (tindex == NOT_FOUND)
634 {
635 return fileId_invalid;
636 }
637 else
638 {
639 return tindex;
640 }
641}
642
28bf4b0b 643/*
644** This is pretty awkward --- when we find the real path of
645** a .xh file, we may need to change the recorded name. [Sigh]
646*/
647
648void
649fileTable_setFilePath (fileTable ft, fileId fid, cstring path)
650{
651 llassert (fileId_isValid (fid));
652 llassert (fileTable_isDefined (ft));
653 /* Need to put new string in hash table */
654 cstringTable_insert (ft->htable, cstring_copy (path), fid);
655 ft->elements[fid]->fname = cstring_copy (path);
656}
657
616915dd 658fileId
659fileTable_lookupBase (fileTable ft, cstring base)
660{
2cecdaff 661 int tindex;
662
663 if (context_getFlag (FLG_CASEINSENSITIVEFILENAMES))
664 {
665 cstring dbase = cstring_downcase (base);
666 tindex = fileTable_getIndex (ft, dbase);
667 cstring_free (dbase);
668 }
669 else
670 {
671 tindex = fileTable_getIndex (ft, base);
672 }
616915dd 673
674 if (tindex == NOT_FOUND)
675 {
616915dd 676 return fileId_invalid;
677 }
678 else
679 {
680 fileId der;
681
682 llassert (fileTable_isDefined (ft));
683
684 der = ft->elements[tindex]->fder;
685
686 if (!fileId_isValid (der))
687 {
688 der = tindex;
689 }
690
691 return der;
692 }
693}
694
695cstring
696fileTable_getName (fileTable ft, fileId fid)
697{
698 if (!fileId_isValid (fid))
699 {
700 llcontbug
701 (message ("fileTable_getName: called with invalid type id: %d", fid));
702 return cstring_makeLiteralTemp ("<invalid>");
703 }
704
705 llassert (fileTable_isDefined (ft));
706 return (ft->elements[fid]->fname);
707}
708
709cstring
710fileTable_getRootName (fileTable ft, fileId fid)
711{
712 fileId fder;
713
714 if (!fileId_isValid (fid))
715 {
716 llcontbug (message ("fileTable_getName: called with invalid id: %d", fid));
717 return cstring_makeLiteralTemp ("<invalid>");
718 }
719
720 if (!fileTable_isDefined (ft))
721 {
722 return cstring_makeLiteralTemp ("<no file table>");
723 }
724
616915dd 725 fder = ft->elements[fid]->fder;
726
727 if (fileId_isValid (fder))
728 {
729 return (ft->elements[fder]->fname);
730 }
731 else
732 {
733 return (ft->elements[fid]->fname);
734 }
735}
736
737cstring
738fileTable_getNameBase (fileTable ft, fileId fid)
739{
740 if (!fileId_isValid (fid))
741 {
742 llcontbug (message ("fileTable_getName: called with invalid id: %d", fid));
743 return cstring_makeLiteralTemp ("<invalid>");
744 }
745
746 if (!fileTable_isDefined (ft))
747 {
748 return cstring_makeLiteralTemp ("<no file table>");
749 }
750
751 return (ft->elements[fid]->basename);
752}
753
754bool
755fileTable_sameBase (fileTable ft, fileId f1, fileId f2)
756{
757 fileId fd1, fd2;
758
759 if (!fileId_isValid (f1))
760 {
761 return FALSE;
762 }
763
764 if (!fileId_isValid (f2))
765 {
766 return FALSE;
767 }
768
769 llassert (fileTable_isDefined (ft));
770
771 if (f1 == f2)
772 {
773 return TRUE;
774 }
775
776 fd1 = ft->elements[f1]->fder;
777
778 if (!fileId_isValid (fd1))
779 {
780 fd1 = f1;
781 }
782
783 fd2 = ft->elements[f2]->fder;
784
785
786 if (!fileId_isValid (fd2))
787 {
788 fd2 = f2;
789 }
790
791 return (fd1 == fd2);
792}
793
794void
795fileTable_cleanup (fileTable ft)
796{
797 int i;
798 bool msg;
799 int skip;
800
801 llassert (fileTable_isDefined (ft));
802
803 msg = ((ft->nentries > 40) && context_getFlag (FLG_SHOWSCAN));
804 skip = ft->nentries / 10;
805
806 if (msg)
807 {
80489f0a 808 (void) fflush (g_warningstream);
ce7034f0 809 displayScanOpen (cstring_makeLiteral ("cleaning"));
616915dd 810 }
811
812 for (i = 0; i < ft->nentries; i++)
813 {
814 ftentry fe = ft->elements[i];
815
816 if (fe->ftemp)
817 {
818 /* let's be real careful now, hon! */
819
820 /*
821 ** Make sure it is really a derived file
822 */
4dd72714 823
616915dd 824
825 if (fe->ftype == FILE_LSLTEMP || fe->ftype == FILE_NODELETE)
826 {
827 ; /* already removed */
828 }
829 else if (fileId_isValid (fe->fder))
830 {
28bf4b0b 831 /*@i423 this should use close (fd) also... */
832 (void) osd_unlink (fe->fname);
616915dd 833 }
834 else if (fe->ftype == FILE_MACROS)
835 {
28bf4b0b 836 (void) osd_unlink (fe->fname);
616915dd 837 }
838 else
839 {
840 llbug (message ("Temporary file is not derivative: %s "
841 "(not deleted)", fe->fname));
842 }
843 }
844 else
845 {
846 ;
847 }
848
849 if (msg && ((i % skip) == 0))
850 {
ce7034f0 851 displayScanContinue (cstring_makeLiteral (i == 0 ? " " : "."));
616915dd 852 }
853 }
140c27a8 854
616915dd 855 if (msg)
856 {
140c27a8 857 displayScanClose ();
616915dd 858 }
859}
860
861void
862fileTable_free (/*@only@*/ fileTable f)
863{
864 int i = 0;
865
866 if (f == (fileTable)NULL)
867 {
868 return;
869 }
870
871 while ( i < f->nentries )
872 {
873 ftentry_free (f->elements[i]);
874 i++;
875 }
876
28bf4b0b 877 cstringTable_free (f->htable);
616915dd 878 sfree (f->elements);
6fcd0b1e 879 sfree (f->openelements); /*!! why didn't splint report this? */
616915dd 880 sfree (f);
881}
882
883/*
884** unique temp filename are constructed from <dir><pre><pid><msg>.<suf>
885** requires: <dir> must end in '/'
886*/
887
888static void nextMsg (char *msg)
889{
890 /*@+charint@*/
891 if (msg[0] < 'Z')
892 {
893 msg[0]++;
894 }
895 else
896 {
897 msg[0] = 'A';
898 if (msg[1] < 'Z')
899 {
900 msg[1]++;
901 }
902 else
903 {
904 msg[1] = 'A';
905 if (msg[2] < 'Z')
906 {
907 msg[2]++;
908 }
909 else
910 {
911 msg[2] = 'A';
912 if (msg[3] < 'Z')
913 {
914 msg[3]++;
915 }
916 else
917 {
918 llassertprint (FALSE, ("nextMsg: out of unique names!!!"));
919 }
920 }
921 }
922 }
923 /*@-charint@*/
924}
925
28bf4b0b 926static /*@only@*/ cstring makeTempName (cstring dir, cstring pre, cstring suf)
616915dd 927{
928 static int pid = 0;
929 static /*@owned@*/ char *msg = NULL;
28bf4b0b 930 static /*@only@*/ cstring pidname = NULL;
931 int maxlen;
932 cstring smsg;
616915dd 933
28bf4b0b 934 llassert (cstring_length (pre) <= 3);
616915dd 935
936 /*
937 ** We limit the temp name to 8 characters:
938 ** pre: 3 or less
939 ** msg: 3
940 ** pid: 2 (% 100)
941 */
942
943 if (msg == NULL)
944 {
945 msg = mstring_copy ("AAA"); /* there are 26^3 temp names */
946 }
947
948 if (pid == 0)
949 {
950 /*@+matchanyintegral@*/
951 pid = osd_getPid ();
952 /*@=matchanyintegral@*/
953 }
954
28bf4b0b 955 if (cstring_isUndefined (pidname))
616915dd 956 {
28bf4b0b 957 pidname = message ("%d", pid % 100);
616915dd 958 }
959
28bf4b0b 960 maxlen = (cstring_length (dir) + cstring_length (pre) + mstring_length (msg)
961 + cstring_length (pidname) + cstring_length (suf) + 2);
616915dd 962
4dd72714 963 DPRINTF (("Dir: %s / %s / %s / %s / %s",
964 dir, pre, pidname, msg, suf));
965
28bf4b0b 966 smsg = message ("%s%s%s%s%s", dir, pre, pidname, cstring_fromChars (msg), suf);
616915dd 967 nextMsg (msg);
968
4dd72714 969 DPRINTF (("Trying: %s", smsg));
970
28bf4b0b 971 while (osd_fileExists (smsg))
616915dd 972 {
28bf4b0b 973 cstring_free (smsg);
974 smsg = message ("%s%s%s%s%s", dir, pre, pidname, cstring_fromChars (msg), suf);
616915dd 975 nextMsg (msg);
976 }
616915dd 977
28bf4b0b 978 return smsg;
979}
dfd82dce 980
981static foentry
982foentry_create (/*@exposed@*/ FILE *f, /*@only@*/ cstring fname)
983{
984 foentry t = (foentry) dmalloc (sizeof (*t));
985 t->f = f;
986 t->fname = fname;
987 return t;
988}
989
990static void
991foentry_free (/*@only@*/ foentry foe)
992{
993 cstring_free (foe->fname);
994 sfree (foe);
995}
996
997static void
998fileTable_addOpen (fileTable ft, /*@observer@*/ FILE *f, /*@only@*/ cstring fname)
999{
1000 llassert (fileTable_isDefined (ft));
1001
1002 if (ft->nopenspace <= 0)
1003 {
1004 fileTable_growOpen (ft);
1005 }
1006
1007 ft->nopenspace--;
1008 ft->openelements[ft->nopen] = foentry_create (f, fname);
1009 ft->nopen++;
1010}
1011
d5047b91 1012FILE *fileTable_createFile (fileTable ft, cstring fname)
1013{
1014 int fdesc = open (cstring_toCharsSafe (fname), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, S_IRUSR | S_IWUSR);
1015
1016 if (fdesc == -1)
1017 {
1018 osd_setTempError ();
1019 llfatalerror (message ("Temporary file for "
1020 "pre-processor output already exists. Trying to "
1021 "open: %s.",
1022 fname));
1023
1024 /*@notreached@*/ return NULL;
1025 }
1026 else
1027 {
1028 FILE *res = fdopen (fdesc, "w");
1029
1030 if (res != NULL)
1031 {
1032 fileTable_addOpen (ft, res, cstring_copy (fname));
1033 DPRINTF (("Opening file: %s / %p", fname, res));
1034 }
1035 else
1036 {
1037 DPRINTF (("Error opening: %s", fname));
1038 }
1039
1040 return res;
1041 }
1042}
1043
1044FILE *fileTable_createMacrosFile (fileTable ft, cstring fname)
1045{
1046 int fdesc = open (cstring_toCharsSafe (fname), O_RDWR | O_CREAT | O_TRUNC | O_EXCL, S_IRUSR | S_IWUSR);
1047
1048 if (fdesc == -1)
1049 {
1050 osd_setTempError ();
1051 llfatalerror (message ("Temporary file for "
1052 "pre-processor output already exists. Trying to "
1053 "open: %s.",
1054 fname));
1055
1056 /*@notreached@*/ return NULL;
1057 }
1058 else
1059 {
1060 FILE *res = fdopen (fdesc, "w+");
1061
1062 if (res != NULL)
1063 {
1064 fileTable_addOpen (ft, res, cstring_copy (fname));
1065 DPRINTF (("Opening file: %s / %p", fname, res));
1066 }
1067 else
1068 {
1069 DPRINTF (("Error opening: %s", fname));
1070 }
1071
1072 return res;
1073 }
1074}
1075
1076FILE *fileTable_openReadFile (fileTable ft, cstring fname)
dfd82dce 1077{
d5047b91 1078 FILE *res = fopen (cstring_toCharsSafe (fname), "r");
1079
1080 if (res != NULL)
1081 {
1082 fileTable_addOpen (ft, res, cstring_copy (fname));
1083 DPRINTF (("Opening read file: %s / %p", fname, res));
1084 }
1085 else
1086 {
1087 DPRINTF (("Cannot open read file: %s", fname));
1088 }
1089
1090 return res;
1091}
1092
1093/*
1094** Allows overwriting
1095*/
1096
1097FILE *fileTable_openWriteFile (fileTable ft, cstring fname)
1098{
1099 FILE *res = fopen (cstring_toCharsSafe (fname), "w");
1100
1101 if (res != NULL) {
1102 fileTable_addOpen (ft, res, cstring_copy (fname));
1103 DPRINTF (("Opening file: %s / %p", fname, res));
1104 }
1105
1106 return res;
1107}
1108
1109FILE *fileTable_openWriteUpdateFile (fileTable ft, cstring fname)
1110{
1111 FILE *res = fopen (cstring_toCharsSafe (fname), "w+");
dfd82dce 1112
1113 if (res != NULL) {
1114 fileTable_addOpen (ft, res, cstring_copy (fname));
1115 DPRINTF (("Opening file: %s / %p", fname, res));
1116 }
1117
1118 return res;
1119}
1120
1121bool fileTable_closeFile (fileTable ft, FILE *f)
1122{
1123 bool foundit = FALSE;
1124 int i = 0;
1125
1126 llassert (fileTable_isDefined (ft));
1127
1128 DPRINTF (("Closing file: %p", f));
1129
1130 for (i = 0; i < ft->nopen; i++)
1131 {
1132 if (ft->openelements[i]->f == f)
1133 {
1134 DPRINTF (("Closing file: %p = %s", f, ft->openelements[i]->fname));
d5047b91 1135
dfd82dce 1136 if (i == ft->nopen - 1)
1137 {
1138 foentry_free (ft->openelements[i]);
1139 ft->openelements[i] = NULL;
1140 }
1141 else
1142 {
1143 foentry_free (ft->openelements[i]);
1144 ft->openelements[i] = ft->openelements[ft->nopen - 1];
1145 ft->openelements[ft->nopen - 1] = NULL;
1146 }
1147
1148 ft->nopen--;
1149 ft->nopenspace++;
1150 foundit = TRUE;
1151 break;
1152 }
1153 }
1154
1155 llassert (foundit);
1156 return (fclose (f) == 0);
1157}
1158
1159void fileTable_closeAll (fileTable ft)
1160{
1161 int i = 0;
1162
abd7f895 1163 llassert (fileTable_isDefined (ft));
1164
dfd82dce 1165 for (i = 0; i < ft->nopen; i++)
1166 {
107b60d6 1167 /*
1168 lldiagmsg (message ("Unclosed file at exit: %s", ft->openelements[i]->fname));
1169 */
abd7f895 1170
1171 if (ft->openelements[i]->f != NULL)
1172 {
1173 (void) fclose (ft->openelements[i]->f); /* No check - cleaning up after errors */
1174 }
107b60d6 1175
dfd82dce 1176 ft->openelements[i]->f = NULL;
1177 foentry_free (ft->openelements[i]);
1178 ft->openelements[i] = NULL;
1179 }
1180
1181 ft->nopenspace += ft->nopen;
1182 ft->nopen = 0;
1183}
1184
This page took 0.86053 seconds and 5 git commands to generate.