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