]> andersk Git - splint.git/blob - src/constraintList.c
Merged this branch with the one in the splint.sf.net repository.
[splint.git] / src / constraintList.c
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2000 University of Virginia,
4 **         Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 ** 
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ** General Public License for more details.
15 ** 
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
19 **
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
23 */
24
25 /*
26 ** constraintList.c
27 **
28 ** based on list_template.c
29 **
30 ** where T has T_equal (or change this) and T_unparse
31 */
32
33 # include "splintMacros.nf"
34 # include "llbasic.h"
35
36 /*@-nullderef@*/ /* !!! DRL needs to fix this code! */
37 /*@-nullstate@*/ /* !!! DRL needs to fix this code! */
38 /*@-nullpass@*/ /* !!! DRL needs to fix this code! */
39
40
41 /*@iter constraintList_elements_private_only (sef constraintList x, yield only constraint el); @*/
42 # define constraintList_elements_private_only(x, m_el) \
43    { if (constraintList_isDefined (x)) { int m_ind; constraint *m_elements = &((x)->elements[0]); \
44      for (m_ind = 0 ; m_ind < (x)->nelements; m_ind++) \
45        { constraint m_el = *(m_elements++); 
46
47 # define end_constraintList_elements_private_only }}}
48
49
50 /*@iter constraintList_elements_private (sef constraintList x, yield  constraint el); @*/
51 # define constraintList_elements_private(x, m_el) \
52    { if (constraintList_isDefined (x)) { int m_ind; constraint *m_elements = &((x)->elements[0]); \
53      for (m_ind = 0 ; m_ind < (x)->nelements; m_ind++) \
54        { constraint m_el = *(m_elements++); 
55
56 # define end_constraintList_elements_private }}}
57
58
59 /*@only@*/ constraintList constraintList_makeNew ()
60 {
61   constraintList s = (constraintList) dmalloc (sizeof (*s));
62
63   s->nelements = 0;
64   s->nspace = constraintListBASESIZE;
65   s->elements = (constraint *)
66     dmalloc (sizeof (*s->elements) * constraintListBASESIZE);
67   
68   return (s);
69 }
70
71 static void
72 constraintList_grow (constraintList s)
73 {
74   int i;
75   constraint *newelements; 
76
77   llassert (constraintList_isDefined (s));
78
79   s->nspace += constraintListBASESIZE;
80   newelements = (constraint *) dmalloc (sizeof (*newelements)
81                                      * (s->nelements + s->nspace));
82
83   for (i = 0; i < s->nelements; i++)
84     {
85       newelements[i] = s->elements[i]; 
86     }
87
88   sfree (s->elements); 
89   s->elements = newelements;
90 }
91
92
93 constraintList 
94 constraintList_add (/*@returned@*/ constraintList s, /*@only@*/ constraint el)
95 {
96   llassert (constraintList_isDefined (s));
97
98   /*drl7x */
99
100   if (constraintList_resolve (el, s) )
101     {
102       constraint_free (el);
103       return s;
104     }
105   
106   if (s->nspace <= 0)
107     constraintList_grow (s);
108
109   s->nspace--;
110   s->elements[s->nelements] = el;
111   s->nelements++;
112   return s;
113 }
114
115 /* frees everything but actual constraints */
116 /* This function should only be used if you have 
117    other references to unshared constraints 
118 */
119 static void constraintList_freeShallow (/*@only@*/ constraintList c)
120 {
121   if (constraintList_isDefined(c) )
122     {
123       free (c->elements);
124       c->elements = NULL;
125       c->nelements = -1;
126       c->nspace = -1;
127     }
128   free (c);
129   c = NULL;
130 }
131
132 /*@only@*/ constraintList constraintList_addList (/*@only@*/ /*@returned@*/ constraintList s, /*@observer@*/ /*@temp@*/ constraintList newList)
133 {
134   llassert(constraintList_isDefined(s) );
135   llassert(constraintList_isDefined(newList) );
136
137   if (newList == constraintList_undefined)
138     return s;
139   
140   constraintList_elements (newList, elem)
141     {
142     s = constraintList_add (s, constraint_copy(elem) );
143     }
144   end_constraintList_elements;
145
146   return s;
147 }
148
149 constraintList constraintList_addListFree (/*@returned@*/ constraintList s, /*@only@*/ constraintList newList)
150 {
151   llassert(constraintList_isDefined(s) );
152   llassert(constraintList_isDefined(newList) );
153
154   if (constraintList_isUndefined(newList) )
155     return s;
156   
157   constraintList_elements_private_only(newList, elem)
158     {
159     s = constraintList_add (s, elem);
160     }
161   end_constraintList_elements_private_only
162
163     constraintList_freeShallow(newList);
164     return s;
165 }
166
167
168 constraintList constraintList_removeSurpressed (/*@only@*/ constraintList s)
169 {
170   constraintList ret;
171   fileloc loc;
172   llassert(constraintList_isDefined(s) );
173
174   ret = constraintList_makeNew();
175   
176   constraintList_elements_private_only(s, elem)
177     {
178       loc = constraint_getFileloc(elem);
179
180       if (fileloc_isUndefined(loc))
181         {
182           ret = constraintList_add (ret, elem);
183         }
184       
185       else if (context_suppressFlagMsg(FLG_BOUNDSWRITE, loc) )
186         {
187           DPRINTF ((message ("constraintList_removeSurpressed getting rid of surpressed constraint %q", 
188                              constraint_print(elem))));
189           constraint_free(elem);
190         }
191       
192       else if (!constraint_hasMaxSet(elem) && context_suppressFlagMsg(FLG_BOUNDSREAD, loc))
193         {
194           DPRINTF ((message("constraintList_removeSurpressed getting rid of surpressed constraint %q", 
195                             constraint_print(elem))));
196           constraint_free(elem);
197         }
198       else
199         {
200           ret = constraintList_add (ret, elem);
201         } 
202       fileloc_free(loc);
203     } 
204   end_constraintList_elements_private_only;
205
206   constraintList_freeShallow(s);
207   
208   return ret;
209 }
210
211
212 extern /*@only@*/ cstring constraintList_unparse ( /*@observer@*/ constraintList s) /*@*/
213 {
214   return (constraintList_print(s));
215 }
216
217 # if 0
218 static /*@only@*/ cstring
219 constraintList_printLocation (/*@temp@*/ constraintList s) /*@*/
220 {
221   int i;
222   cstring st = cstring_undefined;
223   bool first = TRUE;
224   
225   if (!constraintList_isDefined (s))
226     {
227       return cstring_makeLiteral ("<undefined>");
228     }
229
230   if (s->nelements == 0)
231     {
232       st = cstring_makeLiteral("<List Empty>");
233       return st;
234     }
235
236   for (i = 0; i < s->nelements; i++)
237     {
238       cstring type = cstring_undefined;
239       constraint current = s->elements[i];
240
241       if (constraint_isDefined(current) )
242         {
243           cstring temp1;
244               temp1 = constraint_printLocation(current);
245           type = message ("%q %q\n", type, temp1 );
246         }
247
248       if (first)
249         {
250           st = type;
251           first = FALSE;
252         }
253       else
254         {
255           st = message ("%q, %q", st, type);
256         }
257     } 
258
259   return st;
260 }
261 # endif
262
263 /*@only@*/ cstring
264 constraintList_print (/*@temp@*/ constraintList s) /*@*/
265 {
266   int i;
267   cstring st = cstring_undefined;
268   bool first = TRUE;
269   
270   if (!constraintList_isDefined (s))
271     {
272       return cstring_makeLiteral ("<undefined>");
273     }
274
275   if (s->nelements == 0)
276     {
277       st = cstring_makeLiteral("<List Empty>");
278       return st;
279     }
280
281   for (i = 0; i < s->nelements; i++)
282     {
283       cstring type = cstring_undefined;
284       constraint current = s->elements[i];
285
286       if (constraint_isDefined(current) )
287         {
288           cstring temp1;
289
290           if (context_getFlag (FLG_ORCONSTRAINT))
291               temp1 = constraint_printOr(current);
292             else
293               temp1 = constraint_print(current);
294           type = message ("%q %q ", type, temp1 );
295         }
296
297       if (first)
298         {
299           st = type;
300           first = FALSE;
301         }
302       else
303         {
304           st = message ("%q /\\ %q", st, type);
305         }
306     } 
307
308   return st;
309 }
310
311 void constraintList_printErrorPostConditions (constraintList s, fileloc loc)
312 {
313
314   constraintList_elements (s, elem)
315     {
316       if (constraint_isDefined(elem))
317         {
318           constraint_printErrorPostCondition (elem, loc);
319         }
320     }
321   end_constraintList_elements;
322   return;
323 }
324
325 void constraintList_printError (constraintList s, fileloc loc)
326 {
327
328   constraintList_elements (s, elem)
329     {
330       if (constraint_isDefined(elem) )
331         {
332           if (constraint_isPost(elem) )
333             constraint_printErrorPostCondition (elem, loc);
334           else
335             constraint_printError (elem, loc);
336         }
337     }
338   end_constraintList_elements;
339   return;
340 }
341
342
343 cstring
344 constraintList_printDetailed (constraintList s)
345 {
346   int i;
347   cstring st = cstring_undefined;
348   bool first = TRUE;
349
350   if (!constraintList_isDefined (s))
351     {
352       return cstring_makeLiteral ("<undefined>");
353     }
354
355   if (s->nelements == 0)
356     {
357       st = cstring_makeLiteral("<List Empty>");
358       return st;
359     }
360
361   for (i = 0; i < s->nelements; i++)
362     {
363       cstring type = cstring_undefined;
364       constraint current = s->elements[i];
365
366       if (constraint_isDefined(current ) )
367         {
368           cstring temp1 = constraint_printDetailed (current);
369           type = message ("%s %s\n", type, temp1 );
370           cstring_free(temp1);
371         }
372
373       if (first)
374         {
375           st = type;
376           first = FALSE;
377           type = NULL;
378         }
379       else
380         {
381           st = message ("%q %q", st, type);
382         }
383     }
384   return st;
385 }
386
387 /*{ x: constraint | (x in l1 -> resolve (x, l2) || (x in l2 -> resolve (x, l1)
388 } */
389
390 constraintList
391 constraintList_logicalOr (/*@observer@*/ constraintList l1, /*@observer@*/ constraintList l2)
392 {
393   constraint temp;
394   constraintList ret;
395   DPRINTF ((message ("Logical or on %s and %s",
396                       constraintList_print(l1), 
397                       constraintList_print(l2)) ) );
398   
399   ret = constraintList_makeNew();
400   constraintList_elements (l1, el)
401     {
402       temp = constraint_substitute (el, l2);
403       
404       if (constraintList_resolve (el, l2) || constraintList_resolve(temp,l2) )
405         {   /*avoid redundant constraints*/
406           if (!constraintList_resolve (el, ret) )
407             {
408               constraint temp2;
409               temp2 = constraint_copy(el);
410               ret = constraintList_add (ret, temp2);
411             }
412         }
413       constraint_free(temp);
414     }
415   end_constraintList_elements;
416
417    constraintList_elements (l2, el)
418     {
419       temp = constraint_substitute (el, l1);
420       
421       if (constraintList_resolve (el, l1) || constraintList_resolve(temp,l1) )
422         {
423           /*avoid redundant constraints*/
424           if (!constraintList_resolve (el, ret) )
425             {
426               constraint temp2;
427               temp2 = constraint_copy(el);
428               ret = constraintList_add (ret, temp2);
429             }
430         }
431       constraint_free(temp);
432     }
433   end_constraintList_elements;
434
435   
436   return ret;
437 }
438
439 void
440 constraintList_free (/*@only@*/ constraintList s)
441 {
442   int i;
443
444   llassert(constraintList_isDefined(s) );
445
446   
447   for (i = 0; i < s->nelements; i++)
448     {
449       constraint_free (s->elements[i]); 
450     }
451
452   sfree (s->elements);
453   s->elements = NULL;
454   s->nelements = -1;
455   s->nspace = -1;
456   sfree (s);
457   s = NULL;
458 }
459
460 constraintList
461 constraintList_copy (/*@observer@*/ /*@temp@*/ constraintList s)
462 {
463   constraintList ret = constraintList_makeNew ();
464
465   constraintList_elements (s, el)
466     {
467       ret = constraintList_add (ret, constraint_copy (el));
468     } end_constraintList_elements;
469
470   return ret;
471 }
472
473 constraintList constraintList_preserveOrig (constraintList c)
474 {
475   DPRINTF((message("constraintList_preserveOrig preserving the originial constraints for %s ", constraintList_print (c) ) ));
476
477   constraintList_elements_private (c, el)
478   {
479     el = constraint_preserveOrig (el);
480   }
481   end_constraintList_elements_private;
482   return c;
483 }
484
485 constraintList constraintList_preserveCallInfo (/*@returned@*/ constraintList c,/*@observer@*/ /*@dependent@*/ /*@observer@*/  exprNode fcn)
486 {
487   DPRINTF((message("constraintList_preserveCallInfo %s ", constraintList_print (c) ) ));
488
489   constraintList_elements_private (c, el)
490   {
491     el = constraint_setFcnPre(el);
492     el = constraint_origAddGeneratingExpr (el, fcn);
493   }
494   end_constraintList_elements_private;
495   return c;
496 }
497
498 constraintList constraintList_single (constraint c)
499 {
500   constraintList res;
501   res = constraintList_makeNew();
502   res = constraintList_add (res, c);
503   return res;
504 }
505
506 constraintList constraintList_addGeneratingExpr (constraintList c,/*@dependent@*/ exprNode e)
507 {
508   DPRINTF ((message ("entering constraintList_addGeneratingExpr for %s ", exprNode_unparse(e) ) ));
509   
510   constraintList_elements_private (c, el)
511   {
512     DPRINTF ((message ("setting generatingExpr for %s to %s", constraint_print(el), exprNode_unparse(e) )  ));
513     el = constraint_addGeneratingExpr (el, e);
514   }
515   end_constraintList_elements_private;
516   return c;
517 }
518
519 /*@only@*/ constraintList constraintList_doFixResult (/*@only@*/constraintList postconditions, exprNode fcnCall)
520 {
521   constraintList ret;
522   ret = constraintList_makeNew();
523   constraintList_elements_private (postconditions, el)
524     {
525       ret = constraintList_add (ret, constraint_doFixResult (el, fcnCall) );
526     }
527   end_constraintList_elements_private;
528
529   constraintList_free(postconditions);
530   return ret;
531 }
532 /*
533 Commenting out because function is not yet stable
534   
535 / *@only@* / constraintList constraintList_doSRefFixStructConstraint(constraintList invars, sRef s, ctype ct )
536 {
537   constraintList ret;
538   ret = constraintList_makeNew();
539   
540   constraintList_elements (invars, el)
541     {
542       ret = constraintList_add(ret, constraint_doSRefFixInvarConstraint (el, s, ct) );
543     }
544   end_constraintList_elements;
545
546   / *  constraintList_free (invars);* /
547
548   return ret;
549 }
550 */
551
552 /*@only@*/ constraintList constraintList_doSRefFixConstraintParam (constraintList preconditions, /*@temp@*/ /*@observer@*/ exprNodeList arglist)
553 {
554   constraintList ret;
555   ret = constraintList_makeNew();
556
557   constraintList_elements (preconditions, el)
558     {
559       ret = constraintList_add(ret, constraint_doSRefFixConstraintParam (el, arglist) );
560     }
561   end_constraintList_elements;
562
563   constraintList_free (preconditions);
564
565   return ret;
566 }
567 constraintList constraintList_doSRefFixBaseParam (constraintList preconditions, /*@observer@*/
568                                                    exprNodeList arglist)
569 {
570   constraintList ret;
571   constraint temp;
572   ret = constraintList_makeNew();
573
574   constraintList_elements (preconditions, el)
575     {
576       temp = constraint_copy(el);
577       ret = constraintList_add(ret, constraint_doSRefFixBaseParam (temp, arglist) );
578     }
579   end_constraintList_elements;
580
581   return ret;
582 }
583
584 constraintList constraintList_togglePost (/*@returned@*/ constraintList c)
585 {
586   constraintList_elements_private (c, el)
587     {
588       el = constraint_togglePost(el);
589       if (constraint_hasOrig(el) )
590         {
591           el = constraint_togglePostOrig (el);
592         }
593     }
594   end_constraintList_elements_private;
595   return c;
596 }
597
598 /*@only@*/ constraintList constraintList_undump (FILE *f)
599 {
600   constraintList ret;
601   char *s;
602   char *os;
603   
604   ret = constraintList_makeNew();
605
606   os =  mstring_create (MAX_DUMP_LINE_LENGTH);
607   s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
608
609   while (s != NULL && *s != ';')
610     {
611       constraint temp;
612       char * c;
613
614       c =  reader_getWord(&s);
615       
616       if (strcmp (c, "C") != 0)
617         {
618           llfatalbug(message("Error reading library.  File may be corrupted"));
619         }
620
621       temp = constraint_undump (f);
622       ret = constraintList_add (ret, temp);
623       s = fgets (os, MAX_DUMP_LINE_LENGTH, f);
624       free(c);
625     }
626   free(s);
627
628   return ret;
629 }
630
631
632 void constraintList_dump (/*@observer@*/ constraintList c,  FILE *f)
633 {
634   constraintList_elements (c, el)
635     {
636       fprintf(f, "C\n");
637       constraint_dump (el, f);
638     }
639   end_constraintList_elements; ;
640 }
641
642
643 constraintList constraintList_sort (/*@returned@*/ constraintList ret)
644 {
645   qsort (ret->elements, (size_t) ret->nelements,
646          (sizeof (*ret->elements)), 
647          (int (*)(const void *, const void *)) constraint_compare);
648   
649   DPRINTF((message("onstraint_sort returning") ));
650   return ret;
651 }
652
653
This page took 0.087288 seconds and 5 git commands to generate.