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