]> andersk Git - splint.git/blob - src/sRefSet.c
9fffe5f85be9d8713fa8e1d9a610f9b9c36f291e
[splint.git] / src / sRefSet.c
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 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 ** sRefSet.c
26 **
27 ** based on set_template.c
28 **
29 ** where T has T_equal (or change this) and T_unparse
30 */
31
32 # include "splintMacros.nf"
33 # include "basic.h"
34
35 sRefSet
36 sRefSet_new ()
37 {
38   return sRefSet_undefined;
39 }
40
41 static /*@notnull@*/ /*@only@*/ sRefSet
42 sRefSet_newEmpty (void)
43 {
44   sRefSet s = (sRefSet) dmalloc (sizeof (*s));
45   
46   s->entries = 0;
47   s->nspace = sRefSetBASESIZE;
48   s->elements = (sRef *) dmalloc (sizeof (*s->elements) * sRefSetBASESIZE);
49
50   return (s);
51 }
52
53 /*@only@*/ sRefSet
54 sRefSet_single (/*@exposed@*/ sRef sr)
55 {
56   sRefSet s = (sRefSet) dmalloc (sizeof (*s));
57   
58   s->entries = 1;
59   s->nspace = sRefSetBASESIZE - 1;
60   s->elements = (sRef *) dmalloc (sizeof (*s->elements) * sRefSetBASESIZE);
61   s->elements[0] = sr;
62
63   return (s);
64 }
65
66 static void
67 sRefSet_grow (/*@notnull@*/ sRefSet s)
68 {
69   int i;
70   sRef *newelements; 
71
72   s->nspace = sRefSetBASESIZE;
73   newelements = (sRef *) dmalloc (sizeof (*newelements) * (s->entries + s->nspace));
74
75   for (i = 0; i < s->entries; i++)
76     {
77       newelements[i] = s->elements[i];
78     }
79
80   sfree (s->elements);
81   s->elements = newelements;
82 }
83
84 sRefSet
85 sRefSet_insert (sRefSet s, /*@exposed@*/ sRef el)
86 {
87   if (sRefSet_isUndefined (s))
88     {
89       s = sRefSet_newEmpty ();
90     }
91
92   
93   if (!sRefSet_isSameMember (s, el))
94     {
95       
96       if (s->nspace <= 0)
97         sRefSet_grow (s);
98
99       s->nspace--;
100
101       llassert (s->elements != NULL);
102       s->elements[s->entries] = el;
103       s->entries++;
104     }
105   else
106     {
107       ;
108     }
109   
110   return s;
111 }
112
113 void
114 sRefSet_clear (sRefSet s)
115 {
116   if (sRefSet_isDefined (s))
117     {
118       s->nspace += s->entries;
119       s->entries = 0;
120     }
121 }
122
123 /*
124 ** slow algorithm...but it doesn't matter
125 */
126
127 void
128 sRefSet_clearStatics (sRefSet s)
129 {
130   if (sRefSet_isDefined (s))
131     {
132       int i;
133       
134       for (i = 0; i < s->entries; i++)
135         {
136           sRef current = s->elements[i];
137           
138           if (sRef_isFileStatic (sRef_getRootBase (current)))
139             {
140               int j;
141               
142               for (j = i; j < s->entries - 1; j++)
143                 {
144                   s->elements[j] = s->elements[j+1];
145                 }
146               
147               s->entries--;
148               s->nspace++;
149               i--;
150             }
151         }
152     }
153 }
154
155 bool
156 sRefSet_delete (sRefSet s, sRef el)
157 {
158   int i;
159
160   if (sRefSet_isUndefined (s)) return FALSE;
161
162   if (s->elements != NULL)
163     {
164       for (i = 0; i < s->entries; i++)
165         {
166           sRef current = s->elements[i];
167           
168           if (sRef_realSame (el, current))
169             {
170               int j;
171
172               for (j = i; j < s->entries - 1; j++)
173                 {
174                   s->elements[j] = s->elements[j+1];
175                 }
176               
177               s->entries--;
178               s->nspace++;
179               return TRUE;
180             }
181         }
182     }
183
184   return FALSE;
185 }
186
187 /*@exposed@*/ sRef
188 sRefSet_choose (sRefSet s)
189 {
190   llassert (sRefSet_isDefined (s));
191   llassert (s->entries > 0);
192   llassert (s->elements != NULL);
193
194   return (s->elements[0]);
195 }
196
197 /*@exposed@*/ sRef
198 sRefSet_mergeIntoOne (sRefSet s)
199 {
200   sRef res;
201   int i;
202
203   if (sRefSet_isUndefined (s)) return sRef_undefined;
204   if (s->entries == 0) return sRef_undefined;
205
206   llassert (s->elements != NULL);
207
208   res = s->elements[0];
209
210   for (i = 1; i < s->entries; i++)
211     {
212       sRef tmp;
213
214       tmp = sRef_makeConj (res, s->elements[i]);
215       res = tmp;
216     }
217   
218   return res;
219 }
220
221 /*
222 ** this is really yucky...but it works...
223 */
224
225 bool
226 sRefSet_deleteBase (sRefSet s, sRef base)
227 {
228   int i = 0;
229   int offset = 0;
230
231   if (sRefSet_isUndefined (s) || (s->elements == NULL))
232     {
233       return FALSE;
234     } ;
235
236   while (i + offset < s->entries)
237     {
238       sRef current = s->elements[i + offset];
239
240       while (sRef_includedBy (current, base))
241         {
242                   offset++;
243           if (i + offset >= s->entries) goto doneLoop;
244           current = s->elements [i + offset];
245         }
246       
247       if (offset > 0)
248         {
249                   s->elements [i] = current;
250         }
251       
252       i++;
253     }
254
255  doneLoop:
256   s->entries -= offset;
257   s->nspace += offset;
258
259   return (offset > 0);
260 }
261
262 /*
263 ** modifies *s1
264 */
265
266 sRefSet
267 sRefSet_unionFree (/*@returned@*/ sRefSet s1, sRefSet s2)
268 {
269   sRefSet res = sRefSet_union (s1, s2);
270
271   sRefSet_free (s2);
272   return res;
273 }
274
275 sRefSet
276 sRefSet_union (/*@returned@*/ sRefSet s1, sRefSet s2)
277 {
278   if (s1 == s2) 
279     {
280       return s1;
281     }
282
283   if (sRefSet_isEmpty (s1))
284     {
285       s1 = sRefSet_copyInto (s1, s2);
286     }
287   else
288     {
289       sRefSet_allElements (s2, el)
290         {
291           s1 = sRefSet_insert (s1, el);
292         } end_sRefSet_allElements;
293     }
294
295   return s1;
296 }
297
298 /*
299 ** s1 <- s1 U (s2 - ex - params)
300 */
301
302 sRefSet
303 sRefSet_unionExcept (/*@returned@*/ sRefSet s1, sRefSet s2, sRef ex)
304 {
305   if (s1 == s2) return s1;
306
307   sRefSet_allElements (s2, el)
308     {
309       if (sRef_same (el, ex))
310         {
311           ;
312         }
313       else
314         {
315           s1 = sRefSet_insert (s1, el);
316         }
317     } end_sRefSet_allElements;
318   
319   return s1;
320 }
321
322 /*@only@*/ sRefSet
323 sRefSet_realNewUnion (sRefSet s1, sRefSet s2)
324 {
325   llassert (NOALIAS (s1, s2));
326
327   if (sRefSet_isUndefined (s1))
328     {
329       return (sRefSet_newCopy (s2));
330     }
331   else
332     {
333       sRefSet ret = sRefSet_newCopy (s1);
334       
335       sRefSet_allElements (s2, el)
336         {
337           ret = sRefSet_insert (ret, el);
338         } end_sRefSet_allElements;
339       
340       return ret;
341     }
342 }
343
344 /* slow! */
345
346 /*@only@*/ sRefSet
347 sRefSet_intersect (sRefSet s1, sRefSet s2)
348 {
349   sRefSet s = sRefSet_new ();
350
351   llassert (NOALIAS (s1, s2));
352
353   sRefSet_allElements (s1, el)
354     {
355       if (sRefSet_member (s2, el))
356         {
357           s = sRefSet_insert (s, el);
358         }
359     } end_sRefSet_allElements;
360   
361     return s;
362 }
363
364 sRefSet
365 sRefSet_levelUnion (/*@returned@*/ sRefSet sr, sRefSet s, int lexlevel)
366 {
367   llassert (NOALIAS (sr, s));
368
369   sRefSet_allElements (s, el)
370     {
371       if (sRef_lexLevel (el) <= lexlevel)
372         {
373           sr = sRefSet_insert (sr, el);
374         }
375     } end_sRefSet_allElements;
376
377   return sr;
378 }
379
380 void
381 sRefSet_levelPrune (sRefSet s, int lexlevel)
382 {
383   if (sRefSet_isDefined (s))
384     {
385       int i;
386       int backcount = sRefSet_size (s) - 1;
387       
388       for (i = 0; i <= backcount; i++)
389         {
390           sRef el = s->elements[i]; 
391           
392           if (sRef_lexLevel (el) > lexlevel)
393             {
394               int j;
395               
396               
397               for (j = backcount; j > i; j--)
398                 {
399                   backcount--;
400                   s->entries--;
401                   s->nspace++;
402                   
403                   if (sRef_lexLevel (s->elements[j]) <= lexlevel)
404                     {
405                       s->elements[i] = s->elements[j];
406                       
407                       if (backcount == i) s->entries++;
408                       /*@innerbreak@*/ break;
409                     }
410                 }
411
412               if (backcount == i)
413                 {
414                   s->entries--;
415                 }
416             }
417         }
418     }
419 }
420
421 /*
422 ** s1 <- s2
423 */
424
425 sRefSet sRefSet_copyInto (/*@returned@*/ sRefSet s1, /*@exposed@*/ sRefSet s2)
426 {
427   int origentries;
428   
429   llassert (NOALIAS (s1, s2));
430   
431   if (sRefSet_isUndefined (s1))
432     {
433       if (sRefSet_isEmpty (s2))
434         {
435           return s1;
436         }
437       else
438         {
439           s1 = sRefSet_newEmpty ();
440         }
441     } 
442
443   origentries = s1->entries;
444
445   s1->nspace = s1->entries + s1->nspace;
446   s1->entries = 0;
447
448   sRefSet_allElements (s2, el)
449     {
450       if (s1->nspace == 0)
451         {
452           sRefSet_grow (s1);
453         }
454
455       s1->elements[s1->entries] = el; 
456       s1->nspace--;
457       s1->entries++;
458     } end_sRefSet_allElements;
459
460   return s1;
461 }
462
463 /*@only@*/ sRefSet
464   sRefSet_newCopy (/*@exposed@*/ sRefSet s)
465 {
466   if (sRefSet_isEmpty (s))
467     {
468       return sRefSet_undefined;
469     }
470   else
471     {
472       sRefSet r = (sRefSet) dmalloc (sizeof (*r));
473       int i;
474       
475       r->entries = s->entries;
476       r->nspace = s->nspace;
477       r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries + s->nspace));
478       
479       for (i = 0; i < s->entries; i++)
480         {
481           r->elements[i] = s->elements[i]; 
482         }  
483       
484       return r;
485     }
486 }
487
488 /*@only@*/ sRefSet
489 sRefSet_levelCopy (/*@exposed@*/ sRefSet s, int lexlevel)
490 {
491   if (sRefSet_isEmpty (s))
492     {
493       return sRefSet_undefined;
494     }
495   else
496     {
497       sRefSet r = (sRefSet) dmalloc (sizeof (*r));
498       int i;
499       
500       r->nspace = s->entries;
501       r->entries = 0;
502       r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries)); 
503
504       for (i = 0; i < s->entries; i++)
505         {
506           if (sRef_lexLevel (s->elements[i]) <= lexlevel)
507             {
508               r->elements[r->entries] = s->elements[i];
509               r->entries++;
510               r->nspace--;
511             }
512         }  
513       
514       return r;
515     }
516 }
517
518 /*@only@*/ sRefSet
519 sRefSet_newDeepCopy (sRefSet s)
520 {
521   if (sRefSet_isUndefined (s))
522     {
523       return sRefSet_newEmpty ();
524     }
525   else
526     {
527       sRefSet r = (sRefSet) dmalloc (sizeof (*r));
528       int i;
529       
530       r->entries = s->entries;
531       r->nspace = s->nspace;
532       r->elements = (sRef *) dmalloc (sizeof (*r->elements) * (s->entries + s->nspace));
533       
534       for (i = 0; i < s->entries; i++)
535         {
536           r->elements[i] = sRef_copy (s->elements[i]);
537         }  
538       
539       return r;
540     }
541 }
542
543 static bool
544 sRefSet_isElementCompare (bool (*test)(sRef, sRef), sRefSet s, sRef el)
545 {
546   sRefSet_allElements (s, e)
547     {
548       if ((test)(el, e))
549         {
550           return TRUE;
551         }
552     } end_sRefSet_allElements;
553
554   return FALSE;
555 }
556
557 static bool
558 sRefSet_isElementTest (bool (*test)(sRef), sRefSet s)
559 {
560   sRefSet_allElements (s, e)
561     {
562       if ((test)(e))
563         {
564           return TRUE;
565         }
566     } end_sRefSet_allElements;
567
568   return FALSE;
569 }
570
571 bool
572 sRefSet_hasRealElement (sRefSet s)
573 {
574   sRefSet_allElements (s, e)
575     {
576       if (sRef_isMeaningful (e) && !sRef_isUnconstrained (e))
577         {
578           return TRUE;
579         }
580     } end_sRefSet_allElements;
581
582   return FALSE;
583 }
584
585 bool
586 sRefSet_containsSameObject (sRefSet s, sRef el)
587 {
588   return (sRefSet_isElementCompare (sRef_sameObject, s, el));
589 }
590
591 bool
592 sRefSet_isSameMember (sRefSet s, sRef el)
593 {
594   return (sRefSet_isElementCompare (sRef_realSame, s, el));
595 }
596
597 bool
598 sRefSet_isSameNameMember (sRefSet s, sRef el)
599 {
600   return (sRefSet_isElementCompare (sRef_sameName, s, el));
601 }
602
603 bool
604 sRefSet_member (sRefSet s, sRef el)
605 {
606   return (sRefSet_isElementCompare (sRef_similar, s, el));
607 }
608
609 bool
610 sRefSet_hasStatic (sRefSet s)
611 {
612   return (sRefSet_isElementTest (sRef_isFileStatic, s));
613 }
614
615 bool
616 sRefSet_hasUnconstrained (sRefSet s)
617 {
618   return (sRefSet_isElementTest (sRef_isUnconstrained, s));
619 }
620
621 cstring
622   sRefSet_unparseUnconstrained (sRefSet s)
623 {
624   int num = 0;
625   cstring res = cstring_undefined;
626   
627   sRefSet_allElements (s, el)
628     {
629       if (sRef_isUnconstrained (el))
630         {
631           if (cstring_isUndefined (res))
632             {
633               res = cstring_copy (sRef_unconstrainedName (el));
634             }
635           else
636             {
637               res = message ("%q, %s", res, sRef_unconstrainedName (el));
638             }
639           
640           num++;
641         }
642     } end_sRefSet_allElements ;
643   
644   if (num == 0)
645     {
646       llassert (cstring_isUndefined (res));
647       return (cstring_makeLiteral ("<ERROR: no unconstrained calls>"));
648     }
649   else if (num == 1)
650     {
651       return (message ("unconstrained function %q", res));
652     }
653   else
654     {
655       return (message ("unconstrained functions %q", res));
656     }
657 }
658
659 cstring
660 sRefSet_unparseUnconstrainedPlain (sRefSet s)
661 {
662   cstring res = cstring_undefined;
663
664   sRefSet_allElements (s, el)
665     {
666       if (sRef_isUnconstrained (el))
667         {
668           if (cstring_isUndefined (res))
669             {
670               res = cstring_copy (sRef_unconstrainedName (el));
671             }
672           else
673             {
674               res = message ("%q, %s", res, sRef_unconstrainedName (el));
675             }
676         }
677     } end_sRefSet_allElements ;
678
679   return res;
680 }
681       
682 bool
683 sRefSet_modifyMember (sRefSet s, sRef m)
684 {
685   bool ret = FALSE;
686
687   sRefSet_allElements (s, e)
688     {
689       if (sRef_similar (m, e))
690         {
691           sRef_setModified (e);
692           ret = TRUE;
693         }
694     } end_sRefSet_allElements;
695
696   
697   return ret;
698 }
699
700 /*@exposed@*/ sRef
701 sRefSet_lookupMember (sRefSet s, sRef el)
702 {
703   sRefSet_allElements (s, e)
704     {
705       if (sRef_similar (el, e))
706         {
707           return e;
708         }
709     } end_sRefSet_allElements;
710   
711   return sRef_undefined;
712 }
713
714 int sRefSet_size (sRefSet s)
715 {
716   if (sRefSet_isUndefined (s)) return 0;
717   return s->entries;
718 }
719
720 /*@only@*/ cstring
721 sRefSet_unparse (sRefSet s)
722 {
723   int i;
724   cstring st = cstring_makeLiteral ("{");
725
726   if (sRefSet_isDefined (s))
727     {
728       for (i = 0; i < sRefSet_size (s); i++)
729         {
730           if (i == 0)
731             st = message ("%q %q", st, sRef_unparse (s->elements[i]));
732           else
733             st = message ("%q, %q", st, sRef_unparse (s->elements[i]));
734         }
735     }
736   
737   st = message ("%q }", st);
738   return st;
739 }
740
741 cstring sRefSet_unparsePlain (sRefSet s)
742 {
743   int i;
744   cstring st = cstring_undefined;
745
746   if (sRefSet_isDefined (s))
747     {
748       for (i = 0; i < sRefSet_size (s); i++)
749         {
750           if (i == 0)
751             st = sRef_unparse (s->elements[i]);
752           else
753             st = message ("%q, %q", st, sRef_unparse (s->elements[i]));
754         }
755     }
756   
757   return st;
758 }
759
760 cstring
761 sRefSet_unparseDebug (sRefSet s)
762 {
763   int i;
764   cstring st = cstring_makeLiteral ("{");
765
766   if (sRefSet_isDefined (s))
767     {
768       for (i = 0; i < sRefSet_size (s); i++)
769         {
770           if (i == 0)
771             {
772               st = message ("%q %q", st, sRef_unparseDebug (s->elements[i]));
773             }
774           else
775             {
776               st = message ("%q, %q", st, sRef_unparseDebug (s->elements[i]));
777             }
778         }
779     }
780   
781   st = message ("%q }", st);
782   return st;
783 }
784
785 cstring
786 sRefSet_unparseFull (sRefSet s)
787 {
788   int i;
789   cstring st = cstring_makeLiteral ("{");
790
791   if (sRefSet_isDefined (s))
792     {
793       for (i = 0; i < sRefSet_size (s); i++)
794         {
795           if (i == 0)
796             {
797               st = message ("%q %q", st, sRef_unparseFull (s->elements[i]));
798             }
799           else
800             {
801               st = message ("%q, %q", st, sRef_unparseFull (s->elements[i]));
802             }
803         }
804     }
805   
806   st = message ("%q }", st);
807   return st;
808 }
809
810 void
811 sRefSet_fixSrefs (sRefSet s)
812 {
813   if (sRefSet_isDefined (s))
814     {
815       int i;
816       
817       for (i = 0; i < sRefSet_size (s); i++)
818         {
819           sRef current = s->elements[i];
820
821           if (sRef_isLocalVar (current))
822             {
823               s->elements[i] = uentry_getSref (sRef_getUentry (current));
824             }
825         }
826     }
827 }
828
829 void
830 sRefSet_free (/*@only@*/ sRefSet s)
831 {
832   if (!sRefSet_isUndefined (s))
833     {
834       llassertprint (s->entries < 1000, ("sRefSet free size: %d", s->entries));
835
836       sfree (s->elements); 
837       sfree (s);
838     }
839 }
840
841 sRefSet sRefSet_removeIndirection (sRefSet s)
842 {
843   /*
844   ** returns a NEW sRefSet containing references to all sRef's in s
845   */
846
847   sRefSet t = sRefSet_new ();
848   
849   
850   sRefSet_allElements (s, el)
851     {
852       if (!sRef_isAddress (el))
853         {
854           t = sRefSet_insert (t, sRef_makeAddress (el));
855         }
856     } end_sRefSet_allElements;
857
858   return t;
859 }
860
861 sRefSet sRefSet_addIndirection (sRefSet s)
862 {
863   /*
864   ** returns a NEW sRefSet containing references to all sRef's in s
865   */
866
867   sRefSet t = sRefSet_new ();
868   
869   
870   sRefSet_allElements (s, el)
871     {
872       ctype ct = ctype_realType (sRef_getType (el));
873       
874       
875       if ((ctype_isArrayPtr (ct)))
876         {
877           
878           sRef a = sRef_constructPointer (el);
879           t = sRefSet_insert (t, a);   
880         }
881     } end_sRefSet_allElements;
882
883     return t;
884 }
885
886 sRefSet sRefSet_accessField (sRefSet s, /*@observer@*/ cstring f)
887 {
888   /*
889   ** returns a NEW sRefSet containing references to all sRef's in s
890   */
891   
892   sRefSet t = sRefSet_new ();
893   
894   sRefSet_allElements (s, el)
895     {
896       ctype ct = ctype_realType (sRef_getType (el));
897       
898       if ((ctype_isStruct (ct) || ctype_isUnion (ct))
899           && (!uentry_isUndefined (uentryList_lookupField (ctype_getFields (ct), f))))
900         {
901           t = sRefSet_insert (t, sRef_makeNCField (el, f));
902         }
903     } end_sRefSet_allElements;
904   
905     return t;
906 }
907
908 sRefSet sRefSet_fetchUnknown (sRefSet s)
909 {
910   sRefSet t = sRefSet_new ();
911   
912   sRefSet_allElements (s, el)
913     {
914       ctype ct = ctype_realType (sRef_getType (el));
915       
916       if (ctype_isArrayPtr (ct))
917         {
918           t = sRefSet_insert (t, sRef_makeArrayFetch (el));
919         }
920     } end_sRefSet_allElements;
921
922   return t;
923 }
924
925 sRefSet sRefSet_fetchKnown (sRefSet s, int i)
926 {
927   sRefSet t = sRefSet_new ();
928   
929   sRefSet_allElements (s, el)
930     {
931       ctype ct = ctype_realType (sRef_getType (el));
932       
933       if (ctype_isArrayPtr (ct))
934         {
935           t = sRefSet_insert (t, sRef_makeArrayFetchKnown (el, i));
936         }
937     } end_sRefSet_allElements;
938
939   return t;
940 }
941
942 int sRefSet_compare (sRefSet s1, sRefSet s2)
943 {
944   sRefSet_allElements (s1, el)
945     {
946       if (!sRefSet_isSameMember (s2, el))
947         {
948           return -1;
949         }
950     } end_sRefSet_allElements;
951
952   sRefSet_allElements (s2, el)
953     {
954       if (!sRefSet_isSameMember (s1, el))
955         {
956           return 1;
957         }
958     } end_sRefSet_allElements;
959
960   return 0;
961 }
962
963 bool sRefSet_equal (sRefSet s1, sRefSet s2)
964 {
965   sRefSet_allElements (s1, el)
966     {
967       if (!sRefSet_isSameMember (s2, el))
968         {
969           return FALSE;
970         }
971     } end_sRefSet_allElements;
972
973   sRefSet_allElements (s2, el)
974     {
975       if (!sRefSet_isSameMember (s1, el))
976         {
977           return FALSE;
978         }
979     } end_sRefSet_allElements;
980
981   return TRUE;
982 }
983
984 /*@only@*/ sRefSet
985 sRefSet_undump (char **s)
986 {
987   char c;
988   sRefSet sl = sRefSet_new ();
989
990   while ((c = **s) != '#' && c != '@' && c != '$' && c != '&')
991     {
992       sl = sRefSet_insert (sl, sRef_undump (s));
993
994       
995       if (**s == ',')
996         {
997           (*s)++;
998         }
999     }
1000
1001     return sl;
1002 }
1003
1004 /*@only@*/ cstring
1005 sRefSet_dump (sRefSet sl)
1006 {
1007   cstring st = cstring_undefined;
1008   bool first = TRUE;
1009
1010   
1011   sRefSet_allElements (sl, el)
1012     {
1013       if (!first)
1014         {
1015           st = cstring_appendChar (st, ',');
1016         }
1017       else
1018         {
1019           first = FALSE;
1020         }
1021
1022       st = cstring_concatFree (st, sRef_dump (el));
1023     } end_sRefSet_allElements;
1024
1025   return st;
1026 }
1027
1028 void
1029 sRefSet_markImmutable (sRefSet s)
1030 {
1031   sRefSet_allElements (s, el)
1032     {
1033       sRef_markImmutable (el);
1034     } end_sRefSet_allElements;
1035 }
1036
This page took 0.107877 seconds and 3 git commands to generate.