opvisit.c

Go to the documentation of this file.
00001 
00002 /*  $Id: opvisit.c 355 2005-01-11 22:48:55Z andreradke $    */
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 "op.h"
00032 #include "opinternal.h"
00033 
00034 
00035 
00036 boolean oplistvisit (hdlheadrecord hnode, opvisitcallback visit, ptrvoid refcon) {
00037     
00038     /*
00039     just visit the node and its siblings, no recursion.
00040     */
00041     
00042     register hdlheadrecord nomad = hnode, nextnomad;
00043     
00044     while (true) {
00045         
00046         nextnomad = (**nomad).headlinkdown;
00047         
00048         if (!(*visit) (nomad, refcon))
00049             return (false);
00050             
00051         if (nextnomad == nomad) 
00052             return (true);
00053             
00054         nomad = nextnomad;
00055         } /*while*/
00056     } /*oplistvisit*/
00057     
00058     
00059 boolean opsummitvisit (opvisitcallback visit, ptrvoid refcon) {
00060     
00061     hdlheadrecord nomad = (**outlinedata).hsummit, nextnomad;
00062     
00063     while (true) {
00064         
00065         nextnomad = (**nomad).headlinkdown;
00066         
00067         if (!(*visit) (nomad, refcon))
00068             return (false);
00069         
00070         if (nextnomad == nomad)
00071             return (true);
00072             
00073         nomad = nextnomad;
00074         } /*while*/
00075     } /*opsummitvisit*/
00076     
00077 
00078 boolean opparentvisit (hdlheadrecord nomad, boolean flincludenode, opvisitcallback visit, ptrvoid refcon) {
00079     
00080     hdlheadrecord nextnomad;
00081     
00082     if (!flincludenode) {
00083         
00084         nextnomad = (**nomad).headlinkleft;
00085         
00086         if (nextnomad == nomad)
00087             return (true);
00088          
00089         nomad = nextnomad;
00090         }
00091         
00092     while (true) {
00093         
00094         nextnomad = (**nomad).headlinkleft;
00095         
00096         if (!(*visit) (nomad, refcon))
00097             return (false);
00098         
00099         if (nextnomad == nomad)
00100             return (true);
00101             
00102         nomad = nextnomad;
00103         } /*while*/
00104     } /*opparentvisit*/
00105     
00106 
00107 boolean oprecursivelyvisit (hdlheadrecord h, short lev, opvisitcallback visit, ptrvoid refcon) {
00108     
00109     register hdlheadrecord nomad, nextnomad;
00110     
00111     if (h == nil)
00112         return (true);
00113     
00114     nomad = (**h).headlinkright;
00115     
00116     if (nomad == h) /*nothing to the right*/
00117         return (true);
00118     
00119     while (true) {
00120         
00121         nextnomad = (**nomad).headlinkdown;
00122         
00123         if (!(*visit) (nomad, refcon))
00124             return (false);
00125             
00126         if (lev > 1) {
00127         
00128             if (!oprecursivelyvisit (nomad, lev - 1, visit, refcon))
00129                 return (false);
00130             }
00131             
00132         if (nextnomad == nomad) /*just processed last subhead*/
00133             return (true);
00134             
00135         nomad = nextnomad;
00136         } /*while*/
00137     } /*oprecursivelyvisit*/
00138 
00139 
00140 boolean opvisiteverything (opvisitcallback visit, ptrvoid refcon) {
00141     
00142     /*
00143     visit every node in the outline
00144     */
00145     
00146     hdlheadrecord nomad = (**outlinedata).hsummit, nextnomad;
00147     
00148     while (true) {
00149         
00150         nextnomad = (**nomad).headlinkdown;
00151         
00152         if (!(*visit) (nomad, refcon)) /*visit the summit*/
00153             return (false);
00154             
00155         if (!oprecursivelyvisit (nomad, infinity, visit, refcon)) /*visit its subs*/
00156             return (false);
00157         
00158         if (nextnomad == nomad)
00159             return (true);
00160             
00161         nomad = nextnomad;
00162         } /*while*/
00163     
00164     } /*opvisiteverything*/
00165     
00166     
00167 boolean oprecursivelyvisitkidsfirst (hdlheadrecord h, short lev, opvisitcallback visit, ptrvoid refcon) {
00168         
00169     register hdlheadrecord nomad, nextnomad;
00170     
00171     if (h == nil)
00172         return (true);
00173         
00174     nomad = (**h).headlinkright;
00175     
00176     if (nomad == h) /*nothing to the right*/
00177         return (true);
00178         
00179     while (true) {
00180         
00181         if (lev > 1)
00182             if (!oprecursivelyvisitkidsfirst (nomad, lev - 1, visit, refcon))
00183                 return (false);
00184         
00185         nextnomad = (**nomad).headlinkdown; /*visit may dealloc nomad*/
00186         
00187         if (!(*visit) (nomad, refcon))
00188             return (false);
00189             
00190         if (nextnomad == nomad) /*just processed last subhead*/
00191             return (true);
00192             
00193         nomad = nextnomad;
00194         } /*while*/
00195     } /*oprecursivelyvisitkidsfirst*/
00196     
00197 
00198 boolean opsiblingvisiter (hdlheadrecord hnode, boolean flkidsfirst, opvisitcallback visit, ptrvoid refcon) {
00199 
00200     /*
00201     visit the node indicated by hnode, and all of its submaterial, and all if its
00202     siblings and their submaterial.
00203     
00204     DW 8/27/93: added special case, if visit returns -1, we don't visit the submaterial.
00205     clay basket needs this to optimize its system idle routine when scanning CDs
00206     and other readonly media. they can't change, and they're slow to traverse.
00207     */
00208     
00209     register hdlheadrecord nomad = hnode;
00210     register hdlheadrecord nextnomad;
00211     
00212     if (nomad == nil) /*defensive driving*/
00213         return (false);
00214     
00215     while (true) {
00216         
00217         nextnomad = (**nomad).headlinkdown;
00218         
00219         if (flkidsfirst) {
00220             
00221             if (!oprecursivelyvisitkidsfirst (nomad, infinity, visit, refcon))
00222                 return (false);
00223                 
00224             if (!(*visit) (nomad, refcon))
00225                 return (false);
00226             }
00227             
00228         else {
00229             short visitresult;
00230             
00231             visitresult = (*visit) (nomad, refcon);
00232             
00233             if (visitresult == 0) /*false*/
00234                 return (false);
00235             
00236             if (visitresult != -1) {
00237             
00238                 if (!oprecursivelyvisit (nomad, infinity, visit, refcon))
00239                     return (false);
00240                 }
00241             }
00242             
00243         if (nextnomad == nomad) /*have visited the last sibling*/
00244             return (true);
00245             
00246         if (nextnomad == nil) /*11/10/88: houtlinescrap sometimes has a nil down ptr*/
00247             return (true);
00248             
00249         nomad = nextnomad; /*advance to the next sibling*/
00250         } /*while*/
00251     } /*opsiblingvisiter*/
00252 
00253 
00254 static boolean oprecursivelyvisitmarked (hdlheadrecord h, tydirection dir, opvisitcallback visit, ptrvoid refcon) {
00255     
00256     register hdlheadrecord nomad = h;
00257     register hdlheadrecord hnext;
00258     register hdlheadrecord hright;
00259     
00260     if (nomad == nil)
00261         return (true);
00262     
00263     if (dir == up)
00264         nomad = oprepeatedbump (down, longinfinity, nomad, false);
00265     
00266     while (true) {
00267         
00268         if (dir == up)
00269             hnext = (**nomad).headlinkup;
00270         else
00271             hnext = (**nomad).headlinkdown;
00272         
00273         if ((**nomad).flmarked)  {
00274             
00275             if (!(*visit) (nomad, refcon))
00276                 return (false);
00277             }
00278         else {
00279             
00280             hright = (**nomad).headlinkright;
00281             
00282             if (hright != nomad) {
00283                 
00284                 if (!oprecursivelyvisitmarked (hright, dir, visit, refcon))
00285                     return (false);
00286                 }
00287             }
00288         
00289         if (hnext == nomad) /*just processed last subhead*/
00290             return (true);
00291         
00292         nomad = hnext;
00293         } /*while*/
00294     } /*oprecursivelyvisitmarked*/
00295 
00296 
00297 boolean opvisitmarked (tydirection dir, opvisitcallback visit, ptrvoid refcon) {
00298     
00299     /*
00300     call the visit routine for every node which is marked in the current
00301     structure.
00302     
00303     8/27/92 dmb: added dir parameter. for certain structural changes, 
00304     must visit bottom-up
00305     */
00306     
00307     hdloutlinerecord ho = outlinedata;
00308     
00309     if ((**ho).ctmarked == 0)
00310         return ((*visit) ((**ho).hbarcursor, refcon));
00311     else
00312         return (oprecursivelyvisitmarked ((**ho).hsummit, dir, visit, refcon));
00313     } /*opvisitmarked*/
00314 
00315 
00316 boolean opbumpvisit (hdlheadrecord hstart, tydirection dir, opvisitcallback visit, ptrvoid refcon) {
00317     
00318     /*
00319     5.0a25 dmb: created to support true shift-clicking, there are probably 
00320     a number of places this could be used. opgetscreenline for sure, but now 
00321     isn't the time to futz with working code
00322     
00323     we visit hstart itself, then those nodes we navigate to.
00324     
00325     if performance if ever an issue, we could duplicate more of the 
00326     oprepeatedbump code here instead of calling it
00327     
00328     5.0b1 dmb: bump expanded only. Maybe we'll want to make that a parameter
00329     at some point, but not now.
00330     */
00331     
00332     hdlheadrecord nomad = hstart;
00333     hdlheadrecord hnext;
00334     
00335     while (true) {
00336         
00337         if (!visit (nomad, refcon))
00338             return (false);
00339         
00340         hnext = oprepeatedbump (dir, 1, nomad, true);
00341         
00342         if (hnext == nomad)
00343             return (true);
00344         
00345         nomad = hnext;
00346         }
00347     } /*opbumpvisit*/
00348 
00349 
00350 
00351 

Generated on Wed May 31 18:19:57 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6