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