symtab.c

Go to the documentation of this file.
00001 /****************************************************************************/
00002 /*                                                                          */
00003 /*  This file is part of QSopt_ex.                                          */
00004 /*                                                                          */
00005 /*  (c) Copyright 2006 by David Applegate, William Cook, Sanjeeb Dash,      */
00006 /*  and Daniel Espinoza                                                     */
00007 /*                                                                          */
00008 /*  Sanjeeb Dash ownership of copyright in QSopt_ex is derived from his     */
00009 /*  copyright in QSopt.                                                     */
00010 /*                                                                          */
00011 /*  This code may be used under the terms of the GNU General Public License */
00012 /*  (Version 2.1 or later) as published by the Free Software Foundation.    */
00013 /*                                                                          */
00014 /*  Alternatively, use is granted for research purposes only.               */
00015 /*                                                                          */
00016 /*  It is your choice of which of these two licenses you are operating      */
00017 /*  under.                                                                  */
00018 /*                                                                          */
00019 /*  We make no guarantees about the correctness or usefulness of this code. */
00020 /*                                                                          */
00021 /****************************************************************************/
00022 
00023 /* RCSINFO $Id: symboltab.c,v 1.2 2003/11/05 16:47:22 meven Exp $ */
00024 #include "util.h"
00025 #include "trace.h"
00026 #include "except.h"
00027 #include "symtab.h"
00028 #ifdef USEDMALLOC
00029 #include "dmalloc.h"
00030 #endif
00031 
00032 
00033 static int TRACE = 0;
00034 
00035 static unsigned int stringhash (
00036   const char *key,
00037   int tsize);
00038 static int look_it_up (
00039   ILLsymboltab * h,
00040   const char *s);
00041 static int grow_symboltab (
00042   ILLsymboltab * h);
00043 static int grow_namelist (
00044   ILLsymboltab * h);
00045 static int add_string (
00046   ILLsymboltab * h,
00047   const char *s,
00048   int *symbol);
00049 static void delete_from_list (
00050   ILLsymboltab * h,
00051   int del_ind,
00052   int prev_ind,
00053   int x);
00054 
00055 #ifdef TRY_CODE
00056 /* debug support */
00057 static const char *get_str (
00058   const ILLsymboltab * h,
00059   int indx);
00060 static void prt_xchain (
00061   const ILLsymboltab * h,
00062   int x);
00063 static void prt_chain (
00064   const ILLsymboltab * h,
00065   char *s);
00066 #endif
00067 
00068 
00069 void ILLsymboltab_init (
00070   ILLsymboltab * h)
00071 {
00072   h->tablesize = 0;
00073   h->strsize = 0;
00074   h->freedchars = 0;
00075   h->hashspace = 0;
00076   h->name_space = 0;
00077   h->strspace = 0;
00078   h->hashtable = (int *) NULL;
00079   h->nametable = (ILLsymbolent *) NULL;
00080   h->namelist = (char *) NULL;
00081 }
00082 
00083 void ILLsymboltab_free (
00084   ILLsymboltab * h)
00085 {
00086   ILL_IFFREE (h->hashtable, int);
00087 
00088   ILL_IFFREE (h->nametable, ILLsymbolent);
00089   ILL_IFFREE (h->namelist, char);
00090 
00091   ILLsymboltab_init (h);
00092 }
00093 
00094 int ILLsymboltab_create (
00095   ILLsymboltab * h,
00096   int init_size)
00097 {
00098   int rval = 0;
00099   int i;
00100 
00101   if (init_size <= 0)
00102     init_size = 1000;
00103 
00104   ILLsymboltab_free (h);
00105 
00106   h->tablesize = 0;
00107   h->strsize = 0;
00108   h->freedchars = 0;
00109   h->name_space = init_size;
00110   h->hashspace = ILLutil_nextprime (((unsigned) h->name_space));
00111 #ifdef TRY_CODE
00112   h->strspace = init_size;
00113 #else
00114   h->strspace = init_size * 5;
00115 #endif
00116   h->index_ok = 0;
00117 
00118   ILL_SAFE_MALLOC (h->hashtable, h->hashspace, int);
00119 
00120   ILL_SAFE_MALLOC (h->nametable, h->name_space, ILLsymbolent);
00121   ILL_SAFE_MALLOC (h->namelist, h->strspace, char);
00122 
00123   for (i = 0; i < h->hashspace; i++)
00124   {
00125     h->hashtable[i] = ILL_SYM_NOINDEX;
00126   }
00127 
00128 CLEANUP:
00129   if (rval)
00130   {
00131     ILLsymboltab_free (h);
00132   }
00133   ILL_RETURN (rval, "ILLsymboltab_create");
00134 }
00135 
00136 int ILLsymboltab_copy (
00137   ILLsymboltab * src,
00138   ILLsymboltab * dst)
00139 {
00140   int rval = 0;
00141   int i;
00142 
00143   ILLsymboltab_free (dst);
00144 
00145   *dst = *src;
00146   ILL_SAFE_MALLOC (dst->hashtable, dst->hashspace, int);
00147 
00148   ILL_SAFE_MALLOC (dst->nametable, dst->name_space, ILLsymbolent);
00149   ILL_SAFE_MALLOC (dst->namelist, dst->strspace, char);
00150 
00151   for (i = 0; i < src->hashspace; i++)
00152   {
00153     dst->hashtable[i] = src->hashtable[i];
00154   }
00155   for (i = 0; i < src->tablesize; i++)
00156   {
00157     dst->nametable[i] = src->nametable[i];
00158   }
00159   for (i = 0; i < src->strsize; i++)
00160   {
00161     dst->namelist[i] = src->namelist[i];
00162   }
00163 
00164 CLEANUP:
00165   if (rval)
00166   {
00167     ILLsymboltab_free (dst);
00168   }
00169   ILL_RETURN (rval, "ILLsymboltab_copy");
00170 }
00171 
00172 
00173 const char *ILLsymboltab_get (
00174   const ILLsymboltab * h,
00175   int i)
00176 {
00177   char *name = NULL;
00178 
00179   ILL_FAILfalse_no_rval ((i >= 0) && (i <= h->tablesize), "Index out of range");
00180   if (h->nametable[i].symbol != -1)
00181     name = h->namelist + h->nametable[i].symbol;
00182 CLEANUP:
00183   return name;
00184 }
00185 
00186 int ILLsymboltab_index_ok (
00187   ILLsymboltab * h)
00188 {
00189   return (h && (h->index_ok == 1));
00190 }
00191 
00192 int ILLsymboltab_index_reset (
00193   ILLsymboltab * h,
00194   int icount,
00195   char **names)
00196 {
00197   int rval = 0;
00198   int i, k;
00199 
00200   /* Note may have tablesize 1 larger than icount, due to objname */
00201 
00202   if ((h->tablesize != icount) && (h->tablesize != icount + 1))
00203   {
00204     fprintf (stderr, "symbol table (%d) does not match reset list (%d)\n",
00205              h->tablesize, icount);
00206     rval = 1;
00207     ILL_CLEANUP;
00208   }
00209 
00210   for (i = 0; i < icount; i++)
00211   {
00212     k = look_it_up (h, (const char *) names[i]);
00213     if (k)
00214     {
00215       fprintf (stderr, "Symbol %s is not in table\n", names[i]);
00216       rval = 1;
00217       ILL_CLEANUP;
00218     }
00219     k = h->the_index;
00220     h->nametable[k].index = i;
00221   }
00222 
00223   h->index_ok = 1;
00224 
00225 CLEANUP:
00226   return rval;
00227 }
00228 
00229 int ILLsymboltab_getindex (
00230   ILLsymboltab * h,
00231   const char *name,
00232   int *hindex)
00233 {
00234   int rval = 0;
00235   int k;
00236 
00237   *hindex = -1;
00238 
00239   if (!h || !h->index_ok)
00240   {
00241     fprintf (stderr, "symbol table index out of date\n");
00242     rval = 1;
00243     ILL_CLEANUP;
00244   }
00245 
00246   k = look_it_up (h, name);
00247   if (k)
00248   {
00249     printf ("Symbol %s is not in table\n", name);
00250     fflush (stdout);
00251     ILL_CLEANUP;
00252   }
00253   k = h->the_index;
00254 
00255   *hindex = h->nametable[k].index;
00256 
00257 CLEANUP:
00258 
00259   ILL_RETURN (rval, "ILLsymboltab_getindex");
00260 }
00261 
00262 int ILLsymboltab_rename (
00263   ILLsymboltab * h,
00264   int i,
00265   const char *new_name)
00266 {
00267   int rval = 0;
00268   int symbol = 0;
00269 
00270   ILL_FAILfalse ((i >= 0) && (i <= h->tablesize), "Index out of range");
00271   if ((new_name != NULL) && (look_it_up (h, new_name) == 0))
00272   {
00273     rval = (i != h->the_index);
00274     ILL_RETURN (rval, "ILLsymboltab_rename");
00275   }
00276   if (h->nametable[i].symbol != -1)
00277   {
00278     (void) look_it_up (h, h->namelist + h->nametable[i].symbol);
00279     ILL_FAILfalse (i == h->the_index, "must find it at i");
00280     delete_from_list (h, i, h->the_prev_index, h->the_hash);
00281   }
00282   if (new_name != NULL)
00283   {
00284     rval = add_string (h, new_name, &symbol);
00285     ILL_CLEANUP_IF (rval);
00286     h->the_hash = stringhash (new_name, h->hashspace);
00287     h->nametable[i].symbol = symbol;
00288     h->nametable[i].next = h->hashtable[h->the_hash];
00289     h->hashtable[h->the_hash] = i;
00290   }
00291   else
00292   {
00293     h->nametable[i].symbol = -1;
00294     h->nametable[i].next = ILL_SYM_NOINDEX;
00295   }
00296 CLEANUP:
00297   ILL_RETURN (rval, "ILLsymboltab_rename");
00298 }
00299 
00300 int ILLsymboltab_lookup (
00301   ILLsymboltab * h,
00302   const char *s,
00303   int *ind)
00304 {
00305   int rval = look_it_up (h, s);
00306 
00307   *ind = h->the_index;
00308   return rval;
00309 }
00310 
00311 int ILLsymboltab_contains (
00312   ILLsymboltab * tab,
00313   const char *name)
00314 {
00315   return !look_it_up (tab, name);
00316 }
00317 
00318 void ILLsymboltab_size (
00319   const ILLsymboltab * h,
00320   int *p_size)
00321 {
00322   *p_size = h->tablesize;
00323 }
00324 
00325 int ILLsymboltab_register (
00326   ILLsymboltab * h,
00327   const char *s,
00328   int itemindex,
00329   int *the_prev_index,
00330   int *existed)
00331 {
00332   ILLsymbolent *nametable = h->nametable;
00333   int e, symbol = 0;
00334   int rval = 0;
00335 
00336   if (itemindex < 0)
00337   {
00338     h->index_ok = 0;
00339   }
00340 
00341   h->the_prev_index = ILL_SYM_NOINDEX;
00342   h->the_index = ILL_SYM_NOINDEX;
00343   if (s == NULL)
00344   {
00345     e = h->tablesize;
00346     h->the_index = e;
00347     *existed = 0;
00348     while (h->tablesize >= h->name_space)
00349     {
00350       rval = grow_symboltab (h);
00351       ILL_CLEANUP_IF (rval);
00352     }
00353     h->tablesize++;
00354     h->nametable[e].symbol = -1;
00355     h->nametable[e].index = itemindex;
00356     h->nametable[e].next = ILL_SYM_NOINDEX;
00357     ILL_IFTRACE ("register: %s NULL entry#=%d\n", (*existed) ? "OLD" : "NEW",
00358                  e);
00359   }
00360   else
00361   {
00362     *existed = !look_it_up (h, s);
00363     if (*existed)
00364     {
00365       ILL_IFTRACE ("register: OLD %s entry#=%d hash=%d\n",
00366                    s, h->the_index, h->the_hash);
00367       return 0;
00368     }
00369 
00370     rval = add_string (h, s, &symbol);
00371     ILL_CLEANUP_IF (rval);
00372 
00373     while (h->tablesize >= h->name_space)
00374     {
00375       rval = grow_symboltab (h);
00376       ILL_CLEANUP_IF (rval);
00377       h->the_hash = stringhash (s, h->hashspace); /*hash changes with bigger table */
00378     }
00379 
00380     nametable = h->nametable;
00381 
00382     e = h->tablesize;
00383     h->tablesize++;
00384     h->the_prev_index = e;
00385 
00386     nametable[e].symbol = symbol;
00387     nametable[e].index = itemindex;
00388     nametable[e].next = h->hashtable[h->the_hash];
00389     h->hashtable[h->the_hash] = e;
00390 
00391     ILL_IFTRACE ("register: %s NULL entry#=%d\n", (*existed) ? "OLD" : "NEW",
00392                  e);
00393   }
00394 
00395 CLEANUP:
00396   *the_prev_index = h->the_prev_index;
00397   ILL_RETURN (rval, "ILLsymboltab_register");
00398 }
00399 
00400 int ILLsymboltab_delete (
00401   ILLsymboltab * h,
00402   const char *s)
00403 {
00404   int del_ind, rval = 0;
00405   char *last;
00406 
00407   ILL_FAILtrue (s == NULL, "must give non NULL str");
00408 
00409   rval = look_it_up (h, s);
00410   del_ind = h->the_index;
00411   ILL_CLEANUP_IF (rval);        /* was not in table */
00412   ILL_FAILfalse ((del_ind != ILL_SYM_NOINDEX) &&
00413                  (h->nametable[del_ind].symbol != -1),
00414                  "we should have found this non NULL str");
00415   h->index_ok = 0;
00416   delete_from_list (h, del_ind, h->the_prev_index, h->the_hash);
00417 
00418   h->tablesize--;
00419   if (del_ind != h->tablesize)
00420   {
00421     if (h->nametable[h->tablesize].symbol != -1)
00422     {
00423       last = h->namelist + h->nametable[h->tablesize].symbol;
00424       rval = look_it_up (h, last);
00425       ILL_FAILfalse ((rval == 0) && (h->the_index == h->tablesize),
00426                      "Should find last entry");
00427       if (h->the_prev_index != ILL_SYM_NOINDEX)
00428       {
00429         h->nametable[h->the_prev_index].next = del_ind;
00430       }
00431       else
00432       {
00433         h->hashtable[h->the_hash] = del_ind;
00434       }
00435     }
00436     h->nametable[del_ind] = h->nametable[h->tablesize];
00437   }
00438 CLEANUP:
00439   ILL_RETURN (rval, "ILLsymboltab_delete");
00440 }
00441 
00442 void ILLsymboltab_prt (
00443   FILE * fd,
00444   ILLsymboltab * h)
00445 {
00446   char *str;
00447   int i;
00448 
00449   for (i = 0; i < h->tablesize; i++)
00450   {
00451     if (h->nametable[i].symbol == -1)
00452     {
00453       fprintf (fd, "%d: NULL nohash\n", i);
00454     }
00455     else
00456     {
00457       str = h->namelist + h->nametable[i].symbol;
00458       fprintf (fd, "%d: %s hash=%d\n", i, str, stringhash (str, h->hashspace));
00459     }
00460   }
00461 }
00462 
00463 static int look_it_up (
00464   ILLsymboltab * h,
00465   const char *s)
00466 {
00467   ILLsymbolent *nametable = h->nametable;
00468   char *namelist = h->namelist;
00469   int e;
00470 
00471   if(!h->hashspace) goto CLEANUP;
00472   ILL_FAILfalse_no_rval (s, "Should never call with NULL string");
00473   h->the_prev_index = ILL_SYM_NOINDEX;
00474   h->the_hash = stringhash (s, h->hashspace);
00475   for (e = h->hashtable[h->the_hash]; e != ILL_SYM_NOINDEX;
00476        e = nametable[e].next)
00477   {
00478     if (strcmp (namelist + nametable[e].symbol, s) == 0)
00479     {
00480       h->the_index = e;
00481       ILL_IFTRACE ("look_it_up: OLD %s entry#=%d hash=%d\n", s, e, h->the_hash);
00482       return 0;
00483     }
00484     h->the_prev_index = e;
00485   }
00486 CLEANUP:
00487   h->the_index = ILL_SYM_NOINDEX;
00488   ILL_IFTRACE ("look_it_up: NEW %s \n", s);
00489   return 1;
00490 }
00491 
00492 
00493 static void delete_from_list (
00494   ILLsymboltab * h,
00495   int del_ind,
00496   int prev_ind,
00497   int x)
00498 {
00499   if (prev_ind != ILL_SYM_NOINDEX)
00500   {
00501     ILL_FAILtrue_no_rval (h->nametable[prev_ind].symbol == -1,
00502                           "A NULL str with same hash ?");
00503     h->nametable[prev_ind].next = h->nametable[del_ind].next;
00504   }
00505   else
00506   {
00507     h->hashtable[x] = h->nametable[del_ind].next;
00508   }
00509   h->freedchars += strlen (h->namelist + h->nametable[del_ind].symbol) + 1;
00510 CLEANUP:
00511   ;
00512 }
00513 
00514 
00515 static int grow_symboltab (
00516   ILLsymboltab * h)
00517 {
00518   int newnamespace, newhashspace, *newhash, tablesize;
00519   ILLsymbolent *newname;
00520   char *namelist = h->namelist;
00521   int i;
00522   unsigned int x;
00523   int rval = 0;
00524 
00525   newnamespace = h->name_space * 2;
00526   newhashspace = ILLutil_nextprime (((unsigned) newnamespace));
00527   // rval = ILLutil_reallocrus_count ((void **) (&h->nametable), newnamespace,
00528   //                                 sizeof (ILLsymbolent));
00529   //ILL_CLEANUP_IF (rval);
00530   h->nametable = EGrealloc (h->nametable, sizeof (ILLsymbolent) * newnamespace);
00531   newname = h->nametable;
00532 
00533   ILL_SAFE_MALLOC (newhash, newhashspace, int);
00534   ILL_IFFREE (h->hashtable, int);
00535 
00536   h->hashtable = newhash;
00537 
00538   h->name_space = newnamespace;
00539   h->hashspace = newhashspace;
00540 
00541   newhash = h->hashtable;
00542   tablesize = h->tablesize;
00543 
00544   for (i = 0; i < newhashspace; i++)
00545   {
00546     newhash[i] = ILL_SYM_NOINDEX;
00547   }
00548   for (i = 0; i < tablesize; i++)
00549   {
00550     if (newname[i].symbol != -1)
00551     {
00552       x = stringhash (namelist + newname[i].symbol, newhashspace);
00553       newname[i].next = newhash[x];
00554       newhash[x] = i;
00555     }
00556   }
00557 CLEANUP:
00558   ILL_RETURN (rval, "grow_symboltab");
00559 }
00560 
00561 static int grow_namelist (
00562   ILLsymboltab * h)
00563 {
00564   int newstrspace, i, j, newsymbol, rval = 0;
00565   char *newnamelist, *newc;
00566 
00567   if (2 * h->freedchars >= h->strspace)
00568   {
00569     /* compact string array */
00570     ILL_SAFE_MALLOC (newnamelist, h->strspace, char);
00571 
00572     newc = newnamelist;
00573     for (i = 0; i < h->tablesize; i++)
00574     {
00575       if (h->nametable[i].symbol != -1)
00576       {
00577         newsymbol = newc - newnamelist;
00578         for (j = h->nametable[i].symbol; h->namelist[j] != '\0'; j++)
00579         {
00580           *newc = h->namelist[j];
00581           newc++;
00582         }
00583         *newc = '\0';
00584         newc++;
00585         h->nametable[i].symbol = newsymbol;
00586       }
00587     }
00588     ILL_IFFREE (h->namelist, char);
00589 
00590     h->namelist = newnamelist;
00591     h->strsize = newc - newnamelist;
00592     h->freedchars = 0;
00593   }
00594   else
00595   {
00596     newstrspace = h->strspace * 2;
00597     h->namelist = EGrealloc (h->namelist, sizeof (char) * newstrspace);
00598     //rval = ILLutil_reallocrus_count ((void **) &h->namelist, newstrspace,
00599     //                                 sizeof (char));
00600     //ILL_CLEANUP_IF (rval);
00601     h->strspace = newstrspace;
00602   }
00603 CLEANUP:
00604   ILL_RETURN (rval, "grow_namelist");
00605 }
00606 
00607 static int add_string (
00608   ILLsymboltab * h,
00609   const char *s,
00610   int *symbol)
00611 {
00612   int l, rval = 0;
00613 
00614   l = strlen (s) + 1;
00615   while (h->strsize + l > h->strspace)
00616   {
00617     rval = grow_namelist (h);
00618     ILL_CLEANUP_IF (rval);
00619   }
00620   strcpy (h->namelist + h->strsize, s);
00621   *symbol = h->strsize;
00622   h->strsize += l;
00623 CLEANUP:
00624   ILL_RETURN (rval, "add_string");
00625 }
00626 
00627 static unsigned int stringhash (
00628   const char *key,
00629   int tsize)
00630 {
00631   unsigned int x = 0;
00632 
00633 #ifdef TRY_CODE
00634   while (*key)
00635   {
00636     x += *key;
00637     key++;
00638   }
00639 #else
00640   while (*key)
00641   {
00642     x = 37 * x + *key;
00643     key++;
00644   }
00645 #endif
00646   return x % tsize;
00647 }
00648 
00649 /**************************************************************************/
00650 /* ILLsymboltab_unique_name and its support                                */
00651 /**************************************************************************/
00652 static void make_var (
00653   char *new_var,
00654   const char *prefix,
00655   char *name)
00656 {
00657   size_t plen = strlen (prefix);
00658   size_t nlen = strlen (name);
00659   char *p;
00660 
00661   if (nlen + plen >= ILL_namebufsize)
00662   {
00663     nlen = ILL_namebufsize - plen - 1;
00664   }
00665   strcpy (new_var, prefix);
00666   p = new_var + plen;
00667   strncpy (p, name, nlen + 1);
00668 }
00669 
00670 int ILLsymboltab_uname (
00671   ILLsymboltab * symtab,
00672   char *name,
00673   const char *try_prefix1,
00674   const char *try_prefix2)
00675 {
00676   int nvars = symtab->tablesize;
00677   int rval = 0;
00678   int i, found, numlen;
00679   const char *try_prefix[3];
00680   char prefix[ILL_namebufsize];
00681   char new_pre[ILL_namebufsize];
00682   char new[ILL_namebufsize];
00683 
00684   ILL_FAILtrue (try_prefix1 == NULL, "try_prefix must not be NULL");
00685   try_prefix[0] = try_prefix1;
00686   try_prefix[1] = try_prefix2;
00687   try_prefix[2] = NULL;
00688   new[0] = '\0';
00689   found = 0;
00690   for (i = 0; (!found) && try_prefix[i]; i++)
00691   {
00692     make_var (new, try_prefix[i], name);
00693     found = !ILLsymboltab_contains (symtab, new);
00694   }
00695   if (!found)
00696   {
00697     i = 0;
00698     sprintf (prefix, "%s", try_prefix[0]);
00699     numlen = (log10 ((double) (symtab->tablesize - 1) * 10)) + 1;
00700     while (!found)
00701     {
00702       ILL_FAILfalse (i <= nvars, "something wrong in find_unique_name");
00703       make_var (new_pre, prefix, name);
00704       new_pre[ILL_namebufsize - numlen - 1] = '\0';
00705       sprintf (new, "%s_%d", new_pre, i);
00706       found = !ILLsymboltab_contains (symtab, new);
00707       i++;
00708     }
00709   }
00710 
00711 CLEANUP:
00712   strcpy (name, new);
00713   return rval;
00714 }
00715 
00716 void ILLsymboltab_unique_name (
00717   ILLsymboltab * tab,
00718   int i,
00719   const char *pref,
00720   char uname2[ILL_namebufsize])
00721 {
00722   int notUnique;
00723 
00724   sprintf (uname2, "%d", i);
00725   notUnique = ILLsymboltab_uname (tab, uname2, pref, NULL);
00726   ILL_FAILtrue_no_rval (notUnique, "Programming error");
00727 CLEANUP:
00728   return;
00729 }
00730 
00731 #ifdef TRY_CODE
00732 /* debugging */
00733 static const char *get_str (
00734   const ILLsymboltab * h,
00735   int indx)
00736 {
00737   if (indx < 0 || indx >= h->tablesize)
00738   {
00739     return "INDEX OUT OF RANGE";
00740   }
00741   if (h->nametable[indx].symbol == -1)
00742   {
00743     return "NULL";
00744   }
00745   else
00746   {
00747     return h->namelist + h->nametable[indx].symbol;
00748   }
00749 }
00750 
00751 static void prt_xchain (
00752   const ILLsymboltab * h,
00753   int x)
00754 {
00755   int e;
00756   char *str;
00757 
00758   x = x % h->hashspace;
00759   printf ("chain hash %d:", x);
00760   for (e = h->hashtable[x]; e != ILL_SYM_NOINDEX; e = h->nametable[e].next)
00761   {
00762     if (h->nametable[e].symbol >= 0)
00763     {
00764       str = h->namelist + h->nametable[e].symbol;
00765       x = stringhash (str, h->hashspace);
00766       printf (" %s(h=%d, e=%d)", str, x, e);
00767     }
00768     else
00769     {
00770       printf (" NULL");
00771     }
00772   }
00773   printf ("\n");
00774 }
00775 
00776 static void prt_chain (
00777   const ILLsymboltab * h,
00778   char *s)
00779 {
00780   int e;
00781 
00782   if (s != NULL)
00783   {
00784     prt_xchain (h, stringhash (s, h->hashspace));
00785   }
00786   else
00787   {
00788     for (e = 0; e < h->hashspace; e++)
00789     {
00790       if (h->hashtable[e] != ILL_SYM_NOINDEX)
00791         prt_xchain (h, e);
00792     }
00793   }
00794 }
00795 #endif
00796 
00797 #ifdef TRY_CODE
00798 int main (
00799   int ac,
00800   char **av)
00801 {
00802 
00803   int i, rval, index, pre_exist, nwords;
00804   const char *prefix[3];
00805   ILLsymboltab t, *tab = &t;
00806   char cmd[100], symbol[100], line[256], str[100];
00807   const char *s;
00808   int ok;
00809 
00810   TRACE = 1;
00811   prefix[0] = "C";
00812   prefix[1] = "c";
00813   prefix[2] = NULL;
00814   ILLsymboltab_init (tab);
00815   ILLsymboltab_create (tab, 1);
00816 
00817   fprintf (stdout, "> ");
00818   fflush (stdout);
00819   while (fgets (line, 100, stdin))
00820   {
00821     ok = 0;
00822     symbol[0] = '\0';
00823     nwords = sscanf (line, "%s%s%s", cmd, symbol, str);
00824     if (nwords >= 1)
00825     {
00826       fprintf (stdout, ":: %s", line);
00827       if ((nwords >= 2) && strcmp (cmd, "REG") == 0)
00828       {
00829         ok = 1;
00830         if (strcmp (symbol, "NULL") == 0)
00831         {
00832           rval = ILLsymboltab_register (tab, NULL, &index, &pre_exist);
00833         }
00834         else
00835         {
00836           rval = ILLsymboltab_register (tab, symbol, &index, &pre_exist);
00837         }
00838       }
00839       if ((nwords >= 2) && strcmp (cmd, "LOOK") == 0)
00840       {
00841         ok = 1;
00842         rval = ILLsymboltab_register (tab, symbol, &index, &pre_exist);
00843       }
00844       if ((nwords >= 2) && strcmp (cmd, "DEL") == 0)
00845       {
00846         ok = 1;
00847         rval = ILLsymboltab_delete (tab, symbol);
00848       }
00849       if ((nwords >= 2) && strcmp (cmd, "UNIQUE") == 0)
00850       {
00851         ok = 1;
00852         rval = ILLsymboltab_uname (tab, symbol, "c", "C");
00853       }
00854       if ((nwords >= 1) && strcmp (cmd, "PRT") == 0)
00855       {
00856         ok = 1;
00857         ILLsymboltab_prt (stdout, tab);
00858       }
00859       if ((nwords >= 2) && strcmp (cmd, "GET") == 0)
00860       {
00861         ok = 1;
00862         i = atoi (symbol);
00863         s = ILLsymboltab_get (tab, i);
00864         fprintf (stdout, "%d: %s\n", i, (s != NULL) ? s : "NULL");
00865       }
00866       if ((nwords >= 3) && strcmp (cmd, "RENAME") == 0)
00867       {
00868         ok = 1;
00869         i = atoi (symbol);
00870         if (strcmp (str, "NULL") == 0)
00871         {
00872           ILLsymboltab_rename (tab, i, NULL);
00873         }
00874         else
00875         {
00876           ILLsymboltab_rename (tab, i, str);
00877         }
00878       }
00879       if (strcmp (cmd, "CHAIN") == 0)
00880       {
00881         ok = 1;
00882         if ((nwords == 1) || strcmp (symbol, "NULL") == 0)
00883         {
00884           prt_chain (tab, NULL);
00885           fprintf (stdout,
00886                    "last %s(%d) strsize/space: %d/%d freedchars: %d\n",
00887                    get_str (tab, tab->tablesize - 1), tab->tablesize - 1,
00888                    tab->strsize, tab->strspace, tab->freedchars);
00889         }
00890         else
00891         {
00892           prt_chain (tab, symbol);
00893         }
00894       }
00895       if ((nwords >= 1) && strcmp (cmd, "INFO") == 0)
00896       {
00897         ok = 1;
00898         fprintf (stdout,
00899                  "last %s(%d) strsize/space: %d/%d freedchars: %d\n",
00900                  get_str (tab, tab->tablesize - 1), tab->tablesize - 1,
00901                  tab->strsize, tab->strspace, tab->freedchars);
00902       }
00903       if ((nwords >= 1) && strcmp (cmd, "STR") == 0)
00904       {
00905         ok = 1;
00906         for (i = 0; i < tab->strsize; i++)
00907         {
00908           if (tab->namelist[i] == '\0')
00909             fprintf (stdout, "\\0");
00910           else
00911             fprintf (stdout, "%c", tab->namelist[i]);
00912         }
00913         fprintf (stdout, "\n");
00914       }
00915     }
00916     if (ok == 0)
00917     {
00918       fprintf (stdout, "commands: REG, LOOK, DEL, RENAME, GET, %s\n",
00919                "RENAME, UNIQUE, CHAIN, STR, INFO, PRT");
00920     }
00921     fprintf (stdout, "> ");
00922     fflush (stdout);
00923   }
00924 
00925   return 0;
00926 }
00927 
00928 /* sample input for testing symboltab */
00929 #ifdef NEVER
00930 REG aabb REG aabb               // its already there 
00931   REG abab REG abab             // its already there 
00932   REG baba REG baba             // its already there 
00933   REG bbaa REG bbaa             // its already there 
00934   CHAIN aabb STR                // all with same hash 
00935   DEL abab                      // remove from middle
00936   CHAIN baba DEL aabb           // remove last
00937   CHAIN baba DEL bbaa           // remove first
00938   CHAIN baba DEL baba           // remove the only element 
00939   CHAIN PRT STR REG 123456789012  // compact name list no entries in table
00940   STR REG longnametoo INFO REG a REG b DEL 123456789012 DEL longnametoo INFO STR REG more // compact name list with entries in table
00941   STR INFO PRT REG NULL         // add NULL str 
00942   PRT DEL b                     // remove with NULL being last entry
00943   PRT CHAIN DEL a               // remove with NULL somewhere in table
00944   PRT DEL more CHAIN            // nothing left in table
00945   REG NULL                      // add NULL str 
00946   REG NULL                      // add NULL str 
00947   REG NULL                      // add NULL str 
00948   REG more PRT CHAIN            // only chain is for more
00949   RENAME 0 more                 // should fail
00950   RENAME 0 another              // own hash 
00951   RENAME 0 another              // must fail 
00952   CHAIN RENAME 1 orem           // existing hash 
00953   CHAIN RENAME 2 makestrarraygrowevenlongerwiththisid CHAIN PRT INFO STR DEL makestrarraygrowevenlongerwiththisid STR RENAME 3 somemore // should trigger grownamelist
00954  
00955   PRT
00956   REG omemore
00957   STR
00958   CHAIN
00959   INFO
00960   UNIQUE a
00961   UNIQUE a
00962   REG Ca
00963   UNIQUE a REG ca UNIQUE a REG Ca_0 REG Ca_1 REG Ca_2 REG Ca_3 REG Ca_4 UNIQUE a
00964 #endif
00965 #endif

Generated on Thu Mar 29 09:32:33 2012 for QSopt_ex by  doxygen 1.4.7