mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	
		
			
	
	
		
			290 lines
		
	
	
	
		
			6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			290 lines
		
	
	
	
		
			6 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>
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 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; | ||
|  | } |