]> andersk Git - splint.git/blob - src/fileloc.c
*** empty log message ***
[splint.git] / src / fileloc.c
1 /*
2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 University of Virginia,
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
41 static /*@only@*/ fileloc fileloc_createPrim (flkind p_kind, fileId p_fid, int p_line, int p_col);
42
43 static flkind fileId_kind (fileId s)
44 {
45   cstring fname = rootFileName (s);
46   
47   if (fileLib_isLCLFile (fname))
48     {
49       return (FL_SPEC);
50     }
51   else if (cstring_equalPrefix (fname, cstring_makeLiteralTemp (SYSTEM_LIBDIR)))
52     {
53       return (FL_STDHDR); 
54     }
55   else
56     {
57       return (FL_NORMAL);
58     }
59 }  
60
61 fileloc
62 fileloc_decColumn (fileloc f, int x)
63 {
64   fileloc ret = fileloc_copy (f);
65
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
75 fileloc
76 fileloc_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
95 void
96 fileloc_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
105 fileloc 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
129 fileloc 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
151 fileloc 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
168 void
169 fileloc_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             {
181               sfree (f);  
182               /*@-branchstate@*/ 
183             } 
184         }
185       else
186         {
187           ; /* Don't free g_currentloc ever! */
188         }
189       /*@=branchstate@*/
190     }
191 }
192
193 void
194 fileloc_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
209 cstring fileloc_getBase (fileloc f)
210 {
211   llassert (fileloc_isDefined (f));
212
213   return (fileNameBase (f->fid));
214 }
215
216 bool
217 fileloc_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
225 int
226 fileloc_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
241
242   /* drl 8-11-01 fix what I think is a bug
243      lineno should more important than column number*/
244
245   INTCOMPARERETURN (f1->lineno, f2->lineno);   
246   INTCOMPARERETURN (f1->column, f2->column);
247   
248   return 0;
249 }
250
251 bool
252 fileloc_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
262 bool
263 fileloc_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
280 bool
281 fileloc_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
293 bool
294 fileloc_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
307 bool
308 fileloc_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
315 bool
316 fileloc_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
329 bool
330 fileloc_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
357 bool
358 fileloc_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
374 bool 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
386 bool fileloc_isXHFile (fileloc f1)
387 {
388   if (fileloc_isDefined (f1)
389       && !fileloc_isBuiltin (f1)
390       && !fileloc_isExternal (f1))
391     {
392       DPRINTF (("Fileloc is XH: [%p] %s", f1, fileloc_unparse (f1)));
393       return (fileTable_isXHFile (context_fileTable (), f1->fid));
394     }
395   
396   return FALSE;
397 }
398
399 bool
400 fileloc_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
433 fileloc_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
451 fileloc_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
461   if (cstring_equalPrefix (ln, cstring_makeLiteralTemp (SYSTEM_LIBDIR)))
462     {
463       fk = FL_STDLIB;
464     }
465
466   return (fileloc_createPrim (fk, fid, 0, 0));
467 }
468
469 fileloc 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
476 fileloc fileloc_createExternal (void)
477 {
478   /*@i@*/ return (fileloc_getExternal ()); 
479 }
480
481 fileloc 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
493 fileloc fileloc_observeBuiltin ()
494 {
495   /*@-onlytrans@*/ return (fileloc_getBuiltin ()); /*@=onlytrans@*/
496 }
497
498 fileloc 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
510 fileloc
511 fileloc_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
522 fileloc
523 fileloc_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
543 fileloc_createBuiltin ()
544 {
545   return (fileloc_createPrim (FL_BUILTIN, fileId_invalid, 0, 0)); 
546 }
547
548 # ifndef NOLCL
549 /*@only@*/ fileloc
550 fileloc_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
563 static /*@only@*/ fileloc
564 fileloc_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;
572
573   DPRINTF (("Fileloc create: [%p] %s", f, fileloc_unparse (f)));
574   return (f);
575 }
576
577 # ifndef NOLCL
578 /*@only@*/ fileloc
579 fileloc_createSpec (fileId fid, int line, int col)
580 {
581   return (fileloc_createPrim (FL_SPEC, fid, line, col));
582 }
583 # endif
584
585 fileloc fileloc_create (fileId fid, int line, int col)
586 {
587   return (fileloc_createPrim (fileId_kind (fid), fid, line, col));
588 }
589
590 /*@observer@*/ cstring
591 fileloc_filename (fileloc f)
592 {
593   return (fileloc_isDefined (f)
594           ? rootFileName (f->fid) : cstring_makeLiteralTemp ("<unknown>"));
595 }
596
597 cstring
598 fileloc_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
619 int
620 fileloc_lineno (fileloc f)
621 {
622   return (fileloc_isDefined (f) ? f->lineno : -1);
623 }
624
625 int
626 fileloc_column (fileloc f)
627 {
628   return (fileloc_isDefined (f) ? f->column : -1);
629 }
630
631 /*@only@*/ cstring
632 fileloc_unparse (fileloc f)
633 {
634   bool parenFormat = context_getFlag (FLG_PARENFILEFORMAT); 
635
636   if (fileloc_isDefined (f))
637     {
638        switch (f->kind)
639         {
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:
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           }
721         }
722     }
723
724   return (cstring_makeLiteral ("< Location unknown >"));
725 }
726
727 /*@only@*/ cstring
728 fileloc_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
743 fileloc_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
764 bool 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
777 bool 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
785 bool 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
791 bool fileloc_isRealSpec (fileloc f)
792 {
793   return (fileloc_isDefined (f) && (f->kind == FL_SPEC));
794 }
795
796 bool 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
802 bool 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
821 bool fileloc_isUser (fileloc f)
822 {
823   return (fileloc_isDefined (f) 
824           && f->kind == FL_NORMAL);
825 }
826
827
828
829
This page took 0.09846 seconds and 5 git commands to generate.