]> andersk Git - splint.git/blob - src/cttable.i
Fixed internal error that occured if user tried to load a lcd file they created for...
[splint.git] / src / cttable.i
1 /* ;-*-C-*-; 
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: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
23 */
24 /*
25 ** cttable.i
26 **
27 ** NOTE: This is not a stand-alone source file, but is included in ctype.c.
28 **       (This is necessary becuase there is no other way in C to have a
29 **       hidden scope, besides at the file level.)
30 */
31
32 /*@access ctype@*/
33            
34 /*
35 ** type definitions and forward declarations in ctbase.i
36 */
37
38 static void
39 ctentry_free (/*@only@*/ ctentry c)
40 {
41   ctbase_free (c->ctbase);
42   cstring_free (c->unparse);
43   sfree (c);
44 }
45
46 static void cttable_reset (void)
47    /*@globals cttab@*/
48    /*@modifies cttab@*/
49 {
50   if (cttab.entries != NULL) 
51     {
52       int i;  
53
54       for (i = 0; i < cttab.size; i++)
55         {
56           /*drl bee: si*/   ctentry_free (cttab.entries[i]);
57         }
58       
59       /*@-compdestroy@*/ 
60       sfree (cttab.entries);
61       /*@=compdestroy@*/
62
63       cttab.entries = NULL;
64     }
65
66   cttab.size = 0 ;
67   cttab.nspace = 0 ;
68 }
69
70 static ctentry
71 ctentry_makeNew (ctkind ctk, /*@only@*/ ctbase c)
72 {
73   
74   return (ctentry_make (ctk, c, ctype_dne, ctype_dne, ctype_dne, cstring_undefined));
75 }
76
77 static /*@only@*/ ctentry
78 ctentry_make (ctkind ctk,
79               /*@keep@*/ ctbase c, ctype base,
80               ctype ptr, ctype array,
81               /*@keep@*/ cstring unparse) /*@*/ 
82 {
83   ctentry cte = (ctentry) dmalloc (sizeof (*cte));
84   cte->kind = ctk;
85   cte->ctbase = c;
86   cte->base = base;
87   cte->ptr = ptr;
88   cte->array = array;
89   cte->unparse = unparse;
90   return cte;
91 }
92
93 static cstring
94 ctentry_unparse (ctentry c)
95 {
96   return (message 
97           ("%20s [%d] [%d] [%d]",
98            (cstring_isDefined (c->unparse) ? c->unparse : cstring_makeLiteral ("<no name>")),
99            c->base, 
100            c->ptr,
101            c->array));
102 }
103
104 static bool
105 ctentry_isInteresting (ctentry c)
106 {
107   return (cstring_isNonEmpty (c->unparse));
108 }
109
110 static /*@only@*/ cstring
111 ctentry_dump (ctentry c)
112 {
113   DPRINTF (("Dumping: %s", ctentry_unparse (c)));
114
115   if (c->ptr == ctype_dne
116       && c->array == ctype_dne
117       && c->base == ctype_dne)
118     {
119       return (message ("%d %q&", 
120                        ctkind_toInt (c->kind),
121                        ctbase_dump (c->ctbase)));
122     }
123   else if (c->base == ctype_undefined
124            && c->array == ctype_dne)
125     {
126       if (c->ptr == ctype_dne)
127         {
128           return (message ("%d %q!", 
129                            ctkind_toInt (c->kind),
130                            ctbase_dump (c->ctbase)));
131         }
132       else
133         {
134           return (message ("%d %q^%d", 
135                            ctkind_toInt (c->kind),
136                            ctbase_dump (c->ctbase),
137                            c->ptr));
138         }
139     }
140   else if (c->ptr == ctype_dne
141            && c->array == ctype_dne)
142     {
143       return (message ("%d %q%d&", 
144                        ctkind_toInt (c->kind),
145                        ctbase_dump (c->ctbase),
146                        c->base));
147     }
148   else
149     {
150       return (message ("%d %q%d %d %d", 
151                        ctkind_toInt (c->kind),
152                        ctbase_dump (c->ctbase),
153                        c->base, c->ptr, c->array));
154     }
155 }
156
157
158 static /*@only@*/ ctentry
159 ctentry_undump (/*@dependent@*/ char *s) /*@requires maxRead(s) >= 2 @*/
160 {
161   int base, ptr, array;
162   ctkind kind;
163   ctbase ct;
164
165   kind = ctkind_fromInt (reader_getInt (&s));
166   ct = ctbase_undump (&s);
167
168   if (reader_optCheckChar (&s, '&'))
169     {
170       base = ctype_dne;
171       ptr = ctype_dne;
172       array = ctype_dne;
173     }
174   else if (reader_optCheckChar (&s, '!'))
175     {
176       base = ctype_undefined;
177       ptr = ctype_dne;
178       array = ctype_dne;
179     }
180   else if (reader_optCheckChar (&s, '^'))
181     {
182       base = ctype_undefined;
183       ptr = reader_getInt (&s);
184       array = ctype_dne;
185     }
186   else
187     {
188       base = reader_getInt (&s);
189       
190       if (reader_optCheckChar (&s, '&'))
191         {
192           ptr = ctype_dne;
193           array = ctype_dne;
194         }
195       else
196         {
197           ptr = reader_getInt (&s);
198           array = reader_getInt (&s);
199         }
200     }
201
202   /* can't unparse w/o typeTable */
203   return (ctentry_make (kind, ct, base, ptr, array, cstring_undefined));
204 }
205
206 static /*@observer@*/ cstring
207 ctentry_doUnparse (ctentry c) /*@modifies c@*/
208 {
209   if (cstring_isDefined (c->unparse))
210     {
211       return (c->unparse);
212     }
213   else
214     {
215       cstring s = ctbase_unparse (c->ctbase);
216
217       if (!cstring_isEmpty (s) && !cstring_containsChar (s, '<'))
218         {
219           c->unparse = s;
220         }
221       else
222         {
223           cstring_markOwned (s);
224         }
225
226       return (s);
227     }
228 }
229
230 static /*@observer@*/ cstring
231 ctentry_doUnparseDeep (ctentry c)
232 {
233   if (cstring_isDefined (c->unparse))
234     {
235       return (c->unparse);
236     }
237   else
238     {
239       c->unparse = ctbase_unparseDeep (c->ctbase);
240       return (c->unparse);
241     }
242 }
243
244 /*
245 ** cttable operations
246 */
247
248 static /*@only@*/ cstring
249 cttable_unparse (void)
250 {
251   int i;
252   cstring s = cstring_undefined;
253
254   /*@access ctbase@*/
255   for (i = 0; i < cttab.size; i++)
256     {
257      /*drl bee: si*/    ctentry cte = cttab.entries[i];
258       if (ctentry_isInteresting (cte))
259         {
260           if (ctbase_isUA (cte->ctbase))
261             {
262               s = message ("%s%d\t%q [%d]\n", s, i, ctentry_unparse (cttab.entries[i]),
263                            cte->ctbase->contents.tid);
264             }
265           else
266             {
267               s = message ("%s%d\t%q\n", s, i, ctentry_unparse (cttab.entries[i]));
268             }
269         }
270     }
271   /*@noaccess ctbase@*/
272   return (s);
273 }
274
275 void
276 cttable_print (void)
277 {
278   int i;
279
280   /*@access ctbase@*/
281   for (i = 0; i < cttab.size; i++)
282     {
283    /*drl bee: si*/     ctentry cte = cttab.entries[i];
284
285       if (TRUE) /* ctentry_isInteresting (cte)) */
286         {
287           if (ctbase_isUA (cte->ctbase))
288             {
289               fprintf (g_warningstream, "%3d: %s [%d]\n", i, 
290                        cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])),
291                        cte->ctbase->contents.tid);
292             }
293           else
294             {
295               fprintf (g_warningstream, "%3d: %s\n", i, 
296                        cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])));
297             }
298         }
299       else
300         {
301           /* fprintf (g_warningstream, "%3d: <no name>\n", i); */
302         }
303     }
304   /*@noaccess ctbase@*/
305 }
306
307 /*
308 ** cttable_dump
309 **
310 ** Output cttable for dump file
311 */
312
313 static void
314 cttable_dump (FILE *fout)
315 {
316   bool showdots = FALSE;
317   int showdotstride = 0;
318   int i;
319   
320   if (context_getFlag (FLG_SHOWSCAN) && cttab.size > 5000)
321     {
322       displayScanClose ();
323       displayScanOpen (message ("Dumping type table (%d types)", cttab.size));
324       showdotstride = cttab.size / 5;
325       showdots = TRUE;
326     }
327
328   for (i = 0; i < cttab.size; i++)
329     {
330       cstring s;
331
332    /*drl bee: si*/     s = ctentry_dump (cttab.entries[i]);
333       DPRINTF (("[%d] = %s", i, ctentry_unparse (cttab.entries[i])));
334       llassert (cstring_length (s) < MAX_DUMP_LINE_LENGTH);
335       fputline (fout, cstring_toCharsSafe (s));
336       cstring_free (s);
337
338       if (showdots && (i != 0 && ((i - 1) % showdotstride == 0)))
339         {
340           (void) fflush (g_warningstream);
341           displayScanContinue (cstring_makeLiteralTemp ("."));
342           (void) fflush (stderr);
343         }
344     }
345
346   if (showdots)
347     {
348       displayScanClose ();
349       displayScanOpen (cstring_makeLiteral ("Continuing dump "));
350     }
351   
352 }
353
354 /*
355 ** load cttable from init file
356 */
357
358 static void cttable_load (FILE *f) 
359   /*@globals cttab @*/
360   /*@modifies cttab, f @*/
361 {
362   char *s = mstring_create (MAX_DUMP_LINE_LENGTH);
363   ctentry cte;
364
365   cttable_reset ();
366
367   /*
368   DPRINTF (("Loading cttable: "));
369   cttable_print ();
370   */
371
372   while (reader_readLine (f, s, MAX_DUMP_LINE_LENGTH) != NULL && *s == ';')
373     {
374       ;
375     }
376   
377   if (mstring_length (s) == (MAX_DUMP_LINE_LENGTH - 1))
378     {
379       llbug (message ("Library line too long: %s\n", cstring_fromChars (s)));
380     }
381   
382   while (s != NULL && *s != ';' && *s != '\0')
383     {
384       ctype ct;
385
386   /*drl bee: tcf*/      cte = ctentry_undump (s);
387       ct = cttable_addFull (cte);
388
389       DPRINTF (("Type: %d: %s", ct, ctype_unparse (ct)));
390
391       if (ctbase_isConj (cte->ctbase)
392           && !(ctbase_isExplicitConj (cte->ctbase)))
393         {
394           ctype_recordConj (ct);
395         }
396
397       (void) reader_readLine (f, s, MAX_DUMP_LINE_LENGTH);
398     }
399
400   sfree (s);
401
402   /*
403   DPRINTF (("Done loading cttable: "));
404   cttable_print ();
405   */
406 }
407
408 /*
409 ** cttable_init
410 **
411 ** fill up the cttable with basic types, and first order derivations.
412 ** this is done without using our constructors for efficiency reasons
413 ** (probably bogus)
414 **
415 */
416
417 /*@access cprim@*/
418 static void cttable_init (void) 
419    /*@globals cttab@*/ /*@modifies cttab@*/
420 {
421   ctkind i;
422   cprim  j;
423   ctbase ct = ctbase_undefined; 
424
425   llassert (cttab.size == 0);
426
427   /* do for plain, pointer, arrayof */
428   for (i = CTK_PLAIN; i <= CTK_ARRAY; i++)      
429     {
430       for (j = CTX_UNKNOWN; j <= CTX_LAST; j++)
431         {
432           if (i == CTK_PLAIN)
433             {
434               if (j == CTX_BOOL)
435                 {
436                   ct = ctbase_createBool (); /* why different? */
437                 }
438               else if (j == CTX_UNKNOWN)
439                 {
440                   ct = ctbase_createUnknown ();
441                 }
442               else
443                 {
444                   ct = ctbase_createPrim ((cprim)j);
445                 }
446
447               (void) cttable_addFull 
448                 (ctentry_make (CTK_PLAIN,
449                                ct, ctype_undefined, 
450                                j + CTK_PREDEFINED, j + CTK_PREDEFINED2,
451                                ctbase_unparse (ct)));
452             }
453           else
454             {
455               switch (i)
456                 {
457                 case CTK_PTR:
458                   ct = ctbase_makePointer (j);
459                   /*@switchbreak@*/ break;
460                 case CTK_ARRAY:
461                   ct = ctbase_makeArray (j);
462                   /*@switchbreak@*/ break;
463                 default:
464                   llbugexitlit ("cttable_init: base case");
465                 }
466               
467               (void) cttable_addDerived (i, ct, j);
468             }
469         }
470     }
471
472   /**** reserve a slot for userBool ****/
473   (void) cttable_addFull (ctentry_make (CTK_INVALID, ctbase_undefined, 
474                                         ctype_undefined, ctype_dne, ctype_dne, 
475                                         cstring_undefined));
476 }
477
478 /*@noaccess cprim@*/
479
480 static void
481 cttable_grow ()
482 {
483   int i;
484   o_ctentry *newentries ;
485
486   cttab.nspace = CTK_BASESIZE;
487   newentries = (ctentry *) dmalloc (sizeof (*newentries) * (cttab.size + cttab.nspace));
488
489   if (newentries == NULL)
490     {
491       llfatalerror (message ("cttable_grow: out of memory.  Size: %d", 
492                              cttab.size));
493     }
494
495   for (i = 0; i < cttab.size; i++)
496     {
497       /*drl bee: dm*/  /*drl bee: si*/  newentries[i] = cttab.entries[i];
498     }
499
500   /*@-compdestroy@*/
501   sfree (cttab.entries);
502   /*@=compdestroy@*/
503
504   cttab.entries = newentries;
505 /*@-compdef@*/
506 } /*@=compdef@*/
507
508 static ctype
509 cttable_addDerived (ctkind ctk, /*@keep@*/ ctbase cnew, ctype base)
510 {
511   if (cttab.nspace == 0)
512     cttable_grow ();
513   
514   /*drl bee: si*/  cttab.entries[cttab.size] = 
515     ctentry_make (ctk, cnew, base, ctype_dne, ctype_dne, cstring_undefined);
516
517   cttab.nspace--;
518   
519   return (cttab.size++);
520 }
521
522 static ctype
523 cttable_addComplex (/*@only@*/ ctbase cnew)
524    /*@modifies cttab; @*/
525 {
526   /*@access ctbase@*/
527   if (cnew->type != CT_FCN && cnew->type != CT_EXPFCN) 
528     {
529       ctype i;
530       int ctstop = cttable_lastIndex () - DEFAULT_OPTLEVEL;
531       
532       if (ctstop < LAST_PREDEFINED)
533         {
534           ctstop = LAST_PREDEFINED;
535         }
536
537       for (i = cttable_lastIndex (); i >= ctstop; i--)  /* better to go from back... */
538         {
539           ctbase ctb;
540           
541           ctb = ctype_getCtbase (i);
542           
543           /*@i32 is this optimization really worthwhile??? */
544
545           if (ctbase_isDefined (ctb) && ctbase_equivStrict (cnew, ctb))
546             {
547               DPRINTF (("EQUIV!! %s / %s",
548                         ctbase_unparse (cnew),
549                         ctbase_unparse (ctb)));
550
551               ctbase_free (cnew);
552               return i;
553             }
554         }
555     }
556   
557   if (cttab.nspace == 0)
558     cttable_grow ();
559   
560   /*drl bee: si*/  cttab.entries[cttab.size] = ctentry_make (CTK_COMPLEX, cnew, ctype_undefined, 
561                                             ctype_dne, ctype_dne,
562                                             cstring_undefined);
563   cttab.nspace--;
564   
565   return (cttab.size++);
566   /*@noaccess ctbase@*/
567 }
568
569 static ctype
570 cttable_addFull (ctentry cnew)
571 {
572   if (cttab.nspace == 0)
573     {
574       cttable_grow ();
575     }
576
577   /*drl bee: si*/  cttab.entries[cttab.size] = cnew;
578   cttab.nspace--;
579
580   return (cttab.size++);
581 }
582
583 static ctype
584 cttable_addFullSafe (/*@only@*/ ctentry cnew)
585 {
586   int i;
587   ctbase cnewbase = cnew->ctbase;
588
589   llassert (ctbase_isDefined (cnewbase));
590
591   for (i = cttable_lastIndex (); i >= CT_FIRST; i--)
592     {
593       ctbase ctb = ctype_getCtbase (i);
594
595       if (ctbase_isDefined (ctb) 
596           && ctbase_equiv (cnewbase, ctype_getCtbaseSafe (i)))
597         {
598           ctentry_free (cnew);
599           return i;
600         }
601     }
602
603   if (cttab.nspace == 0)
604     cttable_grow ();
605
606   /*drl bee: si*/  cttab.entries[cttab.size] = cnew;
607
608   cttab.nspace--;
609   
610   return (cttab.size++);
611 }
612
This page took 0.085777 seconds and 5 git commands to generate.