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