]> andersk Git - splint.git/blob - src/constraintTerm.c
Merged code tree with Dave Evans's version. Many changes to numberous to list....
[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 /*@unused@*/ static bool constraintTerm_same (constraintTerm p_term1, constraintTerm p_term2) ;
23
24 void constraintTerm_free (/*@only@*/ constraintTerm term)
25 {
26   llassert(constraintTerm_isDefined(term) );
27   fileloc_free (term->loc);
28   
29   switch (term->kind) 
30     {
31     case EXPRNODE:
32       /* we don't free an exprNode*/
33       break;
34     case SREF:
35       /* sref */
36       //sRef_free (term->value.sref);
37       break;
38     case INTLITERAL:
39       /* don't free an int */
40       break;
41     case  ERRORBADCONSTRAINTTERMTYPE:
42     default:
43       /* type was set incorrectly */
44       llcontbug (message("constraintTerm_free type was set incorrectly"));
45     }
46   free (term);
47 }
48
49 /*@only@*/ static/*@out@*/ constraintTerm new_constraintTermExpr (void)
50 {
51   constraintTerm ret;
52   ret = dmalloc (sizeof (* ret ) );
53   ret->value.intlit = 0;
54   return ret;
55 }
56
57
58 bool constraintTerm_isIntLiteral (constraintTerm term)
59 {
60   llassert(term != NULL);
61   
62   if (term->kind == INTLITERAL)
63     return TRUE;
64
65   return FALSE;
66 }
67
68 bool constraintTerm_isStringLiteral (constraintTerm c) /*@*/
69 {
70   llassert (c != NULL);
71   if (c->kind == EXPRNODE)
72     {
73       if (exprNode_knownStringValue(c->value.expr) )
74         {
75           return TRUE;
76         }
77     }
78   return FALSE;
79 }
80
81 cstring constraintTerm_getStringLiteral (constraintTerm c)
82 {
83   llassert (c != NULL);
84   llassert (constraintTerm_isStringLiteral (c) );
85   llassert (c->kind == EXPRNODE);
86   
87   return (cstring_copy ( multiVal_forceString (exprNode_getValue (c->value.expr) ) ) );
88 }
89
90 constraintTerm constraintTerm_simplify (/*@returned@*/ constraintTerm term) /*@modifies term@*/
91 {
92   if (term->kind == EXPRNODE)
93     {
94       if ( exprNode_knownIntValue (term->value.expr ) )
95         {
96           long int temp;
97
98           temp  = exprNode_getLongValue (term->value.expr);
99           term->value.intlit = (int)temp;
100           term->kind = INTLITERAL;
101         }
102     }
103   return term;
104 }
105
106 fileloc constraintTerm_getFileloc (constraintTerm t)
107 {
108   return (fileloc_copy (t->loc) );
109 }
110
111 constraintTermType constraintTerm_getKind (constraintTerm t)
112 {
113   llassert (constraintTerm_isDefined(t) );
114   
115   return (t->kind);
116 }
117
118 /*@exposed@*/ sRef constraintTerm_getSRef (constraintTerm t)
119 {
120   llassert (constraintTerm_isDefined(t) );
121   llassert (t->kind == SREF);
122
123   return (t->value.sref);
124 }
125
126 /*@only@*/ constraintTerm constraintTerm_makeExprNode (/*@depenedent@*/  exprNode e)
127 {
128   constraintTerm ret = new_constraintTermExpr();
129   ret->loc =  fileloc_copy(exprNode_getfileloc(e));
130   ret->value.expr = e;
131   ret->kind = EXPRNODE;
132   ret = constraintTerm_simplify(ret);
133   return ret;
134 }
135
136 /*@only@*/ constraintTerm constraintTerm_makesRef  (/*@temp@*/ /*@observer@*/ sRef s)
137 {
138   constraintTerm ret = new_constraintTermExpr();
139   ret->loc =  fileloc_undefined;
140   ret->value.sref = sRef_saveCopy(s);
141   ret->kind = SREF;
142   ret = constraintTerm_simplify(ret);
143   return ret;
144 }
145
146 constraintTerm constraintTerm_copy (constraintTerm term)
147 {
148   constraintTerm ret;
149   ret = new_constraintTermExpr();
150   ret->loc = fileloc_copy (term->loc);
151   constraintTermValue_copy (ret->value, term->value);
152   ret->kind = term->kind;
153   return ret;
154 }
155
156 constraintTerm constraintTerm_setFileloc (/*@returned@*/ constraintTerm term, fileloc loc) 
157 {
158   llassert(term != NULL);
159
160   if ( fileloc_isDefined(  term->loc ) )
161     fileloc_free(term->loc);
162
163   term->loc = fileloc_copy(loc);
164   return term;
165 }
166
167
168 static cstring constraintTerm_getName (constraintTerm term)
169 {
170   cstring s;
171   s = cstring_undefined;
172   
173   llassert (term != NULL);
174
175   switch (term->kind)
176     {
177     case EXPRNODE:
178       /*@i334*/  //wtf
179       s = message ("%s", exprNode_unparse (term->value.expr) );
180       break;
181     case INTLITERAL:
182       s = message (" %d ", term->value.intlit);
183       break;
184       
185     case SREF:
186       s = message ("%q", sRef_unparse (term->value.sref) );
187
188       break;
189     default:
190       BADEXIT;
191       /*@notreached@*/
192       break;
193     }
194   
195   return s;
196 }
197
198 constraintTerm 
199 constraintTerm_doSRefFixBaseParam (/*@returned@*/constraintTerm term, exprNodeList arglist) /*@modifies term@*/
200 {
201   llassert (term != NULL);
202   
203   switch (term->kind)
204     {
205     case EXPRNODE:
206       /*@i334*/  //wtf
207       //   s = message ("%s @ %s ", exprNode_unparse (term->value.expr),
208       //           fileloc_unparse (term->loc) );
209       break;
210     case INTLITERAL:
211       //  s = message (" %d ", term->value.intlit);
212        break;
213       
214     case SREF:
215       term->value.sref = sRef_fixBaseParam (term->value.sref, arglist);
216       //      s = message ("%s ", sRef_unparse (term->value.sref) );
217
218       break;
219     default:
220       BADEXIT;
221     }
222   return term;
223   
224 }
225
226 cstring constraintTerm_print (constraintTerm term)  /*@*/
227 {
228   cstring s;
229   s = cstring_undefined;
230   
231   llassert (term != NULL);
232
233   switch (term->kind)
234     {
235     case EXPRNODE:
236       /*@i334*/  //wtf
237       s = message ("%s @ %q ", exprNode_unparse (term->value.expr),
238                    fileloc_unparse (term->loc) );
239       break;
240     case INTLITERAL:
241       s = message (" %d ", term->value.intlit);
242       break;
243       
244     case SREF:
245       s = message ("%q ", sRef_unparseDebug (term->value.sref) );
246
247       break;
248     default:
249       BADEXIT;
250     }
251   
252   return s;
253 }
254
255
256 constraintTerm constraintTerm_makeIntLiteral (int i)
257 {
258   constraintTerm ret = new_constraintTermExpr();
259   ret->value.intlit = i;
260   ret->kind = INTLITERAL;
261   ret->loc =  fileloc_undefined;
262   return ret;
263 }
264
265 bool constraintTerm_canGetValue (constraintTerm term)
266 {
267   if (term->kind == INTLITERAL)
268     return TRUE;
269   else
270     return FALSE;
271 }
272
273 int constraintTerm_getValue (constraintTerm term) 
274 {
275   llassert (term->kind == INTLITERAL);
276   return term->value.intlit;
277 }
278
279 /* same and similar are similar but not the same*/
280 static bool constraintTerm_same (constraintTerm term1, constraintTerm term2)
281 {
282   llassert (term1 !=NULL && term2 !=NULL);
283
284   if ( (term1->kind != term2->kind) || (term1->kind != EXPRNODE) )
285     {
286       return FALSE;
287     }
288       
289  DPRINTF ( (message
290             ("Comparing srefs for %s and  %s ", constraintTerm_print(term1), constraintTerm_print(term2)
291              )
292             )
293            );
294  
295  if (sRef_same (term1->value.expr->sref, term2->value.expr->sref) )
296    {
297      DPRINTF ((message (" %s and %s are same", constraintTerm_print(term1), constraintTerm_print(term2)  )  ));
298      return TRUE;
299    }
300  else
301    {
302      DPRINTF ((message (" %s and %s are not same", constraintTerm_print(term1), constraintTerm_print(term2)  )  ));
303      return FALSE;
304    }     
305     
306 }
307
308 static /*@exposed@*/ sRef constraintTerm_getsRef (constraintTerm t)
309 {
310   llassert (t != NULL);
311   if (t->kind == EXPRNODE)
312     {
313       return exprNode_getSref(t->value.expr);
314     }
315
316   if (t->kind == SREF)
317     {
318       return t->value.sref;
319     }
320
321   return sRef_undefined;
322 }
323
324 bool constraintTerm_probSame (constraintTerm term1, constraintTerm term2)
325 {
326   cstring s1, s2;
327
328   llassert (term1 !=NULL && term2 !=NULL);
329      
330  DPRINTF ( (message
331             ("Comparing srefs for %s and  %s ", constraintTerm_print(term1), constraintTerm_print(term2)
332              )
333             )
334            );
335   
336   s1 = constraintTerm_getName (term1);
337   s2 = constraintTerm_getName (term2);
338
339   if (cstring_equal (s1, s2) )
340     {
341       DPRINTF ((message (" %q and %q are same", s1, s2 ) ) );
342      return TRUE;
343    }
344   else
345      {
346      DPRINTF ((message (" %q and %q are not same", s1, s2 ) ) );
347      return FALSE;
348    }   
349 }
350
351 bool constraintTerm_similar (constraintTerm term1, constraintTerm term2)
352 {
353   sRef s1, s2;
354   
355   llassert (term1 !=NULL && term2 !=NULL);
356   
357   if ( (term1->kind == INTLITERAL) && (term2->kind == INTLITERAL) )
358     {
359       int t1, t2;
360       llassert (constraintTerm_canGetValue(term1) );
361       t1 = constraintTerm_getValue (term1);
362
363       llassert (constraintTerm_canGetValue(term2) );
364       t2 = constraintTerm_getValue (term2);
365       if (t1 == t2)
366         return TRUE;
367       
368        return FALSE;
369     }
370     
371   s1 = constraintTerm_getsRef (term1);
372   s2 = constraintTerm_getsRef (term2);
373
374   if ( ! (sRef_isValid(s1) && sRef_isValid(s2) ) )
375     {
376       return FALSE;
377     }
378   
379  DPRINTF( (message
380             ("Comparing srefs for %s and  %s ", constraintTerm_print(term1), constraintTerm_print(term2)
381              )
382             )
383            );
384  
385  if (sRef_similarRelaxed(s1, s2)   || sRef_sameName (s1, s2) )
386    {
387      DPRINTF ((message (" %s and %s are same", constraintTerm_print(term1), constraintTerm_print(term2)  )  ));
388      return TRUE;
389    }
390  else
391    {
392      DPRINTF ((message (" %s and %s are not same", constraintTerm_print(term1), constraintTerm_print(term2)  )  ));
393      return FALSE;
394    }     
395     
396 }
397
398 void constraintTerm_dump ( /*@observer@*/ constraintTerm t,  FILE *f)
399 {
400   fileloc loc;
401   constraintTermValue value;
402   constraintTermType kind;
403   uentry u;
404   
405   loc = t->loc;
406
407   value = t->value;
408
409   kind  = t->kind;
410
411   fprintf(f, "%d\n", (int) kind);
412   
413   switch (kind)
414     {
415       
416     case EXPRNODE:
417       u = exprNode_getUentry(t->value.expr);
418       fprintf(f, "%s\n", cstring_toCharsSafe( uentry_rawName (u) )
419               );
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", cstring_toCharsSafe(ctString), (int) param );
445             cstring_free(ctString);
446           }
447         else
448           {
449             u = sRef_getUentry(s);
450             fprintf(f, "%s\n", cstring_toCharsSafe(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   constraintTermType kind;
470   constraintTerm ret;
471   
472   uentry ue;
473   
474   char * str;
475   char * os;
476
477   str = mstring_create (MAX_DUMP_LINE_LENGTH);
478   os = str;
479   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
480
481   kind = (constraintTermType) reader_getInt(&str);
482   str = fgets(os, MAX_DUMP_LINE_LENGTH, f);
483
484   switch (kind)
485     {
486       
487     case SREF:
488       {
489         sRef s;
490         char * term;
491         term = reader_getWord(&str);
492         
493         if (strcmp (term, "Result") == 0 )
494           {
495             s = sRef_makeResult();
496           }
497         else if (strcmp (term, "Param" ) == 0 )
498           {
499             int param;
500             char *str2, *ostr2;
501             
502             ctype t;
503
504             reader_checkChar(&str, ' ');
505             str2  = reader_getWord(&str);
506             param = reader_getInt(&str);
507
508             ostr2 = str2;
509             t = ctype_undump(&str2) ;
510             s = sRef_makeParam (param, t );
511             free (ostr2);
512           }
513         else  //This must be an identified that we can search for
514           // in usymTab
515           {
516             cstring termStr = cstring_makeLiteralTemp(term);
517
518             ue = usymtab_lookup (termStr);
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         cstring termStr;
533                 
534         term = reader_getWord(&str);
535         //This must be an identifier that we can search for
536           // in usymTab
537         termStr = cstring_makeLiteralTemp(term);
538         
539         ue = usymtab_lookup (termStr);
540         s = uentry_getSref(ue);
541         ret = constraintTerm_makesRef(s);
542
543         free (term);
544       }
545       break;
546       
547       
548     case INTLITERAL:
549       {
550         int i;
551
552         i = reader_getInt(&str);
553         ret = constraintTerm_makeIntLiteral (i);
554       }
555       break;
556       
557     default:
558       BADEXIT;
559     }
560   free (os);
561
562   return ret;
563 }
564
565
566
567
This page took 0.079804 seconds and 5 git commands to generate.