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