tableops.c

Go to the documentation of this file.
00001 
00002 /*  $Id: tableops.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 "quickdraw.h"
00032 #include "cursor.h"
00033 #include "resources.h"
00034 #include "strings.h"
00035 
00036 #ifndef odbengine
00037 #include "search.h"
00038 #endif
00039 
00040 #include "langexternal.h"
00041 #include "tablestructure.h"
00042 #include "tableinternal.h"
00043 #include "tableverbs.h"
00044 #include "claybrowser.h"
00045 
00046 
00047 
00048 #ifdef fldebug
00049 
00050 hdlhashtable debugtable;
00051 hdltableformats debugformats;
00052 hdltablevariable debugvariable;
00053 bigstring debugfirstsort;
00054 hdlhashnode debugnode;
00055 bigstring debughashkey;
00056 
00057 
00058 boolean tablesetdebugglobals (register hdlhashtable ht, register hdlhashnode hnode) {
00059     
00060     /*
00061     set debug globals.  we're about to dive into the indicated node in 
00062     the table ht
00063     
00064     12/12/91 dmb: return true so this can be called as an assertion
00065     */
00066     
00067     assert (ht && even ((long) ht) && even ((long) *ht));
00068     
00069     debugtable = ht;
00070     
00071     debugvariable = (hdltablevariable) (**ht).hashtablerefcon;
00072     
00073     #if !flruntime
00074     
00075     debugformats = (hdltableformats) (**ht).hashtableformats;
00076     
00077     #endif
00078     
00079     if ((**ht).hfirstsort)
00080         gethashkey ((**ht).hfirstsort, debugfirstsort);
00081     
00082     debugnode = hnode;
00083     
00084     gethashkey (hnode, debughashkey);
00085     
00086     return (true);
00087     } /*tablesetdebugglobals*/
00088 
00089 #endif
00090 
00091 
00092 #if defined (isFrontier) && !defined (flruntime)
00093 
00094 
00095 hdlhashtable tablegetlinkedhashtable (void) {
00096     
00097     return ((hdlhashtable) (**tableformatsdata).htable);
00098     } /*tablegetlinkedhashtable*/
00099 
00100 
00101 hdltablevariable tablegetlinkedtablevariable (void) {
00102     
00103     register hdlhashtable ht = tablegetlinkedhashtable ();
00104     
00105     return ((hdltablevariable) (**ht).hashtablerefcon);
00106     } /*tablegetlinkedtablevariable*/
00107 
00108 
00109 boolean tablegetiteminfo (hdlheadrecord hnode, hdlhashtable *htable, bigstring bs, tyvaluerecord *val, hdlhashnode *hhashnode) {
00110     
00111     tybrowserinfo info;
00112     
00113     if (!browsergetrefcon (hnode, &info))
00114         return (false);
00115     
00116     *htable = info.dirid;
00117     
00118     opgetheadstring (hnode, bs);
00119     
00120     if (val == nil) // caller doesn't need value
00121         return (true);
00122     else
00123         return (hashtablelookup (info.dirid, bs, val, hhashnode));
00124     } /*tablegetiteminfo*/
00125 
00126 
00127 boolean tablegetcursorinfo (hdlhashtable *htable, bigstring bs, tyvaluerecord *val, hdlhashnode *hhashnode) {
00128     
00129     /*
00130     get the name and value of the table line that the cursor points at.
00131     
00132     factors code that was appearing all over the place.
00133     */
00134     
00135     if (outlinedata == nil)
00136         return (false);
00137 
00138     return (tablegetiteminfo ((**outlinedata).hbarcursor, htable, bs, val, hhashnode));
00139     } /*tablegetcursorinfo*/
00140 
00141 
00142 void tablelinkformats (hdlhashtable htable, hdltableformats hformats) {
00143     
00144     /*
00145     establish links between hashtable and formats record.  the pointing is
00146     two-way.
00147     */
00148     
00149     (**htable).hashtableformats = hformats;
00150     
00151     (**hformats).htable = htable;
00152     } /*tablelinkformats*/
00153 
00154 #endif
00155 
00156 
00157 boolean istablevariable (hdlexternalvariable hv) {
00158     
00159     switch ((**hv).id) {
00160         
00161         case idtableprocessor:
00162         #ifdef xmlfeatures
00163             case idxmlprocessor:
00164         #endif
00165             return true;
00166 
00167         default:
00168             return (false);
00169         }
00170     } /*istablevariable*/
00171 
00172 
00173 boolean gettablevariable (tyvaluerecord val, hdltablevariable *hvariable, short *errcode) {
00174     
00175     /*
00176     extract a handle to a table variable record from the value record.
00177     
00178     return true if you got one.  this factors code which was appearing all over 
00179     the place.
00180     */
00181     
00182     register hdlexternalvariable hv;
00183     
00184     if (val.valuetype != externalvaluetype) {
00185         
00186         *errcode = namenottableerror;
00187         
00188         return (false);
00189         }
00190         
00191     hv = (hdlexternalhandle) val.data.externalvalue;
00192     
00193     if (!istablevariable (hv)) {
00194         
00195         *errcode = namenottableerror;
00196         
00197         return (false);
00198         }
00199     
00200     *hvariable = (hdltablevariable) hv;
00201     
00202     return (true);
00203     } /*gettablevariable*/
00204 
00205 
00206 boolean findnamedtable (hdlhashtable htable, bigstring bs, hdlhashtable *hnamedtable) {
00207     
00208     /*
00209     look for a table in the indicated table with the indicated name.  return a 
00210     handle to the table we found.  return false if it isn't defined.
00211     */
00212     
00213     hdlhashnode hnode;
00214     register boolean fl;
00215     
00216     pushhashtable (htable);
00217     
00218     fl = langfindsymbol (bs, &htable, &hnode);
00219     
00220     pophashtable ();
00221     
00222     if (!fl) 
00223         return (false);
00224     
00225     if (!tablevaltotable ((**hnode).val, hnamedtable, hnode))
00226         return (false);
00227     
00228     #if !flruntime
00229     
00230     (***hnamedtable).parenthashtable = htable; /*retain parental link*/
00231     
00232     #endif
00233     
00234     return (true);
00235     } /*findnamedtable*/
00236 
00237 
00238 boolean newtablevariable (boolean flinmemory, long variabledata, hdltablevariable *h, boolean flxml) {
00239 #pragma unused (flxml)
00240 
00241     /*
00242     tytablevariable item;
00243     
00244     clearbytes ((ptrchar) &item, longsizeof (item));
00245     
00246     item.flinmemory = flinmemory;
00247     
00248     item.variabledata = variabledata;
00249     
00250     return (newfilledhandle ((ptrchar) &item, longsizeof (item), (Handle *) h));
00251     */
00252     
00253     if (!langnewexternalvariable (flinmemory, variabledata, (hdlexternalvariable *) h))
00254         return (false);
00255 
00256     #ifdef xmlfeatures
00257         (**h).flxml = flxml;
00258     #endif
00259 
00260     return (true);
00261     } /*newtablevariable*/
00262 
00263 
00264 boolean tablenewtablevalue (hdlhashtable *newtable, tyvaluerecord *newval) {
00265     
00266     if (!langexternalnewvalue (idtableprocessor, nil, newval))
00267         return (false);
00268     
00269     langexternalvaltotable (*newval, newtable, HNoNode);
00270     
00271     return (true);
00272     } /*tablenewtablevalue*/
00273 
00274 
00275 #if defined (isFrontier) && !defined (flruntime)
00276 
00277 boolean tablefinddatawindow (hdlhashtable htable, hdlwindowinfo *hinfo) {
00278     
00279     /*
00280     find the window that's displaying the indicated hash table.
00281     */
00282     
00283     register hdlhashtable ht = htable;
00284     
00285     if (!(**ht).flwindowopen) /*can't find window for a table that isn't displayed*/
00286         return (false);
00287     
00288     return (shellfinddatawindow ((Handle) (**ht).hashtableformats, hinfo));
00289     } /*tablefinddatawindow*/
00290 
00291 
00292 boolean tabledisposetable (hdlhashtable htable, boolean fldisk) {
00293     
00294     register hdlhashtable ht = htable;
00295     register hdltableformats hf;
00296     hdlwindowinfo hinfo;
00297     
00298     if (ht) {
00299         
00300         #ifdef fldebug
00301 
00302             if (tablefinddatawindow (ht, &hinfo)) {
00303                 
00304                 shellinternalerror (0, BIGSTRING ("\x1d" "table shouldn't have a window"));
00305                 
00306                 shellclosewindow ((**hinfo).macwindow);
00307                 }
00308         #endif
00309         
00310         hf = (hdltableformats) (**ht).hashtableformats;
00311         
00312         if (hf) {
00313             
00314             disposetableformats (hf);
00315             }
00316         
00317         disposehashtable (ht, fldisk);
00318         }
00319     
00320     return (true);
00321     } /*tabledisposetable*/
00322 
00323 
00324 hdldatabaserecord tablegetdatabase (hdlhashtable ht) {
00325     
00326     if (ht == nil)
00327         return (nil);
00328 
00329     return (langexternalgetdatabase ((hdlexternalvariable) (**ht).hashtablerefcon));
00330     } /*tablegetdatabase*/
00331 
00332 
00333 boolean tablesortedinversesearch (hdlhashtable htable, langsortedinversesearchcallback visit, ptrvoid refcon) {
00334     
00335     /*
00336     like the langhash version, but we push the table's database in case 
00337     a disk value must be resolved
00338     */
00339     
00340     hdldatabaserecord hdb = tablegetdatabase (htable);
00341     hdldatabaserecord hdbsave = databasedata;
00342     boolean fl;
00343     
00344     if (hdb)
00345         databasedata = hdb;
00346     
00347     fl = hashsortedinversesearch (htable, visit, refcon);
00348     
00349     if (hdb)
00350         databasedata = hdbsave;
00351     
00352     return (fl);
00353     } /*tablesortedinversesearch*/
00354 
00355 
00356 boolean tablecheckwindowrect (hdlhashtable htable) {
00357     
00358     /*
00359     some factored code -- if the indicated table is in an open
00360     window, we check to see if its windowrect has changed, and dirty the
00361     table if so.  return true if the windowrect changed.
00362     */
00363     
00364     register hdlhashtable ht = htable;
00365     register hdltableformats hf = (hdltableformats) (**ht).hashtableformats;
00366     hdlwindowinfo hinfo;
00367     Rect r;
00368     
00369     if (!tablefinddatawindow (ht, &hinfo)) 
00370         return (false);
00371         
00372     shellgetglobalwindowrect (hinfo, &r);
00373         
00374     if (equalrects (r, (**hf).windowrect)) 
00375         return (false);
00376         
00377     (**hf).windowrect = r;
00378             
00379     (**ht).fldirty = true;
00380     
00381     return (true);
00382     } /*tablecheckwindowrect*/
00383 
00384 #else
00385 
00386 boolean tabledisposetable (hdlhashtable htable, boolean fldisk) {
00387     
00388     register hdlhashtable ht = htable;
00389     
00390     if (ht) {
00391         
00392         disposehashtable (ht, fldisk);
00393         }
00394     
00395     return (true);
00396     } /*tabledisposetable*/
00397 
00398 #endif
00399 
00400 
00401 boolean tableverbunload (hdlexternalvariable hvariable) {
00402     
00403     /*
00404     the table was loaded into memory temporarily, the caller is asking us to
00405     get rid of the in-memory version of the table.
00406     */
00407     
00408     register hdltablevariable hv = (hdltablevariable) hvariable;
00409     
00410     if ((**hv).flinmemory) { /*if it's on disk, don't need to do anything*/
00411         
00412         tabledisposetable ((hdlhashtable) (**hv).variabledata, false);
00413         
00414         (**hv).variabledata = (**hv).oldaddress;
00415         
00416         (**hv).oldaddress = 0;
00417         
00418         (**hv).flinmemory = false;
00419         }
00420     
00421     return (true);
00422     } /*tableverbunload*/
00423 
00424 
00425 boolean findvariablesearch (hdlhashtable intable, hdlexternalvariable forvariable, boolean flonlyinmemory, hdlhashtable *foundintable, bigstring foundname, tyfindvariablecallback ancestorcallback) {
00426 
00427     register hdlhashtable ht = intable;
00428     register hdlhashnode x;
00429     register short i;
00430     tyvaluerecord val;
00431     register hdlexternalvariable hv = nil;
00432     
00433     for (i = 0; i < ctbuckets; i++) {
00434         
00435         x = (**ht).hashbucket [i];
00436         
00437         while (x != nil) { /*chain through the hash list*/
00438             
00439             register boolean fltempload = false;
00440             
00441             val = (**x).val;
00442             
00443             if (val.valuetype != externalvaluetype) 
00444                 goto nextx;
00445                 
00446             hv = (hdlexternalvariable) val.data.externalvalue;
00447             
00448             if (hv == forvariable) { /*bravo!  we found it...*/
00449                 
00450                 *foundintable = ht;
00451                 
00452                 gethashkey (x, foundname);
00453                 
00454                 if (ancestorcallback != nil)
00455                     (*ancestorcallback) (ht, x);
00456                 
00457                 return (true);
00458                 }
00459             
00460             if (!istablevariable (hv))
00461                 goto nextx;
00462             
00463             if (!(**hv).flinmemory) {
00464                 
00465                 if (flonlyinmemory)
00466                     goto nextx;
00467                     
00468                 if (!tableverbinmemory (hv, x))
00469                     return (false);
00470                     
00471                 fltempload = true;
00472                 }
00473             
00474             assert (tablesetdebugglobals (ht, x)); /*set debug globals*/
00475             
00476             if (findvariablesearch ((hdlhashtable) (**hv).variabledata, forvariable, flonlyinmemory, foundintable, foundname, ancestorcallback)) {
00477                 
00478                 if (ancestorcallback != nil)
00479                     (*ancestorcallback) (ht, x);
00480                 
00481                 //  this was an idea, but I don't think it's needed or speeds things up
00482                 //if ((**(hdlhashtable) (**hv).variabledata).parenthashtable == nil)
00483                 //  (**(hdlhashtable) (**hv).variabledata).parenthashtable = ht;
00484                 
00485                 return (true); /*unwind recursion*/
00486                 }
00487                 
00488             nextx:
00489             
00490             if (fltempload)
00491                 tableverbunload (hv);
00492             
00493             x = (**x).hashlink; /*advance to next node in chain*/
00494             } /*while*/
00495         } /*for*/
00496         
00497     return (false);
00498     } /*findvariablesearch*/
00499 
00500 
00501 boolean tablefindvariable (hdlexternalvariable hvariable, hdlhashtable *htable, bigstring bsname) {
00502     
00503     /*
00504     conduct an extensive but quick research project for the caller.  he has an
00505     external variable, and wants to know where the hashnode that points to it 
00506     can be located, ie what table it's in, and what the name of the variable is.
00507     
00508     this is alternate to storing back-pointers in each variable record, something
00509     that would cost a lot of code to maintain, and which would add complexity to
00510     something that's already quite complex.
00511     
00512     11/14/90 DW: if we don't find it by traversing through in-memory structures,
00513     try going over things that are swapped out before giving up.
00514     
00515     11/15/90 DW: undid the previous feature.  think about it -- if you have a 
00516     variable record handle to ask about it must live in an in-memory table.  this
00517     slowed down the home window's "Object DB" button, which zooms out the root table,
00518     which won't be found in itself -- it searches the whole object database, even
00519     stuff on disk before it gives up.  no, if it can't be found in memory, it 
00520     can't be found.
00521     
00522     4/19/91 dmb: special case for root variable
00523     */
00524     
00525     if (hvariable == nil) /*defensive driving*/
00526         return (false);
00527     
00528     if (roottable == nil) /*most defense*/
00529         return (false);
00530 
00531     if (hvariable == (hdlexternalvariable) rootvariable) { /*special case; root variable doesn't live in a table*/
00532         
00533         *htable = nil; /*langvalue.c will deal with "root" better this way*/
00534         
00535         copystring (nameroottable, bsname);
00536         
00537         return (true);
00538         }
00539     
00540     if (findvariablesearch (roottable, hvariable, true, htable, bsname, nil))
00541         return (true);
00542     
00543     return (false); /*wire off following feature*/
00544     
00545     /*return (findvariablesearch (roottable, hvariable, false, htable, bsname, nil));*/
00546     } /*tablefindvariable*/
00547 
00548 
00549 static boolean nosubsdirtyvisit (hdlhashnode hnode, ptrvoid refcon) {
00550 #pragma unused (refcon)
00551 
00552     /*
00553     return true if hnode and its substructure is all clean
00554     */
00555     
00556     tyvaluerecord val;
00557     register hdlexternalvariable hv;
00558     
00559     val = (**hnode).val;
00560     
00561     if (val.valuetype != externalvaluetype) 
00562         return (true);
00563     
00564     hv = (hdlexternalvariable) val.data.externalvalue;
00565     
00566     if (!istablevariable (hv))
00567         return (!langexternalisdirty (hv)); /*for e.g. a dirty outline or wpdoc*/
00568     
00569     if (!(**hv).flinmemory) /*can't be dirty if it isn't in memory*/
00570         return (true);
00571         
00572     /* RAB 97-05-21  --  taken from packstubs, should this be part of Frontier? dmb: yes!*/
00573     if ((**hnode).fldontsave)
00574         return (true);
00575     
00576     return (tablenosubsdirty ((hdlhashtable) (**hv).variabledata)); /*daisy-chain recursion*/
00577     } /*nosubsdirtyvisit*/
00578 
00579 
00580 boolean tablenosubsdirty (hdlhashtable htable) {
00581     
00582     /*
00583     recursively branch out from htable and return false if any of its subtables
00584     are dirty.  also return false if the table itself is dirty.
00585     
00586     changes need to be saved for any table that has dirty subs.
00587     */
00588     
00589     register hdlhashtable ht = htable;
00590     
00591     if ((**ht).fldirty) 
00592         return (false);
00593     
00594     return (hashtablevisit (ht, nosubsdirtyvisit, nil));
00595     } /*tablenosubsdirty*/
00596 
00597 
00598 static boolean tableupdatesubsdirtyflag (hdlhashtable ht); /*forward declaration*/
00599 
00600 static boolean updatesubsdirtyvisit (hdlhashnode hnode, ptrvoid refcon) {
00601 
00602     tyvaluerecord val = (**hnode).val;
00603     boolean *flsubsdirty = (boolean *) refcon;
00604     
00605     if (val.valuetype == externalvaluetype) {
00606     
00607         register hdlexternalvariable hv = (hdlexternalvariable) val.data.externalvalue;
00608         
00609         if (!istablevariable (hv)) /*once fldirtysub is true, we only need to visit sub-tables but none of the other externals*/
00610             *flsubsdirty = *flsubsdirty || langexternalisdirty (hv);
00611         else
00612             *flsubsdirty = ((**hv).flinmemory
00613                                 && !(**hnode).fldontsave
00614                                 && tableupdatesubsdirtyflag ((hdlhashtable) (**hv).variabledata))
00615                             || *flsubsdirty;
00616         }
00617     
00618     return (true);
00619     }/*updatesubsdirtyvisit*/
00620     
00621     
00622 static boolean tableupdatesubsdirtyflag (hdlhashtable ht) {
00623 
00624     boolean flsubsdirty = false;
00625     
00626     hashtablevisit (ht, updatesubsdirtyvisit, &flsubsdirty);
00627     
00628     (**ht).flsubsdirty = flsubsdirty;
00629     
00630     return (flsubsdirty || (**ht).fldirty);
00631     }/*tableupdatesubsdirtyflag*/
00632     
00633     
00634 boolean tablepreflightsubsdirtyflag (hdlexternalvariable hv) {
00635     
00636      /*
00637      6.2a15 AR: Call this function to update the flsubsdirty flag
00638      of every loaded and saveable table in the table structure
00639      */
00640         
00641     if (fldatabasesaveas)
00642         return (true); /*not really interested if we're saving a copy*/
00643     
00644     if (!(**hv).flinmemory)
00645         return (true); /*not likely, but might just as well handle it*/
00646         
00647     tableupdatesubsdirtyflag ((hdlhashtable) (**hv).variabledata);
00648     
00649     return (true);
00650     }/*tablepreflightsubsdirtyflag*/
00651 
00652 
00653 #if defined (isFrontier) && !defined (flruntime)
00654 
00655 typedef struct findtableinfo {
00656     
00657     hdlhashtable htablelookfor;
00658     
00659     hdlhashnode hnodelookfor;
00660     } tyfindtableinfo, *ptrfindtableinfo;
00661 
00662 
00663 static boolean findtablevisit (hdlhashnode hnode, ptrvoid refcon) {
00664     
00665     /*
00666     we're looking for a node that's a table variable -- a specific one, the
00667     one pointed to by info.htablelookfor.
00668     */
00669     ptrfindtableinfo info = (ptrfindtableinfo) refcon;
00670     hdltablevariable hvariable;
00671     register hdlhashtable ht;
00672     short errcode;
00673     
00674     if (!gettablevariable ((**hnode).val, &hvariable, &errcode))
00675         return (true);
00676         
00677     ht = (hdlhashtable) (**hvariable).variabledata;
00678         
00679     if (ht != (*info).htablelookfor) /*keep visiting, this ain't it*/
00680         return (true);
00681     
00682     (*info).hnodelookfor = hnode;
00683     
00684     return (false); /*false terminates traversal*/
00685     } /*findtablevisit*/
00686 
00687 
00688 static boolean parentsearch (hdlhashtable intable, hdlhashtable fortable, boolean flonlyinmemory, hdlhashtable *hparent, bigstring bsname) {
00689     
00690     /*
00691     4/29/96 4.0b8 dmb: we need to convert fortable to a parenttable/name address pair
00692     
00693     root is a special case.
00694     
00695     we have no direct way of making a table-to-parent connection independent of 
00696     windows. someday, we should make the parenttable field always valid, but that 
00697     will require relatively extensive (minor but widely distributed) code change.
00698     
00699     5.0.2b13 dmb: moved this in from langvalue.c
00700     */
00701     
00702     register hdlhashtable ht = intable;
00703     register hdlhashnode x;
00704     register short i;
00705     tyvaluerecord val;
00706     register hdlexternalvariable hv = nil;
00707     
00708     if (intable == fortable) {  /*special case for root*/
00709     
00710         *hparent = nil;
00711         
00712         if ((**intable).fllocaltable)
00713             setemptystring (bsname);
00714         else
00715             copystring (nameroottable, bsname);
00716         
00717         return (true);
00718         }
00719     
00720     for (i = 0; i < ctbuckets; i++) {
00721         
00722         x = (**ht).hashbucket [i];
00723         
00724         while (x != nil) { /*chain through the hash list*/
00725             
00726             register boolean fltempload = false;
00727             hdlhashtable htable;
00728             
00729             val = (**x).val;
00730             
00731             if (val.valuetype != externalvaluetype) 
00732                 goto nextx;
00733                 
00734             hv = (hdlexternalvariable) val.data.externalvalue;
00735     
00736             if ((**hv).id != idtableprocessor)
00737                 goto nextx;
00738             
00739             if (!(**hv).flinmemory) {
00740             
00741                 if (flonlyinmemory) /*can't find it if it isn't in memory*/
00742                     goto nextx;
00743                 
00744                 if (!tableverbinmemory (hv, x))
00745                     return (false);
00746                     
00747                 fltempload = true;
00748                 }
00749             
00750             htable = (hdlhashtable) (**hv).variabledata;
00751             
00752             if (htable == fortable) {
00753                 
00754                 *hparent = ht;
00755                 
00756                 gethashkey (x, bsname);
00757                 
00758                 return (true);
00759                 }
00760             
00761             if (parentsearch (htable, fortable, flonlyinmemory, hparent, bsname)) {
00762                 
00763                 return (true); /*unwind recursion*/
00764                 }
00765                 
00766             nextx:
00767             
00768             if (fltempload)
00769                 tableverbunload (hv);
00770             
00771             x = (**x).hashlink; /*advance to next node in chain*/
00772             } /*while*/
00773         } /*for*/
00774         
00775     return (false);
00776     } /*parentsearch*/
00777 
00778 
00779 boolean findinparenttable (hdlhashtable htable, hdlhashtable *hparent, bigstring bs) {
00780     
00781     /*
00782     return enough information to identify the line in the table that the indicated
00783     table zoomed from.  return false if that table isn't displayed in a window, or
00784     if for some reason a node couldn't be found.
00785     
00786     11/14/90 DW: add flopen flag -- if true and the window isn't open, we try to 
00787     open it, returning false if it couldn't be opened.
00788     
00789     5.0d18 dmb: removed flopen flag, making this function public
00790     
00791     5.0.2b13 dmb: if parenthashtable is nil, search for it and set it. parentOf func
00792     now calls us (we stole its code).
00793     */
00794     
00795     hdlhashtable h, ht = (**htable).parenthashtable;
00796     tyfindtableinfo info;
00797     
00798     setemptystring (bs);
00799     
00800     if (ht == nil) { // parent isn't set; search globally (& set name)
00801     
00802         if ((**htable).fllocaltable) {
00803             
00804             for (h = currenthashtable; h != nil; h = (**h).prevhashtable) {
00805                 
00806                 if (parentsearch (h, htable, true, &ht, bs))
00807                     break;
00808                 }
00809             }
00810         else
00811             parentsearch (roottable, htable, true, &ht, bs);
00812         
00813         (**htable).parenthashtable = ht; // retain link for future ops
00814         }
00815     else { // parent already set, just need to find name
00816     
00817         info.htablelookfor = htable; /*set global for traversal*/
00818         
00819         if (hashtablevisit (ht, &findtablevisit, &info))
00820             return (false);
00821         
00822         gethashkey (info.hnodelookfor, bs);
00823         }
00824     
00825     *hparent = ht;
00826     
00827     return (ht != nil) || (htable == roottable);
00828     } /*findinparenttable*/
00829 
00830 /*
00831 boolean tablevisicursor (void) {
00832     
00833     register hdltableformats hf = tableformatsdata;
00834     
00835     return (tablevisi ((**hf).rowcursor, (**hf).colcursor));
00836     } /%tablevisicursor%/
00837 */
00838 
00839 
00840 boolean tableexiteditmode (void) {
00841     
00842     return (opsettextmode (false));
00843     } /*tableexiteditmode*/
00844 
00845 
00846 boolean tablemovetoname (hdlhashtable htable, bigstring bsname) {
00847 #pragma unused (htable)
00848 
00849     /*
00850     2/4/91 dmb: must visi if already on cell
00851 
00852     5.0a25 dmb: use opfindhead, not opflatfind deriviative.
00853     Added htable param, but we're not using it now
00854     */
00855     
00856     hdlheadrecord hfound;
00857     boolean fl;
00858     
00859     /*
00860     if (!hashsortedsearch (tablegetlinkedhashtable (), bsname, &row))
00861         return (false);
00862     */
00863     
00864     if (!tableexiteditmode ())
00865         return (false);
00866     
00867     fl = opfindhead (opfirstatlevel ((**outlinedata).hbarcursor), bsname, &hfound);
00868     
00869     if (fl) {
00870     
00871         opclearallmarks ();
00872         
00873         opmoveto (hfound);
00874         }
00875     
00876 //  tableexiteditmode ();
00877     
00878     return (fl); //tablemovecursor (row, namecolumn)
00879     } /*tablemovetoname*/
00880 
00881 
00882 boolean tablemovetonode (hdlhashnode hnode) {
00883     
00884     hdlheadrecord hsummit;
00885     long row;
00886     
00887     if (!hashgetsortedindex (tablegetlinkedhashtable (), hnode, &row))
00888         return (false);
00889     
00890     if (!opnthsummit (row, &hsummit))
00891         return (false);
00892     
00893     opclearallmarks ();
00894     
00895     return (opmoveto (hsummit));
00896     } /*tablemovetonode*/
00897 
00898 
00899 boolean tablebringtofront (hdlhashtable htable) {
00900     
00901     /*
00902     find the window that displays the indicated table, bring it to front.
00903     
00904     also set the table globals for this window, if we're successful.
00905     
00906     1/9/91 dmb: it's not cool to set globals unless we know for sure that 
00907     we'll never be called in a context where something higher in the calling 
00908     chain will expect its globals to remain intact.  as a utility routine, 
00909     we can't assume that, so we leave it to our caller to push and pop 
00910     globals as neccessary.  also, there's no reason to force an immediate 
00911     update.
00912     */
00913     
00914     hdlwindowinfo hinfo;
00915     
00916     if (!tablefinddatawindow (htable, &hinfo))
00917         return (false);
00918     
00919     shellbringtofront (hinfo);
00920     
00921     /*
00922     shellsetglobals ((**hinfo).macwindow);
00923     
00924     shellupdatenow ((**hinfo).macwindow);
00925     */
00926     
00927     return (true);
00928     } /*tablebringtofront*/
00929     
00930 
00931 /*
00932 static boolean tablesavebarcursor (hdlhashnode *hnode) {
00933     
00934     register hdltableformats hf = tableformatsdata;
00935 
00936     return (hashgetnthnode (tablegetlinkedhashtable (), (**hf).rowcursor, hnode));
00937     } /%tablesavebarcursor%/
00938     
00939     
00940 static boolean tablerestorebarcursor (hdlhashnode hnode) {
00941     
00942     short index;
00943     
00944     hashgetsortedindex (tablegetlinkedhashtable (), hnode, &index);
00945     
00946     (**tableformatsdata).rowcursor = index; 
00947     
00948     return (true);
00949     } /%tablerestorebarcursor%/
00950 */
00951 
00952 boolean tableresort (hdlhashtable ht, hdlhashnode hresort) {
00953     
00954     /*
00955     re-sort the current hashtable.
00956     
00957     3/31/93 dmb: added hresort parameter. if it's not nil, then only that 
00958     node needs to be resorted.
00959     */
00960     
00961     register boolean fl;
00962     hdlheadrecord hcursor = (**outlinedata).hbarcursor;
00963     
00964 //  flmustexiteditmode = true;
00965     
00966     tableexiteditmode ();
00967     
00968     opsaveeditbuffer ();
00969     
00970     fl = hashresort (ht, hresort);
00971     
00972     opmoveto (hcursor);
00973     
00974     oprestoreeditbuffer ();
00975     
00976 //  invalrect ((**tableformatsdata).tablerect);
00977     
00978     tablesymbolsresorted (ht);
00979     
00980     tabledirty ();
00981     
00982     return (fl);
00983     } /*tableresort*/
00984 
00985 
00986 boolean tablesetsortorder (hdlhashtable ht, short sortorder) {
00987     
00988     /*
00989     3/23/93 dmb: set watch cursor before sorting
00990     */
00991     
00992     register hdltableformats hf = (hdltableformats) (**ht).hashtableformats;
00993     
00994     (**ht).sortorder = sortorder;
00995     
00996     if (hf != nil) {
00997         
00998         invalrect ((**hf).titlerect);
00999         
01000         setcursortype (cursoriswatch);
01001         
01002         shellforcecursoradjust (); /*make sure it reverts ASAP*/
01003         
01004         tableresort (ht, nil);
01005         
01006         opvisibarcursor ();
01007         }
01008     
01009     return (true);
01010     } /*tablesetsortorder*/
01011 
01012 
01013 boolean tablegetsortorder (hdlhashtable ht, short *sortorder) {
01014     
01015     /*
01016     3/23/93 dmb: set watch cursor before sorting
01017     */
01018     
01019     *sortorder = (**ht).sortorder;
01020     
01021     return (true);
01022     } /*tablegetsortorder*/
01023 
01024 
01025 boolean tablegetcursorpath (bigstring bspath) {
01026     
01027     /*
01028     return the full path from root to the item pointed to by the table cursor.
01029     
01030     7/12/91 dmb: get the quoted path, not just the full path
01031     */
01032     
01033     hdlhashtable htable;
01034     bigstring bs;
01035     tyvaluerecord val;
01036     hdlhashnode hnode;
01037     
01038     if (!tablegetcursorinfo (&htable, bs, &val, &hnode))
01039         return (false);
01040     
01041     return (langexternalgetquotedpath (htable, bs, bspath));
01042     } /*tablegetcursorpath*/
01043 
01044 
01045 static boolean contextneedsobjectmodeltable (hdlhashtable htable, tyvaluetype type) {
01046     
01047     return ((type == objspecvaluetype) 
01048             && (objectmodeltable != nil) 
01049             && (objectmodeltable != htable)); 
01050             //&& !(**htable).fllocaltable);
01051     } /*contextneedsobjectmodeltable*/
01052 
01053 
01054 boolean tablepushcontext (hdlhashtable ht, tyvaluetype type) {
01055     
01056     /*
01057     establish the appropriate context to evaluate a script as part of 
01058     a direct table manipulation.
01059     
01060     5.1.5b12 dmb: always put ht in the most local scope -- unless it's the root and already is
01061     */
01062     
01063     if ((**ht).fllocaltable)
01064         return (pushhashtable (ht));
01065     
01066     langpushscopechain ();
01067     
01068     if (contextneedsobjectmodeltable (ht, type))
01069         chainhashtable (objectmodeltable);
01070     
01071     if (ht != roottable)
01072         chainhashtable (ht);
01073     
01074     return (true);
01075     } /*tablepushcontext*/
01076 
01077 
01078 boolean tablepopcontext (hdlhashtable ht, tyvaluetype type) {
01079     
01080     /*
01081     reverse the action of tablepushcontext
01082     */
01083     
01084     if ((**ht).fllocaltable)
01085         return (pophashtable ());
01086     
01087     if (contextneedsobjectmodeltable (ht, type))
01088         unchainhashtable ();
01089     
01090     if (ht != roottable)
01091         unchainhashtable ();
01092     
01093     langpopscopechain ();
01094     
01095     return (true);
01096     } /*tablepopcontext*/
01097 
01098 
01099 #endif
01100 
01101 
01102 boolean tablegetstringlist (short id, bigstring bs) {
01103     
01104     return (getstringlist (tablestringlist, id, bs));
01105     } /*tablegetstringlist*/
01106 
01107 
01108 
01109 
01110 

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