Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

usymIdSet.c

Go to the documentation of this file.
00001 /*
00002 ** LCLint - annotation-assisted static program checker
00003 ** Copyright (C) 1994-2000 University of Virginia,
00004 **         Massachusetts Institute of Technology
00005 **
00006 ** This program is free software; you can redistribute it and/or modify it
00007 ** under the terms of the GNU General Public License as published by the
00008 ** Free Software Foundation; either version 2 of the License, or (at your
00009 ** option) any later version.
00010 ** 
00011 ** This program is distributed in the hope that it will be useful, but
00012 ** WITHOUT ANY WARRANTY; without even the implied warranty of
00013 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 ** General Public License for more details.
00015 ** 
00016 ** The GNU General Public License is available from http://www.gnu.org/ or
00017 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00018 ** MA 02111-1307, USA.
00019 **
00020 ** For information on lclint: lclint-request@cs.virginia.edu
00021 ** To report a bug: lclint-bug@cs.virginia.edu
00022 ** For more information: http://lclint.cs.virginia.edu
00023 */
00024 /*
00025 ** usymIdSet.c
00026 **
00027 ** based on set_template.c
00028 **
00029 ** where T has T_equal (or change this) and T_unparse
00030 */
00031 
00032 # include "lclintMacros.nf"
00033 # include "basic.h"
00034 
00035 usymIdSet
00036 usymIdSet_new ()
00037 {
00038   return usymIdSet_undefined;
00039 }
00040 
00041 static /*@notnull@*/ /*@only@*/ usymIdSet
00042 usymIdSet_newEmpty (void)
00043 {
00044   usymIdSet s = (usymIdSet) dmalloc (sizeof (*s));
00045   
00046   s->entries = 0;
00047   s->nspace = usymIdSetBASESIZE;
00048   s->elements = (usymId *) dmalloc (sizeof (*s->elements) * usymIdSetBASESIZE);
00049 
00050   return (s);
00051 }
00052 
00053 static void
00054 usymIdSet_grow (/*@notnull@*/ usymIdSet s)
00055 {
00056   int i;
00057   usymId *newelements;
00058 
00059   s->nspace = usymIdSetBASESIZE;
00060   newelements = (usymId *) dmalloc (sizeof (*newelements) * (s->entries + s->nspace));
00061 
00062   for (i = 0; i < s->entries; i++)
00063     {
00064       newelements[i] = s->elements[i];
00065     }
00066 
00067   sfree (s->elements);
00068   s->elements = newelements;
00069 }
00070 
00071 /*@only@*/ usymIdSet
00072 usymIdSet_single (usymId t)
00073 {
00074   usymIdSet s = (usymIdSet) dmalloc (sizeof (*s));
00075    
00076   s->entries = 1;
00077   s->nspace = usymIdSetBASESIZE - 1;
00078   s->elements = (usymId *) dmalloc (sizeof (*s->elements) * usymIdSetBASESIZE);
00079   s->elements[0] = t;
00080 
00081   return (s);
00082 }
00083 
00084 static usymIdSet 
00085   usymIdSet_insert (/*@returned@*/ usymIdSet s, usymId el)
00086 {
00087   if (usymIdSet_isUndefined (s))
00088     {
00089       s = usymIdSet_newEmpty ();
00090     }
00091 
00092   if (usymIdSet_member (s, el))
00093     {
00094       return s;
00095     }
00096   else
00097     {
00098       if (s->nspace <= 0)
00099         usymIdSet_grow (s);
00100       s->nspace--;
00101       s->elements[s->entries] = el;
00102       s->entries++;
00103       return s;
00104     }
00105 }
00106 
00107 static usymIdSet
00108 usymIdSet_copy (/*@notnull@*/ usymIdSet s)
00109 {
00110   int size = s->entries + 1;
00111   usymIdSet t = (usymIdSet) dmalloc (sizeof (*t));
00112   int i;
00113   
00114   t->entries = s->entries;
00115   t->nspace = 1;
00116   t->elements = (usymId *) dmalloc (sizeof (*t->elements) * size);
00117   
00118   for (i = 0; i < s->entries; i++)
00119     {
00120       t->elements[i] = s->elements[i];
00121     }
00122   
00123   return t;
00124 }
00125 
00126 usymIdSet
00127 usymIdSet_add (usymIdSet s, usymId el)
00128 {
00129   if (usymIdSet_isDefined (s))
00130     {
00131       llassert (!usymIdSet_member (s, el));
00132       
00133       return (usymIdSet_insert (usymIdSet_copy (s), el));
00134     }
00135   else
00136     {
00137       return (usymIdSet_single (el));
00138     }
00139 }
00140 
00141 usymIdSet
00142 usymIdSet_removeFresh (/*@temp@*/ usymIdSet s, usymId el)
00143 {
00144   if (usymIdSet_isDefined (s))
00145     {
00146       usymIdSet t = usymIdSet_newEmpty ();
00147       int i;
00148       
00149       for (i = 0; i < s->entries; i++)
00150         {
00151           if (!usymId_equal (el, s->elements[i]))
00152             {
00153               t = usymIdSet_insert (t, s->elements[i]);
00154             }
00155         }
00156       
00157       return t;
00158     }
00159   else
00160     {
00161       return usymIdSet_undefined;
00162     }
00163 }
00164 
00165 usymIdSet
00166 usymIdSet_newUnion (usymIdSet s1, usymIdSet s2)
00167 {
00168   usymIdSet t = usymIdSet_new ();
00169 
00170   usymIdSet_elements (s1, current)
00171     {
00172       t = usymIdSet_insert (t, current);
00173     } end_usymIdSet_elements;
00174 
00175   usymIdSet_elements (s2, current)
00176     {
00177       t = usymIdSet_insert (t, current);
00178     } end_usymIdSet_elements;
00179 
00180   return t;
00181 }
00182 
00183 /*
00184 ** returns a new usymIdSet comprised of all elements
00185 ** in s which are not in t.
00186 */
00187 
00188 usymIdSet
00189 usymIdSet_subtract (usymIdSet s, usymIdSet t)
00190 {
00191   usymIdSet r = usymIdSet_new ();
00192 
00193   usymIdSet_elements (s, current)
00194     {
00195       if (!usymIdSet_member (t, current))
00196         {
00197           r = usymIdSet_insert (r, current);
00198         }
00199     } end_usymIdSet_elements;
00200 
00201   return r;
00202 }
00203 
00204 bool
00205 usymIdSet_member (usymIdSet s, usymId el)
00206 {
00207   if (usymIdSet_isUndefined (s))
00208     {
00209       return FALSE;
00210     }
00211   else
00212     {
00213       int i;
00214       
00215       for (i = 0; i < s->entries; i++)
00216         {
00217           if (usymId_equal (el, s->elements[i]))
00218             return TRUE;
00219         }
00220       return FALSE;
00221     }
00222 }
00223 
00224 void
00225 usymIdSet_free (/*@only@*/ usymIdSet s)
00226 {
00227   if (!usymIdSet_isUndefined (s))
00228     {
00229       int i;
00230       for (i = 0; i < s->entries; i++)
00231         {
00232           /*      usymId_free (s->elements[i]); */
00233         }
00234       
00235       sfree (s->elements); 
00236       sfree (s);
00237     }
00238 }
00239 
00240 cstring usymIdSet_dump (usymIdSet lset)
00241 {
00242   cstring st = cstring_undefined;
00243   
00244   if (!usymIdSet_isUndefined (lset))
00245     {
00246       bool first = TRUE;
00247       int i;
00248       
00249       for (i = 0; i < lset->entries; i++)
00250         {
00251           usymId current = lset->elements[i];
00252           
00253           if (!usymId_isInvalid (current))
00254             {
00255               current = usymtab_convertId (current);
00256 
00257               if (first)
00258                 {
00259                   st = message ("%d", current);
00260                   first = FALSE;
00261                 }
00262               else
00263                 {
00264                   st = message ("%q,%d", st, current);
00265                 }
00266             }
00267         }
00268     }
00269   return (st);
00270 }
00271 
00272 /*
00273 ** end of list is '@' or '\0'
00274 */
00275 
00276 usymIdSet
00277 usymIdSet_undump (char **s)
00278 {
00279   usymIdSet t = usymIdSet_new ();
00280   char *olds = *s;
00281   char c;
00282 
00283   
00284   while ((c = **s) != '\0' && c != '@' && c != '#' && c != '\n')
00285     {
00286       int tid = 0;
00287 
00288       while (c != '@' && c != '#' && c != ',' && c != '\0' && c != '\n')
00289         {
00290           while (c >= '0' && c <= '9')
00291             {
00292               tid *= 10;
00293               tid += (int) (c - '0');
00294               (*s)++;
00295               c = **s;
00296             }
00297 
00298           if (*s == olds)
00299             {
00300               llcontbug (message ("usymIdSet_undump: loop: %s", 
00301                                   cstring_fromChars (*s)));
00302 
00303               while (**s != '\0') 
00304                 {
00305                   (*s)++;
00306                 }
00307 
00308               /*@innerbreak@*/ break;
00309             }
00310 
00311           olds = *s;
00312           
00313           t = usymIdSet_insert (t, usymId_fromInt (tid));
00314         }
00315 
00316       if (c == ',')
00317         {
00318           (*s)++;
00319         }
00320     }
00321 
00322   return t;
00323 }
00324 
00325 /*@only@*/ cstring
00326 usymIdSet_unparse (usymIdSet ll)
00327 {
00328   cstring s = cstring_undefined;
00329 
00330   if (!usymIdSet_isUndefined (ll))
00331     {
00332       int i;
00333       
00334       for (i = 0; i < ll->entries; i++)
00335         {
00336           usymId current = ll->elements[i];
00337 
00338           if (i == 0)
00339             s = uentry_getName (usymtab_getGlobalEntry (current));
00340           else
00341             s = message ("%q, %q", s, uentry_getName (usymtab_getGlobalEntry (current)));
00342         }
00343     }
00344   
00345   return s;
00346 }
00347 
00348 int 
00349 usymIdSet_compare (usymIdSet l1, usymIdSet l2)
00350 {
00351   if (usymIdSet_isUndefined (l1))
00352     {
00353       return (usymIdSet_size (l2) == 0 ? 0 : 1);
00354     }
00355   
00356   if (usymIdSet_isUndefined (l2))
00357     {
00358       return (usymIdSet_size (l1) == 0 ? 0 : 1);
00359     }
00360   
00361   {
00362     int li1 = l1->entries;
00363     int li2 = l2->entries;
00364     int leastelements = (li1 < li2) ? li1 : li2;
00365     int i = 0;
00366     
00367     while (i < leastelements)
00368       {
00369         if (usymId_equal (l1->elements[i], l2->elements[i]))
00370           {
00371             i++;
00372           }
00373         else
00374           {
00375             if (l1->elements[i] > l2->elements[i]) 
00376               {
00377                 return 1;
00378               }
00379             else
00380               {
00381                 return -1;
00382               }
00383           }
00384       }
00385 
00386     return (int_compare (li1, li2));
00387   }
00388 }

Generated at Fri Nov 3 18:57:46 2000 for LCLint by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000