]> andersk Git - splint.git/blame - src/fileloc.c
Fixed test suite (temporarily) to run nested test cases
[splint.git] / src / fileloc.c
CommitLineData
616915dd 1/*
2** LCLint - annotation-assisted static program checker
28bf4b0b 3** Copyright (C) 1994-2001 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**
20** For information on lclint: lclint-request@cs.virginia.edu
21** To report a bug: lclint-bug@cs.virginia.edu
22** For more information: http://lclint.cs.virginia.edu
23*/
24/*
25** fileloc.c
26*/
27/*
28 * Modified by Herbert 04/19/97:
29 * - added new include file portab.h.
30 * - added new private function fileloc_filenameForCpp() to handle
31 * filenames belonging to "#line" statements for OS/2 and MSDOS. It
32 * gets called by fileloc_lineMarker() and fileloc_previousLineMarker()
33 * instead of fileloc_unparseFilename().
34 */
35
36# include "lclintMacros.nf"
37# include "llbasic.h"
38# include "fileIdList.h"
39# include "portab.h"
40
41static /*@only@*/ fileloc fileloc_createPrim (flkind p_kind, fileId p_fid, int p_line, int p_col);
42
43static flkind fileId_kind (fileId s)
44{
45 cstring fname = rootFileName (s);
46
28bf4b0b 47 if (fileLib_isLCLFile (fname))
616915dd 48 {
49 return (FL_SPEC);
50 }
68de3f33 51 else if (cstring_equalPrefix (fname, cstring_makeLiteralTemp (SYSTEM_LIBDIR)))
616915dd 52 {
53 return (FL_STDHDR);
54 }
55 else
56 {
57 return (FL_NORMAL);
58 }
59}
60
61fileloc
62fileloc_decColumn (fileloc f, int x)
63{
64 fileloc ret = fileloc_copy (f);
68de3f33 65
616915dd 66 if (x > 0 && fileloc_isDefined (ret))
67 {
68 llassertprint (ret->column > x, ("decColumn: %d", x));
69 ret->column -= x;
70 }
71
72 return ret;
73}
74
75fileloc
76fileloc_noColumn (fileloc f)
77{
78 if (fileloc_isDefined (f))
79 {
80 fileloc ret = fileloc_copy (f);
81
82 if (fileloc_isDefined (ret))
83 {
84 ret->column = 0;
85 }
86
87 return ret;
88 }
89 else
90 {
91 return fileloc_undefined;
92 }
93}
94
95void
96fileloc_subColumn (fileloc f, int x)
97{
98 if (x > 0 && fileloc_isDefined (f))
99 {
100 llassert (f->column > x);
101 f->column -= x;
102 }
103}
104
105fileloc fileloc_copy (fileloc f)
106{
107 if (fileloc_isDefined (f))
108 {
109 if (fileloc_isBuiltin (f) || fileloc_isExternal (f))
110 {
111 /*
112 ** Legitimate (spurious) errors reported since no copy
113 ** is made.
114 */
115
116 /*@i3@*/ return f; /* No copy is necessary. */
117 }
118 else
119 {
120 return (fileloc_createPrim (f->kind, f->fid, f->lineno, f->column));
121 }
122 }
123 else
124 {
125 return fileloc_undefined;
126 }
127}
128
129fileloc fileloc_update (/*@only@*/ fileloc old, fileloc fnew)
130{
131 if (fileloc_isUndefined (fnew))
132 {
133 fileloc_free (old);
134 return fileloc_undefined;
135 }
136 else if (fileloc_isUndefined (old) || fileloc_isBuiltin (old) || fileloc_isExternal (old))
137 {
138 return (fileloc_copy (fnew));
139 }
140 else
141 {
142 old->kind = fnew->kind;
143 old->fid = fnew->fid;
144 old->lineno = fnew->lineno;
145 old->column = fnew->column;
146
147 return old;
148 }
149}
150
151fileloc fileloc_updateFileId (/*@only@*/ fileloc old, fileId s)
152{
153 if (fileloc_isUndefined (old) || fileloc_isBuiltin (old) || fileloc_isExternal (old))
154 {
155 return (fileloc_create (s, 1, 1));
156 }
157 else
158 {
159 old->kind = fileId_kind (s);
160 old->fid = s;
161 old->lineno = 1;
162 old->column = 1;
163
164 return old;
165 }
166}
167
168void
169fileloc_free (/*@only@*/ fileloc f)
170{
171 if (fileloc_isDefined (f))
172 {
173 if (f != g_currentloc)
174 {
175 if (fileloc_isBuiltin (f) || fileloc_isExternal (f))
176 {
177 ; /* don't free */
178 }
179 else
180 {
ccf0a4a8 181 sfree (f);
616915dd 182 /*@-branchstate@*/
183 }
184 }
185 else
186 {
ccf0a4a8 187 ; /* Don't free g_currentloc ever! */
188 }
616915dd 189 /*@=branchstate@*/
190 }
191}
192
193void
194fileloc_reallyFree (/*@only@*/ fileloc f)
195{
196 if (fileloc_isDefined (f))
197 {
198 if (fileloc_isBuiltin (f) || fileloc_isExternal (f))
199 {
200 ; /* don't free */
201 }
202 else
203 {
204 sfree (f);
205 /*@-branchstate@*/ } /*@=branchstate@*/
206 }
207}
208
209cstring fileloc_getBase (fileloc f)
210{
211 llassert (fileloc_isDefined (f));
212
213 return (fileNameBase (f->fid));
214}
215
216bool
217fileloc_equal (fileloc f1, fileloc f2)
218{
219 return ((f1 == f2)
220 || (fileloc_isDefined (f1) && fileloc_isDefined (f2)
221 && ((f1->column == f2->column) &&
222 (f1->lineno == f2->lineno) && fileloc_sameFile (f1, f2))));
223}
224
225int
226fileloc_compare (fileloc f1, fileloc f2)
227{
228 if (fileloc_isUndefined (f1))
229 {
230 if (fileloc_isUndefined (f2)) return 0;
231 return -1;
232 }
233
234 if (fileloc_isUndefined (f2))
235 return 1;
236
237 /*@access fileId@*/
238 INTCOMPARERETURN (f1->fid, f2->fid);
239 /*@noaccess fileId@*/
240
f4ec8018 241
242 /* drl 8-11-01 fix what I think is a bug
b7e84605 243 lineno should more important than column number*/
244
245 INTCOMPARERETURN (f1->lineno, f2->lineno);
f4ec8018 246 INTCOMPARERETURN (f1->column, f2->column);
247
616915dd 248 return 0;
249}
250
251bool
252fileloc_withinLines (fileloc f1, fileloc f2, int n)
253{
254
255 return (fileloc_isDefined (f1) &&
256 fileloc_isDefined (f2) &&
257 ((f2->lineno <= f1->lineno + n)
258 && (f2->lineno >= f1->lineno)
259 && fileloc_sameFile (f1, f2)));
260}
261
262bool
263fileloc_lessthan (fileloc f1, fileloc f2)
264{
265 /*@access fileId*/
266 return ((fileloc_isDefined (f1) && fileloc_isDefined (f2))
267 && ((f1->fid < f2->fid)
268 || ((f1->fid == f2->fid)
269 && ((f1->lineno < f2->lineno)
270 || ((f1->lineno == f2->lineno)
271 && (f1->column < f2->column))))));
272 /*@noaccess fileId*/
273}
274
275/*
276** returns true if f1 and f2 are different files,
277** or f1 is before f2 in same file
278*/
279
280bool
281fileloc_notAfter (fileloc f1, fileloc f2)
282{
283 /*@access fileId*/
284 return ((fileloc_isDefined (f1) && fileloc_isDefined (f2))
285 && ((f1->fid != f2->fid)
286 || ((f1->lineno < f2->lineno)
287 || ((f1->lineno == f2->lineno)
288 && (f1->column <= f2->column)))));
289 /*@noaccess fileId@*/
290}
291
292# ifndef NOLCL
293bool
294fileloc_isStandardLibrary (fileloc f)
295{
296 cstring s = fileloc_getBase (f);
297
298 return (cstring_equalLit (s, LLSTDLIBS_NAME)
299 || cstring_equalLit (s, LLSTRICTLIBS_NAME)
300 || cstring_equalLit (s, LLUNIXLIBS_NAME)
301 || cstring_equalLit (s, LLUNIXSTRICTLIBS_NAME)
302 || cstring_equalLit (s, LLPOSIXSTRICTLIBS_NAME)
303 || cstring_equalLit (s, LLPOSIXLIBS_NAME));
304}
305# endif
306
28bf4b0b 307bool
308fileloc_sameFileAndLine (fileloc f1, fileloc f2)
309{
310 return (fileloc_sameFile (f1, f2)
311 && (fileloc_isDefined (f1) && fileloc_isDefined (f2)
312 && f1->lineno == f2->lineno));
313}
314
616915dd 315bool
316fileloc_sameFile (fileloc f1, fileloc f2)
317{
318 if ((fileloc_isUndefined (f1) || (fileloc_isUndefined (f2))
319 || (fileloc_isLib (f1)) || (fileloc_isLib (f2))))
320 {
321 return FALSE;
322 }
323 else
324 {
325 return (fileId_equal (f1->fid, f2->fid));
326 }
327}
328
329bool
330fileloc_sameModule (fileloc f1, fileloc f2)
331{
332 if (fileloc_isUndefined (f1))
333 {
334 return (fileloc_isUndefined (f2));
335 }
336 else if (fileloc_isUndefined (f2))
337 {
338 return (FALSE);
339 }
340 else
341 {
342 if (fileloc_isBuiltin (f1) || fileloc_isBuiltin (f2)
343 || fileloc_isExternal (f1) || fileloc_isExternal (f2))
344 {
345 return fileloc_sameFile (f1, f2);
346 }
347 else
348 {
349 cstring s1 = fileloc_getBase (f1);
350 cstring s2 = fileloc_getBase (f2);
351
352 return (cstring_equal (s1, s2));
353 }
354 }
355}
356
357bool
358fileloc_sameBaseFile (fileloc f1, fileloc f2)
359{
360 if (fileloc_isUndefined (f1))
361 {
362 return (fileloc_isUndefined (f2));
363 }
364 else if (fileloc_isUndefined (f2))
365 {
366 return (FALSE);
367 }
368 else
369 {
370 return (fileId_baseEqual (f1->fid, f2->fid));
371 }
372}
373
374bool fileloc_isSystemFile (fileloc f1)
375{
376 if (fileloc_isDefined (f1)
377 && !fileloc_isBuiltin (f1)
378 && !fileloc_isExternal (f1))
379 {
380 return (fileTable_isSystemFile (context_fileTable (), f1->fid));
381 }
382
383 return FALSE;
384}
385
28bf4b0b 386bool fileloc_isXHFile (fileloc f1)
387{
388 if (fileloc_isDefined (f1)
389 && !fileloc_isBuiltin (f1)
390 && !fileloc_isExternal (f1))
391 {
ccf0a4a8 392 DPRINTF (("Fileloc is XH: [%p] %s", f1, fileloc_unparse (f1)));
28bf4b0b 393 return (fileTable_isXHFile (context_fileTable (), f1->fid));
394 }
395
396 return FALSE;
397}
398
616915dd 399bool
400fileloc_almostSameFile (fileloc f1, fileloc f2)
401{
402 if ((fileloc_isUndefined (f1) || (fileloc_isUndefined (f2))
403 || (fileloc_isLib (f1)) || (fileloc_isLib (f2))))
404 {
405 return FALSE;
406 }
407 else
408 {
409 if (fileId_baseEqual (f1->fid, f2->fid))
410 {
411 return TRUE;
412 }
413 else if (fileTable_isSystemFile (context_fileTable (), f1->fid)
414 || fileTable_isSystemFile (context_fileTable (), f2->fid))
415 {
416 return TRUE;
417 }
418 else if (fileTable_isSpecialFile (context_fileTable (), f1->fid)
419 || fileTable_isSpecialFile (context_fileTable (), f2->fid))
420 {
421 return (cstring_equal (fileloc_getBase (f1),
422 fileloc_getBase (f2)));
423 }
424 else
425 {
426 return FALSE;
427 }
428 }
429}
430
431# ifndef NOLCL
432/*@only@*/ fileloc
433fileloc_fromTok (ltoken t)
434{
435 cstring fname = ltoken_fileName (t);
436 fileId fid = fileTable_lookup (context_fileTable (), fname);
437 fileloc fl;
438
439 if (!fileId_isValid (fid))
440 {
441 fid = fileTable_addLCLFile (context_fileTable (), fname);
442 }
443
444 fl = fileloc_create (fid, (int) ltoken_getLine (t), (int) ltoken_getCol (t));
445
446 return (fl);
447}
448# endif
449
450/*@only@*/ fileloc
451fileloc_createLib (cstring ln)
452{
453 flkind fk = FL_LIB;
454 fileId fid = fileTable_lookup (context_fileTable (), ln);
455
456 if (!fileId_isValid (fid))
457 {
458 fid = fileTable_addLibraryFile (context_fileTable (), ln);
459 }
460
68de3f33 461 if (cstring_equalPrefix (ln, cstring_makeLiteralTemp (SYSTEM_LIBDIR)))
616915dd 462 {
463 fk = FL_STDLIB;
464 }
465
466 return (fileloc_createPrim (fk, fid, 0, 0));
467}
468
469fileloc fileloc_createRc (cstring name)
470{
471 fileId fid = fileTable_addFile (context_fileTable (), name);
472
473 return (fileloc_createPrim (FL_RC, fid, 0, 0));
474}
475
476fileloc fileloc_createExternal (void)
477{
478 /*@i@*/ return (fileloc_getExternal ());
479}
480
481fileloc fileloc_getExternal (void)
482{
483 static /*@owned@*/ fileloc res = fileloc_undefined;
484
485 if (res == fileloc_undefined)
486 {
487 res = fileloc_createPrim (FL_EXTERNAL, fileId_invalid, 0, 0);
488 }
489
490 return res;
491}
492
493fileloc fileloc_observeBuiltin ()
494{
495 /*@-onlytrans@*/ return (fileloc_getBuiltin ()); /*@=onlytrans@*/
496}
497
498fileloc fileloc_getBuiltin ()
499{
500 static /*@owned@*/ fileloc res = fileloc_undefined;
501
502 if (res == fileloc_undefined)
503 {
504 res = fileloc_createPrim (FL_BUILTIN, fileId_invalid, 0, 0);
505 }
506
507 return res;
508}
509
510fileloc
511fileloc_makePreproc (fileloc loc)
512{
513 if (fileloc_isDefined (loc))
514 {
515 return (fileloc_createPrim (FL_PREPROC, loc->fid,
516 loc->lineno, loc->column));
517 }
518
519 return (fileloc_createPrim (FL_PREPROC, fileId_invalid, 0, 0));
520}
521
522fileloc
523fileloc_makePreprocPrevious (fileloc loc)
524{
525 if (fileloc_isDefined (loc))
526 {
527 if (loc->lineno > 1)
528 {
529 return (fileloc_createPrim (FL_PREPROC, loc->fid,
530 loc->lineno - 1, 0));
531 }
532 else
533 {
534 return (fileloc_createPrim (FL_PREPROC, loc->fid,
535 loc->lineno, 0));
536 }
537 }
538
539 return (fileloc_createPrim (FL_PREPROC, fileId_invalid, 0, 0));
540}
541
542/*@only@*/ fileloc
543fileloc_createBuiltin ()
544{
545 return (fileloc_createPrim (FL_BUILTIN, fileId_invalid, 0, 0));
546}
547
548# ifndef NOLCL
549/*@only@*/ fileloc
550fileloc_createImport (cstring fname, int lineno)
551{
552 fileId fid = fileTable_lookup (context_fileTable (), fname);
553
554 if (!fileId_isValid (fid))
555 {
556 fid = fileTable_addImportFile (context_fileTable (), fname);
557 }
558
559 return (fileloc_createPrim (FL_IMPORT, fid, lineno, 0));
560}
561# endif
562
563static /*@only@*/ fileloc
564fileloc_createPrim (flkind kind, fileId fid, int line, int col)
565{
566 fileloc f = (fileloc) dmalloc (sizeof (*f));
567
568 f->kind = kind;
569 f->fid = fid;
570 f->lineno = line;
571 f->column = col;
28bf4b0b 572
ccf0a4a8 573 DPRINTF (("Fileloc create: [%p] %s", f, fileloc_unparse (f)));
616915dd 574 return (f);
575}
576
577# ifndef NOLCL
578/*@only@*/ fileloc
579fileloc_createSpec (fileId fid, int line, int col)
580{
581 return (fileloc_createPrim (FL_SPEC, fid, line, col));
582}
583# endif
584
585fileloc fileloc_create (fileId fid, int line, int col)
586{
587 return (fileloc_createPrim (fileId_kind (fid), fid, line, col));
588}
589
590/*@observer@*/ cstring
591fileloc_filename (fileloc f)
592{
593 return (fileloc_isDefined (f)
594 ? rootFileName (f->fid) : cstring_makeLiteralTemp ("<unknown>"));
595}
596
597cstring
598fileloc_unparseFilename (fileloc f)
599{
600 if (fileloc_isDefined (f))
601 {
602 switch (f->kind)
603 {
604 case FL_LIB:
605 return (message ("load file %s", fileloc_filename (f)));
606 case FL_BUILTIN:
607 return (cstring_makeLiteral ("# builtin #"));
608 case FL_IMPORT:
609 return (message ("import file %s", fileloc_filename (f)));
610 case FL_EXTERNAL:
611 return (cstring_makeLiteral ("<external>"));
612 default:
613 return (cstring_copy (fileloc_filename (f)));
614 }
615 }
616 return cstring_undefined;
617}
618
619int
620fileloc_lineno (fileloc f)
621{
622 return (fileloc_isDefined (f) ? f->lineno : -1);
623}
624
625int
626fileloc_column (fileloc f)
627{
628 return (fileloc_isDefined (f) ? f->column : -1);
629}
630
631/*@only@*/ cstring
632fileloc_unparse (fileloc f)
633{
634 bool parenFormat = context_getFlag (FLG_PARENFILEFORMAT);
635
636 if (fileloc_isDefined (f))
637 {
28bf4b0b 638 switch (f->kind)
616915dd 639 {
616915dd 640 case FL_BUILTIN:
641 return (cstring_makeLiteral ("Command Line"));
642 case FL_IMPORT:
643 if (parenFormat)
644 {
645 return (message ("import file %s(%d)", rootFileName (f->fid), f->lineno));
646 }
647 else
648 {
649 return (message ("import file %s:%d", rootFileName (f->fid), f->lineno));
650 }
651 case FL_PREPROC:
652 if (parenFormat)
653 {
654 return (message ("%s(%d)", rootFileName (f->fid), f->lineno));
655 }
656 else
657 {
658 return (message ("%s:%d", rootFileName (f->fid), f->lineno));
659 }
660 case FL_EXTERNAL:
661 return (cstring_makeLiteral ("<external>"));
662 default:
28bf4b0b 663 {
664 cstring fname;
665
666 if (f->kind == FL_LIB)
667 {
668 fname = message ("load file %s", rootFileName (f->fid));
669 cstring_markOwned (fname); /*@i32 memory leak...@*/
670 }
671 else
672 {
673 fname = rootFileName (f->fid);
674 }
675
676 if (context_getFlag (FLG_SHOWCOL))
677 {
678 if (fileloc_linenoDefined (f))
679 {
680 if (fileloc_columnDefined (f))
681 {
682 if (parenFormat)
683 {
684 return (message ("%s(%d,%d)", fname, f->lineno, f->column));
685 }
686 else
687 {
688 return (message ("%s:%d:%d", fname, f->lineno, f->column));
689 }
690 }
691 else
692 {
693 if (parenFormat)
694 {
695 return (message ("%s(%d)", fname, f->lineno));
696 }
697 else
698 {
699 return (message ("%s:%d", fname, f->lineno));
700 }
701 }
702 }
703 return (cstring_copy (fname));
704 }
705 else if (fileloc_linenoDefined (f))
706 {
707 if (parenFormat)
708 {
709 return (message ("%s(%d)", fname, f->lineno));
710 }
711 else
712 {
713 return (message ("%s:%d", fname, f->lineno));
714 }
715 }
716 else
717 {
718 return (cstring_copy (fname));
719 }
720 }
616915dd 721 }
722 }
28bf4b0b 723
616915dd 724 return (cstring_makeLiteral ("< Location unknown >"));
725}
726
727/*@only@*/ cstring
728fileloc_unparseRaw (cstring fname, int lineno)
729{
730 bool parenFormat = context_getFlag (FLG_PARENFILEFORMAT);
731
732 if (parenFormat)
733 {
734 return (message ("%s(%d)", fname, lineno));
735 }
736 else
737 {
738 return (message ("%s:%d", fname, lineno));
739 }
740}
741
742/*@only@*/ cstring
743fileloc_unparseRawCol (cstring fname, int lineno, int col)
744{
745 if (context_getFlag (FLG_SHOWCOL))
746 {
747 bool parenFormat = context_getFlag (FLG_PARENFILEFORMAT);
748
749 if (parenFormat)
750 {
751 return (message ("%s(%d,%d)", fname, lineno, col));
752 }
753 else
754 {
755 return (message ("%s:%d:%d", fname, lineno, col));
756 }
757 }
758 else
759 {
760 return fileloc_unparseRaw (fname, lineno);
761 }
762}
763
764bool fileloc_isSpecialFile (fileloc f)
765{
766 if (fileloc_isDefined (f)
767 && fileId_isValid (f->fid))
768 {
769 return (fileTable_isSpecialFile (context_fileTable (), f->fid));
770 }
771 else
772 {
773 return FALSE;
774 }
775}
776
777bool fileloc_isHeader (fileloc f)
778{
779 /* returns true if is not a .c file */
780
781 return (fileloc_isDefined (f) && fileId_isValid (f->fid)
782 && fileId_isHeader (f->fid));
783}
784
785bool fileloc_isSpec (fileloc f)
786{
787 return (fileloc_isDefined (f) &&
788 (f->kind == FL_LIB || f->kind == FL_STDLIB || f->kind == FL_SPEC));
789}
790
791bool fileloc_isRealSpec (fileloc f)
792{
793 return (fileloc_isDefined (f) && (f->kind == FL_SPEC));
794}
795
616915dd 796bool fileloc_isLib (fileloc f)
797{
798 return (fileloc_isDefined (f)
799 && (f->kind == FL_LIB || f->kind == FL_STDHDR || f->kind == FL_STDLIB));
800}
801
802bool fileloc_isStandardLib (fileloc f)
803{
804 return (fileloc_isDefined (f) && f->kind == FL_STDLIB);
805}
806
807/*@only@*/ cstring fileloc_unparseDirect (fileloc fl)
808{
809 if (fileloc_isDefined (fl))
810 {
811 return (message ("%d:%d:%d",
812 /*@access fileId@*/ (int) fl->fid, /*@noaccess fileId@*/
813 fl->lineno, fl->column));
814 }
815 else
816 {
817 return (cstring_makeLiteral ("<undef>"));
818 }
819}
820
821bool fileloc_isUser (fileloc f)
822{
823 return (fileloc_isDefined (f)
824 && f->kind == FL_NORMAL);
825}
826
827
828
829
This page took 0.235165 seconds and 5 git commands to generate.