]> andersk Git - splint.git/blame - src/cttable.i
Changed library version constant.\a
[splint.git] / src / cttable.i
CommitLineData
885824d3 1/* ;-*-C-*-;
1b8ae690 2** Splint - annotation-assisted static program checker
3** Copyright (C) 1994-2002 University of Virginia,
4** Massachusetts Institute of Technology
885824d3 5**
1b8ae690 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.
885824d3 19**
155af98d 20** For information on splint: info@splint.org
21** To report a bug: splint-bug@splint.org
1b8ae690 22** For more information: http://www.splint.org
885824d3 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
38static void
39ctentry_free (/*@only@*/ ctentry c)
40{
41 ctbase_free (c->ctbase);
42 cstring_free (c->unparse);
43 sfree (c);
44}
45
46static 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 {
86d93ed3 56 /*drl bee: si*/ ctentry_free (cttab.entries[i]);
885824d3 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
885824d3 70static ctentry
71ctentry_makeNew (ctkind ctk, /*@only@*/ ctbase c)
72{
73
74 return (ctentry_make (ctk, c, ctype_dne, ctype_dne, ctype_dne, cstring_undefined));
75}
76
77static /*@only@*/ ctentry
78ctentry_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
93static cstring
94ctentry_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
104static bool
105ctentry_isInteresting (ctentry c)
106{
107 return (cstring_isNonEmpty (c->unparse));
108}
109
110static /*@only@*/ cstring
111ctentry_dump (ctentry c)
112{
a0a162cd 113 DPRINTF (("Dumping: %s", ctentry_unparse (c)));
114
885824d3 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
158static /*@only@*/ ctentry
86d93ed3 159ctentry_undump (/*@dependent@*/ char *s) /*@requires maxRead(s) >= 2 @*/
885824d3 160{
161 int base, ptr, array;
162 ctkind kind;
163 ctbase ct;
164
28bf4b0b 165 kind = ctkind_fromInt (reader_getInt (&s));
885824d3 166 ct = ctbase_undump (&s);
167
28bf4b0b 168 if (reader_optCheckChar (&s, '&'))
885824d3 169 {
170 base = ctype_dne;
171 ptr = ctype_dne;
172 array = ctype_dne;
173 }
28bf4b0b 174 else if (reader_optCheckChar (&s, '!'))
885824d3 175 {
176 base = ctype_undefined;
177 ptr = ctype_dne;
178 array = ctype_dne;
179 }
28bf4b0b 180 else if (reader_optCheckChar (&s, '^'))
885824d3 181 {
182 base = ctype_undefined;
28bf4b0b 183 ptr = reader_getInt (&s);
885824d3 184 array = ctype_dne;
185 }
186 else
187 {
28bf4b0b 188 base = reader_getInt (&s);
885824d3 189
28bf4b0b 190 if (reader_optCheckChar (&s, '&'))
885824d3 191 {
192 ptr = ctype_dne;
193 array = ctype_dne;
194 }
195 else
196 {
28bf4b0b 197 ptr = reader_getInt (&s);
198 array = reader_getInt (&s);
885824d3 199 }
200 }
201
202 /* can't unparse w/o typeTable */
203 return (ctentry_make (kind, ct, base, ptr, array, cstring_undefined));
204}
205
206static /*@observer@*/ cstring
207ctentry_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
230static /*@observer@*/ cstring
231ctentry_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
248static /*@only@*/ cstring
249cttable_unparse (void)
250{
251 int i;
252 cstring s = cstring_undefined;
253
254 /*@access ctbase@*/
255 for (i = 0; i < cttab.size; i++)
256 {
86d93ed3 257 /*drl bee: si*/ ctentry cte = cttab.entries[i];
885824d3 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
275void
276cttable_print (void)
277{
278 int i;
279
280 /*@access ctbase@*/
281 for (i = 0; i < cttab.size; i++)
282 {
86d93ed3 283 /*drl bee: si*/ ctentry cte = cttab.entries[i];
885824d3 284
28bf4b0b 285 if (TRUE) /* ctentry_isInteresting (cte)) */
885824d3 286 {
287 if (ctbase_isUA (cte->ctbase))
288 {
80489f0a 289 fprintf (g_warningstream, "%3d: %s [%d]\n", i,
885824d3 290 cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])),
291 cte->ctbase->contents.tid);
292 }
293 else
294 {
80489f0a 295 fprintf (g_warningstream, "%3d: %s\n", i,
885824d3 296 cstring_toCharsSafe (ctentry_doUnparse (cttab.entries[i])));
297 }
298 }
299 else
300 {
80489f0a 301 /* fprintf (g_warningstream, "%3d: <no name>\n", i); */
885824d3 302 }
303 }
304 /*@noaccess ctbase@*/
305}
306
307/*
308** cttable_dump
309**
310** Output cttable for dump file
311*/
312
313static void
314cttable_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 {
80489f0a 322 displayScanClose ();
ce7034f0 323 displayScanOpen (message ("Dumping type table (%d types)", cttab.size));
885824d3 324 showdotstride = cttab.size / 5;
325 showdots = TRUE;
326 }
327
328 for (i = 0; i < cttab.size; i++)
329 {
330 cstring s;
331
86d93ed3 332 /*drl bee: si*/ s = ctentry_dump (cttab.entries[i]);
28bf4b0b 333 DPRINTF (("[%d] = %s", i, ctentry_unparse (cttab.entries[i])));
885824d3 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 {
80489f0a 340 (void) fflush (g_warningstream);
ce7034f0 341 displayScanContinue (cstring_makeLiteralTemp ("."));
885824d3 342 (void) fflush (stderr);
343 }
344 }
345
346 if (showdots)
347 {
ce7034f0 348 displayScanClose ();
349 displayScanOpen (cstring_makeLiteral ("Continuing dump "));
885824d3 350 }
351
a0a162cd 352}
885824d3 353
354/*
355** load cttable from init file
356*/
357
358static 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
28bf4b0b 367 /*
368 DPRINTF (("Loading cttable: "));
369 cttable_print ();
370 */
371
372 while (reader_readLine (f, s, MAX_DUMP_LINE_LENGTH) != NULL && *s == ';')
885824d3 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
86d93ed3 386 /*drl bee: tcf*/ cte = ctentry_undump (s);
885824d3 387 ct = cttable_addFull (cte);
388
28bf4b0b 389 DPRINTF (("Type: %d: %s", ct, ctype_unparse (ct)));
390
885824d3 391 if (ctbase_isConj (cte->ctbase)
28bf4b0b 392 && !(ctbase_isExplicitConj (cte->ctbase)))
885824d3 393 {
394 ctype_recordConj (ct);
395 }
396
28bf4b0b 397 (void) reader_readLine (f, s, MAX_DUMP_LINE_LENGTH);
885824d3 398 }
399
400 sfree (s);
28bf4b0b 401
402 /*
403 DPRINTF (("Done loading cttable: "));
404 cttable_print ();
405 */
406}
885824d3 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@*/
418static 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
480static void
481cttable_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 {
86d93ed3 497 /*drl bee: dm*/ /*drl bee: si*/ newentries[i] = cttab.entries[i];
885824d3 498 }
499
500 /*@-compdestroy@*/
501 sfree (cttab.entries);
502 /*@=compdestroy@*/
503
504 cttab.entries = newentries;
505/*@-compdef@*/
506} /*@=compdef@*/
507
508static ctype
509cttable_addDerived (ctkind ctk, /*@keep@*/ ctbase cnew, ctype base)
510{
511 if (cttab.nspace == 0)
512 cttable_grow ();
513
86d93ed3 514 /*drl bee: si*/ cttab.entries[cttab.size] =
885824d3 515 ctentry_make (ctk, cnew, base, ctype_dne, ctype_dne, cstring_undefined);
516
517 cttab.nspace--;
518
519 return (cttab.size++);
520}
521
522static ctype
28bf4b0b 523cttable_addComplex (/*@only@*/ ctbase cnew)
885824d3 524 /*@modifies cttab; @*/
525{
28bf4b0b 526 /*@access ctbase@*/
885824d3 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
885824d3 541 ctb = ctype_getCtbase (i);
28bf4b0b 542
543 /*@i32 is this optimization really worthwhile??? */
885824d3 544
545 if (ctbase_isDefined (ctb) && ctbase_equivStrict (cnew, ctb))
546 {
a0a162cd 547 DPRINTF (("EQUIV!! %s / %s",
548 ctbase_unparse (cnew),
549 ctbase_unparse (ctb)));
28bf4b0b 550
885824d3 551 ctbase_free (cnew);
885824d3 552 return i;
553 }
554 }
555 }
556
557 if (cttab.nspace == 0)
558 cttable_grow ();
559
86d93ed3 560 /*drl bee: si*/ cttab.entries[cttab.size] = ctentry_make (CTK_COMPLEX, cnew, ctype_undefined,
885824d3 561 ctype_dne, ctype_dne,
562 cstring_undefined);
563 cttab.nspace--;
564
565 return (cttab.size++);
28bf4b0b 566 /*@noaccess ctbase@*/
885824d3 567}
568
569static ctype
570cttable_addFull (ctentry cnew)
571{
572 if (cttab.nspace == 0)
573 {
574 cttable_grow ();
575 }
576
86d93ed3 577 /*drl bee: si*/ cttab.entries[cttab.size] = cnew;
885824d3 578 cttab.nspace--;
579
580 return (cttab.size++);
581}
582
583static ctype
584cttable_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
86d93ed3 606 /*drl bee: si*/ cttab.entries[cttab.size] = cnew;
885824d3 607
608 cttab.nspace--;
609
610 return (cttab.size++);
611}
612
This page took 0.143061 seconds and 5 git commands to generate.