]> andersk Git - splint.git/blob - src/constraintTerm.c
215430ff855ec259bdf7d66f1da01e2cfa5662c2
[splint.git] / src / constraintTerm.c
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 "exprNodeSList.h"
15
16 /*@-czechfcns@*/
17
18 //#include "constraintExpr.h"
19
20 /*@access exprNode @*/
21
22 bool constraintTerm_isDefined (constraintTerm t)
23 {
24   return t != NULL;
25 }
26
27 void constraintTerm_free (/*@only@*/ constraintTerm term)
28 {
29   llassert (constraintTerm_isDefined (term));
30
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 */
40       sRef_free (term->value.sref);
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     }
50   //  term->value.intlit = 0;
51   term->kind =  ERRORBADCONSTRAINTTERMTYPE;
52   free (term);
53 }
54
55 /*@only@*/ static/*@out@*/ constraintTerm new_constraintTermExpr (void)
56 {
57   constraintTerm ret;
58   ret = dmalloc (sizeof (* ret ) );
59   ret->value.intlit = 0;
60   return ret;
61 }
62
63
64 bool constraintTerm_isIntLiteral (constraintTerm term)
65 {
66   llassert(term != NULL);
67   
68   if (term->kind == INTLITERAL)
69     return TRUE;
70
71   return FALSE;
72 }
73
74
75 bool 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
90 bool 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
101 int 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
130 bool constraintTerm_isStringLiteral (constraintTerm c) /*@*/
131 {
132   llassert (c != NULL);
133   if (c->kind == EXPRNODE)
134     {
135       if (exprNode_knownStringValue(c->value.expr) )
136         {
137           return TRUE;
138         }
139     }
140   return FALSE;
141 }
142
143
144
145 cstring constraintTerm_getStringLiteral (constraintTerm c)
146 {
147   llassert (c != NULL);
148   llassert (constraintTerm_isStringLiteral (c) );
149   llassert (c->kind == EXPRNODE);
150   
151   return (cstring_copy ( multiVal_forceString (exprNode_getValue (c->value.expr) ) ) );
152 }
153
154 constraintTerm constraintTerm_simplify (/*@returned@*/ constraintTerm term) /*@modifies term@*/
155 {
156   if (term->kind == EXPRNODE)
157     {
158       if ( exprNode_knownIntValue (term->value.expr ) )
159         {
160           long int temp;
161
162           temp  = exprNode_getLongValue (term->value.expr);
163           term->value.intlit = (int)temp;
164           term->kind = INTLITERAL;
165         }
166     }
167   return term;
168 }
169
170 fileloc constraintTerm_getFileloc (constraintTerm t)
171 {
172   llassert (constraintTerm_isDefined (t));
173   return (fileloc_copy (t->loc) );
174 }
175
176 constraintTermType 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
191 /*@only@*/ constraintTerm constraintTerm_makeExprNode (/*@dependent@*/  exprNode e)
192 {
193   constraintTerm ret = new_constraintTermExpr();
194   ret->loc =  fileloc_copy(exprNode_getfileloc(e));
195   ret->value.expr = e;
196   ret->kind = EXPRNODE;
197   ret = constraintTerm_simplify(ret);
198   return ret;
199 }
200
201 /*@only@*/ constraintTerm constraintTerm_makesRef  (/*@temp@*/ /*@observer@*/ sRef s)
202 {
203   constraintTerm ret = new_constraintTermExpr();
204   ret->loc =  fileloc_undefined;
205   ret->value.sref = sRef_saveCopy(s);
206   ret->kind = SREF;
207   ret = constraintTerm_simplify(ret);
208   return ret;
209 }
210
211
212
213 constraintTerm constraintTerm_copy (constraintTerm term)
214 {
215   constraintTerm ret;
216   ret = new_constraintTermExpr();
217   ret->loc = fileloc_copy (term->loc);
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     }
234   ret->kind = term->kind;
235   return ret;
236 }
237
238 constraintTerm constraintTerm_setFileloc (/*@returned@*/ constraintTerm term, fileloc loc) 
239 {
240   llassert(term != NULL);
241
242   if ( fileloc_isDefined(  term->loc ) )
243     fileloc_free(term->loc);
244
245   term->loc = fileloc_copy(loc);
246   return term;
247 }
248
249
250 static cstring constraintTerm_getName (constraintTerm term)
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:
264       s = message (" %d ", (int) term->value.intlit);
265       break;
266       
267     case SREF:
268       s = message ("%q", sRef_unparse (term->value.sref) );
269
270       break;
271     default:
272       BADEXIT;
273       /*@notreached@*/
274       break;
275     }
276   
277   return s;
278 }
279
280 constraintTerm 
281 constraintTerm_doSRefFixBaseParam (/*@returned@*/constraintTerm term, exprNodeList arglist) /*@modifies term@*/
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;
301     default:
302       BADEXIT;
303     }
304   return term;
305   
306 }
307
308 cstring 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
319       s = message ("%s @ %q", exprNode_unparse (term->value.expr),
320                    fileloc_unparse (term->loc) );
321       break;
322     case INTLITERAL:
323       s = message ("%d", (int)term->value.intlit);
324       break;
325       
326     case SREF:
327       s = message ("%q", sRef_unparseDebug (term->value.sref) );
328
329       break;
330     default:
331       BADEXIT;
332     }
333   
334   return s;
335 }
336
337
338 constraintTerm constraintTerm_makeIntLiteral (long i)
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
347 bool constraintTerm_canGetValue (constraintTerm term)
348 {
349   if (term->kind == INTLITERAL)
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     }
370   else
371     {
372       return FALSE;
373     }
374 }
375
376 long constraintTerm_getValue (constraintTerm term) 
377 {
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
406   BADEXIT;
407 }
408
409 static /*@exposed@*/ sRef constraintTerm_getsRef (constraintTerm t)
410 {
411   llassert (t != NULL);
412   if (t->kind == EXPRNODE)
413     {
414       return exprNode_getSref(t->value.expr);
415     }
416
417   if (t->kind == SREF)
418     {
419       return t->value.sref;
420     }
421
422   return sRef_undefined;
423 }
424
425 bool 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     {
442       DPRINTF ((message (" %q and %q are same", s1, s2 ) ) );
443      return TRUE;
444    }
445   else
446      {
447      DPRINTF ((message (" %q and %q are not same", s1, s2 ) ) );
448      return FALSE;
449    }   
450 }
451
452 bool constraintTerm_similar (constraintTerm term1, constraintTerm term2)
453 {
454   sRef s1, s2;
455   
456   llassert (term1 !=NULL && term2 !=NULL);
457   
458   if (constraintTerm_canGetValue (term1) && constraintTerm_canGetValue (term2))
459     /* evans 2001-07-24: was (term1->kind == INTLITERAL) && (term2->kind == INTLITERAL) ) */
460     {
461       long t1, t2;
462
463       t1 = constraintTerm_getValue (term1);
464       t2 = constraintTerm_getValue (term2);
465
466       return (t1 == t2);
467     }
468   
469   if (constraintTerm_canGetValue (term1) || constraintTerm_canGetValue (term2))
470     {
471       /* evans 2001-07-24: is this right? */ /*@i534@*/
472       return FALSE;
473     }
474
475   s1 = constraintTerm_getsRef (term1);
476   s2 = constraintTerm_getsRef (term2);
477
478   if (!(sRef_isValid(s1) && sRef_isValid(s2)))
479     {
480       return FALSE;
481     }
482   
483   DPRINTF( (message
484             ("Comparing srefs for %s and  %s ", constraintTerm_print(term1), constraintTerm_print(term2)
485              )
486             )
487            );
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     }       
499 }
500
501 void 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);
521       fprintf(f, "%s\n", cstring_toCharsSafe( uentry_rawName (u) )
522               );
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             
547             fprintf(f, "Param %s %d\n", cstring_toCharsSafe(ctString), (int) param );
548             cstring_free(ctString);
549           }
550         else
551           {
552             u = sRef_getUentry(s);
553             fprintf(f, "%s\n", cstring_toCharsSafe(uentry_rawName (u) ) );
554           }
555         
556       }
557       break;
558       
559     case INTLITERAL:
560       fprintf (f, "%ld\n", t->value.intlit);
561       break;
562       
563     default:
564       BADEXIT;
565     }
566   
567 }
568
569
570 /*@only@*/ constraintTerm constraintTerm_undump ( FILE *f)
571 {
572   constraintTermType kind;
573   constraintTerm ret;
574   
575   uentry ue;
576   
577   char *str;
578   char *os;
579
580   str = mstring_create (MAX_DUMP_LINE_LENGTH);
581   os = str;
582   str = fgets (os, MAX_DUMP_LINE_LENGTH, f);
583
584   kind = (constraintTermType) reader_getInt(&str);
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;
594         term = reader_getWord(&str);
595         
596         if (strcmp (term, "Result") == 0 )
597           {
598             s = sRef_makeResult (ctype_unknown);
599           }
600         else if (strcmp (term, "Param" ) == 0 )
601           {
602             int param;
603             char *str2, *ostr2;
604             
605             ctype t;
606
607             reader_checkChar(&str, ' ');
608             str2  = reader_getWord(&str);
609             param = reader_getInt(&str);
610
611             ostr2 = str2;
612             t = ctype_undump(&str2) ;
613             s = sRef_makeParam (param, t, stateInfo_makeLoc (g_currentloc));
614             free (ostr2);
615           }
616         else  //This must be an identified that we can search for
617           // in usymTab
618           {
619             cstring termStr = cstring_makeLiteralTemp(term);
620
621             ue = usymtab_lookup (termStr);
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;
635         cstring termStr;
636                 
637         term = reader_getWord(&str);
638         //This must be an identifier that we can search for
639           // in usymTab
640         termStr = cstring_makeLiteralTemp(term);
641         
642         ue = usymtab_lookup (termStr);
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
655         i = reader_getInt(&str);
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.075697 seconds and 3 git commands to generate.