tablevalidate.c

Go to the documentation of this file.
00001 
00002 /*  $Id: tablevalidate.c 1254 2006-04-12 20:27:14Z sethdill $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #include "cursor.h"
00032 #include "memory.h"
00033 #include "strings.h"
00034 #include "shell.h"
00035 #include "langinternal.h"
00036 #include "tableinternal.h"
00037 #include "tablestructure.h"
00038 #include "tableverbs.h"
00039 
00040 
00041 
00042 
00043 static boolean flonlyinmemory = true;
00044 
00045 
00046 static boolean validate (hdlhashtable htable, boolean flalert) {
00047     
00048     /*
00049     a bullshit detector for hash tables.  written on 3/21/90 by DW.
00050     
00051     we call it invalid if:
00052     
00053     1. the table handle is nil -- there's nothing we can do with such a table!
00054     
00055     2. one of the hashbuckets has an item chained into it that shouldn't be in 
00056     its list.  this is a very strong test -- it seems improbable if the chain
00057     is somehow invalid that all the handles would work out to point to a key
00058     string that just happens to hash to the same bucket number.
00059     
00060     3. the sorted list is out of order -- this seems like a little icing on the
00061     cake -- how could it pass test 2 and not pass this test?
00062     
00063     11/13/90 DW: relaxed the rule about the sorted list being in order, since
00064     we're allowing it.
00065     
00066     11/14/90 DW: added flonlyinmemory -- if false, not being in memory is not an 
00067     obstacle.  side-effect of doing a full traversal -- all the tables get loaded
00068     into memory.
00069     */
00070     
00071     register hdlhashtable ht = htable;
00072     register short i;
00073     register hdlhashnode x;
00074     hdltablevariable hvariable;
00075     short errcode;
00076     
00077     if (ht == nil) {
00078         
00079         if (flalert)
00080             shellinternalerror (idnilhashtable, BIGSTRING ("\x17" "hashtable handle is nil"));
00081         
00082         return (false);
00083         }
00084     
00085     if (!(**ht).fllocaltable) { /*8/15/92 dmb*/
00086         
00087         for (i = 0; i < (**ht).cttmpstack; i++) {
00088             
00089             if ((**ht).tmpstack [i].data.binaryvalue != nil) {
00090                 
00091                 if (flalert)
00092                     shellinternalerror (idnilhashtable, BIGSTRING ("\x14" "non-empty temp stack"));
00093                 
00094                 return (false);
00095                 }
00096             }
00097         }
00098     
00099     for (i = 0; i < ctbuckets; i++) {
00100         
00101         x = (**ht).hashbucket [i];
00102         
00103         while (x != nil) { /*chain through the hash list*/
00104             
00105             bigstring bs;
00106             
00107             if (!flonlyinmemory)
00108                 rollbeachball ();
00109             
00110             gethashkey (x, bs);
00111             
00112             if (gethandlesize ((Handle) x) != (long) sizeof (tyhashnode) + stringsize (bs)) {
00113                 
00114                 if (flalert)
00115                     shellinternalerror (idbadbucketliststring, BIGSTRING ("\x17" "bad string in hash node"));
00116                 
00117                 return (false);
00118                 }
00119             
00120             if (hashfunction (bs) != i) {
00121                 
00122                 if (flalert)
00123                     shellinternalerror (idbadbucketliststring, BIGSTRING ("\x1b" "bad string in a bucket list"));
00124                 
00125                 return (false);
00126                 }
00127             
00128             if (!gettablevariable ((**x).val, &hvariable, &errcode))
00129                 goto nextx;
00130             
00131             if (!(**hvariable).flinmemory) {
00132                 
00133                 if (flonlyinmemory)
00134                     goto nextx;
00135                     
00136                 if (!tableverbinmemory ((hdlexternalvariable) hvariable, x)) {
00137                     
00138                     if (flalert)
00139                         shellinternalerror (iderrorloadingtable, BIGSTRING ("\x13" "error loading table"));
00140                     
00141                     return (false);
00142                     }
00143                 }
00144             
00145             assert (tablesetdebugglobals (ht, x));
00146             
00147             if (!validate ((hdlhashtable) (**hvariable).variabledata, flalert)) /*recurse*/
00148                 return (false);
00149             
00150             nextx:
00151             
00152             x = (**x).hashlink; /*advance to next node in chain*/
00153             } /*while*/
00154         } /*for*/
00155     
00156     /*
00157     x = (**ht).hfirstsort;
00158     
00159     setstringlength (bslast, 0);
00160     
00161     while (x != nil) {
00162         
00163         bigstring bs;
00164         
00165         gethashkey (x, bs);
00166         
00167         if (!stringlessthan (bslast, bs)) {
00168         
00169             if (flalert)
00170                 shellinternalerror (idunsortedhashlist, "\psorted list out of order");
00171             
00172             return (false);
00173             }
00174         
00175         x = (**x).sortedlink;
00176         
00177         copystring (bs, bslast);
00178         } /%while%/
00179     */
00180     
00181     return (true);
00182     } /*validate*/
00183 
00184 
00185 boolean tablevalidate (hdlhashtable htable, boolean flalert) {
00186     
00187     flonlyinmemory = true;
00188     
00189     return (validate (htable, flalert));
00190     } /*tablevalidate*/
00191 
00192 
00193 
00194 

Generated on Wed May 31 18:20:03 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6