cpython/Mac/Contrib/osam/ScriptRunner.c

309 lines
6.3 KiB
C

/*
*
* This is a simple module to allow the
* user to compile and execute an applescript
* which is passed in as a text item.
*
* Sean Hummel <seanh@prognet.com>
* 1/20/98
* RealNetworks
*
* Jay Painter <jpaint@serv.net> <jpaint@gimp.org> <jpaint@real.com>
*
*
*/
#include <Resources.h>
#include <Files.h>
#include <OSA.h>
#include <string.h>
#include "ScriptRunner.h"
#include <script.h>
#include <resources.h>
#ifdef TARGET_API_MAC_CARBON
static
p2cstr(StringPtr p)
{
unsigned char *c = p;
int len = c[0];
strncpy((char *)c+1, (char *)c, len);
c[len] = 0;
}
static c2pstr(const char *cc)
{
char *c = (char *)cc; /* Ouch */
int len = strlen(c);
if ( len > 255 ) len = 255;
strncpy(c, c+1, len);
c[0] = len;
}
#endif
OSAError LoadScriptingComponent (ComponentInstance * scriptingComponent);
/*
* store the script as a compile script so that OSA
* components may load and execute the script easily
*/
OSAError
CompileAndSave (const char *text,
const char *outfile,
OSAActiveUPP proc,
AEDesc * result)
{
OSAError err2 = 0;
AEDesc theScript;
OSAID compiledScriptID = 0;
ComponentInstance scriptingComponent;
FSSpec outfilespec;
AEDesc theCompiledScript;
OSAID scriptid = kOSANullScript;
short saveres = 0;
/* Initialize theScript here because it is a struct */
theScript.dataHandle = NULL;
theCompiledScript.dataHandle = NULL;
/* open the component manager */
err2 = LoadScriptingComponent (&scriptingComponent);
if (err2)
return err2; /* <<< Fail quietly?? */
/* construct the AppleEvent Descriptor to contain the text of script */
AECreateDesc ('TEXT', text, strlen (text), &theScript);
err2 = OSACompile (scriptingComponent,
&theScript,
kOSAModeCompileIntoContext,
&scriptid);
if (err2)
{
OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result);
goto CleanUp;
}
err2 = OSAStore (scriptingComponent,
scriptid,
typeOSAGenericStorage,
kOSAModeCompileIntoContext,
&theCompiledScript);
if (err2)
{
OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result);
goto CleanUp;
}
c2pstr (outfile);
FSMakeFSSpec (0, 0, (StringPtr) outfile, &outfilespec);
p2cstr ((StringPtr) outfile);
FSpDelete (&outfilespec);
FSpCreateResFile (&outfilespec, 'ToyS', 'osas', smRoman);
saveres = CurResFile ();
if (saveres)
{
short myres = 0;
myres = FSpOpenResFile (&outfilespec, fsWrPerm);
UseResFile (myres);
AddResource (theCompiledScript.dataHandle, 'scpt', 128, "\p");
CloseResFile (myres);
UseResFile (saveres);
}
CleanUp:
if (theScript.dataHandle)
AEDisposeDesc (&theScript);
if (theCompiledScript.dataHandle)
AEDisposeDesc (&theCompiledScript);
if (scriptid)
OSADispose (scriptingComponent, scriptid);
if (scriptingComponent != 0)
CloseComponent (scriptingComponent);
return err2;
}
OSAError
CompileAndExecute (const char *text,
AEDesc * result,
OSAActiveUPP proc)
{
OSAError err2 = 0;
AEDesc theScript;
OSAID compiledScriptID = 0;
ComponentInstance scriptingComponent;
/* initialize theScript here because it is a struct */
theScript.dataHandle = NULL;
/* Open the component manager */
err2 = LoadScriptingComponent (&scriptingComponent);
if (err2)
return err2; /* <<< Fail quietly?? */
/* construct the AppleEvent Descriptor to contain the text of script */
AECreateDesc ('TEXT', text, strlen (text), &theScript);
err2 = OSASetActiveProc (scriptingComponent, proc, NULL);
if (err2)
goto CleanUp;
err2 = OSADoScript (scriptingComponent, &theScript, kOSANullScript, 'TEXT', 0, result);
if (err2)
{
OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result);
goto CleanUp;
}
CleanUp:
if (theScript.dataHandle)
AEDisposeDesc (&theScript);
if (scriptingComponent != 0)
CloseComponent (scriptingComponent);
return err2;
}
/*
* This routine reads in a saved script file and executes
* the script contained within (from a 'scpt' resource.)
*/
OSAError
ExecuteScriptFile (const char *theFilePath,
OSAActiveUPP proc,
AEDesc * result)
{
OSAError err2;
short resRefCon;
AEDesc theScript;
OSAID compiledScriptID, scriptResultID;
ComponentInstance scriptingComponent;
FSSpec theFile;
c2pstr (theFilePath);
FSMakeFSSpec (0, 0, (StringPtr) theFilePath, &theFile);
p2cstr ((StringPtr) theFilePath);
/* open a connection to the OSA */
err2 = LoadScriptingComponent (&scriptingComponent);
if (err2)
return err2; /* <<< Fail quietly?? */
err2 = OSASetActiveProc (scriptingComponent, proc, NULL);
if (err2)
goto error;
/* now, try and read in the script
* Open the script file and get the resource
*/
resRefCon = FSpOpenResFile (&theFile, fsRdPerm);
if (resRefCon == -1)
return ResError ();
theScript.dataHandle = Get1IndResource (typeOSAGenericStorage, 1);
if ((err2 = ResError ()) || (err2 = resNotFound, theScript.dataHandle == NULL))
{
CloseResFile (resRefCon);
return err2;
}
theScript.descriptorType = typeOSAGenericStorage;
DetachResource (theScript.dataHandle);
CloseResFile (resRefCon);
err2 = noErr;
/* give a copy of the script to AppleScript */
err2 = OSALoad (scriptingComponent,
&theScript,
0L,
&compiledScriptID);
if (err2)
goto error;
AEDisposeDesc (&theScript);
theScript.dataHandle = NULL;
err2 = OSAExecute (scriptingComponent,
compiledScriptID,
kOSANullScript,
0,
&scriptResultID);
if (compiledScriptID)
OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result);
if (err2)
goto error;
/* If there was an error, return it. If there was a result, return it. */
(void) OSADispose (scriptingComponent, compiledScriptID);
if (err2)
goto error;
else
goto done;
error:
if (theScript.dataHandle)
AEDisposeDesc (&theScript);
done:
return err2;
}
OSAError
LoadScriptingComponent (ComponentInstance * scriptingComponent)
{
OSAError err2;
/* Open a connection to the Open Scripting Architecture */
*scriptingComponent = OpenDefaultComponent (kOSAComponentType,
kOSAGenericScriptingComponentSubtype);
err2 = GetComponentInstanceError (*scriptingComponent);
return err2;
}