]> andersk Git - splint.git/blob - src/constraintTerm.c
Fixed library dump support so that buffer constraint annotations are read and written...
[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 "aliasChecks.h"
15 # include "exprNodeSList.h"
16
17 /*@-czechfcns@*/
18
19 //#include "constraintExpr.h"
20
21 /*@access exprNode, constraintTermValue @*/
22
23 /*@unused@*/ static bool constraintTerm_same (constraintTerm term1, constraintTerm term2) ;
24
25 void 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 }
49
50 /*@only@*/ static/*@out@*/ constraintTerm new_constraintTermExpr (void)
51 {
52   constraintTerm ret;
53   ret = dmalloc (sizeof (* ret ) );
54   ret->value.intlit = 0;
55   return ret;
56 }
57
58
59 bool constraintTerm_isIntLiteral (constraintTerm term)
60 {
61   llassert(term != NULL);
62   
63   if (term->kind == INTLITERAL)
64     return TRUE;
65
66   return FALSE;
67 }
68
69 bool constraintTerm_isStringLiteral (constraintTerm c) /*@*/
70 {
71   llassert (c != NULL);
72   if (c->kind == EXPRNODE)
73     {
74       if (exprNode_knownStringValue(c->value.expr) )
75         {
76           return TRUE;
77         }
78     }
79   return FALSE;
80 }
81
82 cstring constraintTerm_getStringLiteral (constraintTerm c)
83 {
84   llassert (c != NULL);
85   llassert (constraintTerm_isStringLiteral (c) );
86   llassert (c->kind == EXPRNODE);
87   
88   return (cstring_copy ( multiVal_forceString (exprNode_getValue (c->value.expr) ) ) );
89 }
90
91 constraintTerm constraintTerm_simplify (/*@returned@*/ constraintTerm term) /*@modifies term@*/
92 {
93   if (term->kind == EXPRNODE)
94     {
95       if ( exprNode_knownIntValue (term->value.expr ) )
96         {
97           long int temp;
98           #warning is this a leak?
99           temp  = exprNode_getLongValue (term->value.expr);
100           term->value.intlit = (int)temp;
101           term->kind = INTLITERAL;
102         }
103     }
104   return term;
105 }
106
107 fileloc constraintTerm_getFileloc (constraintTerm t)
108 {
109   return (fileloc_copy (t->loc) );
110 }
111
112 constraintTermType 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
127 /*@only@*/ constraintTerm constraintTerm_makeExprNode (/*@dependent@*/ exprNode e)
128 {
129   constraintTerm ret = new_constraintTermExpr();
130   ret->loc =  fileloc_copy(exprNode_getfileloc(e));
131   ret->value.expr = e;
132   ret->kind = EXPRNODE;
133   ret = constraintTerm_simplify(ret);
134   return ret;
135 }
136
137 /*@only@*/ constraintTerm constraintTerm_makesRef  (/*@exposed@*/ sRef s)
138 {
139   constraintTerm ret = new_constraintTermExpr();
140   ret->loc =  fileloc_undefined;
141   ret->value.sref = sRef_saveCopy(s);
142   ret->kind = SREF;
143   ret = constraintTerm_simplify(ret);
144   return ret;
145 }
146
147 constraintTerm constraintTerm_copy (constraintTerm term)
148 {
149   constraintTerm ret;
150   ret = new_constraintTermExpr();
151   ret->loc = fileloc_copy (term->loc);
152   constraintTermValue_copy (ret->value, term->value);
153   ret->kind = term->kind;
154   return ret;
155 }
156
157 constraintTerm constraintTerm_setFileloc (/*@returned@*/ constraintTerm term, fileloc loc) 
158 {
159   llassert(term != NULL);
160
161   if (term->loc != fileloc_undefined)
162     fileloc_free(term->loc);
163
164   term->loc = fileloc_copy(loc);
165   return term;
166 }
167
168
169 static cstring constraintTerm_getName (constraintTerm term)
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:
187       s = message ("%q", sRef_unparse (term->value.sref) );
188
189       break;
190     default:
191       BADEXIT;
192       /*@notreached@*/
193       break;
194     }
195   
196   return s;
197 }
198
199 constraintTerm 
200 constraintTerm_doSRefFixBaseParam (/*@returned@*/constraintTerm term, exprNodeList arglist) /*@modifies term@*/
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;
220     default:
221       BADEXIT;
222     }
223   return term;
224   
225 }
226
227 cstring 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
238       s = message ("%s @ %q ", exprNode_unparse (term->value.expr),
239                    fileloc_unparse (term->loc) );
240       break;
241     case INTLITERAL:
242       s = message (" %d ", term->value.intlit);
243       break;
244       
245     case SREF:
246       s = message ("%q ", sRef_unparseDebug (term->value.sref) );
247
248       break;
249     default:
250       BADEXIT;
251     }
252   
253   return s;
254 }
255
256
257 constraintTerm 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
266 bool constraintTerm_canGetValue (constraintTerm term)
267 {
268   if (term->kind == INTLITERAL)
269     return TRUE;
270   else
271     return FALSE;
272 }
273
274 int constraintTerm_getValue (constraintTerm term) 
275 {
276   llassert (term->kind == INTLITERAL);
277   return term->value.intlit;
278 }
279
280 /* same and similar are similar but not the same*/
281 static bool constraintTerm_same (constraintTerm term1, constraintTerm term2)
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
309 static /*@exposed@*/ sRef constraintTerm_getsRef (constraintTerm t)
310 {
311   llassert (t != NULL);
312   if (t->kind == EXPRNODE)
313     {
314       return exprNode_getSref(t->value.expr);
315     }
316
317   if (t->kind == SREF)
318     {
319       return t->value.sref;
320     }
321
322   return sRef_undefined;
323 }
324
325 bool 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     {
342       DPRINTF ((message (" %q and %q are same", s1, s2 ) ) );
343      return TRUE;
344    }
345   else
346      {
347      DPRINTF ((message (" %q and %q are not same", s1, s2 ) ) );
348      return FALSE;
349    }   
350 }
351
352 bool constraintTerm_similar (constraintTerm term1, constraintTerm term2)
353 {
354   sRef s1, s2;
355   
356   llassert (term1 !=NULL && term2 !=NULL);
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     
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 }
398
399 void 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.082212 seconds and 5 git commands to generate.