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