tablestructure.c

Go to the documentation of this file.
00001 
00002 /*  $Id: tablestructure.c 1317 2006-04-21 02:06:59Z 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 "file.h"
00032 #include "memory.h"
00033 #include "strings.h"
00034 #include "timedate.h"
00035 #include "resources.h"
00036 #include "langinternal.h"
00037 #include "langexternal.h"
00038 #include "tableinternal.h"
00039 #include "tableverbs.h"
00040 #include "tablestructure.h"
00041 #include "byteorder.h"  /* 2006-04-08 aradke: endianness conversion macros */
00042 
00043 
00044 /*
00045 the routines in this file determine the overall structure of the system
00046 symbol tables in CanCoon.
00047 */
00048 
00049 
00050 
00051 byte nameinternaltable [] = STR_compiler;
00052 
00053 byte namemenubar [] = STR_menubar;
00054 
00055 byte namebuiltinstable [] = STR_builtins;
00056 
00057 byte namepathstable [] = STR_paths;
00058 
00059 byte nameverbstable [] = STR_verbs;
00060 
00061 byte nameiacgluetable [] = STR_apps;
00062 
00063 byte nameiachandlertable [] = STR_traps;
00064 
00065 byte nameagentstable [] = STR_agents;
00066 
00067 byte nameresourcestable [] = STR_misc;
00068 
00069 byte nameefptable [] = STR_kernel;
00070 
00071 byte namelangtable [] = STR_language;
00072 
00073 byte namestacktable [] = STR_stack;
00074 
00075 byte namesemaphoretable [] = STR_semaphores; /*4.0b7 dmb*/
00076 
00077 byte namethreadtable [] = STR_threads;  /* 4.0.1b1 dmb*/
00078 
00079 byte namefilewindowtable [] = STR_filewindows; // 5.0d16 dmb
00080 
00081 byte nameroottable [] = STR_root;
00082 
00083 byte namestartuptable [] = STR_startup;
00084 
00085 byte namesuspendtable [] = STR_suspend;
00086 
00087 byte nameresumetable [] = STR_resume;
00088 
00089 byte nameshutdowntable [] = STR_shutdown;
00090 
00091 byte namesystembranch [] = STR_system;
00092 
00093 byte namemenubartable [] = STR_menubars;
00094 
00095 static byte namemacintoshtable [] = STR_macintosh;
00096 
00097 static byte nameobjectmodeltable [] = STR_objectmodel;
00098 
00099 static byte nametemptable [] = STR_temp;
00100 
00101 byte nameenvironmenttable [] = STR_environment;
00102 
00103 byte namecharsetstable [] = STR_charsets;
00104 
00105 
00106 
00107 Handle rootvariable = nil;
00108 
00109 hdlhashtable roottable = nil;
00110 
00111 hdlhashtable systemtable = nil;
00112 
00113 hdlhashtable internaltable = nil;
00114 
00115 hdlhashtable efptable = nil;
00116 
00117 hdlhashtable langtable = nil;
00118 
00119 hdlhashtable runtimestacktable = nil;
00120 
00121 hdlhashtable semaphoretable = nil;
00122 
00123 hdlhashtable threadtable = nil;
00124 
00125 hdlhashtable filewindowtable = nil;
00126 
00127 hdlhashtable builtinstable = nil;
00128 
00129 hdlhashtable pathstable = nil;
00130 
00131 hdlhashtable verbstable = nil;
00132 
00133 hdlhashtable iacgluetable = nil;
00134 
00135 hdlhashtable iachandlertable = nil;
00136 
00137 hdlhashtable resourcestable = nil;
00138 
00139 hdlhashtable agentstable = nil;
00140 
00141 /*
00142 hdlhashtable usertable = nil;
00143 */
00144 
00145 hdlhashtable menubartable = nil;
00146 
00147 hdlhashtable objectmodeltable = nil;
00148 
00149 hdlhashtable environmenttable = nil;
00150 
00151 hdlhashtable charsetstable = nil;
00152 
00153 
00154 
00155 boolean getsystemtablescript (short idscript, bigstring bsscript) {
00156     
00157     return (getstringlist (idsystemtablescripts, idscript, bsscript));
00158     } /*getsystemtablescript*/
00159 
00160 
00161 static boolean checktable (hdlhashtable htable, bigstring bs, boolean flcreate, hdlhashtable *hsubtable) {
00162     
00163     /*
00164     locate the table named bs in the htable.  return in hsubtable the table you're 
00165     looking for.  if flcreate is true we create the table if it doesn't exist.
00166     
00167     return false if we couldn't find or create the table.
00168     
00169     3/4/91 dmb: if we create a new table, look for a packed hash resource 
00170     with a matching named, and try to unpack the values
00171     */
00172     
00173     #ifdef MACVERSION
00174         Handle hpacked;
00175     #endif
00176 
00177     register hdlhashtable *ht = hsubtable;
00178     
00179     if (findnamedtable (htable, bs, ht)) /*no problem, it exists*/
00180         goto exit;
00181     
00182     *ht = nil;
00183     
00184     if (!flcreate)
00185         return (false);
00186     
00187     if (!tablenewsubtable (htable, bs, ht))
00188         return (false);
00189     
00190     #if MACVERSION && !defined (odbengine)
00191     
00192     hpacked = filegetresource (filegetapplicationrnum (), 'HASH', 0, bs);
00193     
00194     if (hpacked != nil) { /*try unpacking from resource*/
00195         
00196         DetachResource (hpacked);
00197         
00198         hashunpacktable (hpacked, true, *ht); /*he always disposes of hpackedtable*/
00199         }
00200     
00201     #endif
00202     
00203     exit:
00204     
00205     #ifdef smartmemory
00206     
00207     (***ht).fllocked = true; /*currently only respected by purgetable code in langhash.c*/
00208     
00209     #endif
00210     
00211     return (true);
00212     } /*checktable*/
00213 
00214 
00215 static boolean linksystemtable (hdlhashtable hsystem, bigstring bstable, hdlhashtable htable) {
00216     
00217     /*
00218     link htable into the system table using the given name
00219     */
00220 
00221     Handle hdata = (Handle) (**htable).hashtablerefcon;
00222     
00223     if (!langsetexternalsymbol (hsystem, bstable, idtableprocessor, hdata))
00224         return (false);
00225     
00226     langexternaldontsave (hsystem, bstable);
00227     
00228     return (true);
00229     } /*linksystemtable*/
00230 
00231 
00232 boolean linksystemtablestructure (hdlhashtable hroot) {
00233     
00234     /*
00235     have a look at the system table -- there's a table called compiler.
00236     
00237     it's assumed to be read-only, so it can be linked into every open cancoon
00238     file.  this routine links the variable that represents the compiler table
00239     into the system table of the root table passed in as a parameter.
00240     
00241     3/25/91 dmb: use checktable instead of findnamedtable to find the system 
00242     table so that one will be created if it's missing.  this allows us to 
00243     change the name of the system table without breaking old files.
00244     
00245     5.1 dmb: create the temp table (not shared between roots)
00246     
00247     5.1.4 dmb: do the environment table, break out linksystemtable code.
00248     
00249     the environment table is created in langstartup, as is the compiler table
00250     */
00251     
00252     hdlhashtable hsystem, htemp;
00253     
00254     // make sure the system table exists
00255     if (!checktable (hroot, namesystembranch, true, &hsystem))
00256         return (false);
00257     
00258     // link in the compiler table, not part of saved structure
00259     if (!linksystemtable (hsystem, nameinternaltable, internaltable))
00260         return (false);
00261     
00262     // link in the environment table, not part of saved structure
00263     if (!linksystemtable (hsystem, nameenvironmenttable, environmenttable))
00264         return (false);
00265     
00266     // link in the charsets table, not part of saved structure
00267     if (!linksystemtable (hsystem, namecharsetstable, charsetstable))
00268         return (false);
00269     
00270     // create the temp table, not part of saved structure
00271     if (checktable (hsystem, nametemptable, true, &htemp))
00272         langexternaldontsave (hsystem, nametemptable);
00273     
00274     return (true);
00275     } /*linksystemtablestructure*/
00276 
00277 
00278 boolean unlinksystemtablestructure (void) {
00279 
00280     /*
00281     try extracting system table from root before disposal.
00282     */
00283     
00284     pushhashtable (systemtable);
00285     
00286     hashdelete (nameinternaltable, false, false);
00287     
00288     pophashtable ();
00289     
00290     return (true);
00291     } /*unlinksystemtablestructure*/
00292 
00293 
00294 boolean tablenewtable (hdltablevariable *hvariable, hdlhashtable *htable) {
00295     
00296     /*
00297     create a new hashtable variable with an empty hashtable linked into it.
00298     */
00299     
00300     register hdltablevariable hv;
00301     register hdlhashtable ht;
00302     
00303     if (!newtablevariable (true, 0L, hvariable, false))
00304         return (false);
00305     
00306     hv = *hvariable; /*copy into register*/
00307     
00308     if (!newhashtable (htable)) {
00309         
00310         disposehandle ((Handle) hv);
00311         
00312         return (false);
00313         }
00314     
00315     ht = *htable; /*copy into register*/
00316     
00317     (**ht).timecreated = (**ht).timelastsave = timenow (); // 5.0a23 dmb
00318     
00319     /*leave the hashtableformats record unallocated, handle == nil*/
00320     
00321     (**hv).variabledata = (long) ht; /*link the table into the variable rec*/
00322     
00323     (**ht).hashtablerefcon = (long) hv; /*the pointing is mutual*/
00324     
00325     (**ht).fldirty = true; /*it's never been saved*/
00326     
00327     return (true);
00328     } /*tablenewtable*/
00329 
00330 
00331 boolean tablenewsubtable (hdlhashtable htable, bigstring bsname, hdlhashtable *hnewtable) {
00332     
00333     /*
00334     create a new hashtable in the table indicated by htable, and return a
00335     handle to the hashtable record.
00336     
00337     the caller can load it full of stuff after we allocate it.  we basically
00338     just rely on the langhash.c to make the new table, and we link it into the 
00339     global table.
00340     
00341     1/23/91: don't set the dontsave bit anymore.  callers that want it set 
00342     should be using tablenewsystemtable.
00343     */
00344     
00345     hdltablevariable hvariable;
00346     
00347     if (!tablenewtable (&hvariable, hnewtable))
00348         return (false);
00349     
00350     if (!langsetexternalsymbol (htable, bsname, idtableprocessor, (Handle) hvariable)) {
00351         
00352         tableverbdispose ((hdlexternalvariable) hvariable, false);
00353         
00354         return (false);
00355         }
00356     
00357     #if !flruntime
00358     
00359     (***hnewtable).parenthashtable = htable; /*retain parental link*/
00360     
00361     #endif
00362     
00363     return (true);
00364     } /*tablenewsubtable*/
00365 
00366 
00367 boolean tablenewsystemtable (hdlhashtable htable, bigstring bs, hdlhashtable *hnewtable) {
00368     
00369     register hdlhashtable ht;
00370     register hdltablevariable hv;
00371     
00372     if (!tablenewsubtable (htable, bs, hnewtable))
00373         return (false);
00374     
00375     langexternaldontsave (htable, bs); /*set the don't-save bit in its hashnode*/
00376     
00377     ht = *hnewtable; /*copy into register*/
00378     
00379     hv = (hdltablevariable) (**ht).hashtablerefcon;
00380     
00381     (**hv).flsystemtable = true;
00382     
00383     return (true);
00384     } /*tablenewsystemtable*/
00385 
00386 
00387 boolean tableloadsystemtable (dbaddress adr, Handle *hvariable, hdlhashtable *htable, boolean flcreate) {
00388     
00389     /*
00390     gets things started -- use this routine to load the initial hierarchic symbol
00391     table.
00392     
00393     create a new table variable, not in memory, with address equal to the indicated
00394     dbaddress.  then load it into memory and return a handle to the variable record.
00395     table.
00396     
00397     also return the handle to the hash table from the variable record.  we don't want
00398     to pollute the call with any knowledge of the format of a table variable record.
00399     
00400     6/11/90 DW: merge the contents of the root hashtable into the new table.  at this
00401     point it contains the handlers implemented in wpverbs.c, opverbs.c, fileverbs.c,
00402     etc.
00403     
00404     6/15/90 DW: if adr is 0, we just allocate an empty table and return it.
00405     
00406     10/5/90 dmb: no longer merge w/root table.  instead, call linksystemtablestructure
00407     
00408     1/21/91 dmb: create SystemLand table when starting with empty table.  also, 
00409     don't set roottable here.  leave that to caller
00410     */
00411     
00412     register hdlexternalvariable hv;
00413     register hdlhashtable ht;
00414     hdlhashtable hsubtable;
00415     
00416     assert (sizeof (tyexternalvariable) == sizeof (tytablevariable));
00417     
00418     if (adr == nildbaddress) { /*start an empty table*/
00419         
00420         if (!tablenewtable ((hdltablevariable *) hvariable, htable)) /*this will be the root table*/
00421             return (false);
00422         
00423         hv = (hdlexternalvariable) *hvariable;
00424         
00425         if (flcreate && !tablenewsubtable (*htable, namesystembranch, &hsubtable)) {
00426             
00427             tableverbdispose (hv, true);
00428             
00429             return (false);
00430             }
00431         }
00432     else {
00433         
00434         if (!newtablevariable (false, adr, (hdltablevariable *) hvariable, false))
00435             return (false);
00436         
00437         hv = (hdlexternalvariable) *hvariable;
00438         
00439         if (!tableverbinmemory (hv, HNoNode)) {
00440             
00441             disposehandle ((Handle) hv);
00442             
00443             return (false);
00444             }
00445         }
00446     
00447     ht = (hdlhashtable) (**hv).variabledata;
00448     
00449     #if !odbengine && !version5orgreater
00450         
00451     if (!linksystemtablestructure (ht)) {
00452         
00453         tabledisposetable (ht, false);
00454         
00455         disposehandle ((Handle) hv);
00456         
00457         return (false);
00458         }
00459 
00460     #endif
00461     
00462     (**hv).id = idtableprocessor; /*so we can make a value out of this variable*/
00463     
00464     *htable = ht;
00465     
00466     return (true);
00467     } /*tableloadsystemtable*/
00468 
00469 
00470 boolean tablesavesystemtable (Handle hvariable, dbaddress *adr) {
00471     
00472     /*
00473     saves out the root symbol table.  adr should be set to the address it was
00474     last saved at, we re-use the space if the new table will fit in it, otherwise
00475     adr returns with a new block, and the old one is released.
00476     
00477     dmb 10/2/90: don't rely on oldaddress; not set during Save As.  grab address 
00478     from handle instead.
00479     
00480     5.1.3 dmb: fancier error reporting
00481     */
00482     
00483     register hdlexternalvariable hv = (hdlexternalvariable) hvariable;
00484     langerrormessagecallback savecallback;
00485     ptrvoid saverefcon;
00486     bigstring bspackerror;
00487     register boolean fl;
00488     Handle htmp;
00489     boolean fldummy;
00490     
00491     if (!newemptyhandle (&htmp)) 
00492         return (false);
00493     
00494     if (!flscriptrunning)
00495         langhookerrors ();
00496         
00497     tablepreflightsubsdirtyflag (hv); //6.2a15 AR
00498     
00499     langtraperrors (bspackerror, &savecallback, &saverefcon);
00500     
00501     fl = tableverbpack (hv, &htmp, &fldummy); /*packs table, saves to db if neccessary, pushes address on htmp*/
00502     
00503     languntraperrors (savecallback, saverefcon, !fl);
00504     
00505     if (!flscriptrunning)
00506         langunhookerrors ();
00507     
00508     popfromhandle (htmp, sizeof (dbaddress), adr);
00509     
00510     disktomemlong (*adr); // un-swap it; tableverbpack swapped it
00511     
00512     disposehandle (htmp); /*we can get the address from the variable record, below*/
00513     
00514     if (!fl) {
00515         
00516         fllangerror = false;
00517         
00518         setstringcharacter (bspackerror, 0, getlower (getstringcharacter (bspackerror, 0)));
00519         
00520         poptrailingchars (bspackerror, '.');
00521         
00522         if (flscriptrunning)
00523             langparamerror (tablesavingerror, bspackerror);
00524         
00525         else {
00526             bigstring bs;
00527             
00528             getstringlist (langerrorlist, tablesavingerror, bs);
00529             
00530             parsedialogstring (bs, bspackerror, nil, nil, nil, bs);
00531             
00532             shellerrormessage (bs);
00533             }
00534         }
00535     /*
00536     *adr = (**hv).oldaddress;
00537     */
00538     
00539     return (fl);
00540     } /*tablesavesystemtable*/
00541 
00542 
00543 boolean checktablestructure (boolean flcreate) {
00544 
00545     /*
00546     if these tables don't exist, we create them.  return true only if everything 
00547     is laid out as it's supposed to.
00548     
00549     2/28/91 dmb: even if we fail, try to locate as many tables as possible
00550 
00551     5.0a16 dmb: last version created system.menus. This version moves paths to system.
00552 
00553     5.0b15 dmb: never auto-create the old "resources" table (system.misc)
00554     */
00555     
00556     register boolean fl;
00557     hdlhashtable menustable;
00558     
00559     #ifdef MACVERSION
00560         hdlhashtable macintoshtable;
00561     #endif
00562     
00563     fl = checktable (roottable, namesystembranch, flcreate, &systemtable);
00564     
00565     if (fl) {
00566         
00567         if (!checktable (systemtable, nameverbstable, flcreate, &verbstable))
00568             fl = false;
00569         
00570         if (!checktable (systemtable, nameagentstable, flcreate, &agentstable))
00571             fl = false;
00572         
00573         if (!checktable (systemtable, nameresourcestable, false, &resourcestable))
00574             fl = false;
00575         
00576         if (!checktable (systemtable, namepathstable, flcreate, &pathstable))
00577             fl = false;
00578 
00579         if (checktable (systemtable, STR_menus, false, &menustable))
00580             checktable (menustable, namemenubartable, false, &menubartable); /*don't auto-create*/
00581         
00582         #ifdef MACVERSION
00583         
00584         if (checktable (systemtable, namemacintoshtable, false, &macintoshtable))
00585             checktable (macintoshtable, nameobjectmodeltable, false, &objectmodeltable);
00586         
00587         #endif
00588         
00589         }
00590     
00591     if (verbstable != nil) {
00592         
00593         if (!checktable (verbstable, namebuiltinstable, flcreate, &builtinstable))
00594             fl = false;
00595         
00596         if (!checktable (verbstable, nameiacgluetable, flcreate, &iacgluetable))
00597             fl = false;
00598         
00599         if (!checktable (verbstable, nameiachandlertable, flcreate, &iachandlertable))
00600             fl = false;
00601         }
00602         
00603     //usertable = roottable; /*does this work?*/
00604     
00605     return (fl);
00606     } /*checktablestructure*/
00607 
00608 
00609 boolean cleartablestructureglobals (void) {
00610 
00611     /*
00612     dmb 9/24/90: clear globals; root table is about to be disposed
00613     */
00614     
00615     rootvariable = nil;
00616     
00617     roottable = nil;
00618     
00619     systemtable = nil;
00620     
00621     builtinstable = nil;
00622     
00623     pathstable = nil;
00624     
00625     verbstable = nil;
00626     
00627     iacgluetable = nil;
00628     
00629     iachandlertable = nil;
00630     
00631     resourcestable = nil;
00632     
00633     agentstable = nil;
00634     
00635     /*
00636     usertable = nil;
00637     */
00638     
00639     menubartable = nil;
00640     
00641     #ifdef flnewfeatures
00642     
00643     objectmodeltable = nil;
00644     
00645     #endif
00646     
00647     /*these are never disposed; they're shared among all files
00648     
00649     internaltable = nil;
00650     
00651     efptable = nil;
00652     
00653     langtable = nil;
00654     
00655     runtimestacktable = nil;
00656     
00657     threadtable = nil;
00658     
00659     filewindowtable = nil;
00660     */
00661     
00662     return (true);
00663     } /*cleartablestructureglobals*/
00664 
00665 
00666 boolean settablestructureglobals (Handle hvariable, boolean flcreatesubs) {
00667     
00668     register hdltablevariable hv = (hdltablevariable) hvariable;
00669     register hdlhashtable ht;
00670     
00671     if (hv == nil)
00672         return (false);
00673     
00674     ht = (hdlhashtable) (**hv).variabledata;
00675     
00676     if (ht == nil)
00677         return (false);
00678     
00679     cleartablestructureglobals ();
00680     
00681     rootvariable = (Handle) hv;
00682     
00683     roottable = ht;
00684     
00685     return (checktablestructure (flcreatesubs)); /*sets agentstable, builtinstable, etc.*/
00686     } /*settablestructureglobals*/
00687 
00688 

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