]> andersk Git - splint.git/blame - src/fileTable.c
Incorporated path for file inclusion in cpplib.c.
[splint.git] / src / fileTable.c
CommitLineData
616915dd 1/*
11db3170 2** Splint - annotation-assisted static program checker
c59f5181 3** Copyright (C) 1994-2003 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"
b73d1009 51# include "basic.h"
616915dd 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
4fab1d8a 232/*@-bounds@*/
616915dd 233static void
234fileTable_grow (fileTable ft)
235{
236 int i;
237 ftentry *newent;
238
239 llassert (fileTable_isDefined (ft));
240
241 ft->nspace = FTBASESIZE;
242
243 newent = (ftentry *) dmalloc ((ft->nentries + ft->nspace) * sizeof (*newent));
244
245 for (i = 0; i < ft->nentries; i++)
246 {
247 newent[i] = ft->elements[i];
248 }
249
250 sfree (ft->elements);
251 ft->elements = newent;
252}
4fab1d8a 253/*@=bounds@*/
dfd82dce 254static void
255fileTable_growOpen (fileTable ft)
256{
257 int i;
258 foentry *newent;
259
260 llassert (fileTable_isDefined (ft));
261
262 ft->nopenspace = FTBASESIZE;
263
264 newent = (foentry *) dmalloc ((ft->nopen + ft->nopenspace) * sizeof (*newent));
265
266 for (i = 0; i < ft->nopen; i++)
267 {
268 newent[i] = ft->openelements[i];
269 }
270
271 sfree (ft->openelements);
272 ft->openelements = newent;
273}
274
616915dd 275static fileId
276fileTable_internAddEntry (fileTable ft, /*@only@*/ ftentry e)
277{
278 llassert (fileTable_isDefined (ft));
279
280 if (ft->nspace <= 0)
281 fileTable_grow (ft);
282
283 ft->nspace--;
284
f2b6724f 285 DPRINTF (("Adding: %s", e->fname));
2cecdaff 286
287 if (context_getFlag (FLG_CASEINSENSITIVEFILENAMES))
288 {
289 cstring sd = cstring_downcase (e->fname);
290 cstringTable_insert (ft->htable, sd, ft->nentries);
2cecdaff 291 }
292 else
293 {
6fcd0b1e 294 cstringTable_insert (ft->htable, cstring_copy (e->fname), ft->nentries);
2cecdaff 295 }
296
6fcd0b1e 297 /* evans 2002-07-12:
298 Before, there was no cstring_copy above, and e->fname was free'd in the if branch.
299 Splint should have caught this, and produced a warning for this assignment.
300 Why not?
301 */
616915dd 302 ft->elements[ft->nentries] = e;
303
304 ft->nentries++;
305 return (ft->nentries - 1);
306}
307
308void fileTable_noDelete (fileTable ft, cstring name)
309{
310 fileId fid = fileTable_lookup (ft, name);
311
4dd72714 312 if (fileId_isValid (fid))
313 {
314 llassert (fileTable_isDefined (ft));
315 ft->elements[fid]->ftype = FILE_NODELETE;
316 }
317 else
318 {
319 DPRINTF (("Invalid no delete: %s", name));
320 }
616915dd 321}
322
323static fileId
53a89507 324fileTable_addFilePrim (fileTable ft, /*@temp@*/ cstring name,
616915dd 325 bool temp, fileType typ, fileId der)
326 /*@modifies ft@*/
327{
53a89507 328 cstring absname = osd_absolutePath (NULL, name);
329 int tindex = fileTable_getIndex (ft, absname);
4dd72714 330
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 {
d767066b 831 /* this should use close (fd) also... */
28bf4b0b 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;
e5081f8c 931 size_t maxlen;
28bf4b0b 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{
53306cab 1014# ifdef WIN32
1015 int fdesc = open (cstring_toCharsSafe (fname), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL); /* not supported by VS.net: , S_IRUSR | S_IWUSR); */
1016# else
1017 int fdesc = open (cstring_toCharsSafe (fname), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, S_IRUSR | S_IWUSR);
1018# endif
d5047b91 1019
1020 if (fdesc == -1)
1021 {
1022 osd_setTempError ();
1023 llfatalerror (message ("Temporary file for "
1024 "pre-processor output already exists. Trying to "
1025 "open: %s.",
1026 fname));
1027
1028 /*@notreached@*/ return NULL;
1029 }
1030 else
1031 {
1032 FILE *res = fdopen (fdesc, "w");
1033
1034 if (res != NULL)
1035 {
1036 fileTable_addOpen (ft, res, cstring_copy (fname));
1037 DPRINTF (("Opening file: %s / %p", fname, res));
1038 }
1039 else
1040 {
1041 DPRINTF (("Error opening: %s", fname));
1042 }
1043
1044 return res;
1045 }
1046}
1047
1048FILE *fileTable_createMacrosFile (fileTable ft, cstring fname)
1049{
1050 int fdesc = open (cstring_toCharsSafe (fname), O_RDWR | O_CREAT | O_TRUNC | O_EXCL, S_IRUSR | S_IWUSR);
1051
1052 if (fdesc == -1)
1053 {
1054 osd_setTempError ();
1055 llfatalerror (message ("Temporary file for "
1056 "pre-processor output already exists. Trying to "
1057 "open: %s.",
1058 fname));
1059
1060 /*@notreached@*/ return NULL;
1061 }
1062 else
1063 {
1064 FILE *res = fdopen (fdesc, "w+");
1065
1066 if (res != NULL)
1067 {
1068 fileTable_addOpen (ft, res, cstring_copy (fname));
1069 DPRINTF (("Opening file: %s / %p", fname, res));
1070 }
1071 else
1072 {
1073 DPRINTF (("Error opening: %s", fname));
1074 }
1075
1076 return res;
1077 }
1078}
1079
1080FILE *fileTable_openReadFile (fileTable ft, cstring fname)
dfd82dce 1081{
d5047b91 1082 FILE *res = fopen (cstring_toCharsSafe (fname), "r");
1083
1084 if (res != NULL)
1085 {
1086 fileTable_addOpen (ft, res, cstring_copy (fname));
1087 DPRINTF (("Opening read file: %s / %p", fname, res));
1088 }
1089 else
1090 {
1091 DPRINTF (("Cannot open read file: %s", fname));
1092 }
1093
1094 return res;
1095}
1096
1097/*
1098** Allows overwriting
1099*/
1100
1101FILE *fileTable_openWriteFile (fileTable ft, cstring fname)
1102{
1103 FILE *res = fopen (cstring_toCharsSafe (fname), "w");
1104
1105 if (res != NULL) {
1106 fileTable_addOpen (ft, res, cstring_copy (fname));
1107 DPRINTF (("Opening file: %s / %p", fname, res));
1108 }
1109
1110 return res;
1111}
1112
1113FILE *fileTable_openWriteUpdateFile (fileTable ft, cstring fname)
1114{
1115 FILE *res = fopen (cstring_toCharsSafe (fname), "w+");
dfd82dce 1116
1117 if (res != NULL) {
1118 fileTable_addOpen (ft, res, cstring_copy (fname));
1119 DPRINTF (("Opening file: %s / %p", fname, res));
1120 }
1121
1122 return res;
1123}
1124
1125bool fileTable_closeFile (fileTable ft, FILE *f)
1126{
1127 bool foundit = FALSE;
1128 int i = 0;
1129
1130 llassert (fileTable_isDefined (ft));
1131
1132 DPRINTF (("Closing file: %p", f));
1133
1134 for (i = 0; i < ft->nopen; i++)
1135 {
1136 if (ft->openelements[i]->f == f)
1137 {
1138 DPRINTF (("Closing file: %p = %s", f, ft->openelements[i]->fname));
d5047b91 1139
dfd82dce 1140 if (i == ft->nopen - 1)
1141 {
1142 foentry_free (ft->openelements[i]);
1143 ft->openelements[i] = NULL;
1144 }
1145 else
1146 {
1147 foentry_free (ft->openelements[i]);
1148 ft->openelements[i] = ft->openelements[ft->nopen - 1];
1149 ft->openelements[ft->nopen - 1] = NULL;
1150 }
1151
1152 ft->nopen--;
1153 ft->nopenspace++;
1154 foundit = TRUE;
1155 break;
1156 }
1157 }
1158
1159 llassert (foundit);
1160 return (fclose (f) == 0);
1161}
1162
1163void fileTable_closeAll (fileTable ft)
1164{
1165 int i = 0;
1166
abd7f895 1167 llassert (fileTable_isDefined (ft));
1168
dfd82dce 1169 for (i = 0; i < ft->nopen; i++)
1170 {
107b60d6 1171 /*
1172 lldiagmsg (message ("Unclosed file at exit: %s", ft->openelements[i]->fname));
1173 */
abd7f895 1174
1175 if (ft->openelements[i]->f != NULL)
1176 {
1177 (void) fclose (ft->openelements[i]->f); /* No check - cleaning up after errors */
1178 }
107b60d6 1179
dfd82dce 1180 ft->openelements[i]->f = NULL;
1181 foentry_free (ft->openelements[i]);
1182 ft->openelements[i] = NULL;
1183 }
1184
1185 ft->nopenspace += ft->nopen;
1186 ft->nopen = 0;
1187}
1188
This page took 0.232469 seconds and 5 git commands to generate.