]> 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, 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   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
74 fileloc
75 fileloc_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
94 void
95 fileloc_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
104 fileloc 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
128 fileloc 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
150 fileloc 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
167 void
168 fileloc_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             {
180               sfree (f);  
181               /*@-branchstate@*/ 
182             } 
183         }
184       else
185         {
186           ; /* Don't free g_currentloc ever! */
187         }
188       /*@=branchstate@*/
189     }
190 }
191
192 void
193 fileloc_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
208 cstring fileloc_getBase (fileloc f)
209 {
210   llassert (fileloc_isDefined (f));
211
212   return (fileNameBase (f->fid));
213 }
214
215 bool
216 fileloc_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
224 int
225 fileloc_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
240
241   /* drl 8-11-01 fix what I think is a bug
242      lineno should more important than column number*/
243
244   INTCOMPARERETURN (f1->lineno, f2->lineno);   
245   INTCOMPARERETURN (f1->column, f2->column);
246   
247   return 0;
248 }
249
250 bool
251 fileloc_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
261 bool
262 fileloc_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
279 bool
280 fileloc_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
292 bool
293 fileloc_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
306 bool
307 fileloc_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
314 bool
315 fileloc_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
328 bool
329 fileloc_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
356 bool
357 fileloc_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
373 bool 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
385 bool fileloc_isXHFile (fileloc f1)
386 {
387   if (fileloc_isDefined (f1)
388       && !fileloc_isBuiltin (f1)
389       && !fileloc_isExternal (f1))
390     {
391       DPRINTF (("Fileloc is XH: [%p] %s", f1, fileloc_unparse (f1)));
392       return (fileTable_isXHFile (context_fileTable (), f1->fid));
393     }
394   
395   return FALSE;
396 }
397
398 bool
399 fileloc_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
432 fileloc_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
450 fileloc_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
468 fileloc 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
475 fileloc fileloc_createExternal (void)
476 {
477   /*@i@*/ return (fileloc_getExternal ()); 
478 }
479
480 fileloc 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
492 fileloc fileloc_observeBuiltin ()
493 {
494   /*@-onlytrans@*/ return (fileloc_getBuiltin ()); /*@=onlytrans@*/
495 }
496
497 fileloc 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
509 fileloc
510 fileloc_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
521 fileloc
522 fileloc_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
542 fileloc_createBuiltin ()
543 {
544   return (fileloc_createPrim (FL_BUILTIN, fileId_invalid, 0, 0)); 
545 }
546
547 # ifndef NOLCL
548 /*@only@*/ fileloc
549 fileloc_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
562 static /*@only@*/ fileloc
563 fileloc_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;
571
572   DPRINTF (("Fileloc create: [%p] %s", f, fileloc_unparse (f)));
573   return (f);
574 }
575
576 # ifndef NOLCL
577 /*@only@*/ fileloc
578 fileloc_createSpec (fileId fid, int line, int col)
579 {
580   return (fileloc_createPrim (FL_SPEC, fid, line, col));
581 }
582 # endif
583
584 fileloc fileloc_create (fileId fid, int line, int col)
585 {
586   return (fileloc_createPrim (fileId_kind (fid), fid, line, col));
587 }
588
589 /*@observer@*/ cstring
590 fileloc_filename (fileloc f)
591 {
592   return (fileloc_isDefined (f)
593           ? rootFileName (f->fid) : cstring_makeLiteralTemp ("<unknown>"));
594 }
595
596 cstring
597 fileloc_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
618 int
619 fileloc_lineno (fileloc f)
620 {
621   return (fileloc_isDefined (f) ? f->lineno : -1);
622 }
623
624 int
625 fileloc_column (fileloc f)
626 {
627   return (fileloc_isDefined (f) ? f->column : -1);
628 }
629
630 /*@only@*/ cstring
631 fileloc_unparse (fileloc f)
632 {
633   bool parenFormat = context_getFlag (FLG_PARENFILEFORMAT); 
634
635   if (fileloc_isDefined (f))
636     {
637        switch (f->kind)
638         {
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:
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           }
720         }
721     }
722
723   return (cstring_makeLiteral ("< Location unknown >"));
724 }
725
726 /*@only@*/ cstring
727 fileloc_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
742 fileloc_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
763 bool 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
776 bool 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
784 bool 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
790 bool fileloc_isRealSpec (fileloc f)
791 {
792   return (fileloc_isDefined (f) && (f->kind == FL_SPEC));
793 }
794
795 bool 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
801 bool 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
820 bool fileloc_isUser (fileloc f)
821 {
822   return (fileloc_isDefined (f) 
823           && f->kind == FL_NORMAL);
824 }
825
826
827
828
This page took 0.137035 seconds and 5 git commands to generate.