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