home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-10-28 | 5.5 KB | 298 lines | [TEXT/MPS ] |
- /* $Header: tyrathect:Development:Perl::RCS:missing.c,v 1.2 1994/05/04 02:12:43 neeri Exp $
- *
- * Copyright (c) 1995 Matthias Neeracher
- *
- * You may distribute under the terms of the Perl Artistic License,
- * as specified in the README file.
- *
- * $Log: XL.xs,v $
- */
-
- #define MAC_CONTEXT
-
- #include "EXTERN.h"
- #include "perl.h"
- #include "XSUB.h"
- #include <Types.h>
- #include <HyperXCmd.h>
- #include <Resources.h>
- #include <TextUtils.h>
- #include <XL.h>
- #include <strings.h>
-
- XLGlue XLPerlGlue;
-
- static void PerlXLGetGlobal(XCmdPtr params)
- {
- StringPtr var = (StringPtr) params->inArgs[0];
- char ch = 0;
- SV * sv;
- char * str;
- STRLEN len;
-
- if (sv = perl_get_sv(p2cstr(var), FALSE)) {
- str = (char *)SvPV(sv,len);
- PtrToHand(str, (Handle *) ¶ms->outArgs[0], len+1);
- } else
- PtrToHand(&ch, (Handle *) ¶ms->outArgs[0], 1);
-
- c2pstr((char *) var);
-
- params->result = xresSucc;
- }
-
- static void PerlXLSetGlobal(XCmdPtr params)
- {
- StringPtr var = (StringPtr) params->inArgs[0];
- Handle val = (Handle) params->inArgs[1];
- char ch = 0;
- SV * sv;
-
- HLock(val);
- if (sv = perl_get_sv(p2cstr(var), TRUE))
- sv_setpv(sv, *val);
- c2pstr((char *) var);
- HUnlock(val);
-
- params->result = sv ? xresSucc : xresFail;
- }
-
- static void InitPerlXL()
- {
- XLCopyGlue(XLPerlGlue, XLDefaultGlue);
-
- XLPerlGlue[xl_GetGlobal] = PerlXLGetGlobal;
- XLPerlGlue[xl_SetGlobal] = PerlXLSetGlobal;
- }
-
- typedef struct {
- short refNum;
- FSSpec file;
- } ResourceFile;
-
- typedef struct {
- short count;
- ResourceFile file[1];
- } ** ResourceFiles;
-
- typedef struct {
- short refNum;
- ResType type;
- short id;
- } Xternal, ** XternalHdl;
-
- static ResourceFiles ResFiles;
- static XternalHdl Xternals;
- static int XternalIndex = 0;
- static Boolean CloseInstalled = false;
-
- static void XLCloseResFiles(void)
- {
- if (ResFiles) {
- while ((*ResFiles)->count--)
- CloseResFile((*ResFiles)->file[(*ResFiles)->count].refNum);
-
- DisposeHandle((Handle) ResFiles);
-
- ResFiles = nil;
- }
-
- if (Xternals) {
- DisposeHandle((Handle) Xternals);
-
- Xternals = nil;
- }
-
- XternalIndex = 0;
- CloseInstalled = false;
- }
-
- static ResType SearchTypes[] = {'XCMD', 'XFCN', 0};
-
- void XS_MacPerl_MP_CallXL(CV *);
-
- static void XLLoadResFile(short refNum)
- {
- Handle xcmd;
- ResType * type;
- short count;
- short id;
- ResType rtyp;
- short oldRes = CurResFile();
- Xternal x;
- CV * cv;
- char * file = __FILE__;
- char name[256];
-
- if (!CloseInstalled) {
- atexit(XLCloseResFiles);
- CloseInstalled = true;
- }
-
- if (!Xternals)
- Xternals = (XternalHdl) NewHandle(0);
-
- UseResFile(refNum);
-
- for (type = SearchTypes; *type; ++type)
- for (count = Count1Resources(*type); count; --count)
- if (xcmd = Get1IndResource(*type, count)) {
- getresinfo(xcmd, &id, &rtyp, name);
-
- x.refNum = refNum;
- x.type = rtyp;
- x.id = id;
-
- PtrAndHand((Ptr) &x, (Handle) Xternals, sizeof(Xternal));
-
- cv = newXS(name, XS_MacPerl_MP_CallXL, file);
- XSANY.any_i32 = XternalIndex++;
- }
-
- UseResFile(oldRes);
- }
-
- static OSErr XLTryResLoad(FSSpec * spec)
- {
- short i;
- short refNum;
- ResourceFile file;
-
- if (!ResFiles) {
- i = 0;
-
- PtrToHand((Ptr) &i, (Handle *) &ResFiles, sizeof(short));
- }
-
- for (i = (*ResFiles)->count; i--; ) {
- ResourceFile * file = (*ResFiles)->file + i;
-
- if (file->file.vRefNum != spec->vRefNum)
- continue;
- if (file->file.parID != spec->parID)
- continue;
-
- if (EqualString(file->file.name, spec->name, false, true))
- return 0;
- }
-
- refNum = HOpenResFile(spec->vRefNum, spec->parID, spec->name, fsRdPerm);
-
- if (refNum == -1)
- return ResError();
-
- file.refNum = refNum;
- file.file = *spec;
-
- PtrAndHand((Ptr) &file, (Handle) ResFiles, sizeof(ResourceFile));
- ++(*ResFiles)->count;
-
- XLLoadResFile(refNum);
-
- return 0;
- }
-
- MODULE = XL PACKAGE = MacPerl PREFIX = MP_
-
- void
- MP_LoadExternals(path)
- char * path
- CODE:
- {
- int i;
- AV * ar;
- OSErr err;
- char buf[256];
- FSSpec spec;
-
- if (strchr(path, ':')) {
- if (!Path2FSSpec(path, &spec))
- err = XLTryResLoad(&spec);
- else
- err = fnfErr;
-
- goto done;
- }
-
- ar = GvAVn(incgv);
- for (i = 0; i <= AvFILL(ar); i++) {
- char *libptr = SvPVx(*av_fetch(ar, i, TRUE), na);
- int colon = (libptr[strlen(libptr)-1] == ':');
-
- if (colon)
- sprintf(buf, "%s%s", libptr, path);
- else
- sprintf(buf, "%s:%s", libptr, path);
-
- if (!Path2FSSpec(buf, &spec) && !XLTryResLoad(&spec)) {
- err = 0;
-
- goto done;
- }
- }
-
- err = fnfErr;
- done:
- switch (err) {
- case noErr:
- break;
- case fnfErr:
- croak("MacPerl::LoadExternals(\"%s\"): File not found.", path);
- default:
- croak("MacPerl::LoadExternals(\"%s\"): OS Error (%d).", err);
- }
- }
-
- void
- MP_CallXL(...)
- CODE:
- {
- dXSI32;
- int i;
- short resFile;
- struct XCmdBlock xcmd;
- Xternal xt;
- Handle xh;
-
- xcmd.paramCount = items;
- for (i = 0; i < items; ++i) {
- STRLEN len;
- char * arg = (char *) SvPV(ST(i), len);
-
- PtrToHand(arg, xcmd.params+i, len+1);
- }
-
- for (i = items; i < 16; ++i)
- xcmd.params[i] = nil;
-
- xcmd.returnValue = nil;
- xcmd.passFlag = 0;
-
- xt = (*Xternals)[ix];
- resFile = CurResFile();
- UseResFile(xt.refNum);
-
- xh = Get1Resource(xt.type, xt.id);
-
- if (!xh)
- croak("XCMD disppeared. Film at 11!");
-
- XLCall(xh, XLPerlGlue, &xcmd);
-
- UseResFile(resFile);
-
- for (i=0; i<16; ++i)
- if (xcmd.params[i])
- DisposeHandle(xcmd.params[i]);
-
- if (xcmd.returnValue) {
- HLock(xcmd.returnValue);
- ST(0) = sv_2mortal(newSVpv(*xcmd.returnValue, 0));
- DisposeHandle(xcmd.returnValue);
- } else
- ST(0) = &sv_undef;
- }
-
- BOOT:
- InitPerlXL();
-