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