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