]> andersk Git - splint.git/blame - src/fileTable.c
Fixed inclusion problems with osd.h.
[splint.git] / src / fileTable.c
CommitLineData
616915dd 1/*
11db3170 2** Splint - annotation-assisted static program checker
c59f5181 3** Copyright (C) 1994-2003 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"
b73d1009 51# include "basic.h"
616915dd 52# include "osd.h"
53# include "llmain.h"
d5047b91 54
4caf866b 55# ifdef WIN32
56# include <io.h>
57# else
616915dd 58# if defined(__IBMC__) && defined(OS2)
59# include <process.h>
36250f22 60# include <io.h>
616915dd 61# define getpid _getpid
36250f22 62# define S_IRUSR S_IREAD
63# define S_IWUSR S_IWRITE
64# define S_IXUSR S_IEXEC
616915dd 65# endif
4caf866b 66# endif
616915dd 67
68/*@access fileId*/
69
80489f0a 70static void
71fileTable_addOpen (fileTable p_ft, /*@observer@*/ FILE *p_f, /*@only@*/ cstring p_fname)
72 /*@modifies p_ft@*/ ;
73
616915dd 74static bool fileTable_inRange (fileTable ft, fileId fid) /*@*/
75{
76 return (fileTable_isDefined (ft) && (fid >= 0) && (fid < ft->nentries));
77}
78
79static fileId fileTable_internAddEntry (fileTable p_ft, /*@only@*/ ftentry p_e)
80 /*@modifies p_ft@*/ ;
28bf4b0b 81static /*@only@*/ cstring makeTempName (cstring p_dir, cstring p_pre, cstring p_suf);
616915dd 82
83static /*@only@*/ cstring
84fileType_unparse (fileType ft)
85{
86 switch (ft)
87 {
88 case FILE_NORMAL: return cstring_makeLiteral ("normal");
89 case FILE_NODELETE: return cstring_makeLiteral ("normal");
90 case FILE_LSLTEMP: return cstring_makeLiteral ("ltemp");
91 case FILE_HEADER: return cstring_makeLiteral ("header");
28bf4b0b 92 case FILE_XH: return cstring_makeLiteral ("xh");
616915dd 93 case FILE_MACROS: return cstring_makeLiteral ("macros");
28bf4b0b 94 case FILE_METASTATE: return cstring_makeLiteral ("metastate");
616915dd 95 }
96
97 BADEXIT;
98}
99
100static int
101fileTable_getIndex (fileTable ft, cstring s)
102{
53a89507 103 int res;
104 cstring abspath;
616915dd 105 if (ft == NULL) return NOT_FOUND;
53a89507 106 abspath = osd_absolutePath (cstring_undefined, s);
2cecdaff 107
108 if (context_getFlag (FLG_CASEINSENSITIVEFILENAMES))
109 {
110 abspath = cstring_downcase (abspath);
111 }
112
f2b6724f 113 DPRINTF (("Absolute path: %s: %s", s, abspath));
53a89507 114 res = cstringTable_lookup (ft->htable, abspath);
115 cstring_free (abspath);
116 return res;
616915dd 117}
118
4dd72714 119static cstring ftentry_unparse (fileTable ft, ftentry fte)
120{
121 if (fileId_isValid (fte->fder))
122 {
abd7f895 123 llassert (fileTable_isDefined (ft));
124
4dd72714 125 return message ("%s %q %d (%s)",
126 fte->fname,
127 fileType_unparse (fte->ftype),
128 fte->fder,
129 ft->elements[fte->fder]->fname);
130 }
131 else
132 {
133 return message ("%s %q", fte->fname,
134 fileType_unparse (fte->ftype));
135 }
136}
137
616915dd 138/*@only@*/ cstring
139fileTable_unparse (fileTable ft)
140{
141 cstring s = cstring_undefined;
142 int i;
143
144 if (fileTable_isUndefined (ft))
145 {
146 return (cstring_makeLiteral ("<fileTable undefined>"));
147 }
148
149 for (i = 0; i < ft->nentries; i++)
150 {
4dd72714 151 s = message ("%s\n[%d] %q", s, i, ftentry_unparse (ft, ft->elements[i]));
152 }
616915dd 153
154 return s;
155}
156
157void fileTable_printTemps (fileTable ft)
158{
159 if (fileTable_isDefined (ft))
160 {
161 int i;
162
163 for (i = 0; i < ft->nentries; i++)
164 {
165 if (ft->elements[i]->ftemp)
166 {
167 if (fileId_isValid (ft->elements[i]->fder))
168 {
169 fprintf (stderr, " %s:1\n\t%s:1\n",
170 cstring_toCharsSafe (ft->elements[ft->elements[i]->fder]->fname),
171 cstring_toCharsSafe (ft->elements[i]->fname));
172 }
173 else
174 {
175 fprintf (stderr, "[no file]\n\t%s:1\n",
176 cstring_toCharsSafe (ft->elements[i]->fname));
177 }
178 }
179 }
180 }
181}
182
183/*
184** loads in fileTable from fileTable_dump
185*/
186
187static /*@notnull@*/ ftentry
188ftentry_create (/*@keep@*/ cstring tn, bool temp, fileType typ, fileId der)
189{
190 ftentry t = (ftentry) dmalloc (sizeof (*t));
191
192 if (cstring_isUndefined (tn))
193 {
194 llbug (cstring_makeLiteral ("Undefined filename!"));
195 }
196
197 t->fname = tn;
616915dd 198 t->basename = cstring_undefined;
199 t->ftemp = temp;
200 t->ftype = typ;
201 t->fder = der;
202
203 /* Don't set these until the basename is needed. */
204 t->fsystem = FALSE;
205 t->fspecial = FALSE;
206
207 return t;
208}
209
210static void
211ftentry_free (/*@only@*/ ftentry t)
212{
213 cstring_free (t->fname);
214 cstring_free (t->basename);
215 sfree (t);
216}
217
218/*@only@*/ /*@notnull@*/ fileTable
219fileTable_create ()
220{
221 fileTable ft = (fileTable) dmalloc (sizeof (*ft));
222
223 ft->nentries = 0;
224 ft->nspace = FTBASESIZE;
225 ft->elements = (ftentry *) dmalloc (FTBASESIZE * sizeof (*ft->elements));
28bf4b0b 226 ft->htable = cstringTable_create (FTHASHSIZE);
dfd82dce 227
228 ft->nopen = 0;
229 ft->nopenspace = FTBASESIZE;
230 ft->openelements = (foentry *) dmalloc (FTBASESIZE * sizeof (*ft->openelements));
6fcd0b1e 231
616915dd 232 return (ft);
233}
234
4fab1d8a 235/*@-bounds@*/
616915dd 236static void
237fileTable_grow (fileTable ft)
238{
239 int i;
240 ftentry *newent;
241
242 llassert (fileTable_isDefined (ft));
243
244 ft->nspace = FTBASESIZE;
245
246 newent = (ftentry *) dmalloc ((ft->nentries + ft->nspace) * sizeof (*newent));
247
248 for (i = 0; i < ft->nentries; i++)
249 {
250 newent[i] = ft->elements[i];
251 }
252
253 sfree (ft->elements);
254 ft->elements = newent;
255}
4fab1d8a 256/*@=bounds@*/
dfd82dce 257static void
258fileTable_growOpen (fileTable ft)
259{
260 int i;
261 foentry *newent;
262
263 llassert (fileTable_isDefined (ft));
264
265 ft->nopenspace = FTBASESIZE;
266
267 newent = (foentry *) dmalloc ((ft->nopen + ft->nopenspace) * sizeof (*newent));
268
269 for (i = 0; i < ft->nopen; i++)
270 {
271 newent[i] = ft->openelements[i];
272 }
273
274 sfree (ft->openelements);
275 ft->openelements = newent;
276}
277
616915dd 278static fileId
279fileTable_internAddEntry (fileTable ft, /*@only@*/ ftentry e)
280{
281 llassert (fileTable_isDefined (ft));
282
283 if (ft->nspace <= 0)
284 fileTable_grow (ft);
285
286 ft->nspace--;
287
f2b6724f 288 DPRINTF (("Adding: %s", e->fname));
2cecdaff 289
290 if (context_getFlag (FLG_CASEINSENSITIVEFILENAMES))
291 {
292 cstring sd = cstring_downcase (e->fname);
293 cstringTable_insert (ft->htable, sd, ft->nentries);
2cecdaff 294 }
295 else
296 {
6fcd0b1e 297 cstringTable_insert (ft->htable, cstring_copy (e->fname), ft->nentries);
2cecdaff 298 }
299
6fcd0b1e 300 /* evans 2002-07-12:
301 Before, there was no cstring_copy above, and e->fname was free'd in the if branch.
302 Splint should have caught this, and produced a warning for this assignment.
303 Why not?
304 */
616915dd 305 ft->elements[ft->nentries] = e;
306
307 ft->nentries++;
308 return (ft->nentries - 1);
309}
310
311void fileTable_noDelete (fileTable ft, cstring name)
312{
313 fileId fid = fileTable_lookup (ft, name);
314
4dd72714 315 if (fileId_isValid (fid))
316 {
317 llassert (fileTable_isDefined (ft));
318 ft->elements[fid]->ftype = FILE_NODELETE;
319 }
320 else
321 {
322 DPRINTF (("Invalid no delete: %s", name));
323 }
616915dd 324}
325
326static fileId
53a89507 327fileTable_addFilePrim (fileTable ft, /*@temp@*/ cstring name,
616915dd 328 bool temp, fileType typ, fileId der)
329 /*@modifies ft@*/
330{
53a89507 331 cstring absname = osd_absolutePath (NULL, name);
332 int tindex = fileTable_getIndex (ft, absname);
4dd72714 333
616915dd 334 llassert (ft != fileTable_undefined);
335
336 if (tindex != NOT_FOUND)
337 {
53a89507 338 llcontbug (message ("fileTable_addFilePrim: duplicate entry: %q", absname));
616915dd 339 return tindex;
340 }
341 else
342 {
53a89507 343 ftentry e = ftentry_create (absname, temp, typ, der);
616915dd 344
345 if (der == fileId_invalid)
346 {
347 llassert (cstring_isUndefined (e->basename));
348
53a89507 349 e->basename = fileLib_removePathFree (fileLib_removeAnyExtension (absname));
350 e->fsystem = context_isSystemDir (absname);
52e90c0f 351
352 /*
353 ** evans 2002-03-15: change suggested by Jim Zelenka
354 ** support relative paths for system directories
355 */
356
357 if (!e->fsystem)
358 {
359 e->fsystem = context_isSystemDir (name);
360 }
361
53a89507 362 e->fspecial = context_isSpecialFile (absname);
616915dd 363
364 if (e->fspecial)
365 {
53a89507 366 cstring srcname = cstring_concatFree1 (fileLib_removeAnyExtension (absname),
28bf4b0b 367 C_EXTENSION);
616915dd 368 fileId fid = fileTable_lookup (ft, srcname);
616915dd 369 cstring_free (srcname);
370
371 if (fileId_isValid (fid))
372 {
373 fileId derid = ft->elements[fid]->fder;
374
375 ft->elements[fid]->fspecial = TRUE;
376
377 if (fileId_isValid (derid))
378 {
379 ft->elements[derid]->fspecial = TRUE;
380 }
381 }
382 }
383 }
384 else
385 {
386 ftentry de = ft->elements[der];
387
388 llassert (cstring_isUndefined (e->basename));
389 e->basename = cstring_copy (de->basename);
390 e->fsystem = de->fsystem;
391 e->fspecial = de->fspecial;
392 }
393
394 return (fileTable_internAddEntry (ft, e));
395 }
396}
397
398fileId
399fileTable_addFile (fileTable ft, cstring name)
400{
53a89507 401 return (fileTable_addFilePrim (ft, name, FALSE, FILE_NORMAL, fileId_invalid));
616915dd 402}
403
404fileId
405fileTable_addFileOnly (fileTable ft, /*@only@*/ cstring name)
406{
53a89507 407 fileId res = fileTable_addFilePrim (ft, name, FALSE, FILE_NORMAL, fileId_invalid);
408 cstring_free (name);
409 return res;
616915dd 410}
411
412fileId
413fileTable_addHeaderFile (fileTable ft, cstring name)
414{
28bf4b0b 415 fileId res;
53a89507 416 res = fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid);
28bf4b0b 417 return res;
418
616915dd 419}
420
80489f0a 421void
422fileTable_addStreamFile (fileTable ft, FILE *fstream, cstring name)
423{
424 fileTable_addOpen (ft, fstream, cstring_copy (name));
425}
426
616915dd 427bool
428fileTable_isHeader (fileTable ft, fileId fid)
429{
430 if (fileId_isInvalid (fid))
431 {
432 return FALSE;
433 }
434
435 llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
436 return (ft->elements[fid]->ftype == FILE_HEADER);
437}
438
439bool
440fileTable_isSystemFile (fileTable ft, fileId fid)
441{
442 if (fileId_isInvalid (fid))
443 {
444 return FALSE;
445 }
446
447 llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
448 return (ft->elements[fid]->fsystem);
449}
450
28bf4b0b 451bool
452fileTable_isXHFile (fileTable ft, fileId fid)
453{
454 if (fileId_isInvalid (fid))
455 {
456 return FALSE;
457 }
458
ccf0a4a8 459 if (!(fileTable_isDefined (ft) && fileTable_inRange (ft, fid)))
460 {
461 llcontbug (message ("Bad file table or id: %s %d", bool_unparse (fileTable_isDefined (ft)), fid));
462 return FALSE;
463 }
464 else
465 {
466 return (ft->elements[fid]->ftype == FILE_XH);
467 }
28bf4b0b 468}
469
616915dd 470bool
471fileTable_isSpecialFile (fileTable ft, fileId fid)
472{
473 if (fileId_isInvalid (fid))
474 {
475 return FALSE;
476 }
ccf0a4a8 477
616915dd 478 llassert (fileTable_isDefined (ft) && fileTable_inRange (ft, fid));
479 return (ft->elements[fid]->fspecial);
480}
481
482fileId
483fileTable_addLibraryFile (fileTable ft, cstring name)
484{
53a89507 485 return (fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid));
616915dd 486}
487
28bf4b0b 488fileId
489fileTable_addXHFile (fileTable ft, cstring name)
490{
53a89507 491 return (fileTable_addFilePrim (ft, name, FALSE, FILE_XH, fileId_invalid));
28bf4b0b 492}
493
616915dd 494fileId
495fileTable_addImportFile (fileTable ft, cstring name)
496{
53a89507 497 return (fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid));
616915dd 498}
499
500fileId
501fileTable_addLCLFile (fileTable ft, cstring name)
502{
53a89507 503 return (fileTable_addFilePrim (ft, name, FALSE, FILE_HEADER, fileId_invalid));
616915dd 504}
616915dd 505
616915dd 506static int tmpcounter = 0;
616915dd 507
508fileId
509fileTable_addMacrosFile (fileTable ft)
510{
28bf4b0b 511 cstring newname =
512 makeTempName (context_tmpdir (), cstring_makeLiteralTemp ("lmx"),
513 cstring_makeLiteralTemp (".llm"));
53a89507 514 fileId res = fileTable_addFilePrim (ft, newname, TRUE, FILE_MACROS, fileId_invalid);
515 cstring_free (newname);
516 return res;
616915dd 517}
518
28bf4b0b 519fileId
520fileTable_addMetastateFile (fileTable ft, cstring name)
521{
53a89507 522 return (fileTable_addFilePrim (ft, name, FALSE, FILE_METASTATE, fileId_invalid));
28bf4b0b 523}
524
616915dd 525fileId
526fileTable_addCTempFile (fileTable ft, fileId fid)
527{
28bf4b0b 528 cstring newname =
529 makeTempName (context_tmpdir (), cstring_makeLiteralTemp ("cl"),
530 C_EXTENSION);
53a89507 531 fileId res;
616915dd 532
4dd72714 533 DPRINTF (("tmp dir: %s", context_tmpdir ()));
534 DPRINTF (("new name: %s", newname));
535
616915dd 536 llassert (fileTable_isDefined (ft));
537
538 if (!fileId_isValid (ft->elements[fid]->fder))
539 {
28bf4b0b 540 if (fileTable_isXHFile (ft, fid))
541 {
53a89507 542 res = fileTable_addFilePrim (ft, newname, TRUE, FILE_XH, fid);
28bf4b0b 543 }
544 else
545 {
53a89507 546 res = fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL, fid);
28bf4b0b 547 }
616915dd 548 }
549 else
550 {
28bf4b0b 551 if (fileTable_isXHFile (ft, fid))
552 {
53a89507 553 res = fileTable_addFilePrim (ft, newname, TRUE, FILE_XH,
554 ft->elements[fid]->fder);
28bf4b0b 555 }
556 else
557 {
53a89507 558 res = fileTable_addFilePrim (ft, newname, TRUE, FILE_NORMAL,
559 ft->elements[fid]->fder);
28bf4b0b 560 }
616915dd 561 }
53a89507 562
4dd72714 563 DPRINTF (("Added file: %s", fileTable_fileName (res)));
53a89507 564 cstring_free (newname);
565 return res;
616915dd 566}
567
616915dd 568fileId
569fileTable_addltemp (fileTable ft)
570{
28bf4b0b 571 cstring newname = makeTempName (context_tmpdir (),
572 cstring_makeLiteralTemp ("ls"),
573 cstring_makeLiteralTemp (".lsl"));
616915dd 574 fileId ret;
575
28bf4b0b 576 if (cstring_hasNonAlphaNumBar (newname))
616915dd 577 {
578 char *lastpath = (char *)NULL;
579
580 if (tmpcounter == 0)
581 {
582 lldiagmsg
583 (message
584 ("Operating system generates tmp filename containing invalid charater: %s",
28bf4b0b 585 newname));
616915dd 586 lldiagmsg (cstring_makeLiteral
587 ("Try cleaning up the tmp directory. Attempting to continue."));
588 }
589
28bf4b0b 590 /*@access cstring@*/
591 llassert (cstring_isDefined (newname));
616915dd 592 lastpath = strrchr (newname, CONNECTCHAR); /* get the directory */
593 llassert (lastpath != NULL);
594 *lastpath = '\0';
595
28bf4b0b 596 newname = message ("%q%hlsl%d.lsl",
597 newname,
598 CONNECTCHAR,
599 tmpcounter);
600 /*@noaccess cstring@*/
616915dd 601 tmpcounter++;
602 }
603
604 /*
605 ** this is kind of yucky...need to make the result of cstring_fromChars
606 ** refer to the same storage as its argument. Of course, this loses,
607 ** since cstring is abstract. Should make it an only?
608 */
609
53a89507 610 ret = fileTable_addFilePrim (ft, newname, TRUE, FILE_LSLTEMP, fileId_invalid);
28bf4b0b 611 cstring_free (newname);
616915dd 612 return (ret);
613}
616915dd 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 {
d767066b 834 /* this should use close (fd) also... */
28bf4b0b 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);
6fcd0b1e 882 sfree (f->openelements); /*!! why didn't splint report this? */
616915dd 883 sfree (f);
884}
885
886/*
887** unique temp filename are constructed from <dir><pre><pid><msg>.<suf>
888** requires: <dir> must end in '/'
889*/
890
891static void nextMsg (char *msg)
892{
893 /*@+charint@*/
894 if (msg[0] < 'Z')
895 {
896 msg[0]++;
897 }
898 else
899 {
900 msg[0] = 'A';
901 if (msg[1] < 'Z')
902 {
903 msg[1]++;
904 }
905 else
906 {
907 msg[1] = 'A';
908 if (msg[2] < 'Z')
909 {
910 msg[2]++;
911 }
912 else
913 {
914 msg[2] = 'A';
915 if (msg[3] < 'Z')
916 {
917 msg[3]++;
918 }
919 else
920 {
921 llassertprint (FALSE, ("nextMsg: out of unique names!!!"));
922 }
923 }
924 }
925 }
926 /*@-charint@*/
927}
928
28bf4b0b 929static /*@only@*/ cstring makeTempName (cstring dir, cstring pre, cstring suf)
616915dd 930{
931 static int pid = 0;
932 static /*@owned@*/ char *msg = NULL;
28bf4b0b 933 static /*@only@*/ cstring pidname = NULL;
e5081f8c 934 size_t maxlen;
28bf4b0b 935 cstring smsg;
616915dd 936
28bf4b0b 937 llassert (cstring_length (pre) <= 3);
616915dd 938
939 /*
940 ** We limit the temp name to 8 characters:
941 ** pre: 3 or less
942 ** msg: 3
943 ** pid: 2 (% 100)
944 */
945
946 if (msg == NULL)
947 {
948 msg = mstring_copy ("AAA"); /* there are 26^3 temp names */
949 }
950
951 if (pid == 0)
952 {
953 /*@+matchanyintegral@*/
954 pid = osd_getPid ();
955 /*@=matchanyintegral@*/
956 }
957
28bf4b0b 958 if (cstring_isUndefined (pidname))
616915dd 959 {
28bf4b0b 960 pidname = message ("%d", pid % 100);
616915dd 961 }
962
28bf4b0b 963 maxlen = (cstring_length (dir) + cstring_length (pre) + mstring_length (msg)
964 + cstring_length (pidname) + cstring_length (suf) + 2);
616915dd 965
4dd72714 966 DPRINTF (("Dir: %s / %s / %s / %s / %s",
967 dir, pre, pidname, msg, suf));
968
28bf4b0b 969 smsg = message ("%s%s%s%s%s", dir, pre, pidname, cstring_fromChars (msg), suf);
616915dd 970 nextMsg (msg);
971
4dd72714 972 DPRINTF (("Trying: %s", smsg));
973
28bf4b0b 974 while (osd_fileExists (smsg))
616915dd 975 {
28bf4b0b 976 cstring_free (smsg);
977 smsg = message ("%s%s%s%s%s", dir, pre, pidname, cstring_fromChars (msg), suf);
616915dd 978 nextMsg (msg);
979 }
616915dd 980
28bf4b0b 981 return smsg;
982}
dfd82dce 983
984static foentry
985foentry_create (/*@exposed@*/ FILE *f, /*@only@*/ cstring fname)
986{
987 foentry t = (foentry) dmalloc (sizeof (*t));
988 t->f = f;
989 t->fname = fname;
990 return t;
991}
992
993static void
994foentry_free (/*@only@*/ foentry foe)
995{
996 cstring_free (foe->fname);
997 sfree (foe);
998}
999
1000static void
1001fileTable_addOpen (fileTable ft, /*@observer@*/ FILE *f, /*@only@*/ cstring fname)
1002{
1003 llassert (fileTable_isDefined (ft));
1004
1005 if (ft->nopenspace <= 0)
1006 {
1007 fileTable_growOpen (ft);
1008 }
1009
1010 ft->nopenspace--;
1011 ft->openelements[ft->nopen] = foentry_create (f, fname);
1012 ft->nopen++;
1013}
1014
d5047b91 1015FILE *fileTable_createFile (fileTable ft, cstring fname)
1016{
53306cab 1017# ifdef WIN32
4caf866b 1018 int fdesc = _open (cstring_toCharsSafe (fname),
1019 O_WRONLY | O_CREAT | O_TRUNC | O_EXCL,
1020 _S_IWRITE | S_IREAD);
53306cab 1021# else
4caf866b 1022 int fdesc = open (cstring_toCharsSafe (fname),
1023 O_WRONLY | O_CREAT | O_TRUNC | O_EXCL,
1024 S_IRUSR | S_IWUSR);
53306cab 1025# endif
d5047b91 1026
1027 if (fdesc == -1)
1028 {
1029 osd_setTempError ();
1030 llfatalerror (message ("Temporary file for "
1031 "pre-processor output already exists. Trying to "
1032 "open: %s.",
1033 fname));
1034
1035 /*@notreached@*/ return NULL;
1036 }
1037 else
1038 {
1039 FILE *res = fdopen (fdesc, "w");
1040
1041 if (res != NULL)
1042 {
1043 fileTable_addOpen (ft, res, cstring_copy (fname));
1044 DPRINTF (("Opening file: %s / %p", fname, res));
1045 }
1046 else
1047 {
1048 DPRINTF (("Error opening: %s", fname));
1049 }
1050
1051 return res;
1052 }
1053}
1054
1055FILE *fileTable_createMacrosFile (fileTable ft, cstring fname)
1056{
4caf866b 1057# ifdef WIN32
1058 int fdesc = _open (cstring_toCharsSafe (fname),
1059 O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
1060 _S_IREAD | _S_IWRITE);
1061# else
1062 int fdesc = open (cstring_toCharsSafe (fname),
1063 O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
1064 S_IRUSR | S_IWUSR);
1065# endif
d5047b91 1066
1067 if (fdesc == -1)
1068 {
1069 osd_setTempError ();
1070 llfatalerror (message ("Temporary file for "
1071 "pre-processor output already exists. Trying to "
1072 "open: %s.",
1073 fname));
1074
1075 /*@notreached@*/ return NULL;
1076 }
1077 else
1078 {
1079 FILE *res = fdopen (fdesc, "w+");
1080
1081 if (res != NULL)
1082 {
1083 fileTable_addOpen (ft, res, cstring_copy (fname));
1084 DPRINTF (("Opening file: %s / %p", fname, res));
1085 }
1086 else
1087 {
1088 DPRINTF (("Error opening: %s", fname));
1089 }
1090
1091 return res;
1092 }
1093}
1094
1095FILE *fileTable_openReadFile (fileTable ft, cstring fname)
dfd82dce 1096{
d5047b91 1097 FILE *res = fopen (cstring_toCharsSafe (fname), "r");
1098
1099 if (res != NULL)
1100 {
1101 fileTable_addOpen (ft, res, cstring_copy (fname));
1102 DPRINTF (("Opening read file: %s / %p", fname, res));
1103 }
1104 else
1105 {
1106 DPRINTF (("Cannot open read file: %s", fname));
1107 }
1108
1109 return res;
1110}
1111
1112/*
1113** Allows overwriting
1114*/
1115
1116FILE *fileTable_openWriteFile (fileTable ft, cstring fname)
1117{
1118 FILE *res = fopen (cstring_toCharsSafe (fname), "w");
1119
1120 if (res != NULL) {
1121 fileTable_addOpen (ft, res, cstring_copy (fname));
1122 DPRINTF (("Opening file: %s / %p", fname, res));
1123 }
1124
1125 return res;
1126}
1127
1128FILE *fileTable_openWriteUpdateFile (fileTable ft, cstring fname)
1129{
1130 FILE *res = fopen (cstring_toCharsSafe (fname), "w+");
dfd82dce 1131
1132 if (res != NULL) {
1133 fileTable_addOpen (ft, res, cstring_copy (fname));
1134 DPRINTF (("Opening file: %s / %p", fname, res));
1135 }
1136
1137 return res;
1138}
1139
1140bool fileTable_closeFile (fileTable ft, FILE *f)
1141{
1142 bool foundit = FALSE;
1143 int i = 0;
1144
1145 llassert (fileTable_isDefined (ft));
1146
1147 DPRINTF (("Closing file: %p", f));
1148
1149 for (i = 0; i < ft->nopen; i++)
1150 {
1151 if (ft->openelements[i]->f == f)
1152 {
1153 DPRINTF (("Closing file: %p = %s", f, ft->openelements[i]->fname));
d5047b91 1154
dfd82dce 1155 if (i == ft->nopen - 1)
1156 {
1157 foentry_free (ft->openelements[i]);
1158 ft->openelements[i] = NULL;
1159 }
1160 else
1161 {
1162 foentry_free (ft->openelements[i]);
1163 ft->openelements[i] = ft->openelements[ft->nopen - 1];
1164 ft->openelements[ft->nopen - 1] = NULL;
1165 }
1166
1167 ft->nopen--;
1168 ft->nopenspace++;
1169 foundit = TRUE;
1170 break;
1171 }
1172 }
1173
1174 llassert (foundit);
1175 return (fclose (f) == 0);
1176}
1177
1178void fileTable_closeAll (fileTable ft)
1179{
1180 int i = 0;
1181
abd7f895 1182 llassert (fileTable_isDefined (ft));
1183
dfd82dce 1184 for (i = 0; i < ft->nopen; i++)
1185 {
107b60d6 1186 /*
1187 lldiagmsg (message ("Unclosed file at exit: %s", ft->openelements[i]->fname));
1188 */
abd7f895 1189
1190 if (ft->openelements[i]->f != NULL)
1191 {
1192 (void) fclose (ft->openelements[i]->f); /* No check - cleaning up after errors */
1193 }
107b60d6 1194
dfd82dce 1195 ft->openelements[i]->f = NULL;
1196 foentry_free (ft->openelements[i]);
1197 ft->openelements[i] = NULL;
1198 }
1199
1200 ft->nopenspace += ft->nopen;
1201 ft->nopen = 0;
1202}
1203
This page took 0.273647 seconds and 5 git commands to generate.