]> 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 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 (/*@depenedent@*/  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 (" %d ", 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 (" %d ", 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 (int 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     return TRUE;
295   else
296     return FALSE;
297 }
298
299 int constraintTerm_getValue (constraintTerm term) 
300 {
301   llassert (term->kind == INTLITERAL);
302   return term->value.intlit;
303 }
304
305 /* same and similar are similar but not the same*/
306 static bool constraintTerm_same (constraintTerm term1, constraintTerm term2)
307 {
308   llassert (term1 !=NULL && term2 !=NULL);
309
310   if ( (term1->kind != term2->kind) || (term1->kind != EXPRNODE) )
311     {
312       return FALSE;
313     }
314       
315  DPRINTF ( (message
316             ("Comparing srefs for %s and  %s ", constraintTerm_print(term1), constraintTerm_print(term2)
317              )
318             )
319            );
320  
321  if (sRef_same (term1->value.expr->sref, term2->value.expr->sref) )
322    {
323      DPRINTF ((message (" %s and %s are same", constraintTerm_print(term1), constraintTerm_print(term2)  )  ));
324      return TRUE;
325    }
326  else
327    {
328      DPRINTF ((message (" %s and %s are not same", constraintTerm_print(term1), constraintTerm_print(term2)  )  ));
329      return FALSE;
330    }     
331     
332 }
333
334 static /*@exposed@*/ sRef constraintTerm_getsRef (constraintTerm t)
335 {
336   llassert (t != NULL);
337   if (t->kind == EXPRNODE)
338     {
339       return exprNode_getSref(t->value.expr);
340     }
341
342   if (t->kind == SREF)
343     {
344       return t->value.sref;
345     }
346
347   return sRef_undefined;
348 }
349
350 bool constraintTerm_probSame (constraintTerm term1, constraintTerm term2)
351 {
352   cstring s1, s2;
353
354   llassert (term1 !=NULL && term2 !=NULL);
355      
356  DPRINTF ( (message
357             ("Comparing srefs for %s and  %s ", constraintTerm_print(term1), constraintTerm_print(term2)
358              )
359             )
360            );
361   
362   s1 = constraintTerm_getName (term1);
363   s2 = constraintTerm_getName (term2);
364
365   if (cstring_equal (s1, s2) )
366     {
367       DPRINTF ((message (" %q and %q are same", s1, s2 ) ) );
368      return TRUE;
369    }
370   else
371      {
372      DPRINTF ((message (" %q and %q are not same", s1, s2 ) ) );
373      return FALSE;
374    }   
375 }
376
377 bool constraintTerm_similar (constraintTerm term1, constraintTerm term2)
378 {
379   sRef s1, s2;
380   
381   llassert (term1 !=NULL && term2 !=NULL);
382   
383   if ( (term1->kind == INTLITERAL) && (term2->kind == INTLITERAL) )
384     {
385       int t1, t2;
386       llassert (constraintTerm_canGetValue(term1) );
387       t1 = constraintTerm_getValue (term1);
388
389       llassert (constraintTerm_canGetValue(term2) );
390       t2 = constraintTerm_getValue (term2);
391       if (t1 == t2)
392         return TRUE;
393       
394        return FALSE;
395     }
396     
397   s1 = constraintTerm_getsRef (term1);
398   s2 = constraintTerm_getsRef (term2);
399
400   if ( ! (sRef_isValid(s1) && sRef_isValid(s2) ) )
401     {
402       return FALSE;
403     }
404   
405  DPRINTF( (message
406             ("Comparing srefs for %s and  %s ", constraintTerm_print(term1), constraintTerm_print(term2)
407              )
408             )
409            );
410  
411  if (sRef_similarRelaxed(s1, s2)   || sRef_sameName (s1, s2) )
412    {
413      DPRINTF ((message (" %s and %s are same", constraintTerm_print(term1), constraintTerm_print(term2)  )  ));
414      return TRUE;
415    }
416  else
417    {
418      DPRINTF ((message (" %s and %s are not same", constraintTerm_print(term1), constraintTerm_print(term2)  )  ));
419      return FALSE;
420    }     
421     
422 }
423
424 void constraintTerm_dump ( /*@observer@*/ constraintTerm t,  FILE *f)
425 {
426   fileloc loc;
427   constraintTermValue value;
428   constraintTermType kind;
429   uentry u;
430   
431   loc = t->loc;
432
433   value = t->value;
434
435   kind  = t->kind;
436
437   fprintf(f, "%d\n", (int) kind);
438   
439   switch (kind)
440     {
441       
442     case EXPRNODE:
443       u = exprNode_getUentry(t->value.expr);
444       fprintf(f, "%s\n", cstring_toCharsSafe( uentry_rawName (u) )
445               );
446       break;
447       
448     case SREF:
449       {
450         sRef s;
451
452         s =  t->value.sref;
453         
454         if (sRef_isResult (s ) )
455           {
456             fprintf(f, "Result\n");
457           }
458         else if (sRef_isParam (s ) )
459           {
460             int param;
461             ctype ct;
462             cstring ctString;
463
464             
465             ct =  sRef_getType (s); 
466             param = sRef_getParam(s);
467
468             ctString =  ctype_dump(ct);
469             
470             fprintf(f, "Param %s %d\n", cstring_toCharsSafe(ctString), (int) param );
471             cstring_free(ctString);
472           }
473         else
474           {
475             u = sRef_getUentry(s);
476             fprintf(f, "%s\n", cstring_toCharsSafe(uentry_rawName (u) ) );
477           }
478         
479       }
480       break;
481       
482     case INTLITERAL:
483       fprintf (f, "%d\n", t->value.intlit);
484       break;
485       
486     default:
487       BADEXIT;
488     }
489   
490 }
491
492
493 /*@only@*/ constraintTerm constraintTerm_undump ( FILE *f)
494 {
495   constraintTermType kind;
496   constraintTerm ret;
497   
498   uentry ue;
499   
500   char * str;
501   char * os;
502
503   str = mstring_create (MAX_DUMP_LINE_LENGTH);
504   os = str;
505   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
506
507   kind = (constraintTermType) reader_getInt(&str);
508   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
509
510   switch (kind)
511     {
512       
513     case SREF:
514       {
515         sRef s;
516         char * term;
517         term = reader_getWord(&str);
518         
519         if (strcmp (term, "Result") == 0 )
520           {
521             s = sRef_makeResult();
522           }
523         else if (strcmp (term, "Param" ) == 0 )
524           {
525             int param;
526             char *str2, *ostr2;
527             
528             ctype t;
529
530             reader_checkChar(&str, ' ');
531             str2  = reader_getWord(&str);
532             param = reader_getInt(&str);
533
534             ostr2 = str2;
535             t = ctype_undump(&str2) ;
536             s = sRef_makeParam (param, t );
537             free (ostr2);
538           }
539         else  //This must be an identified that we can search for
540           // in usymTab
541           {
542             cstring termStr = cstring_makeLiteralTemp(term);
543
544             ue = usymtab_lookup (termStr);
545             s = uentry_getSref(ue);
546           }
547         
548         ret = constraintTerm_makesRef(s);
549
550         free(term);
551       }
552       break;
553
554     case EXPRNODE:
555       {
556         sRef s;
557         char * term;
558         cstring termStr;
559                 
560         term = reader_getWord(&str);
561         //This must be an identifier that we can search for
562           // in usymTab
563         termStr = cstring_makeLiteralTemp(term);
564         
565         ue = usymtab_lookup (termStr);
566         s = uentry_getSref(ue);
567         ret = constraintTerm_makesRef(s);
568
569         free (term);
570       }
571       break;
572       
573       
574     case INTLITERAL:
575       {
576         int i;
577
578         i = reader_getInt(&str);
579         ret = constraintTerm_makeIntLiteral (i);
580       }
581       break;
582       
583     default:
584       BADEXIT;
585     }
586   free (os);
587
588   return ret;
589 }
590
591
592
593
This page took 0.717138 seconds and 5 git commands to generate.