]> andersk Git - splint.git/blob - src/constraintTerm.c
*** empty log message ***
[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 /*@unused@*/ static bool constraintTerm_same (constraintTerm p_term1, constraintTerm p_term2) ;
28
29 void constraintTerm_free (/*@only@*/ constraintTerm term)
30 {
31   llassert (constraintTerm_isDefined (term));
32
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 */
42       sRef_free (term->value.sref);
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     }
52   //  term->value.intlit = 0;
53   term->kind =  ERRORBADCONSTRAINTTERMTYPE;
54   free (term);
55 }
56
57 /*@only@*/ static/*@out@*/ constraintTerm new_constraintTermExpr (void)
58 {
59   constraintTerm ret;
60   ret = dmalloc (sizeof (* ret ) );
61   ret->value.intlit = 0;
62   return ret;
63 }
64
65
66 bool constraintTerm_isIntLiteral (constraintTerm term)
67 {
68   llassert(term != NULL);
69   
70   if (term->kind == INTLITERAL)
71     return TRUE;
72
73   return FALSE;
74 }
75
76
77 bool 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
92 int 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
121 bool constraintTerm_isStringLiteral (constraintTerm c) /*@*/
122 {
123   llassert (c != NULL);
124   if (c->kind == EXPRNODE)
125     {
126       if (exprNode_knownStringValue(c->value.expr) )
127         {
128           return TRUE;
129         }
130     }
131   return FALSE;
132 }
133
134
135
136 cstring constraintTerm_getStringLiteral (constraintTerm c)
137 {
138   llassert (c != NULL);
139   llassert (constraintTerm_isStringLiteral (c) );
140   llassert (c->kind == EXPRNODE);
141   
142   return (cstring_copy ( multiVal_forceString (exprNode_getValue (c->value.expr) ) ) );
143 }
144
145 constraintTerm constraintTerm_simplify (/*@returned@*/ constraintTerm term) /*@modifies term@*/
146 {
147   if (term->kind == EXPRNODE)
148     {
149       if ( exprNode_knownIntValue (term->value.expr ) )
150         {
151           long int temp;
152
153           temp  = exprNode_getLongValue (term->value.expr);
154           term->value.intlit = (int)temp;
155           term->kind = INTLITERAL;
156         }
157     }
158   return term;
159 }
160
161 fileloc constraintTerm_getFileloc (constraintTerm t)
162 {
163   llassert (constraintTerm_isDefined (t));
164   return (fileloc_copy (t->loc) );
165 }
166
167 constraintTermType 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
182 /*@only@*/ constraintTerm constraintTerm_makeExprNode (/*@dependent@*/  exprNode e)
183 {
184   constraintTerm ret = new_constraintTermExpr();
185   ret->loc =  fileloc_copy(exprNode_getfileloc(e));
186   ret->value.expr = e;
187   ret->kind = EXPRNODE;
188   ret = constraintTerm_simplify(ret);
189   return ret;
190 }
191
192 /*@only@*/ constraintTerm constraintTerm_makesRef  (/*@temp@*/ /*@observer@*/ sRef s)
193 {
194   constraintTerm ret = new_constraintTermExpr();
195   ret->loc =  fileloc_undefined;
196   ret->value.sref = sRef_saveCopy(s);
197   ret->kind = SREF;
198   ret = constraintTerm_simplify(ret);
199   return ret;
200 }
201
202
203
204 constraintTerm constraintTerm_copy (constraintTerm term)
205 {
206   constraintTerm ret;
207   ret = new_constraintTermExpr();
208   ret->loc = fileloc_copy (term->loc);
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     }
225   ret->kind = term->kind;
226   return ret;
227 }
228
229 constraintTerm constraintTerm_setFileloc (/*@returned@*/ constraintTerm term, fileloc loc) 
230 {
231   llassert(term != NULL);
232
233   if ( fileloc_isDefined(  term->loc ) )
234     fileloc_free(term->loc);
235
236   term->loc = fileloc_copy(loc);
237   return term;
238 }
239
240
241 static cstring constraintTerm_getName (constraintTerm term)
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:
255       s = message (" %d ", (int) term->value.intlit);
256       break;
257       
258     case SREF:
259       s = message ("%q", sRef_unparse (term->value.sref) );
260
261       break;
262     default:
263       BADEXIT;
264       /*@notreached@*/
265       break;
266     }
267   
268   return s;
269 }
270
271 constraintTerm 
272 constraintTerm_doSRefFixBaseParam (/*@returned@*/constraintTerm term, exprNodeList arglist) /*@modifies term@*/
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;
292     default:
293       BADEXIT;
294     }
295   return term;
296   
297 }
298
299 cstring 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
310       s = message ("%s @ %q ", exprNode_unparse (term->value.expr),
311                    fileloc_unparse (term->loc) );
312       break;
313     case INTLITERAL:
314       s = message (" %d ", (int)term->value.intlit);
315       break;
316       
317     case SREF:
318       s = message ("%q ", sRef_unparseDebug (term->value.sref) );
319
320       break;
321     default:
322       BADEXIT;
323     }
324   
325   return s;
326 }
327
328
329 constraintTerm constraintTerm_makeIntLiteral (long i)
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
338 bool constraintTerm_canGetValue (constraintTerm term)
339 {
340   if (term->kind == INTLITERAL)
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     }
361   else
362     {
363       return FALSE;
364     }
365 }
366
367 long constraintTerm_getValue (constraintTerm term) 
368 {
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
397   BADEXIT;
398 }
399
400 /* same and similar are similar but not the same*/
401 static bool constraintTerm_same (constraintTerm term1, constraintTerm term2)
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
429 static /*@exposed@*/ sRef constraintTerm_getsRef (constraintTerm t)
430 {
431   llassert (t != NULL);
432   if (t->kind == EXPRNODE)
433     {
434       return exprNode_getSref(t->value.expr);
435     }
436
437   if (t->kind == SREF)
438     {
439       return t->value.sref;
440     }
441
442   return sRef_undefined;
443 }
444
445 bool 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     {
462       DPRINTF ((message (" %q and %q are same", s1, s2 ) ) );
463      return TRUE;
464    }
465   else
466      {
467      DPRINTF ((message (" %q and %q are not same", s1, s2 ) ) );
468      return FALSE;
469    }   
470 }
471
472 bool constraintTerm_similar (constraintTerm term1, constraintTerm term2)
473 {
474   sRef s1, s2;
475   
476   llassert (term1 !=NULL && term2 !=NULL);
477   
478   if (constraintTerm_canGetValue (term1) && constraintTerm_canGetValue (term2))
479     /* evans 2001-07-24: was (term1->kind == INTLITERAL) && (term2->kind == INTLITERAL) ) */
480     {
481       long t1, t2;
482
483       t1 = constraintTerm_getValue (term1);
484       t2 = constraintTerm_getValue (term2);
485
486       return (t1 == t2);
487     }
488   
489   if (constraintTerm_canGetValue (term1) || constraintTerm_canGetValue (term2))
490     {
491       /* evans 2001-07-24: is this right? */ /*@i534@*/
492       return FALSE;
493     }
494
495   s1 = constraintTerm_getsRef (term1);
496   s2 = constraintTerm_getsRef (term2);
497
498   if (!(sRef_isValid(s1) && sRef_isValid(s2)))
499     {
500       return FALSE;
501     }
502   
503   DPRINTF( (message
504             ("Comparing srefs for %s and  %s ", constraintTerm_print(term1), constraintTerm_print(term2)
505              )
506             )
507            );
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     }       
519 }
520
521 void 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);
541       fprintf(f, "%s\n", cstring_toCharsSafe( uentry_rawName (u) )
542               );
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             
567             fprintf(f, "Param %s %d\n", cstring_toCharsSafe(ctString), (int) param );
568             cstring_free(ctString);
569           }
570         else
571           {
572             u = sRef_getUentry(s);
573             fprintf(f, "%s\n", cstring_toCharsSafe(uentry_rawName (u) ) );
574           }
575         
576       }
577       break;
578       
579     case INTLITERAL:
580       fprintf (f, "%ld\n", t->value.intlit);
581       break;
582       
583     default:
584       BADEXIT;
585     }
586   
587 }
588
589
590 /*@only@*/ constraintTerm constraintTerm_undump ( FILE *f)
591 {
592   constraintTermType kind;
593   constraintTerm ret;
594   
595   uentry ue;
596   
597   char *str;
598   char *os;
599
600   str = mstring_create (MAX_DUMP_LINE_LENGTH);
601   os = str;
602   str = fgets (os, MAX_DUMP_LINE_LENGTH, f);
603
604   kind = (constraintTermType) reader_getInt(&str);
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;
614         term = reader_getWord(&str);
615         
616         if (strcmp (term, "Result") == 0 )
617           {
618             s = sRef_makeResult (ctype_unknown);
619           }
620         else if (strcmp (term, "Param" ) == 0 )
621           {
622             int param;
623             char *str2, *ostr2;
624             
625             ctype t;
626
627             reader_checkChar(&str, ' ');
628             str2  = reader_getWord(&str);
629             param = reader_getInt(&str);
630
631             ostr2 = str2;
632             t = ctype_undump(&str2) ;
633             s = sRef_makeParam (param, t, stateInfo_makeLoc (g_currentloc));
634             free (ostr2);
635           }
636         else  //This must be an identified that we can search for
637           // in usymTab
638           {
639             cstring termStr = cstring_makeLiteralTemp(term);
640
641             ue = usymtab_lookup (termStr);
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;
655         cstring termStr;
656                 
657         term = reader_getWord(&str);
658         //This must be an identifier that we can search for
659           // in usymTab
660         termStr = cstring_makeLiteralTemp(term);
661         
662         ue = usymtab_lookup (termStr);
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
675         i = reader_getInt(&str);
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 1.13916 seconds and 5 git commands to generate.