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