]> andersk Git - splint.git/blame - src/fileTable.c
Added html version of manual. (This is the 7 Jan 2002 version.)
[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"
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
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
140c27a8 331 /*@i534 fprintf (stderr, "Got abs path: %s", absname); */
616915dd 332 llassert (ft != fileTable_undefined);
333
334 if (tindex != NOT_FOUND)
335 {
53a89507 336 llcontbug (message ("fileTable_addFilePrim: duplicate entry: %q", absname));
616915dd 337 return tindex;
338 }
339 else
340 {
53a89507 341 ftentry e = ftentry_create (absname, temp, typ, der);
616915dd 342
343 if (der == fileId_invalid)
344 {
345 llassert (cstring_isUndefined (e->basename));
346
53a89507 347 e->basename = fileLib_removePathFree (fileLib_removeAnyExtension (absname));
348 e->fsystem = context_isSystemDir (absname);
52e90c0f 349
350 /*
351 ** evans 2002-03-15: change suggested by Jim Zelenka
352 ** support relative paths for system directories
353 */
354
355 if (!e->fsystem)
356 {
357 e->fsystem = context_isSystemDir (name);
358 }
359
53a89507 360 e->fspecial = context_isSpecialFile (absname);
616915dd 361
362 if (e->fspecial)
363 {
53a89507 364 cstring srcname = cstring_concatFree1 (fileLib_removeAnyExtension (absname),
28bf4b0b 365 C_EXTENSION);
616915dd 366 fileId fid = fileTable_lookup (ft, srcname);
616915dd 367 cstring_free (srcname);
368
369 if (fileId_isValid (fid))
370 {
371 fileId derid = ft->elements[fid]->fder;
372
373 ft->elements[fid]->fspecial = TRUE;
374
375 if (fileId_isValid (derid))
376 {
377 ft->elements[derid]->fspecial = TRUE;
378 }
379 }
380 }
381 }
382 else
383 {
384 ftentry de = ft->elements[der];
385
386 llassert (cstring_isUndefined (e->basename));
387 e->basename = cstring_copy (de->basename);
388 e->fsystem = de->fsystem;
389 e->fspecial = de->fspecial;
390 }
391
392 return (fileTable_internAddEntry (ft, e));
393 }
394}
395
396fileId
397fileTable_addFile (fileTable ft, cstring name)
398{
53a89507 399 return (fileTable_addFilePrim (ft, name, FALSE, FILE_NORMAL, fileId_invalid));
616915dd 400}
401
402fileId
403fileTable_addFileOnly (fileTable ft, /*@only@*/ cstring name)
404{
53a89507 405 fileId res = fileTable_addFilePrim (ft, name, FALSE, FILE_NORMAL, fileId_invalid);
406 cstring_free (name);
407 return res;
616915dd 408}
409
410fileId
411fileTable_addHeaderFile (fileTable ft, cstring name)
412{
28bf4b0b 413 fileId res;
53a89507 414 res = fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid);
28bf4b0b 415 return res;
416
616915dd 417}
418
80489f0a 419void
420fileTable_addStreamFile (fileTable ft, FILE *fstream, cstring name)
421{
422 fileTable_addOpen (ft, fstream, cstring_copy (name));
423}
424
616915dd 425bool
426fileTable_isHeader (fileTable ft, fileId fid)
427{
428 if (fileId_isInvalid (fid))
429 {
430 return FALSE;
431 }
432
433 llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
434 return (ft->elements[fid]->ftype == FILE_HEADER);
435}
436
437bool
438fileTable_isSystemFile (fileTable ft, fileId fid)
439{
440 if (fileId_isInvalid (fid))
441 {
442 return FALSE;
443 }
444
445 llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
446 return (ft->elements[fid]->fsystem);
447}
448
28bf4b0b 449bool
450fileTable_isXHFile (fileTable ft, fileId fid)
451{
452 if (fileId_isInvalid (fid))
453 {
454 return FALSE;
455 }
456
ccf0a4a8 457 if (!(fileTable_isDefined (ft) && fileTable_inRange (ft, fid)))
458 {
459 llcontbug (message ("Bad file table or id: %s %d", bool_unparse (fileTable_isDefined (ft)), fid));
460 return FALSE;
461 }
462 else
463 {
464 return (ft->elements[fid]->ftype == FILE_XH);
465 }
28bf4b0b 466}
467
616915dd 468bool
469fileTable_isSpecialFile (fileTable ft, fileId fid)
470{
471 if (fileId_isInvalid (fid))
472 {
473 return FALSE;
474 }
ccf0a4a8 475
616915dd 476 llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
477 return (ft->elements[fid]->fspecial);
478}
479
480fileId
481fileTable_addLibraryFile (fileTable ft, cstring name)
482{
53a89507 483 return (fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid));
616915dd 484}
485
28bf4b0b 486fileId
487fileTable_addXHFile (fileTable ft, cstring name)
488{
53a89507 489 return (fileTable_addFilePrim (ft, name, FALSE, FILE_XH, fileId_invalid));
28bf4b0b 490}
491
616915dd 492fileId
493fileTable_addImportFile (fileTable ft, cstring name)
494{
53a89507 495 return (fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid));
616915dd 496}
497
498fileId
499fileTable_addLCLFile (fileTable ft, cstring name)
500{
53a89507 501 return (fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid));
616915dd 502}
616915dd 503
616915dd 504static int tmpcounter = 0;
616915dd 505
506fileId
507fileTable_addMacrosFile (fileTable ft)
508{
28bf4b0b 509 cstring newname =
510 makeTempName (context_tmpdir (), cstring_makeLiteralTemp ("lmx"),
511 cstring_makeLiteralTemp (".llm"));
53a89507 512 fileId res = fileTable_addFilePrim (ft, newname, TRUE, FILE_MACROS, fileId_invalid);
513 cstring_free (newname);
514 return res;
616915dd 515}
516
28bf4b0b 517fileId
518fileTable_addMetastateFile (fileTable ft, cstring name)
519{
53a89507 520 return (fileTable_addFilePrim (ft, name, FALSE, FILE_METASTATE, fileId_invalid));
28bf4b0b 521}
522
616915dd 523fileId
524fileTable_addCTempFile (fileTable ft, fileId fid)
525{
28bf4b0b 526 cstring newname =
527 makeTempName (context_tmpdir (), cstring_makeLiteralTemp ("cl"),
528 C_EXTENSION);
53a89507 529 fileId res;
616915dd 530
4dd72714 531 DPRINTF (("tmp dir: %s", context_tmpdir ()));
532 DPRINTF (("new name: %s", newname));
533
616915dd 534 llassert (fileTable_isDefined (ft));
535
536 if (!fileId_isValid (ft->elements[fid]->fder))
537 {
28bf4b0b 538 if (fileTable_isXHFile (ft, fid))
539 {
53a89507 540 res = fileTable_addFilePrim (ft, newname, TRUE, FILE_XH, fid);
28bf4b0b 541 }
542 else
543 {
53a89507 544 res = fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL, fid);
28bf4b0b 545 }
616915dd 546 }
547 else
548 {
28bf4b0b 549 if (fileTable_isXHFile (ft, fid))
550 {
53a89507 551 res = fileTable_addFilePrim (ft, newname, TRUE, FILE_XH,
552 ft->elements[fid]->fder);
28bf4b0b 553 }
554 else
555 {
53a89507 556 res = fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL,
557 ft->elements[fid]->fder);
28bf4b0b 558 }
616915dd 559 }
53a89507 560
4dd72714 561 DPRINTF (("Added file: %s", fileTable_fileName (res)));
53a89507 562 cstring_free (newname);
563 return res;
616915dd 564}
565
616915dd 566fileId
567fileTable_addltemp (fileTable ft)
568{
28bf4b0b 569 cstring newname = makeTempName (context_tmpdir (),
570 cstring_makeLiteralTemp ("ls"),
571 cstring_makeLiteralTemp (".lsl"));
616915dd 572 fileId ret;
573
28bf4b0b 574 if (cstring_hasNonAlphaNumBar (newname))
616915dd 575 {
576 char *lastpath = (char *)NULL;
577
578 if (tmpcounter == 0)
579 {
580 lldiagmsg
581 (message
582 ("Operating system generates tmp filename containing invalid charater: %s",
28bf4b0b 583 newname));
616915dd 584 lldiagmsg (cstring_makeLiteral
585 ("Try cleaning up the tmp directory. Attempting to continue."));
586 }
587
28bf4b0b 588 /*@access cstring@*/
589 llassert (cstring_isDefined (newname));
616915dd 590 lastpath = strrchr (newname, CONNECTCHAR); /* get the directory */
591 llassert (lastpath != NULL);
592 *lastpath = '\0';
593
28bf4b0b 594 newname = message ("%q%hlsl%d.lsl",
595 newname,
596 CONNECTCHAR,
597 tmpcounter);
598 /*@noaccess cstring@*/
616915dd 599 tmpcounter++;
600 }
601
602 /*
603 ** this is kind of yucky...need to make the result of cstring_fromChars
604 ** refer to the same storage as its argument. Of course, this loses,
605 ** since cstring is abstract. Should make it an only?
606 */
607
53a89507 608 ret = fileTable_addFilePrim (ft, newname, TRUE, FILE_LSLTEMP, fileId_invalid);
28bf4b0b 609 cstring_free (newname);
616915dd 610 return (ret);
611}
616915dd 612
613bool
614fileTable_exists (fileTable ft, cstring s)
615{
616 int tindex = fileTable_getIndex (ft, s);
617
618 if (tindex == NOT_FOUND)
f2b6724f 619 {
620 DPRINTF (("Not found: %s", s));
621 return FALSE;
622 }
616915dd 623 else
f2b6724f 624 {
625 return TRUE;
626 }
616915dd 627}
628
629fileId
630fileTable_lookup (fileTable ft, cstring s)
631{
632 int tindex = fileTable_getIndex (ft, s);
633
634 if (tindex == NOT_FOUND)
635 {
636 return fileId_invalid;
637 }
638 else
639 {
640 return tindex;
641 }
642}
643
28bf4b0b 644/*
645** This is pretty awkward --- when we find the real path of
646** a .xh file, we may need to change the recorded name. [Sigh]
647*/
648
649void
650fileTable_setFilePath (fileTable ft, fileId fid, cstring path)
651{
652 llassert (fileId_isValid (fid));
653 llassert (fileTable_isDefined (ft));
654 /* Need to put new string in hash table */
655 cstringTable_insert (ft->htable, cstring_copy (path), fid);
656 ft->elements[fid]->fname = cstring_copy (path);
657}
658
616915dd 659fileId
660fileTable_lookupBase (fileTable ft, cstring base)
661{
2cecdaff 662 int tindex;
663
664 if (context_getFlag (FLG_CASEINSENSITIVEFILENAMES))
665 {
666 cstring dbase = cstring_downcase (base);
667 tindex = fileTable_getIndex (ft, dbase);
668 cstring_free (dbase);
669 }
670 else
671 {
672 tindex = fileTable_getIndex (ft, base);
673 }
616915dd 674
675 if (tindex == NOT_FOUND)
676 {
616915dd 677 return fileId_invalid;
678 }
679 else
680 {
681 fileId der;
682
683 llassert (fileTable_isDefined (ft));
684
685 der = ft->elements[tindex]->fder;
686
687 if (!fileId_isValid (der))
688 {
689 der = tindex;
690 }
691
692 return der;
693 }
694}
695
696cstring
697fileTable_getName (fileTable ft, fileId fid)
698{
699 if (!fileId_isValid (fid))
700 {
701 llcontbug
702 (message ("fileTable_getName: called with invalid type id: %d", fid));
703 return cstring_makeLiteralTemp ("<invalid>");
704 }
705
706 llassert (fileTable_isDefined (ft));
707 return (ft->elements[fid]->fname);
708}
709
710cstring
711fileTable_getRootName (fileTable ft, fileId fid)
712{
713 fileId fder;
714
715 if (!fileId_isValid (fid))
716 {
717 llcontbug (message ("fileTable_getName: called with invalid id: %d", fid));
718 return cstring_makeLiteralTemp ("<invalid>");
719 }
720
721 if (!fileTable_isDefined (ft))
722 {
723 return cstring_makeLiteralTemp ("<no file table>");
724 }
725
616915dd 726 fder = ft->elements[fid]->fder;
727
728 if (fileId_isValid (fder))
729 {
730 return (ft->elements[fder]->fname);
731 }
732 else
733 {
734 return (ft->elements[fid]->fname);
735 }
736}
737
738cstring
739fileTable_getNameBase (fileTable ft, fileId fid)
740{
741 if (!fileId_isValid (fid))
742 {
743 llcontbug (message ("fileTable_getName: called with invalid id: %d", fid));
744 return cstring_makeLiteralTemp ("<invalid>");
745 }
746
747 if (!fileTable_isDefined (ft))
748 {
749 return cstring_makeLiteralTemp ("<no file table>");
750 }
751
752 return (ft->elements[fid]->basename);
753}
754
755bool
756fileTable_sameBase (fileTable ft, fileId f1, fileId f2)
757{
758 fileId fd1, fd2;
759
760 if (!fileId_isValid (f1))
761 {
762 return FALSE;
763 }
764
765 if (!fileId_isValid (f2))
766 {
767 return FALSE;
768 }
769
770 llassert (fileTable_isDefined (ft));
771
772 if (f1 == f2)
773 {
774 return TRUE;
775 }
776
777 fd1 = ft->elements[f1]->fder;
778
779 if (!fileId_isValid (fd1))
780 {
781 fd1 = f1;
782 }
783
784 fd2 = ft->elements[f2]->fder;
785
786
787 if (!fileId_isValid (fd2))
788 {
789 fd2 = f2;
790 }
791
792 return (fd1 == fd2);
793}
794
795void
796fileTable_cleanup (fileTable ft)
797{
798 int i;
799 bool msg;
800 int skip;
801
802 llassert (fileTable_isDefined (ft));
803
804 msg = ((ft->nentries > 40) && context_getFlag (FLG_SHOWSCAN));
805 skip = ft->nentries / 10;
806
807 if (msg)
808 {
80489f0a 809 (void) fflush (g_warningstream);
ce7034f0 810 displayScanOpen (cstring_makeLiteral ("cleaning"));
616915dd 811 }
812
813 for (i = 0; i < ft->nentries; i++)
814 {
815 ftentry fe = ft->elements[i];
816
817 if (fe->ftemp)
818 {
819 /* let's be real careful now, hon! */
820
821 /*
822 ** Make sure it is really a derived file
823 */
4dd72714 824
616915dd 825
826 if (fe->ftype == FILE_LSLTEMP || fe->ftype == FILE_NODELETE)
827 {
828 ; /* already removed */
829 }
830 else if (fileId_isValid (fe->fder))
831 {
28bf4b0b 832 /*@i423 this should use close (fd) also... */
833 (void) osd_unlink (fe->fname);
616915dd 834 }
835 else if (fe->ftype == FILE_MACROS)
836 {
28bf4b0b 837 (void) osd_unlink (fe->fname);
616915dd 838 }
839 else
840 {
841 llbug (message ("Temporary file is not derivative: %s "
842 "(not deleted)", fe->fname));
843 }
844 }
845 else
846 {
847 ;
848 }
849
850 if (msg && ((i % skip) == 0))
851 {
ce7034f0 852 displayScanContinue (cstring_makeLiteral (i == 0 ? " " : "."));
616915dd 853 }
854 }
140c27a8 855
616915dd 856 if (msg)
857 {
140c27a8 858 displayScanClose ();
616915dd 859 }
860}
861
862void
863fileTable_free (/*@only@*/ fileTable f)
864{
865 int i = 0;
866
867 if (f == (fileTable)NULL)
868 {
869 return;
870 }
871
872 while ( i < f->nentries )
873 {
874 ftentry_free (f->elements[i]);
875 i++;
876 }
877
28bf4b0b 878 cstringTable_free (f->htable);
616915dd 879 sfree (f->elements);
6fcd0b1e 880 sfree (f->openelements); /*!! why didn't splint report this? */
616915dd 881 sfree (f);
882}
883
884/*
885** unique temp filename are constructed from <dir><pre><pid><msg>.<suf>
886** requires: <dir> must end in '/'
887*/
888
889static void nextMsg (char *msg)
890{
891 /*@+charint@*/
892 if (msg[0] < 'Z')
893 {
894 msg[0]++;
895 }
896 else
897 {
898 msg[0] = 'A';
899 if (msg[1] < 'Z')
900 {
901 msg[1]++;
902 }
903 else
904 {
905 msg[1] = 'A';
906 if (msg[2] < 'Z')
907 {
908 msg[2]++;
909 }
910 else
911 {
912 msg[2] = 'A';
913 if (msg[3] < 'Z')
914 {
915 msg[3]++;
916 }
917 else
918 {
919 llassertprint (FALSE, ("nextMsg: out of unique names!!!"));
920 }
921 }
922 }
923 }
924 /*@-charint@*/
925}
926
28bf4b0b 927static /*@only@*/ cstring makeTempName (cstring dir, cstring pre, cstring suf)
616915dd 928{
929 static int pid = 0;
930 static /*@owned@*/ char *msg = NULL;
28bf4b0b 931 static /*@only@*/ cstring pidname = NULL;
e5081f8c 932 size_t maxlen;
28bf4b0b 933 cstring smsg;
616915dd 934
28bf4b0b 935 llassert (cstring_length (pre) <= 3);
616915dd 936
937 /*
938 ** We limit the temp name to 8 characters:
939 ** pre: 3 or less
940 ** msg: 3
941 ** pid: 2 (% 100)
942 */
943
944 if (msg == NULL)
945 {
946 msg = mstring_copy ("AAA"); /* there are 26^3 temp names */
947 }
948
949 if (pid == 0)
950 {
951 /*@+matchanyintegral@*/
952 pid = osd_getPid ();
953 /*@=matchanyintegral@*/
954 }
955
28bf4b0b 956 if (cstring_isUndefined (pidname))
616915dd 957 {
28bf4b0b 958 pidname = message ("%d", pid % 100);
616915dd 959 }
960
28bf4b0b 961 maxlen = (cstring_length (dir) + cstring_length (pre) + mstring_length (msg)
962 + cstring_length (pidname) + cstring_length (suf) + 2);
616915dd 963
4dd72714 964 DPRINTF (("Dir: %s / %s / %s / %s / %s",
965 dir, pre, pidname, msg, suf));
966
28bf4b0b 967 smsg = message ("%s%s%s%s%s", dir, pre, pidname, cstring_fromChars (msg), suf);
616915dd 968 nextMsg (msg);
969
4dd72714 970 DPRINTF (("Trying: %s", smsg));
971
28bf4b0b 972 while (osd_fileExists (smsg))
616915dd 973 {
28bf4b0b 974 cstring_free (smsg);
975 smsg = message ("%s%s%s%s%s", dir, pre, pidname, cstring_fromChars (msg), suf);
616915dd 976 nextMsg (msg);
977 }
616915dd 978
28bf4b0b 979 return smsg;
980}
dfd82dce 981
982static foentry
983foentry_create (/*@exposed@*/ FILE *f, /*@only@*/ cstring fname)
984{
985 foentry t = (foentry) dmalloc (sizeof (*t));
986 t->f = f;
987 t->fname = fname;
988 return t;
989}
990
991static void
992foentry_free (/*@only@*/ foentry foe)
993{
994 cstring_free (foe->fname);
995 sfree (foe);
996}
997
998static void
999fileTable_addOpen (fileTable ft, /*@observer@*/ FILE *f, /*@only@*/ cstring fname)
1000{
1001 llassert (fileTable_isDefined (ft));
1002
1003 if (ft->nopenspace <= 0)
1004 {
1005 fileTable_growOpen (ft);
1006 }
1007
1008 ft->nopenspace--;
1009 ft->openelements[ft->nopen] = foentry_create (f, fname);
1010 ft->nopen++;
1011}
1012
d5047b91 1013FILE *fileTable_createFile (fileTable ft, cstring fname)
1014{
53306cab 1015# ifdef WIN32
1016 int fdesc = open (cstring_toCharsSafe (fname), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL); /* not supported by VS.net: , S_IRUSR | S_IWUSR); */
1017# else
1018 int fdesc = open (cstring_toCharsSafe (fname), O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, S_IRUSR | S_IWUSR);
1019# endif
d5047b91 1020
1021 if (fdesc == -1)
1022 {
1023 osd_setTempError ();
1024 llfatalerror (message ("Temporary file for "
1025 "pre-processor output already exists. Trying to "
1026 "open: %s.",
1027 fname));
1028
1029 /*@notreached@*/ return NULL;
1030 }
1031 else
1032 {
1033 FILE *res = fdopen (fdesc, "w");
1034
1035 if (res != NULL)
1036 {
1037 fileTable_addOpen (ft, res, cstring_copy (fname));
1038 DPRINTF (("Opening file: %s / %p", fname, res));
1039 }
1040 else
1041 {
1042 DPRINTF (("Error opening: %s", fname));
1043 }
1044
1045 return res;
1046 }
1047}
1048
1049FILE *fileTable_createMacrosFile (fileTable ft, cstring fname)
1050{
1051 int fdesc = open (cstring_toCharsSafe (fname), O_RDWR | O_CREAT | O_TRUNC | O_EXCL, S_IRUSR | S_IWUSR);
1052
1053 if (fdesc == -1)
1054 {
1055 osd_setTempError ();
1056 llfatalerror (message ("Temporary file for "
1057 "pre-processor output already exists. Trying to "
1058 "open: %s.",
1059 fname));
1060
1061 /*@notreached@*/ return NULL;
1062 }
1063 else
1064 {
1065 FILE *res = fdopen (fdesc, "w+");
1066
1067 if (res != NULL)
1068 {
1069 fileTable_addOpen (ft, res, cstring_copy (fname));
1070 DPRINTF (("Opening file: %s / %p", fname, res));
1071 }
1072 else
1073 {
1074 DPRINTF (("Error opening: %s", fname));
1075 }
1076
1077 return res;
1078 }
1079}
1080
1081FILE *fileTable_openReadFile (fileTable ft, cstring fname)
dfd82dce 1082{
d5047b91 1083 FILE *res = fopen (cstring_toCharsSafe (fname), "r");
1084
1085 if (res != NULL)
1086 {
1087 fileTable_addOpen (ft, res, cstring_copy (fname));
1088 DPRINTF (("Opening read file: %s / %p", fname, res));
1089 }
1090 else
1091 {
1092 DPRINTF (("Cannot open read file: %s", fname));
1093 }
1094
1095 return res;
1096}
1097
1098/*
1099** Allows overwriting
1100*/
1101
1102FILE *fileTable_openWriteFile (fileTable ft, cstring fname)
1103{
1104 FILE *res = fopen (cstring_toCharsSafe (fname), "w");
1105
1106 if (res != NULL) {
1107 fileTable_addOpen (ft, res, cstring_copy (fname));
1108 DPRINTF (("Opening file: %s / %p", fname, res));
1109 }
1110
1111 return res;
1112}
1113
1114FILE *fileTable_openWriteUpdateFile (fileTable ft, cstring fname)
1115{
1116 FILE *res = fopen (cstring_toCharsSafe (fname), "w+");
dfd82dce 1117
1118 if (res != NULL) {
1119 fileTable_addOpen (ft, res, cstring_copy (fname));
1120 DPRINTF (("Opening file: %s / %p", fname, res));
1121 }
1122
1123 return res;
1124}
1125
1126bool fileTable_closeFile (fileTable ft, FILE *f)
1127{
1128 bool foundit = FALSE;
1129 int i = 0;
1130
1131 llassert (fileTable_isDefined (ft));
1132
1133 DPRINTF (("Closing file: %p", f));
1134
1135 for (i = 0; i < ft->nopen; i++)
1136 {
1137 if (ft->openelements[i]->f == f)
1138 {
1139 DPRINTF (("Closing file: %p = %s", f, ft->openelements[i]->fname));
d5047b91 1140
dfd82dce 1141 if (i == ft->nopen - 1)
1142 {
1143 foentry_free (ft->openelements[i]);
1144 ft->openelements[i] = NULL;
1145 }
1146 else
1147 {
1148 foentry_free (ft->openelements[i]);
1149 ft->openelements[i] = ft->openelements[ft->nopen - 1];
1150 ft->openelements[ft->nopen - 1] = NULL;
1151 }
1152
1153 ft->nopen--;
1154 ft->nopenspace++;
1155 foundit = TRUE;
1156 break;
1157 }
1158 }
1159
1160 llassert (foundit);
1161 return (fclose (f) == 0);
1162}
1163
1164void fileTable_closeAll (fileTable ft)
1165{
1166 int i = 0;
1167
abd7f895 1168 llassert (fileTable_isDefined (ft));
1169
dfd82dce 1170 for (i = 0; i < ft->nopen; i++)
1171 {
107b60d6 1172 /*
1173 lldiagmsg (message ("Unclosed file at exit: %s", ft->openelements[i]->fname));
1174 */
abd7f895 1175
1176 if (ft->openelements[i]->f != NULL)
1177 {
1178 (void) fclose (ft->openelements[i]->f); /* No check - cleaning up after errors */
1179 }
107b60d6 1180
dfd82dce 1181 ft->openelements[i]->f = NULL;
1182 foentry_free (ft->openelements[i]);
1183 ft->openelements[i] = NULL;
1184 }
1185
1186 ft->nopenspace += ft->nopen;
1187 ft->nopen = 0;
1188}
1189
This page took 0.233966 seconds and 5 git commands to generate.