langxcmd.c

Go to the documentation of this file.
00001 
00002 /*  $Id: langxcmd.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 "memory.h"
00032 #include "search.h"
00033 #include "strings.h"
00034 #include "ops.h"
00035 #include "frontierconfig.h"
00036 #include "lang.h"
00037 #include "langinternal.h"
00038 #include "langexternal.h"
00039 #include "langxcmd.h"
00040 #include "tablestructure.h"
00041 #include "tableverbs.h"
00042 #include "process.h"
00043 
00044 
00045 
00046 XCmdPtr plangxcmdrec = nil;
00047 
00048 
00049 
00050 static void scantext (byte ch, ptrbyte *ptext) {
00051     
00052     /*
00053     5/5/92 dmb: support routine for xcmdcallback
00054     */
00055     
00056     register ptrbyte p = *ptext;
00057     register byte c = ch;
00058     
00059     while (true) {
00060         
00061         if (*p == c) {
00062             
00063             *ptext = p;
00064             
00065             return;
00066             }
00067         
00068         ++p;
00069         }
00070     } /*scantext*/
00071 
00072 
00073 static long scanlength (byte ch, ptrbyte ptext) {
00074     
00075     register ptrbyte pstart = (ptrbyte) ptext;
00076     ptrbyte pend = pstart;
00077     
00078     scantext (ch, &pend);
00079     
00080     return ((long) (pend - pstart));
00081     } /*scanlength*/
00082 
00083 
00084 void truncatecstringhandle (Handle h) {
00085     
00086     /*
00087     11/6/92 dmb: scan the text in h for a null terminator, and
00088     truncate it there.
00089     */
00090     
00091     long len;
00092     
00093     len = scanlength (chnul, (ptrbyte) *h);
00094     
00095     if (len < gethandlesize (h))
00096         sethandlesize (h, len); /*truncate at zero terminator*/
00097     } /*truncatecstringhandle*/
00098 
00099 
00100 static void valtostring (tyvaluerecord *val, bigstring bsval) {
00101     
00102     /*
00103     take the newly-allocated value, make a string out of it, and 
00104     dispose the value record
00105     */
00106     
00107     coercetostring (val);
00108     
00109     pullstringvalue (val, bsval);
00110     
00111     releaseheaptmp ((*val).data.stringvalue);
00112     } /*valtostring*/
00113 
00114 
00115 static void stringtoval (bigstring bsval, tyvaluetype type, tyvaluerecord *val) {
00116     
00117     setstringvalue (bsval, val);
00118     
00119     disablelangerror ();
00120     
00121     if (!coercevalue (val, type)) {
00122         
00123         releaseheaptmp ((*val).data.stringvalue);
00124         
00125         (*val).data.stringvalue = nil;
00126         }
00127     
00128     enablelangerror ();
00129     } /*stringtoval*/
00130 
00131 
00132 static boolean resolvexcmdglobal (bigstring bsglobal, hdlhashtable *htable, bigstring bsname) {
00133     
00134     /*
00135     7/8/92 dmb: resolve a HyperCard global reference.  If the global string 
00136     can be interpreted as an existing local or global value, use that value. 
00137     otherwise, interpret it as the name of an item in scratchpad
00138     */
00139     
00140     bigstring bs;
00141     boolean fl;
00142     static byte nameglobalstable [] = "\pscratchpad";
00143     
00144     copystring (bsglobal, bs);
00145     
00146     disablelangerror ();
00147     
00148     fl = langexpandtodotparams (bs, htable, bsname);
00149     
00150     enablelangerror ();
00151     
00152     if (!fl) {
00153         
00154         *htable = nil;
00155         
00156         copystring (bs, bsname);
00157         }
00158     
00159     if (*htable == nil) {
00160         
00161         if (!langsearchpathlookup (bsname, htable)) {
00162             
00163             if (!findnamedtable (roottable, nameglobalstable, htable))
00164                 *htable = roottable;
00165             }
00166         }
00167     
00168     return (true);
00169     } /*resolvexcmdglobal*/
00170 
00171 
00172 void xcmdcallback (void) {
00173     
00174     /*
00175     5/4/92 dmb: HyperCard 1.0 XCMD callback emulation
00176     
00177     7/8/92 dmb: set return code; use xresNotImp for unknown request
00178     
00179     9/25/92 dmb: added SendHCEvent callback support. also spotted & fixed 
00180     a bug in ExtToStr handler.
00181     
00182     10/3/92 dmb: it turns out that the protocol requires that the caller 
00183     of the xcmd put the xcmdptr into a global for us; the xcmd code 
00184     doesn't pass it to us consistently.
00185     
00186     11/6/92 dmb: use new truncatecstringhandle instead of just popping last char.
00187     also, fixed NumToHex, NumToStr
00188     */
00189     
00190     register XCmdPtr pxcb;
00191     register long *args;
00192     register long *out;
00193     tyvaluerecord val;
00194     bigstring bs;
00195     hdlhashtable htable;
00196     hdlhashnode hnode;
00197     
00198     pxcb = plangxcmdrec; /*copy global into register*/
00199     
00200     args = (*pxcb).inArgs;
00201     out = (long *) &(*pxcb).outArgs;
00202     
00203     (*pxcb).result = xresSucc;
00204     
00205     switch ((*pxcb).request) {
00206         
00207         /*  HyperTalk Utilities  */
00208         case 0x02: /*Handle EvalExpr (StringPtr expr)*/
00209             
00210             if (!langrunstringnoerror ((ptrstring) args [0], bs))
00211                 (*pxcb).result = xresFail;
00212             
00213             else {
00214                 
00215                 pushchar (chnul, bs);
00216                 
00217                 newtexthandle (bs, (Handle *) out);
00218                 }
00219             
00220             break;
00221         
00222         case 0x01: /*void SendCardMessage (StringPtr msg)*/
00223         case 0x05: /*void SendHCMessage (StringPtr msg)*/
00224             
00225             if (!langrunstringnoerror ((ptrstring) args [0], bs))
00226                 (*pxcb).result = xresFail;
00227             
00228             break;
00229         
00230         /*
00231         case 0x26: /*void RunHandler (Handle handler)%/
00232             
00233             break;
00234         */
00235         
00236         
00237         /*  Memory Utilities  */
00238         case 0x12: /*Handle GetGlobal (StringPtr globName)*/
00239             
00240             resolvexcmdglobal ((ptrstring) args [0], &htable, bs);
00241             
00242             if (hashtablelookup (htable, bs, &val, &hnode)
00243                 && copyvaluerecord (val, &val)
00244                 && coercetostring (&val)
00245                 && enlargehandle (val.data.stringvalue, 1, zerostring)) {
00246                 
00247                 exemptfromtmpstack (&val);
00248                 
00249                 *out = (long) val.data.stringvalue;
00250                 }
00251             else
00252                 *out = 0L;
00253             
00254             break;
00255         
00256         case 0x13: /*void SetGlobal (StringPtr globName, Handle globValue)*/
00257             
00258             resolvexcmdglobal ((ptrstring) args [0], &htable, bs);
00259             
00260             initvalue (&val, stringvaluetype);
00261             
00262             if (!copyhandle ((Handle) args [1], &val.data.stringvalue))
00263                 (*pxcb).result = xresFail;
00264             
00265             else {
00266                 
00267                 truncatecstringhandle (val.data.stringvalue); /*strip zero terminator*/
00268                 
00269                 if (!hashtableassign (htable, bs, val))
00270                     disposevaluerecord (val, false);
00271                 }
00272             
00273             break;
00274         
00275         case 0x06: /*void ZeroBytes (Ptr dstPtr, long longCount)*/
00276             clearbytes ((byte *) args [0], args [1]);
00277             
00278             break;
00279         
00280         
00281         /*  String Utilities  */
00282         case 0x1c: /*void ScanToReturn (Ptr *scanPtr)*/
00283             
00284             scantext (chreturn, (ptrbyte *) args [0]);
00285             
00286             /*** test: ++*(ptrbyte *) args [0]; /*point past return*/
00287             
00288             break;
00289         
00290         case 0x27: /*void ScanToZero (Ptr *scanPtr)*/
00291             
00292             scantext (chnul, (ptrbyte *) args [0]);
00293             
00294             break;
00295         
00296         case 0x1a: /*Boolean StringEqual (StringPtr str1, StringPtr str2)*/
00297             *out = (long) equalstrings ((ptrstring) args [0], (ptrstring) args [1]);
00298             
00299             break;
00300         
00301         case 0x03: { /*long StringLength (Ptr strPtr)*/
00302             
00303             *out = scanlength (chnul, (ptrbyte) args [0]);
00304             
00305             break;
00306             }
00307         
00308         case 0x04: { /*Ptr StringMatch (StringPtr pattern, Ptr target)*/
00309             
00310             tysearchparameters saveparams = searchparams;
00311             long ix = 0;
00312             long len;
00313             
00314             searchparams.flunicase = false;
00315             searchparams.flwholewords = false;
00316             searchparams.flregexp = false;
00317             copystring ((ptrstring) args [0], searchparams.bsfind);
00318             
00319             textsearch ((ptrbyte) args [1], infinity, &ix, &len);
00320             
00321             *out = (long) ((ptrbyte) args [1] + ix);
00322             
00323             searchparams = saveparams;
00324             
00325             break;
00326             }
00327         
00328         case 0x20: /*void ZeroTermHandle (Handle hndl)*/
00329             
00330             enlargehandle ((Handle) args [0], 1, zerostring);
00331             
00332             break;
00333         
00334         
00335         /*  String Conversions  */
00336         case 0x10: /*void BoolToStr (Boolean bool, StringPtr str)*/
00337             setbooleanvalue ((Boolean) args [0], &val);
00338             
00339             valtostring (&val, (ptrstring) args [1]);
00340             
00341             break;
00342         
00343         case 0x11: { /*void ExtToStr (extended num, StringPtr str)*/
00344             
00345             #if __powerc
00346             
00347                 long double x;
00348                 
00349                 safex80told ((extended80 *) args [0], &x);
00350                 
00351                 setdoublevalue (x, &val);
00352             #else
00353             
00354                 setdoublevalue (* (long double *) args [0], &val);
00355             
00356             #endif
00357             
00358             valtostring (&val, (ptrstring) args [1]);
00359                 
00360             break;
00361             }
00362         
00363         case 0x0d: /*void LongToStr (long posNum, StringPtr str)*/
00364             setlongvalue ((unsigned long) args [0], &val); /*11/6/92 dmb*/
00365             
00366             valtostring (&val, (ptrstring) args [1]);
00367             
00368             break;
00369         
00370         case 0x0f: { /*void NumToHex (long num, short nDigits, StringPtr str)*/
00371             
00372             long n = args [0];
00373             byte hex [16];
00374             
00375             if (args [1] <= 4)
00376                 n = (short) n;
00377             
00378             numbertohexstring (n, hex); /*11/6/92 dmb*/
00379             
00380             deletestring (hex, 1, 2); /*remove the "0x"*/
00381             
00382             copystring (hex, (ptrstring) args [2]);
00383             
00384             break;
00385             }
00386         
00387         case 0x0e: /*void NumToStr (long num, StringPtr str)*/
00388             setlongvalue ((long) args [0], &val); /*11/6/92 dmb*/
00389             
00390             valtostring (&val, (ptrstring) args [1]);
00391             
00392             break;
00393         
00394         case 0x07: /*Handle PasToZero (StringPtr str)*/
00395             copystring ((ptrstring) args [0], bs);
00396             
00397             pushchar (chnul, bs);
00398             
00399             newtexthandle (bs, (Handle *) out);
00400             
00401             break;
00402         
00403         case 0x2b: /*void PointToStr (Point pt, StringPtr str)*/
00404             setpointvalue (*(Point *) args [0], &val);
00405             
00406             valtostring (&val, (ptrstring) args [1]);
00407             
00408             break;
00409         
00410         case 0x2c: /*void RectToStr (Rect *rct, StringPtr str)*/
00411             newheapvalue ((Rect *) args [0], longsizeof (Rect), rectvaluetype, &val);
00412             
00413             valtostring (&val, (ptrstring) args [1]);
00414             
00415             break;
00416         
00417         case 0x1b: /*void ReturnToPas (Ptr zeroStr, StringPtr pasStr)*/
00418             texttostring ((ptrbyte) args [0], scanlength (chreturn, (ptrbyte) args [0]), (ptrstring) args [1]);
00419             
00420             break;
00421         
00422         case 0x0b: /*Boolean StrToBool (StringPtr str)*/
00423             stringtoval ((ptrstring) args [0], booleanvaluetype, &val);
00424             
00425             *out = (long) val.data.flvalue;
00426             
00427             break;
00428         
00429         case 0x0c: { /*extended StrToExt (StringPtr str)*/
00430             #if __powerc
00431             
00432                 long double x;
00433                 
00434                 stringtoval ((ptrstring) args [0], doublevaluetype, &val);
00435                 
00436                 x = **val.data.doublevalue;
00437                 
00438                 safeldtox80 (&x, (extended80 *) args [1]);
00439                 
00440             #else
00441                 
00442                 stringtoval ((ptrstring) args [0], doublevaluetype, &val);
00443                 
00444                 *(double *) args [1] = **val.data.doublevalue;
00445                 
00446             #endif
00447             
00448             break;
00449             }
00450         
00451         case 0x09: /*long StrToLong (StringPtr str)*/
00452             stringtoval ((ptrstring) args [0], longvaluetype, &val);
00453             
00454             *out = abs (val.data.longvalue);
00455             
00456             break;
00457         
00458         case 0x0a: /*long StrToNum (StringPtr str)*/
00459             stringtoval ((ptrstring) args [0], longvaluetype, &val);
00460             
00461             *out = (long) val.data.longvalue;
00462             
00463             break;
00464         
00465         case 0x2d: /*void StrToPoint (StringPtr str, Point *pt)*/
00466             stringtoval ((ptrstring) args [0], pointvaluetype, &val);
00467             
00468             *(Point *) args [1] = val.data.pointvalue;
00469             
00470             break;
00471         
00472         case 0x2e: /*void StrToRect (StringPtr str, Rect *rct)*/
00473             stringtoval ((ptrstring) args [0], rectvaluetype, &val);
00474             
00475             *(Rect *) args [1] = **val.data.rectvalue;
00476             
00477             break;
00478         
00479         case 0x08: /*void ZeroToPas (Ptr zeroStr, StringPtr pasStr)*/
00480             texttostring ((ptrbyte) args [0], scanlength (chnul, (ptrbyte) args [0]), (ptrstring) args [1]);
00481             
00482             break;
00483         
00484         #if 0
00485         
00486         /*  Field Utilities  */
00487         case 0x16: /*Handle GetFieldByID (Boolean cardFieldFlag, short fieldID)*/
00488             newfilledhandle (zerostring, 1L, (Handle *) out);
00489             
00490             break;
00491         
00492         case 0x14: /*Handle GetFieldByName (Boolean cardFieldFlag, StringPtr fieldName)*/
00493             newfilledhandle (zerostring, 1L, (Handle *) out);
00494             
00495             break;
00496         
00497         case 0x15: /*Handle GetFieldByNum (Boolean cardFieldFlag, short fieldNum)*/
00498             newfilledhandle (zerostring, 1L, (Handle *) out);
00499             
00500             break;
00501         
00502         case 0x19: /*void SetFieldByID (Boolean cardFieldFlag, short fieldID, Handle fieldVal)*/
00503             break;
00504         
00505         case 0x17: /*void SetFieldByName (Boolean cardFieldFlag, StringPtr fieldName, Handle fieldVal)*/
00506             break;
00507         
00508         case 0x18: /*void SetFieldByNum (Boolean cardFieldFlag, short fieldNum, Handle fieldVal)*/
00509             break;
00510         
00511         case 0x2f: /*TEHandle GetFieldTE (Boolean cardFieldFlag, short fieldID, short fieldNum, StringPtr fieldNamePtr)*/
00512             *out = 0;
00513             
00514             break;
00515                                                             
00516         case 0x30: /*void SetFieldTE (Boolean cardFieldFlag, short fieldID, short fieldNum, StringPtr fieldNamePtr, TEHandle fieldTE)*/
00517             break;
00518         
00519         #endif
00520         
00521         case 0x22: /*void SendHCEvent(EventRecord *event)*/
00522             
00523             /****component***/
00524             
00525             shellpostevent ((EventRecord *) &args [0]); /*yes, the event itself is in args*/
00526             
00527             shellforcebackgroundtask (); /*come back as soon as possible*/
00528             
00529             if (!processyield ()) /*we've been killed*/
00530                 (*pxcb).result = xresFail;
00531             
00532             break;
00533         
00534         default:
00535             *out = 0L;
00536             
00537             (*pxcb).result = xresNotImp;
00538             
00539             break;
00540         }
00541     
00542     plangxcmdrec = pxcb; /*reset in case another xcmd ran in the background*/
00543     } /*xcmdcallback*/
00544 
00545 

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