wpvariables.c

Go to the documentation of this file.
00001 
00002 /*  $Id: wpvariables.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 <standard.h>
00029 #include "memory.h"
00030 #include "strings.h"
00031 #include "quickdraw.h"
00032 #include "shell.h"
00033 #include "shell.rsrc.h"
00034 #include "shellundo.h"
00035 #include "lang.h"
00036 #include "wpengine.h"
00037 #include "wpinternal.h"
00038 
00039 
00040 
00041 typedef struct tywpvariable {
00042     
00043     unsigned char bsname [1]; /*variable name*/
00044     
00045     unsigned char bsvalue [1]; /*expanded text*/
00046     } tywpvariable, *ptrwpvariable, **hdlwpvariable;
00047 
00048 
00049 typedef struct typackedvarheader {
00050     
00051     short version; /*in case format changes*/
00052     
00053     short ctvariables; /*not strictly necessary, but might aid unpacking*/
00054     
00055     long unused; /*space for growth*/
00056     } typackedvarheader;
00057 
00058 
00059 typedef hdlwpvariable tyvariablelist [1], *ptrvariablelist, **hdlvariablelist;
00060 
00061 
00062 static UserStyles variableprocs; /*must be statically allocated*/
00063 
00064 
00065 #ifdef flvariables
00066 
00067 
00068 boolean wpvariablerecalc (void) {
00069     
00070     /*
00071     force a total recalc & redisplay
00072     */
00073     
00074     wptotalrecalc ();
00075     } /*wpvariablerecalc*/
00076 
00077 
00078 static void mungedeleterecord (Handle harray, long ixrecord, long recordsize) {
00079     
00080     /*
00081     remove the indicated record from the heap-allocated array, sliding all 
00082     subsequent records left to fill the gap, and shortening the handle 
00083     accordingly.
00084     */
00085     
00086     Munger (harray, ixrecord * recordsize, nil, recordsize, nil, 0L);
00087     } /*mungedeleterecord*/
00088 
00089 
00090 static boolean wpfindvariable (bigstring bsname, short *ixlist) {
00091     
00092     /*
00093     search the current variable list for the indicated name return its 
00094     index in ixlist.   return true if the variable is found, else false.
00095     */
00096     
00097     register hdlvariablelist hlist;
00098     register short ix;
00099     register short ctvars;
00100     
00101     if (!wpsetglobals ())
00102         return (false);
00103     
00104     hlist = (hdlvariablelist) (**wpdata).hvariablelist;
00105     
00106     ctvars = gethandlesize ((Handle) hlist) / sizeof (hdlwpvariable); /*nil list OK*/
00107     
00108     for (ix = 0; ix < ctvars; ++ix)
00109         
00110         if (equalstrings ((ptrstring) *(*hlist) [ix], bsname)) {
00111             
00112             *ixlist = ix;
00113             
00114             return (true);
00115             }
00116     
00117     return (false);
00118     } /*wpfindvariable*/
00119 
00120 
00121 boolean wpdeletevariable (bigstring bsname) {
00122     
00123     /*
00124     dispose the hdlwpvariable with the indicated name.  delete its entry 
00125     in the variable list.
00126     */
00127     
00128     register hdlvariablelist hlist;
00129     short ixlist;
00130     
00131     if (!wpfindvariable (bsname, &ixlist))
00132         return (false);
00133     
00134     hlist = (hdlvariablelist) (**wpdata).hvariablelist;
00135     
00136     disposehandle ((Handle) (*hlist) [ixlist]);
00137     
00138     mungedeleterecord ((Handle) hlist, (long) ixlist, longsizeof (hdlwprecord));
00139     
00140     return (true);
00141     } /*wpdeletevariable*/
00142 
00143 
00144 void wpdisposevariablelist (Handle hvariablelist) {
00145     
00146     /*
00147     1/23/91 dmb: fixed pointer derefence bug -- heap trasher
00148     */
00149     
00150     register hdlvariablelist hlist = (hdlvariablelist) hvariablelist;
00151     register short ix;
00152     register short ctvars;
00153     
00154     ctvars = gethandlesize ((Handle) hlist) / sizeof (hdlwpvariable); /*nil list OK*/
00155     
00156     for (ix = 0; ix < ctvars; ++ix)
00157         disposehandle ((Handle) (*hlist) [ix]); /*name, value pair*/
00158     
00159     disposehandle ((Handle) hlist);
00160     } /*wpdisposevariablelist*/
00161 
00162 
00163 boolean wpgetnthvariable (short ixlist, bigstring bsname) {
00164     
00165     register hdlvariablelist hlist;
00166     register short ctvars;
00167     
00168     if (!wpsetglobals ())
00169         return (false);
00170     
00171     hlist = (hdlvariablelist) (**wpdata).hvariablelist;
00172     
00173     ctvars = gethandlesize ((Handle) hlist) / sizeof (hdlwpvariable); /*nil list OK*/
00174     
00175     if ((ixlist <= 0) || (ixlist > ctvars))
00176         return (false);
00177     
00178     copystring ((ptrstring) *(*hlist) [ixlist - 1], bsname);
00179     
00180     return (true);
00181     } /*wpgetnthvariable*/
00182 
00183 
00184 #ifdef flstandalone
00185 
00186 boolean wpgetvariablevalue (bigstring bsname, bigstring bsvalue) {
00187     
00188     register hdlvariablelist hlist;
00189     short ixlist;
00190     ptrstring pname, pvalue;
00191     boolean flagentsenabled, fl;
00192     
00193     if (!wpfindvariable (bsname, &ixlist))
00194         return (false);
00195     
00196     hlist = (hdlvariablelist) (**wpdata).hvariablelist;
00197     
00198     pname = (ptrstring) *(*hlist) [ixlist];
00199     
00200     pvalue = pname + stringsize (pname);
00201     
00202     copystring (pvalue, bsvalue);
00203     
00204     return (true);
00205     } /*wpgetvariablevalue*/
00206 
00207 #else
00208 
00209 boolean wpgetvariablevalue (bsname, bsvalue) bigstring bsname, bsvalue; {
00210     
00211     boolean fl;
00212     
00213     /*
00214     agentsdisable (true);
00215     */
00216     
00217     fl = langrunstringnoerror (bsname, bsvalue);
00218     
00219     /*
00220     agentsdisable (false);
00221     */
00222     
00223     return (true);
00224     } /*wpgetvariablevalue*/
00225 
00226 #endif
00227 
00228 
00229 boolean wpsetvariablevalue (bigstring bsname, bigstring bsvalue) {
00230     
00231     register hdlvariablelist hlist;
00232     register hdlwpvariable hvariable;
00233     short ixlist;
00234     register ptrstring pname;
00235     ptrstring pvalue;
00236     
00237     if (!wpfindvariable (bsname, &ixlist))
00238         return (false);
00239     
00240     hlist = (hdlvariablelist) (**wpdata).hvariablelist;
00241     
00242     hvariable = (*hlist) [ixlist];
00243     
00244     pname = (ptrstring) *hvariable;
00245     
00246     if (!sethandlesize ((Handle) hvariable, stringsize (pname) + stringsize (bsvalue)))
00247         return (false);
00248     
00249     pname = (ptrstring) *hvariable; /*may have moved when resized*/
00250     
00251     pvalue = pname + stringsize (pname);
00252     
00253     copystring (bsvalue, pvalue);
00254     
00255     if ((**wpdata).flexpandvariables && !(**wpdata).flinhibitdisplay)
00256         wpvariablerecalc ();
00257     } /*wpsetvariablevalue*/
00258 
00259 
00260 boolean wpnewvariable (bigstring bsname, bigstring bsvalue) {
00261     
00262     /*
00263     add the indicated variable name to the current variable list, with 
00264     the given value.  the if name is already in the list, just update 
00265     its the variable's value
00266     */
00267     
00268     register hdlwprecord hwp = wpdata;
00269     register Handle hvariablelist;
00270     short ixlist;
00271     Handle hvariable;
00272     
00273     if (wpfindvariable (bsname, &ixlist)) /*already exists*/
00274         return (wpsetvariablevalue (bsname, bsvalue));
00275     
00276     if (!wpsetglobals ())
00277         return (false);
00278     
00279     if (!newfilledhandle (bsname, stringsize (bsname), &hvariable))
00280         return (false);
00281     
00282     if (!enlargehandle (hvariable, stringsize (bsvalue), bsvalue)) {
00283         
00284         disposehandle (hvariable);
00285         
00286         return (false);
00287         }
00288     
00289     hvariablelist = (**hwp).hvariablelist;
00290     
00291     if (hvariablelist == nil) {
00292         
00293         hvariablelist = NewHandle (0);
00294         
00295         (**hwp).hvariablelist = hvariablelist;
00296         }
00297     
00298     if (!enlargehandle (hvariablelist, longsizeof (hvariable), &hvariable)) {
00299         
00300         disposehandle (hvariable);
00301         
00302         return (false);
00303         }
00304     
00305     return (true);
00306     } /*wpnewvariable*/
00307 
00308 
00309 boolean wppackvariablelist (Handle *hpackedvarlist) {
00310     
00311     /*
00312     since variable names and values all have length bytes, packing 
00313     end-to-end is easy.
00314     */
00315     
00316     register hdlvariablelist hlist;
00317     register short ctvars;
00318     register short ix;
00319     register Handle h;
00320     typackedvarheader header;
00321     long unused;
00322     
00323     hlist = (hdlvariablelist) (**wpdata).hvariablelist;
00324     
00325     ctvars = gethandlesize ((Handle) hlist) / sizeof (hdlwpvariable); /*nil list OK*/
00326     
00327     header.version = 0;
00328     
00329     header.ctvariables = ctvars;
00330     
00331     header.unused = 0;
00332     
00333     if (!newfilledhandle (&header, longsizeof (header), hpackedvarlist))
00334         return (false);
00335     
00336     h = *hpackedvarlist; /*move into register*/
00337     
00338     for (ix = 0; ix < ctvars; ++ix) {
00339         
00340         if (!pushhandle ((Handle) (*hlist) [ix], h)) { /*name, value pair*/
00341             
00342             disposehandle (h);
00343             
00344             return (false);
00345             }
00346         
00347         if (!enlargehandle (h, longsizeof (unused), &unused)) { /*future expansion*/
00348             
00349             disposehandle (h);
00350             
00351             return (false);
00352             }
00353         }
00354     
00355     return (true);
00356     } /*wppackvariablelist*/
00357 
00358 
00359 boolean wpunpackvariablelist (Handle hpackedvarlist) {
00360     
00361     /*
00362     unpack hpackedvarlist, using wpnewvariable to set the hvariablelist 
00363     in wpdata.  
00364     
00365     scan the format runs in wpdata and set the procptrs for any variable 
00366     formats found.
00367     
00368     always dispose hpackedlist, even when an error occurs during unpacking.  we 
00369     don't need to clean up anything else on error, since everything allocated 
00370     is attached to wpdata.
00371     */
00372     
00373     register short ctvars;
00374     register Handle h = hpackedvarlist;
00375     typackedvarheader header;
00376     long ix = 0;
00377     boolean fl = false;
00378     bigstring bsname, bsvalue;
00379     
00380     if (hpackedvarlist == nil) /*no variables exist -- easy to handle*/
00381         return (true);
00382     
00383     /*unpack variable list*/
00384     
00385     if (!loadfromhandle (h, &ix, longsizeof (header), &header))
00386         goto exit;
00387     
00388     ctvars = header.ctvariables;
00389     
00390     while (--ctvars >= 0) {
00391         
00392         if (!loadfromhandle (h, &ix, (long) stringsize (*h + ix), bsname))
00393             goto exit;
00394         
00395         if (!loadfromhandle (h, &ix, (long) stringsize (*h + ix), bsvalue))
00396             goto exit;
00397         
00398         if (!wpnewvariable (bsname, bsvalue))
00399             goto exit;
00400         
00401         ix += sizeof (long); /*skip over unused field*/
00402         }
00403     
00404     /*walk through user style runs and set up callbacks*/
00405     
00406     if (wpsetglobals ()) {
00407         
00408         long pos, count;
00409         FormatRec fmt;
00410         short ixfmt;
00411         
00412         pos = 0; /*start at beginning*/
00413         
00414         while ((ixfmt = WSFindUserStyle (wpbuffer, 0L, 0L, &pos, &count, &fmt)) >= 0) {
00415             
00416             fmt.UserProcs = &variableprocs;
00417             
00418             WSSetFormatRec (wpbuffer, &fmt, ixfmt);
00419             
00420             pos += count;
00421             }
00422         }
00423     
00424     fl = true; /*if we got here, we succeeded*/
00425     
00426     exit:
00427     
00428     disposehandle (hpackedvarlist);
00429     
00430     return (fl);
00431     } /*wpunpackvariablelist*/
00432 
00433 
00434 boolean wpgetvariablestring (FormatRec *pfmt, bigstring bsdisplay) {
00435     
00436     hdlvariablelist hlist;
00437     short ixvariable;
00438     hdlstring hname;
00439     
00440     ixvariable = (short) (*pfmt).UserSpace;
00441     
00442     hlist = (hdlvariablelist) (**wpdata).hvariablelist;
00443     
00444     hname = (hdlstring) (*hlist) [ixvariable];
00445     
00446     if ((**wpdata).flexpandvariables) {
00447         
00448         if (!wpgetvariablevalue (*hname, bsdisplay))
00449             copystring ("\p???", bsdisplay);
00450         }
00451     else {
00452         
00453         copystring (*hname, bsdisplay);
00454         
00455         /*
00456         insertstring ("\p{", bsdisplay);
00457         
00458         pushchar ('}', bsdisplay);
00459         */
00460         }
00461     
00462     return (true);
00463     } /*wpgetvariablestring*/
00464 
00465 
00466 boolean wpremovevariablestyle (void) {
00467     
00468     /*
00469     the caller is about to insert some text, and wants to ensure that 
00470     the current cursor position doesn't inadvertantly have the userstyles 
00471     set up for a variable.  this would occur if the user clicked immediately 
00472     to the right of an existing variable, or just deleted a variable.
00473     
00474     we assume that wp's globals are set up, and any selection has already 
00475     been deleted.
00476     
00477     return true if a user space was actually removed
00478     */
00479     
00480     long allspaces, anyspaces;
00481     
00482     if (WSGetUserSpace (wpbuffer, &allspaces, &anyspaces) == 0) /*no user space*/
00483         return (false);
00484     
00485     assert (allspaces == anyspaces); /*sanity check -- insert point should be uniform*/
00486     
00487     WSSetUserStyle (wpbuffer, nil, 0L, 0L);
00488     
00489     return (true);
00490     } /*wpremovevariablestyle*/
00491 
00492 
00493 boolean wpinsertvariable (bigstring bsname) {
00494     
00495     /*
00496     replace the selection with the given variable name.  if the variable 
00497     doesn't exist, create it with a null value
00498     */
00499     
00500     boolean flrecalc;
00501     byte chvariable;
00502     short ixvariable;
00503     
00504     if (!wpfindvariable (bsname, &ixvariable)) {
00505         
00506         if (!wpnewvariable (bsname, emptystring))
00507             return (false);
00508         
00509         if (!wpfindvariable (bsname, &ixvariable))
00510             return (false);
00511         }
00512     
00513     if (!wppreedit ())
00514         return (false);
00515     
00516     chvariable = '-'; /*a wordbreak character to represent the variable*/
00517     
00518     pushundoaction (undoformatstring);
00519     
00520     wpresettyping ();
00521     
00522     flrecalc = wpdelete (true); /*insert doesn't automagically delete selection*/
00523     
00524     wppushformatundo ();
00525     
00526     flrecalc = WSSetUserStyle (wpbuffer, &variableprocs, 0L, (long) ixvariable) || flrecalc;
00527     
00528     wppushinsertundo (false, true);
00529     
00530     flrecalc = WSInsert (wpbuffer, (Ptr) &chvariable, 1) || flrecalc;
00531     
00532     wppostedit (true);
00533     } /*wpinsertvariable*/
00534 
00535 
00536 boolean wpgetevaluate (void) {
00537     
00538     return ((**wpdata).flexpandvariables);
00539     } /*wpgetevaluate*/
00540 
00541 
00542 boolean wpsetevaluate (boolean flexpand) {
00543     
00544     /*
00545     2/18/91 dmb: always highlight variables when not expanded
00546     */
00547     
00548     if (flexpand == (**wpdata).flexpandvariables)
00549         return (false);
00550     
00551     (**wpdata).flexpandvariables = flexpand;
00552     
00553     (**wpdata).flhilitevariables = !flexpand;
00554     
00555     wpvariablerecalc ();
00556     
00557     return (true);
00558     } /*wpsetevaluate*/
00559 
00560 
00561 boolean wphilitevariables (boolean flhilite) {
00562     
00563     if (flhilite == (**wpdata).flhilitevariables)
00564         return (false);
00565     
00566     (**wpdata).flhilitevariables = flhilite;
00567     
00568     wpvariablerecalc ();
00569     
00570     return (true);
00571     } /*wphilitevariables*/
00572 
00573 
00574 static pascal boolean wpmeasurevariable (WSHandle hwp, FormatRec *pfmt, byte *ptext, short ctchars, short slop, short *pwidths) {
00575     
00576     bigstring bsdisplay;
00577     register short ct = ctchars;
00578     register short width = 0;
00579     
00580     wpgetvariablestring (pfmt, bsdisplay);
00581     
00582     *pwidths = 0;
00583     
00584     while (--ctchars >= 0) {
00585         
00586         width += StringWidth (bsdisplay);
00587         
00588         *++pwidths = width;
00589         }
00590     
00591     return (TRUE);
00592     } /*wpmeasurevariable*/
00593 
00594 
00595 static pascal boolean wpdrawvariable (WSHandle hwp, FormatRec *pfmt, byte *ptext, short ctchars, short slop, short ascent, short descent) {
00596     
00597     bigstring bsdisplay;
00598     Point ptstart;
00599     Rect r;
00600     
00601     wpgetvariablestring (pfmt, bsdisplay);
00602     
00603     getpenpoint (&topLeft (r)); /*in case we're highlighting below*/
00604     
00605     while (--ctchars >= 0)
00606         pendrawstring (bsdisplay);
00607     
00608     if ((**wpdata).flhilitevariables && !(**wpdata).flprinting) {
00609         
00610         getpenpoint (&botRight (r)); /*topleft was set before drawstring*/
00611         
00612         r.top -= ascent;
00613         
00614         r.bottom += descent;
00615         
00616         grayframerect (r);
00617         }
00618     
00619     return (TRUE);
00620     } /*wpdrawvariable*/
00621 
00622 void wpvariableinit (void) {
00623     
00624     /*
00625     set up the userprocs for the variable format records
00626     */
00627     
00628     variableprocs.hMeasureText = (ProcPtr) &wpmeasurevariable;
00629     
00630     variableprocs.hDrawText = (ProcPtr) &wpdrawvariable;
00631     
00632     variableprocs.hFmtDelete = (ProcPtr) nil; /*nothing to dispose*/
00633     
00634     variableprocs.hFontInfo = nil; /*nothing abnormal here*/
00635     } /*wpvariableinit*/
00636 
00637 
00638 #else
00639 
00640 boolean wpremovevariablestyle (void) {
00641     
00642     return (false);
00643     } /*wpremovevariablestyle*/
00644 
00645 
00646 boolean wpunpackvariablelist (Handle hpackedvarlist) {
00647     
00648     disposehandle (hpackedvarlist); /*checks for nil*/
00649     
00650     return (true);
00651     } /*wpunpackvariablelist*/
00652 
00653 
00654 boolean wppackvariablelist (Handle *hpackedvarlist) {
00655     
00656     return (newemptyhandle (hpackedvarlist));
00657     } /*wppackvariablelist*/
00658 
00659 
00660 void wpdisposevariablelist (Handle hvariablelist) {
00661     
00662     disposehandle (hvariablelist);
00663     } /*wpdisposevariablelist*/
00664 
00665 void wpvariableinit (void) {
00666     
00667     } /*wpvariableinit*/
00668 
00669 #endif
00670 
00671 
00672 

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