]> andersk Git - splint.git/blob - src/fileloc.c
Merged with Dave Evans's changes.
[splint.git] / src / fileloc.c
1 /*
2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2000 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 (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                 }
187       /*@=branchstate@*/
188     }
189 }
190
191 void
192 fileloc_reallyFree (/*@only@*/ fileloc f)
193 {
194   if (fileloc_isDefined (f))
195     {
196       if (fileloc_isBuiltin (f) || fileloc_isExternal (f))
197         {
198           ; /* don't free */
199         }
200       else
201         {
202           sfree (f);  
203         /*@-branchstate@*/ } /*@=branchstate@*/
204     }
205 }
206
207 cstring fileloc_getBase (fileloc f)
208 {
209   llassert (fileloc_isDefined (f));
210
211   return (fileNameBase (f->fid));
212 }
213
214 bool
215 fileloc_equal (fileloc f1, fileloc f2)
216 {
217   return ((f1 == f2)
218           || (fileloc_isDefined (f1) && fileloc_isDefined (f2) 
219               && ((f1->column == f2->column) && 
220                   (f1->lineno == f2->lineno) && fileloc_sameFile (f1, f2))));
221 }
222
223 int
224 fileloc_compare (fileloc f1, fileloc f2)
225 {
226   if (fileloc_isUndefined (f1))
227     {
228       if (fileloc_isUndefined (f2)) return 0;
229       return -1;
230     }
231   
232   if (fileloc_isUndefined (f2))
233     return 1;
234
235   /*@access fileId@*/ 
236   INTCOMPARERETURN (f1->fid, f2->fid); 
237   /*@noaccess fileId@*/
238
239   INTCOMPARERETURN (f1->column, f2->column);
240   INTCOMPARERETURN (f1->lineno, f2->lineno); 
241
242   return 0;
243 }
244
245 bool
246 fileloc_withinLines (fileloc f1, fileloc f2, int n)
247 {
248   
249   return (fileloc_isDefined (f1) && 
250           fileloc_isDefined (f2) &&
251           ((f2->lineno <= f1->lineno + n) 
252            && (f2->lineno >= f1->lineno)
253            && fileloc_sameFile (f1, f2)));
254 }
255
256 bool
257 fileloc_lessthan (fileloc f1, fileloc f2)
258 {
259   /*@access fileId*/
260   return ((fileloc_isDefined (f1) && fileloc_isDefined (f2))
261           && ((f1->fid < f2->fid)
262               || ((f1->fid == f2->fid)
263                   && ((f1->lineno < f2->lineno)
264                       || ((f1->lineno == f2->lineno)
265                           && (f1->column < f2->column))))));
266   /*@noaccess fileId*/
267 }
268
269 /*
270 ** returns true if f1 and f2 are different files,
271 ** or f1 is before f2 in same file
272 */
273
274 bool
275 fileloc_notAfter (fileloc f1, fileloc f2)
276 {
277   /*@access fileId*/
278   return ((fileloc_isDefined (f1) && fileloc_isDefined (f2))
279           && ((f1->fid != f2->fid)
280               || ((f1->lineno < f2->lineno)
281                   || ((f1->lineno == f2->lineno)
282                       && (f1->column <= f2->column)))));
283   /*@noaccess fileId@*/
284 }
285
286 # ifndef NOLCL
287 bool
288 fileloc_isStandardLibrary (fileloc f)
289 {
290   cstring s = fileloc_getBase (f);
291
292   return (cstring_equalLit (s, LLSTDLIBS_NAME)
293           || cstring_equalLit (s, LLSTRICTLIBS_NAME)
294           || cstring_equalLit (s, LLUNIXLIBS_NAME)
295           || cstring_equalLit (s, LLUNIXSTRICTLIBS_NAME)
296           || cstring_equalLit (s, LLPOSIXSTRICTLIBS_NAME)
297           || cstring_equalLit (s, LLPOSIXLIBS_NAME));
298 }
299 # endif
300
301 bool
302 fileloc_sameFile (fileloc f1, fileloc f2)
303 {
304   if ((fileloc_isUndefined (f1) || (fileloc_isUndefined (f2)) 
305        || (fileloc_isLib (f1)) || (fileloc_isLib (f2))))
306     {
307       return FALSE;
308     }
309   else
310     {
311       return (fileId_equal (f1->fid, f2->fid));
312     }
313 }
314
315 bool
316 fileloc_sameModule (fileloc f1, fileloc f2)
317 {
318   if (fileloc_isUndefined (f1))
319     {
320       return (fileloc_isUndefined (f2));
321     }
322   else if (fileloc_isUndefined (f2))
323     {
324       return (FALSE);
325     }
326   else
327     {
328       if (fileloc_isBuiltin (f1) || fileloc_isBuiltin (f2)
329           || fileloc_isExternal (f1) || fileloc_isExternal (f2))
330         {
331           return fileloc_sameFile (f1, f2);
332         }
333       else
334         {
335           cstring s1 = fileloc_getBase (f1);
336           cstring s2 = fileloc_getBase (f2);
337           
338           return (cstring_equal (s1, s2));
339         }
340     }
341 }
342
343 bool
344 fileloc_sameBaseFile (fileloc f1, fileloc f2)
345 {
346   if (fileloc_isUndefined (f1))
347     {
348       return (fileloc_isUndefined (f2));
349     }
350   else if (fileloc_isUndefined (f2))
351     {
352       return (FALSE);
353     }
354   else
355     {
356       return (fileId_baseEqual (f1->fid, f2->fid));
357     }
358 }
359
360 bool fileloc_isSystemFile (fileloc f1)
361 {
362   if (fileloc_isDefined (f1)
363       && !fileloc_isBuiltin (f1)
364       && !fileloc_isExternal (f1))
365     {
366       return (fileTable_isSystemFile (context_fileTable (), f1->fid));
367     }
368
369   return FALSE;
370 }
371
372 bool
373 fileloc_almostSameFile (fileloc f1, fileloc f2)
374 {
375   if ((fileloc_isUndefined (f1) || (fileloc_isUndefined (f2)) 
376        || (fileloc_isLib (f1)) || (fileloc_isLib (f2))))
377     {
378       return FALSE;
379     }
380   else
381     {
382       if (fileId_baseEqual (f1->fid, f2->fid))
383         {
384           return TRUE;
385         }
386       else if (fileTable_isSystemFile (context_fileTable (), f1->fid)
387                || fileTable_isSystemFile (context_fileTable (), f2->fid))
388         {
389           return TRUE;
390         }
391       else if (fileTable_isSpecialFile (context_fileTable (), f1->fid)
392                || fileTable_isSpecialFile (context_fileTable (), f2->fid))
393         {
394           return (cstring_equal (fileloc_getBase (f1), 
395                                  fileloc_getBase (f2)));
396         }
397       else 
398         {
399           return FALSE;
400         }
401     }
402 }
403
404 # ifndef NOLCL
405 /*@only@*/ fileloc
406 fileloc_fromTok (ltoken t) 
407 {
408   cstring fname = ltoken_fileName (t);
409   fileId fid = fileTable_lookup (context_fileTable (), fname);
410   fileloc fl;
411
412   if (!fileId_isValid (fid))
413     {
414       fid = fileTable_addLCLFile (context_fileTable (), fname);
415     }
416   
417   fl = fileloc_create (fid, (int) ltoken_getLine (t), (int) ltoken_getCol (t));
418   
419   return (fl);
420 }
421 # endif
422
423 /*@only@*/ fileloc
424 fileloc_createLib (cstring ln)
425 {
426   flkind fk = FL_LIB;
427   fileId fid = fileTable_lookup (context_fileTable (), ln);
428
429   if (!fileId_isValid (fid))
430     {
431       fid = fileTable_addLibraryFile (context_fileTable (), ln);
432     }
433
434   if (cstring_equalPrefix (ln, SYSTEM_LIBDIR))
435     {
436       fk = FL_STDLIB;
437     }
438
439   return (fileloc_createPrim (fk, fid, 0, 0));
440 }
441
442 fileloc fileloc_createRc (cstring name)
443 {
444   fileId fid = fileTable_addFile (context_fileTable (), name);
445
446   return (fileloc_createPrim (FL_RC, fid, 0, 0));
447 }
448
449 fileloc fileloc_createExternal (void)
450 {
451   /*@i@*/ return (fileloc_getExternal ()); 
452 }
453
454 fileloc fileloc_getExternal (void)
455 {
456   static /*@owned@*/ fileloc res = fileloc_undefined;
457
458   if (res == fileloc_undefined) 
459     {
460       res = fileloc_createPrim (FL_EXTERNAL, fileId_invalid, 0, 0);
461     }
462
463   return res;
464 }
465
466 fileloc fileloc_observeBuiltin ()
467 {
468   /*@-onlytrans@*/ return (fileloc_getBuiltin ()); /*@=onlytrans@*/
469 }
470
471 fileloc fileloc_getBuiltin ()
472 {
473   static /*@owned@*/ fileloc res = fileloc_undefined;
474
475   if (res == fileloc_undefined)
476     {
477       res = fileloc_createPrim (FL_BUILTIN, fileId_invalid, 0, 0); 
478     }
479
480   return res;
481 }
482
483 fileloc
484 fileloc_makePreproc (fileloc loc)
485 {
486   if (fileloc_isDefined (loc))
487     {
488       return (fileloc_createPrim (FL_PREPROC, loc->fid, 
489                                   loc->lineno, loc->column));
490     }
491
492   return (fileloc_createPrim (FL_PREPROC, fileId_invalid, 0, 0));
493 }
494
495 fileloc
496 fileloc_makePreprocPrevious (fileloc loc)
497 {
498   if (fileloc_isDefined (loc))
499     {
500       if (loc->lineno > 1)
501         {
502           return (fileloc_createPrim (FL_PREPROC, loc->fid,
503                                       loc->lineno - 1, 0));
504         }
505       else
506         {
507           return (fileloc_createPrim (FL_PREPROC, loc->fid,
508                                       loc->lineno, 0));
509         }
510     }
511
512   return (fileloc_createPrim (FL_PREPROC, fileId_invalid, 0, 0));
513 }
514
515 /*@only@*/ fileloc
516 fileloc_createBuiltin ()
517 {
518   return (fileloc_createPrim (FL_BUILTIN, fileId_invalid, 0, 0)); 
519 }
520
521 # ifndef NOLCL
522 /*@only@*/ fileloc
523 fileloc_createImport (cstring fname, int lineno)
524 {
525   fileId fid = fileTable_lookup (context_fileTable (), fname);
526
527   if (!fileId_isValid (fid))
528     {
529       fid = fileTable_addImportFile (context_fileTable (), fname);
530     }
531
532   return (fileloc_createPrim (FL_IMPORT, fid, lineno, 0));
533 }
534 # endif
535
536 static /*@only@*/ fileloc
537 fileloc_createPrim (flkind kind, fileId fid, int line, int col)
538 {
539   fileloc f = (fileloc) dmalloc (sizeof (*f));
540   
541   f->kind   = kind;
542   f->fid    = fid; 
543   f->lineno = line;
544   f->column = col;
545   
546   return (f);
547 }
548
549 # ifndef NOLCL
550 /*@only@*/ fileloc
551 fileloc_createSpec (fileId fid, int line, int col)
552 {
553   return (fileloc_createPrim (FL_SPEC, fid, line, col));
554 }
555 # endif
556
557 fileloc fileloc_create (fileId fid, int line, int col)
558 {
559   return (fileloc_createPrim (fileId_kind (fid), fid, line, col));
560 }
561
562 /*@observer@*/ cstring
563 fileloc_filename (fileloc f)
564 {
565   return (fileloc_isDefined (f)
566           ? rootFileName (f->fid) : cstring_makeLiteralTemp ("<unknown>"));
567 }
568
569 cstring
570 fileloc_unparseFilename (fileloc f)
571 {
572   if (fileloc_isDefined (f))
573     {
574       switch (f->kind)
575         {
576         case FL_LIB:
577           return (message ("load file %s", fileloc_filename (f)));
578         case FL_BUILTIN:
579           return (cstring_makeLiteral ("# builtin #"));
580         case FL_IMPORT:
581           return (message ("import file %s", fileloc_filename (f)));
582         case FL_EXTERNAL:
583           return (cstring_makeLiteral ("<external>"));
584         default: 
585           return (cstring_copy (fileloc_filename (f)));
586         }
587     }
588   return cstring_undefined;
589 }
590
591 int
592 fileloc_lineno (fileloc f)
593 {
594   return (fileloc_isDefined (f) ? f->lineno : -1);
595 }
596
597 int
598 fileloc_column (fileloc f)
599 {
600   return (fileloc_isDefined (f) ? f->column : -1);
601 }
602
603 /*@only@*/ cstring
604 fileloc_unparse (fileloc f)
605 {
606   bool parenFormat = context_getFlag (FLG_PARENFILEFORMAT); 
607
608   if (fileloc_isDefined (f))
609     {
610       switch (f->kind)
611         {
612         case FL_LIB:
613           return (message ("load file %s", rootFileName (f->fid)));
614         case FL_BUILTIN:
615           return (cstring_makeLiteral ("Command Line"));
616         case FL_IMPORT:
617           if (parenFormat)
618             {
619               return (message ("import file %s(%d)", rootFileName (f->fid), f->lineno));
620             }
621           else
622             {
623               return (message ("import file %s:%d", rootFileName (f->fid), f->lineno));
624             }
625         case FL_PREPROC:
626           if (parenFormat)
627             {
628               return (message ("%s(%d)", rootFileName (f->fid), f->lineno));
629             }
630           else
631             {
632               return (message ("%s:%d", rootFileName (f->fid), f->lineno));
633             }
634         case FL_EXTERNAL:
635           return (cstring_makeLiteral ("<external>"));
636         default:
637           if (context_getFlag (FLG_SHOWCOL))
638             {
639               if (fileloc_linenoDefined (f))
640                 {
641                   if (fileloc_columnDefined (f))
642                     {
643                       if (parenFormat)
644                         {
645                           return (message ("%s(%d,%d)", 
646                                            rootFileName (f->fid),
647                                            f->lineno, f->column));
648                         }
649                       else
650                         {
651                           return (message ("%s:%d:%d", 
652                                            rootFileName (f->fid),
653                                            f->lineno, f->column));
654                         }
655                     }
656                   else
657                     {
658                       if (parenFormat)
659                         {
660                           return (message ("%s(%d)", rootFileName (f->fid), f->lineno));
661                         }
662                       else
663                         {
664                           return (message ("%s:%d", rootFileName (f->fid), f->lineno));
665                         }
666                     }
667                 }
668               return (cstring_copy (rootFileName (f->fid)));
669             }
670           else if (fileloc_linenoDefined (f))
671             {
672               if (parenFormat)
673                 {
674                   return (message ("%s(%d)",
675                                    rootFileName (f->fid), f->lineno));
676                 }
677               else
678                 {
679                   return (message ("%s:%d", rootFileName (f->fid), f->lineno));
680                 }
681             }
682           else
683             {
684               return (cstring_copy (rootFileName (f->fid)));
685             }
686         }
687     }
688   return (cstring_makeLiteral ("< Location unknown >"));
689 }
690
691 /*@only@*/ cstring
692 fileloc_unparseRaw (cstring fname, int lineno)
693 {
694   bool parenFormat = context_getFlag (FLG_PARENFILEFORMAT); 
695
696   if (parenFormat)
697     {
698       return (message ("%s(%d)", fname, lineno));
699     }
700   else
701     {
702       return (message ("%s:%d", fname, lineno));
703     }
704 }
705
706 /*@only@*/ cstring
707 fileloc_unparseRawCol (cstring fname, int lineno, int col)
708 {
709   if (context_getFlag (FLG_SHOWCOL)) 
710     {
711       bool parenFormat = context_getFlag (FLG_PARENFILEFORMAT); 
712       
713       if (parenFormat)
714         {
715           return (message ("%s(%d,%d)", fname, lineno, col));
716         }
717       else
718         {
719           return (message ("%s:%d:%d", fname, lineno, col));
720         }
721     }
722   else
723     {
724       return fileloc_unparseRaw (fname, lineno);
725     }
726 }
727
728 bool fileloc_isSpecialFile (fileloc f)
729 {
730   if (fileloc_isDefined (f) 
731       && fileId_isValid (f->fid))
732     {
733       return (fileTable_isSpecialFile (context_fileTable (), f->fid));
734     }
735   else
736     {
737       return FALSE;
738     }
739 }
740
741 bool fileloc_isHeader (fileloc f)
742 {
743   /* returns true if is not a .c file */
744
745   return (fileloc_isDefined (f) && fileId_isValid (f->fid)
746           && fileId_isHeader (f->fid));
747 }
748
749 bool fileloc_isSpec (fileloc f)
750 {
751   return (fileloc_isDefined (f) && 
752           (f->kind == FL_LIB || f->kind == FL_STDLIB || f->kind == FL_SPEC));
753 }
754
755 bool fileloc_isRealSpec (fileloc f)
756 {
757   return (fileloc_isDefined (f) && (f->kind == FL_SPEC));
758 }
759
760 bool fileloc_isRealLib (fileloc f)
761 {
762   return (fileloc_isDefined (f) && f->kind == FL_LIB);
763 }
764
765 bool fileloc_isLib (fileloc f)
766 {
767   return (fileloc_isDefined (f) 
768           && (f->kind == FL_LIB || f->kind == FL_STDHDR || f->kind == FL_STDLIB));
769 }
770
771 bool fileloc_isStandardLib (fileloc f)
772 {
773   return (fileloc_isDefined (f) && f->kind == FL_STDLIB);
774 }
775
776 /*@only@*/ cstring fileloc_unparseDirect (fileloc fl)
777 {
778   if (fileloc_isDefined (fl))
779     {
780       return (message ("%d:%d:%d",
781                        /*@access fileId@*/ (int) fl->fid, /*@noaccess fileId@*/
782                        fl->lineno, fl->column));
783     }
784   else
785     {
786       return (cstring_makeLiteral ("<undef>"));
787     }
788 }
789
790 bool fileloc_isUser (fileloc f)
791 {
792   return (fileloc_isDefined (f) 
793           && f->kind == FL_NORMAL);
794 }
795
796
797
798
This page took 0.106644 seconds and 5 git commands to generate.