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