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