/* * * 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 * 1/20/98 * RealNetworks * * Jay Painter * * */ #include #include #include #include #include "ScriptRunner.h" #include #include #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; }