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