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