]> andersk Git - splint.git/blame - src/constraintTerm.c
Updating to use the LEnsures and LRequires instead of the ensures requires so
[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"
14# include "aliasChecks.h"
15# include "exprNodeSList.h"
16
616915dd 17/*@-czechfcns@*/
18
19//#include "constraintExpr.h"
20
a8e557d3 21/*@access exprNode, constraintTermValue @*/
22
920a3797 23/*@unused@*/ static bool constraintTerm_same (constraintTerm term1, constraintTerm term2) ;
2934b455 24
d46ce6a4 25void constraintTerm_free (/*@only@*/ constraintTerm term)
26{
27 llassert(constraintTerm_isDefined(term) );
28 fileloc_free (term->loc);
29
30 switch (term->kind)
31 {
32 case EXPRNODE:
33 /* we don't free an exprNode*/
34 break;
35 case SREF:
36 /* sref */
37 //sRef_free (term->value.sref);
38 break;
39 case INTLITERAL:
40 /* don't free an int */
41 break;
42 case ERRORBADCONSTRAINTTERMTYPE:
43 default:
44 /* type was set incorrectly */
45 llcontbug (message("constraintTerm_free type was set incorrectly"));
46 }
47 free (term);
48}
616915dd 49
4ab867d6 50/*@only@*/ static/*@out@*/ constraintTerm new_constraintTermExpr (void)
616915dd 51{
52 constraintTerm ret;
53 ret = dmalloc (sizeof (* ret ) );
bb25bea6 54 ret->value.intlit = 0;
616915dd 55 return ret;
56}
57
58
59bool constraintTerm_isIntLiteral (constraintTerm term)
60{
dc92450f 61 llassert(term != NULL);
616915dd 62
63 if (term->kind == INTLITERAL)
64 return TRUE;
65
66 return FALSE;
67}
68
dc92450f 69bool constraintTerm_isStringLiteral (constraintTerm c) /*@*/
616915dd 70{
dc92450f 71 llassert (c != NULL);
616915dd 72 if (c->kind == EXPRNODE)
73 {
74 if (exprNode_knownStringValue(c->value.expr) )
75 {
76 return TRUE;
77 }
78 }
79 return FALSE;
80}
81
82cstring constraintTerm_getStringLiteral (constraintTerm c)
83{
dc92450f 84 llassert (c != NULL);
616915dd 85 llassert (constraintTerm_isStringLiteral (c) );
86 llassert (c->kind == EXPRNODE);
87
dc92450f 88 return (cstring_copy ( multiVal_forceString (exprNode_getValue (c->value.expr) ) ) );
616915dd 89}
90
4ab867d6 91constraintTerm constraintTerm_simplify (/*@returned@*/ constraintTerm term) /*@modifies term@*/
616915dd 92{
93 if (term->kind == EXPRNODE)
94 {
95 if ( exprNode_knownIntValue (term->value.expr ) )
96 {
97 long int temp;
4ab867d6 98 #warning is this a leak?
616915dd 99 temp = exprNode_getLongValue (term->value.expr);
dc92450f 100 term->value.intlit = (int)temp;
616915dd 101 term->kind = INTLITERAL;
102 }
103 }
104 return term;
105}
106
107fileloc constraintTerm_getFileloc (constraintTerm t)
108{
109 return (fileloc_copy (t->loc) );
110}
111
a8e557d3 112constraintTermType constraintTerm_getKind (constraintTerm t)
113{
114 llassert (constraintTerm_isDefined(t) );
115
116 return (t->kind);
117}
118
119/*@exposed@*/ sRef constraintTerm_getSRef (constraintTerm t)
120{
121 llassert (constraintTerm_isDefined(t) );
122 llassert (t->kind == SREF);
123
124 return (t->value.sref);
125}
126
4ab867d6 127/*@only@*/ constraintTerm constraintTerm_makeExprNode (/*@dependent@*/ exprNode e)
616915dd 128{
129 constraintTerm ret = new_constraintTermExpr();
d46ce6a4 130 ret->loc = fileloc_copy(exprNode_getfileloc(e));
616915dd 131 ret->value.expr = e;
132 ret->kind = EXPRNODE;
133 ret = constraintTerm_simplify(ret);
134 return ret;
135}
136
4ab867d6 137/*@only@*/ constraintTerm constraintTerm_makesRef (/*@exposed@*/ sRef s)
616915dd 138{
139 constraintTerm ret = new_constraintTermExpr();
140 ret->loc = fileloc_undefined;
4ab867d6 141 ret->value.sref = sRef_saveCopy(s);
616915dd 142 ret->kind = SREF;
143 ret = constraintTerm_simplify(ret);
144 return ret;
145}
146
147constraintTerm constraintTerm_copy (constraintTerm term)
148{
149 constraintTerm ret;
150 ret = new_constraintTermExpr();
151 ret->loc = fileloc_copy (term->loc);
c3e695ff 152 constraintTermValue_copy (ret->value, term->value);
616915dd 153 ret->kind = term->kind;
154 return ret;
155}
156
d46ce6a4 157constraintTerm constraintTerm_setFileloc (/*@returned@*/ constraintTerm term, fileloc loc)
616915dd 158{
dc92450f 159 llassert(term != NULL);
d46ce6a4 160
161 if (term->loc != fileloc_undefined)
162 fileloc_free(term->loc);
163
616915dd 164 term->loc = fileloc_copy(loc);
165 return term;
166}
167
168
d46ce6a4 169static cstring constraintTerm_getName (constraintTerm term)
616915dd 170{
171 cstring s;
172 s = cstring_undefined;
173
174 llassert (term != NULL);
175
176 switch (term->kind)
177 {
178 case EXPRNODE:
179 /*@i334*/ //wtf
180 s = message ("%s", exprNode_unparse (term->value.expr) );
181 break;
182 case INTLITERAL:
183 s = message (" %d ", term->value.intlit);
184 break;
185
186 case SREF:
d46ce6a4 187 s = message ("%q", sRef_unparse (term->value.sref) );
616915dd 188
189 break;
c3e695ff 190 default:
191 BADEXIT;
192 /*@notreached@*/
616915dd 193 break;
194 }
616915dd 195
c3e695ff 196 return s;
616915dd 197}
198
199constraintTerm
d46ce6a4 200constraintTerm_doSRefFixBaseParam (/*@returned@*/constraintTerm term, exprNodeList arglist) /*@modifies term@*/
616915dd 201{
202 llassert (term != NULL);
203
204 switch (term->kind)
205 {
206 case EXPRNODE:
207 /*@i334*/ //wtf
208 // s = message ("%s @ %s ", exprNode_unparse (term->value.expr),
209 // fileloc_unparse (term->loc) );
210 break;
211 case INTLITERAL:
212 // s = message (" %d ", term->value.intlit);
213 break;
214
215 case SREF:
216 term->value.sref = sRef_fixBaseParam (term->value.sref, arglist);
217 // s = message ("%s ", sRef_unparse (term->value.sref) );
218
219 break;
c3e695ff 220 default:
221 BADEXIT;
616915dd 222 }
223 return term;
224
225}
226
616915dd 227cstring constraintTerm_print (constraintTerm term) /*@*/
228{
229 cstring s;
230 s = cstring_undefined;
231
232 llassert (term != NULL);
233
234 switch (term->kind)
235 {
236 case EXPRNODE:
237 /*@i334*/ //wtf
d46ce6a4 238 s = message ("%s @ %q ", exprNode_unparse (term->value.expr),
616915dd 239 fileloc_unparse (term->loc) );
240 break;
241 case INTLITERAL:
242 s = message (" %d ", term->value.intlit);
243 break;
244
245 case SREF:
d46ce6a4 246 s = message ("%q ", sRef_unparseDebug (term->value.sref) );
616915dd 247
248 break;
c3e695ff 249 default:
250 BADEXIT;
616915dd 251 }
252
253 return s;
254}
255
256
257constraintTerm constraintTerm_makeIntLiteral (int i)
258{
259 constraintTerm ret = new_constraintTermExpr();
260 ret->value.intlit = i;
261 ret->kind = INTLITERAL;
262 ret->loc = fileloc_undefined;
263 return ret;
264}
265
266bool constraintTerm_canGetValue (constraintTerm term)
267{
268 if (term->kind == INTLITERAL)
269 return TRUE;
270 else
271 return FALSE;
272}
273
274int constraintTerm_getValue (constraintTerm term)
275{
276 llassert (term->kind == INTLITERAL);
277 return term->value.intlit;
278}
279
616915dd 280/* same and similar are similar but not the same*/
bb25bea6 281static bool constraintTerm_same (constraintTerm term1, constraintTerm term2)
616915dd 282{
283 llassert (term1 !=NULL && term2 !=NULL);
284
285 if ( (term1->kind != term2->kind) || (term1->kind != EXPRNODE) )
286 {
287 return FALSE;
288 }
289
290 DPRINTF ( (message
291 ("Comparing srefs for %s and %s ", constraintTerm_print(term1), constraintTerm_print(term2)
292 )
293 )
294 );
295
296 if (sRef_same (term1->value.expr->sref, term2->value.expr->sref) )
297 {
298 DPRINTF ((message (" %s and %s are same", constraintTerm_print(term1), constraintTerm_print(term2) ) ));
299 return TRUE;
300 }
301 else
302 {
303 DPRINTF ((message (" %s and %s are not same", constraintTerm_print(term1), constraintTerm_print(term2) ) ));
304 return FALSE;
305 }
306
307}
308
bb25bea6 309static /*@exposed@*/ sRef constraintTerm_getsRef (constraintTerm t)
616915dd 310{
dc92450f 311 llassert (t != NULL);
616915dd 312 if (t->kind == EXPRNODE)
313 {
c3e695ff 314 return exprNode_getSref(t->value.expr);
616915dd 315 }
316
317 if (t->kind == SREF)
318 {
c3e695ff 319 return t->value.sref;
616915dd 320 }
321
322 return sRef_undefined;
323}
324
325bool constraintTerm_probSame (constraintTerm term1, constraintTerm term2)
326{
327 cstring s1, s2;
328
329 llassert (term1 !=NULL && term2 !=NULL);
330
331 DPRINTF ( (message
332 ("Comparing srefs for %s and %s ", constraintTerm_print(term1), constraintTerm_print(term2)
333 )
334 )
335 );
336
337 s1 = constraintTerm_getName (term1);
338 s2 = constraintTerm_getName (term2);
339
340 if (cstring_equal (s1, s2) )
341 {
d46ce6a4 342 DPRINTF ((message (" %q and %q are same", s1, s2 ) ) );
616915dd 343 return TRUE;
344 }
345 else
346 {
d46ce6a4 347 DPRINTF ((message (" %q and %q are not same", s1, s2 ) ) );
616915dd 348 return FALSE;
349 }
350}
351
352bool constraintTerm_similar (constraintTerm term1, constraintTerm term2)
353{
354 sRef s1, s2;
355
356 llassert (term1 !=NULL && term2 !=NULL);
90bc41f7 357
358 if ( (term1->kind == INTLITERAL) && (term2->kind == INTLITERAL) )
359 {
360 int t1, t2;
361 llassert (constraintTerm_canGetValue(term1) );
362 t1 = constraintTerm_getValue (term1);
363
364 llassert (constraintTerm_canGetValue(term2) );
365 t2 = constraintTerm_getValue (term2);
366 if (t1 == t2)
367 return TRUE;
368
369 return FALSE;
370 }
371
616915dd 372 s1 = constraintTerm_getsRef (term1);
373 s2 = constraintTerm_getsRef (term2);
374
375 if ( ! (s1 && s2) )
376 {
377 return FALSE;
378 }
379
380 DPRINTF ( (message
381 ("Comparing srefs for %s and %s ", constraintTerm_print(term1), constraintTerm_print(term2)
382 )
383 )
384 );
385
386 if (sRef_similarRelaxed(s1, s2) || sRef_sameName (s1, s2) )
387 {
388 DPRINTF ((message (" %s and %s are same", constraintTerm_print(term1), constraintTerm_print(term2) ) ));
389 return TRUE;
390 }
391 else
392 {
393 DPRINTF ((message (" %s and %s are not same", constraintTerm_print(term1), constraintTerm_print(term2) ) ));
394 return FALSE;
395 }
396
397}
920a3797 398
399void constraintTerm_dump ( /*@observer@*/ constraintTerm t, FILE *f)
400{
401 fileloc loc;
402 constraintTermValue value;
403 constraintTermType kind;
404 uentry u;
405
406 loc = t->loc;
407
408 value = t->value;
409
410 kind = t->kind;
411
412 fprintf(f, "%d\n", (int) kind);
413
414 switch (kind)
415 {
416
417 case EXPRNODE:
418 u = exprNode_getUentry(t->value.expr);
419 fprintf(f, "%s\n", uentry_rawName (u) );
420 break;
421
422 case SREF:
423 {
424 sRef s;
425
426 s = t->value.sref;
427
428 if (sRef_isResult (s ) )
429 {
430 fprintf(f, "Result\n");
431 }
432 else if (sRef_isParam (s ) )
433 {
434 int param;
435 ctype ct;
436 cstring ctString;
437
438
439 ct = sRef_getType (s);
440 param = sRef_getParam(s);
441
442 ctString = ctype_dump(ct);
443
444 fprintf(f, "Param %s %d\n", ctString, (int) param );
445 cstring_free(ctString);
446 }
447 else
448 {
449 u = sRef_getUentry(s);
450 fprintf(f, "%s\n", uentry_rawName (u) );
451 }
452
453 }
454 break;
455
456 case INTLITERAL:
457 fprintf (f, "%d\n", t->value.intlit);
458 break;
459
460 default:
461 BADEXIT;
462 }
463
464}
465
466
467/*@only@*/ constraintTerm constraintTerm_undump ( FILE *f)
468{
469 fileloc loc;
470 constraintTermType kind;
471 constraintTerm ret;
472
473 uentry ue;
474
475 char * str;
476 char * os;
477
478 str = mstring_create (MAX_DUMP_LINE_LENGTH);
479 os = str;
480 str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
481
482 kind = (constraintTermType) getInt(&str);
483 str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
484
485 switch (kind)
486 {
487
488 case SREF:
489 {
490 sRef s;
491 char * term;
492 term = getWord(&str);
493
494 if (strcmp (term, "Result") == 0 )
495 {
496 s = sRef_makeResult();
497 }
498 else if (strcmp (term, "Param" ) == 0 )
499 {
500 int param;
501 char *str2, *ostr2;
502
503 ctype t;
504
505 checkChar(&str, ' ');
506 str2 = getWord(&str);
507 param = getInt(&str);
508
509 ostr2 = str2;
510 t = ctype_undump(&str2) ;
511 s = sRef_makeParam (param, t );
512 free (ostr2);
513 }
514 else //This must be an identified that we can search for
515 // in usymTab
516 {
517
518 ue = usymtab_lookup (term);
519 s = uentry_getSref(ue);
520 }
521
522 ret = constraintTerm_makesRef(s);
523
524 free(term);
525 }
526 break;
527
528 case EXPRNODE:
529 {
530 sRef s;
531 char * term;
532
533 term = getWord(&str);
534 //This must be an identifier that we can search for
535 // in usymTab
536
537 ue = usymtab_lookup (term);
538 s = uentry_getSref(ue);
539 ret = constraintTerm_makesRef(s);
540
541 free (term);
542 }
543 break;
544
545
546 case INTLITERAL:
547 {
548 int i;
549
550 i = getInt(&str);
551 ret = constraintTerm_makeIntLiteral (i);
552 }
553 break;
554
555 default:
556 BADEXIT;
557 }
558 free (os);
559
560 return ret;
561}
562
563
564
565
This page took 0.147321 seconds and 5 git commands to generate.