]> andersk Git - splint.git/blame - src/constraintTerm.c
*** empty log message ***
[splint.git] / src / constraintTerm.c
CommitLineData
616915dd 1/*
2** constraintExpr.c
3*/
4
5//#define DEBUGPRINT 1
6
7# include <ctype.h> /* for isdigit */
8# include "lclintMacros.nf"
9# include "basic.h"
10# include "cgrammar.h"
11# include "cgrammar_tokens.h"
12
13# include "exprChecks.h"
616915dd 14# include "exprNodeSList.h"
15
616915dd 16/*@-czechfcns@*/
17
18//#include "constraintExpr.h"
19
28bf4b0b 20/*@access exprNode @*/
a8e557d3 21
f0171cff 22bool constraintTerm_isDefined (constraintTerm t)
990ec868 23{
24 return t != NULL;
25}
26
d46ce6a4 27void constraintTerm_free (/*@only@*/ constraintTerm term)
28{
990ec868 29 llassert (constraintTerm_isDefined (term));
30
d46ce6a4 31 fileloc_free (term->loc);
32
33 switch (term->kind)
34 {
35 case EXPRNODE:
36 /* we don't free an exprNode*/
37 break;
38 case SREF:
39 /* sref */
795e7f34 40 sRef_free (term->value.sref);
d46ce6a4 41 break;
42 case INTLITERAL:
43 /* don't free an int */
44 break;
45 case ERRORBADCONSTRAINTTERMTYPE:
46 default:
47 /* type was set incorrectly */
48 llcontbug (message("constraintTerm_free type was set incorrectly"));
49 }
795e7f34 50 // term->value.intlit = 0;
51 term->kind = ERRORBADCONSTRAINTTERMTYPE;
d46ce6a4 52 free (term);
53}
616915dd 54
4ab867d6 55/*@only@*/ static/*@out@*/ constraintTerm new_constraintTermExpr (void)
616915dd 56{
57 constraintTerm ret;
58 ret = dmalloc (sizeof (* ret ) );
bb25bea6 59 ret->value.intlit = 0;
616915dd 60 return ret;
61}
62
63
64bool constraintTerm_isIntLiteral (constraintTerm term)
65{
dc92450f 66 llassert(term != NULL);
616915dd 67
68 if (term->kind == INTLITERAL)
69 return TRUE;
70
71 return FALSE;
72}
73
d30bc0c7 74
75bool constraintTerm_isInitBlock (/*@observer@*/ /*@temp@*/ constraintTerm c) /*@*/
76{
77 llassert (c != NULL);
78 if (c->kind == EXPRNODE)
79 {
80
81 if (exprNode_isInitBlock(c->value.expr) )
82 {
83 return TRUE;
84 }
85 }
86 return FALSE;
87}
88
89
a779b61e 90bool constraintTerm_isExprNode (/*@observer@*/ /*@temp@*/ constraintTerm c) /*@*/
91{
92 llassert (c != NULL);
93 if (c->kind == EXPRNODE)
94 {
95 return TRUE;
96 }
97 return FALSE;
98}
99
100
d30bc0c7 101int constraintTerm_getInitBlockLength (/*@observer@*/ /*@temp@*/ constraintTerm c) /*@*/
102{
103
104 exprNodeList list;
105 int ret;
106 llassert (c != NULL);
107 llassert (constraintTerm_isInitBlock (c) );
108 llassert (c->kind == EXPRNODE);
109
110 llassert(exprNode_isDefined(c->value.expr) );
111
112 if (exprNode_isUndefined(c->value.expr) )
113 {
114 return 1;
115 }
116
117 if (c->value.expr->edata == exprData_undefined)
118 {
119 return 1;
120 }
121 list = exprData_getArgs(c->value.expr->edata);
122
123 ret = exprNodeList_size(list);
124
125 return ret;
126}
127
128
129
dc92450f 130bool constraintTerm_isStringLiteral (constraintTerm c) /*@*/
616915dd 131{
dc92450f 132 llassert (c != NULL);
616915dd 133 if (c->kind == EXPRNODE)
134 {
135 if (exprNode_knownStringValue(c->value.expr) )
136 {
137 return TRUE;
138 }
139 }
140 return FALSE;
141}
142
d30bc0c7 143
144
616915dd 145cstring constraintTerm_getStringLiteral (constraintTerm c)
146{
dc92450f 147 llassert (c != NULL);
616915dd 148 llassert (constraintTerm_isStringLiteral (c) );
149 llassert (c->kind == EXPRNODE);
150
dc92450f 151 return (cstring_copy ( multiVal_forceString (exprNode_getValue (c->value.expr) ) ) );
616915dd 152}
153
4ab867d6 154constraintTerm constraintTerm_simplify (/*@returned@*/ constraintTerm term) /*@modifies term@*/
616915dd 155{
156 if (term->kind == EXPRNODE)
157 {
158 if ( exprNode_knownIntValue (term->value.expr ) )
159 {
160 long int temp;
28bf4b0b 161
616915dd 162 temp = exprNode_getLongValue (term->value.expr);
dc92450f 163 term->value.intlit = (int)temp;
616915dd 164 term->kind = INTLITERAL;
165 }
166 }
167 return term;
168}
169
170fileloc constraintTerm_getFileloc (constraintTerm t)
171{
990ec868 172 llassert (constraintTerm_isDefined (t));
616915dd 173 return (fileloc_copy (t->loc) );
174}
175
a8e557d3 176constraintTermType constraintTerm_getKind (constraintTerm t)
177{
178 llassert (constraintTerm_isDefined(t) );
179
180 return (t->kind);
181}
182
183/*@exposed@*/ sRef constraintTerm_getSRef (constraintTerm t)
184{
185 llassert (constraintTerm_isDefined(t) );
186 llassert (t->kind == SREF);
187
188 return (t->value.sref);
189}
190
03d670b6 191/*@only@*/ constraintTerm constraintTerm_makeExprNode (/*@dependent@*/ exprNode e)
616915dd 192{
193 constraintTerm ret = new_constraintTermExpr();
d46ce6a4 194 ret->loc = fileloc_copy(exprNode_getfileloc(e));
616915dd 195 ret->value.expr = e;
196 ret->kind = EXPRNODE;
197 ret = constraintTerm_simplify(ret);
198 return ret;
199}
200
28bf4b0b 201/*@only@*/ constraintTerm constraintTerm_makesRef (/*@temp@*/ /*@observer@*/ sRef s)
616915dd 202{
203 constraintTerm ret = new_constraintTermExpr();
204 ret->loc = fileloc_undefined;
4ab867d6 205 ret->value.sref = sRef_saveCopy(s);
616915dd 206 ret->kind = SREF;
207 ret = constraintTerm_simplify(ret);
208 return ret;
209}
210
795e7f34 211
212
616915dd 213constraintTerm constraintTerm_copy (constraintTerm term)
214{
215 constraintTerm ret;
216 ret = new_constraintTermExpr();
217 ret->loc = fileloc_copy (term->loc);
795e7f34 218
219 switch (term->kind)
220 {
221 case EXPRNODE:
222 ret->value.expr = term->value.expr;
223 break;
224 case INTLITERAL:
225 ret->value.intlit = term->value.intlit;
226 break;
227
228 case SREF:
229 ret->value.sref = sRef_saveCopy(term->value.sref);
230 break;
231 default:
232 BADEXIT;
233 }
616915dd 234 ret->kind = term->kind;
235 return ret;
236}
237
d46ce6a4 238constraintTerm constraintTerm_setFileloc (/*@returned@*/ constraintTerm term, fileloc loc)
616915dd 239{
dc92450f 240 llassert(term != NULL);
d46ce6a4 241
28bf4b0b 242 if ( fileloc_isDefined( term->loc ) )
d46ce6a4 243 fileloc_free(term->loc);
244
616915dd 245 term->loc = fileloc_copy(loc);
246 return term;
247}
248
249
d46ce6a4 250static cstring constraintTerm_getName (constraintTerm term)
616915dd 251{
252 cstring s;
253 s = cstring_undefined;
254
255 llassert (term != NULL);
256
257 switch (term->kind)
258 {
259 case EXPRNODE:
260 /*@i334*/ //wtf
261 s = message ("%s", exprNode_unparse (term->value.expr) );
262 break;
263 case INTLITERAL:
a1fa5e0c 264 s = message (" %d ", (int) term->value.intlit);
616915dd 265 break;
266
267 case SREF:
d46ce6a4 268 s = message ("%q", sRef_unparse (term->value.sref) );
616915dd 269
270 break;
c3e695ff 271 default:
272 BADEXIT;
273 /*@notreached@*/
616915dd 274 break;
275 }
616915dd 276
c3e695ff 277 return s;
616915dd 278}
279
280constraintTerm
d46ce6a4 281constraintTerm_doSRefFixBaseParam (/*@returned@*/constraintTerm term, exprNodeList arglist) /*@modifies term@*/
616915dd 282{
283 llassert (term != NULL);
284
285 switch (term->kind)
286 {
287 case EXPRNODE:
288 /*@i334*/ //wtf
289 // s = message ("%s @ %s ", exprNode_unparse (term->value.expr),
290 // fileloc_unparse (term->loc) );
291 break;
292 case INTLITERAL:
293 // s = message (" %d ", term->value.intlit);
294 break;
295
296 case SREF:
297 term->value.sref = sRef_fixBaseParam (term->value.sref, arglist);
298 // s = message ("%s ", sRef_unparse (term->value.sref) );
299
300 break;
c3e695ff 301 default:
302 BADEXIT;
616915dd 303 }
304 return term;
305
306}
307
616915dd 308cstring constraintTerm_print (constraintTerm term) /*@*/
309{
310 cstring s;
311 s = cstring_undefined;
312
313 llassert (term != NULL);
314
315 switch (term->kind)
316 {
317 case EXPRNODE:
318 /*@i334*/ //wtf
a779b61e 319 s = message ("%s @ %q", exprNode_unparse (term->value.expr),
616915dd 320 fileloc_unparse (term->loc) );
321 break;
322 case INTLITERAL:
a779b61e 323 s = message ("%d", (int)term->value.intlit);
616915dd 324 break;
325
326 case SREF:
a779b61e 327 s = message ("%q", sRef_unparseDebug (term->value.sref) );
616915dd 328
329 break;
c3e695ff 330 default:
331 BADEXIT;
616915dd 332 }
333
334 return s;
335}
336
337
b9904f57 338constraintTerm constraintTerm_makeIntLiteral (long i)
616915dd 339{
340 constraintTerm ret = new_constraintTermExpr();
341 ret->value.intlit = i;
342 ret->kind = INTLITERAL;
343 ret->loc = fileloc_undefined;
344 return ret;
345}
346
347bool constraintTerm_canGetValue (constraintTerm term)
348{
349 if (term->kind == INTLITERAL)
b9904f57 350 {
351 return TRUE;
352 }
353 else if (term->kind == SREF)
354 {
355 if (sRef_hasValue (term->value.sref))
356 {
357 multiVal mval = sRef_getValue (term->value.sref);
358
359 return multiVal_isInt (mval); /* for now, only try to deal with int values */
360 }
361 else
362 {
363 return FALSE;
364 }
365 }
366 else if (term->kind == EXPRNODE)
367 {
368 return FALSE;
369 }
616915dd 370 else
b9904f57 371 {
372 return FALSE;
373 }
616915dd 374}
375
b9904f57 376long constraintTerm_getValue (constraintTerm term)
616915dd 377{
b9904f57 378 llassert (constraintTerm_canGetValue (term));
379
380 if (term->kind == INTLITERAL)
381 {
382 return term->value.intlit;
383 }
384 else if (term->kind == SREF)
385 {
386 if (sRef_hasValue (term->value.sref))
387 {
388 multiVal mval = sRef_getValue (term->value.sref);
389
390 return multiVal_forceInt (mval); /* for now, only try to deal with int values */
391 }
392 else
393 {
394 BADBRANCH;
395 }
396 }
397 else if (term->kind == EXPRNODE)
398 {
399 BADBRANCH;
400 }
401 else
402 {
403 BADBRANCH;
404 }
405
d30bc0c7 406 BADEXIT;
616915dd 407}
408
bb25bea6 409static /*@exposed@*/ sRef constraintTerm_getsRef (constraintTerm t)
616915dd 410{
dc92450f 411 llassert (t != NULL);
616915dd 412 if (t->kind == EXPRNODE)
413 {
c3e695ff 414 return exprNode_getSref(t->value.expr);
616915dd 415 }
416
417 if (t->kind == SREF)
418 {
c3e695ff 419 return t->value.sref;
616915dd 420 }
421
422 return sRef_undefined;
423}
424
425bool constraintTerm_probSame (constraintTerm term1, constraintTerm term2)
426{
427 cstring s1, s2;
428
429 llassert (term1 !=NULL && term2 !=NULL);
430
431 DPRINTF ( (message
432 ("Comparing srefs for %s and %s ", constraintTerm_print(term1), constraintTerm_print(term2)
433 )
434 )
435 );
436
437 s1 = constraintTerm_getName (term1);
438 s2 = constraintTerm_getName (term2);
439
440 if (cstring_equal (s1, s2) )
441 {
d46ce6a4 442 DPRINTF ((message (" %q and %q are same", s1, s2 ) ) );
616915dd 443 return TRUE;
444 }
445 else
446 {
d46ce6a4 447 DPRINTF ((message (" %q and %q are not same", s1, s2 ) ) );
616915dd 448 return FALSE;
449 }
450}
451
452bool constraintTerm_similar (constraintTerm term1, constraintTerm term2)
453{
454 sRef s1, s2;
455
456 llassert (term1 !=NULL && term2 !=NULL);
90bc41f7 457
b9904f57 458 if (constraintTerm_canGetValue (term1) && constraintTerm_canGetValue (term2))
459 /* evans 2001-07-24: was (term1->kind == INTLITERAL) && (term2->kind == INTLITERAL) ) */
90bc41f7 460 {
b9904f57 461 long t1, t2;
90bc41f7 462
b9904f57 463 t1 = constraintTerm_getValue (term1);
90bc41f7 464 t2 = constraintTerm_getValue (term2);
b9904f57 465
466 return (t1 == t2);
90bc41f7 467 }
b9904f57 468
469 if (constraintTerm_canGetValue (term1) || constraintTerm_canGetValue (term2))
470 {
471 /* evans 2001-07-24: is this right? */ /*@i534@*/
472 return FALSE;
473 }
474
616915dd 475 s1 = constraintTerm_getsRef (term1);
476 s2 = constraintTerm_getsRef (term2);
477
b9904f57 478 if (!(sRef_isValid(s1) && sRef_isValid(s2)))
616915dd 479 {
480 return FALSE;
481 }
482
b9904f57 483 DPRINTF( (message
616915dd 484 ("Comparing srefs for %s and %s ", constraintTerm_print(term1), constraintTerm_print(term2)
485 )
486 )
487 );
b9904f57 488
489 if (sRef_similarRelaxed(s1, s2) || sRef_sameName (s1, s2) )
490 {
491 DPRINTF ((message (" %s and %s are same", constraintTerm_print(term1), constraintTerm_print(term2) ) ));
492 return TRUE;
493 }
494 else
495 {
496 DPRINTF ((message (" %s and %s are not same", constraintTerm_print(term1), constraintTerm_print(term2) ) ));
497 return FALSE;
498 }
616915dd 499}
920a3797 500
501void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f)
502{
503 fileloc loc;
504 constraintTermValue value;
505 constraintTermType kind;
506 uentry u;
507
508 loc = t->loc;
509
510 value = t->value;
511
512 kind = t->kind;
513
514 fprintf(f, "%d\n", (int) kind);
515
516 switch (kind)
517 {
518
519 case EXPRNODE:
520 u = exprNode_getUentry(t->value.expr);
28bf4b0b 521 fprintf(f, "%s\n", cstring_toCharsSafe( uentry_rawName (u) )
522 );
920a3797 523 break;
524
525 case SREF:
526 {
527 sRef s;
528
529 s = t->value.sref;
530
531 if (sRef_isResult (s ) )
532 {
533 fprintf(f, "Result\n");
534 }
535 else if (sRef_isParam (s ) )
536 {
537 int param;
538 ctype ct;
539 cstring ctString;
540
541
542 ct = sRef_getType (s);
543 param = sRef_getParam(s);
544
545 ctString = ctype_dump(ct);
546
28bf4b0b 547 fprintf(f, "Param %s %d\n", cstring_toCharsSafe(ctString), (int) param );
920a3797 548 cstring_free(ctString);
549 }
550 else
551 {
552 u = sRef_getUentry(s);
28bf4b0b 553 fprintf(f, "%s\n", cstring_toCharsSafe(uentry_rawName (u) ) );
920a3797 554 }
555
556 }
557 break;
558
559 case INTLITERAL:
b9904f57 560 fprintf (f, "%ld\n", t->value.intlit);
920a3797 561 break;
562
563 default:
564 BADEXIT;
565 }
566
567}
568
569
570/*@only@*/ constraintTerm constraintTerm_undump ( FILE *f)
571{
920a3797 572 constraintTermType kind;
573 constraintTerm ret;
574
575 uentry ue;
576
6970c11b 577 char *str;
578 char *os;
920a3797 579
580 str = mstring_create (MAX_DUMP_LINE_LENGTH);
581 os = str;
6970c11b 582 str = fgets (os, MAX_DUMP_LINE_LENGTH, f);
920a3797 583
28bf4b0b 584 kind = (constraintTermType) reader_getInt(&str);
920a3797 585 str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
586
587 switch (kind)
588 {
589
590 case SREF:
591 {
592 sRef s;
593 char * term;
28bf4b0b 594 term = reader_getWord(&str);
920a3797 595
596 if (strcmp (term, "Result") == 0 )
597 {
b072092f 598 s = sRef_makeResult (ctype_unknown);
920a3797 599 }
600 else if (strcmp (term, "Param" ) == 0 )
601 {
602 int param;
603 char *str2, *ostr2;
604
605 ctype t;
606
28bf4b0b 607 reader_checkChar(&str, ' ');
608 str2 = reader_getWord(&str);
609 param = reader_getInt(&str);
920a3797 610
611 ostr2 = str2;
612 t = ctype_undump(&str2) ;
6970c11b 613 s = sRef_makeParam (param, t, stateInfo_makeLoc (g_currentloc));
920a3797 614 free (ostr2);
615 }
616 else //This must be an identified that we can search for
617 // in usymTab
618 {
28bf4b0b 619 cstring termStr = cstring_makeLiteralTemp(term);
620
621 ue = usymtab_lookup (termStr);
920a3797 622 s = uentry_getSref(ue);
623 }
624
625 ret = constraintTerm_makesRef(s);
626
627 free(term);
628 }
629 break;
630
631 case EXPRNODE:
632 {
633 sRef s;
634 char * term;
28bf4b0b 635 cstring termStr;
920a3797 636
28bf4b0b 637 term = reader_getWord(&str);
920a3797 638 //This must be an identifier that we can search for
639 // in usymTab
28bf4b0b 640 termStr = cstring_makeLiteralTemp(term);
920a3797 641
28bf4b0b 642 ue = usymtab_lookup (termStr);
920a3797 643 s = uentry_getSref(ue);
644 ret = constraintTerm_makesRef(s);
645
646 free (term);
647 }
648 break;
649
650
651 case INTLITERAL:
652 {
653 int i;
654
28bf4b0b 655 i = reader_getInt(&str);
920a3797 656 ret = constraintTerm_makeIntLiteral (i);
657 }
658 break;
659
660 default:
661 BADEXIT;
662 }
663 free (os);
664
665 return ret;
666}
667
668
669
670
This page took 0.17555 seconds and 5 git commands to generate.