home *** CD-ROM | disk | FTP | other *** search
- /*
- * ASTcl -- DoAppleScript package for MacTcl 7.5.1
- * This code adds the command "DoAppleScript <script>" to MacTcl.
- *
- * ASTclUtils.c -- OSA utilities
- * Adapted from "FinderScripter (Scripts)"
- * in Ultimate Mac Programming by Dave Mark.
- * Written on 960927.
- *
- * Copyright (c) 1996 by Theodore C. Belding
- * University of Michigan Program for the Study of Complex Systems
- * <mailto:Ted.Belding@umich.edu>
- * <http://www-personal.engin.umich.edu>
- *
- * This code is freeware.
- */
-
- #include <ASRegistry.h> /* AppleScript constants */
- #include <AEPackObject.h> /* object specifier building utilities */
- #include <OSAGeneric.h>
- #include <AppleScript.h>
- #include <string.h>
-
- #include "ASTclUtils.h"
-
- /* globals */
-
- static ComponentInstance gGenericSC;
-
-
- /* fcn declarations */
-
- int OSAScriptInit( void );
- int ProcessScript( char* scriptStr, char* result );
- static int CompileScript( char* scriptStr, OSAID *scriptIDPtr, char* result);
- static int ExecuteScript( OSAID scriptID, char* result );
- static int GetScriptResults( OSAID resultID, char* result);
- static int GetScriptError( char* result );
- static int DescToString( AEDesc *textDescPtr, char* result );
-
-
- /* OSAScriptInit */
-
- int OSAScriptInit( void )
- {
- OSAError err;
-
- gGenericSC = OpenDefaultComponent( kOSAComponentType,
- kOSAGenericScriptingComponentSubtype );
-
- /* To target a script at a specific language, call OSASetDefaultScriptingComponent() and */
- /* pass in the selector code for AppleScript, kAppleScriptSubtype, which is defined in AppleScript.h. */
- /* By the way, if you want, you can save the old default scripting component */
- /* (a la GetPort()) by calling OSAGetDefaultScriptingComponent()... */
-
- err = OSASetDefaultScriptingComponent( gGenericSC, kAppleScriptSubtype );
-
- if ( err != noErr )
- return 1;
- else
- return 0;
- }
-
- /* ProcessScript */
-
- int ProcessScript( char* scriptStr, char* result )
- /* This routine is called to run the script in scriptStr. */
- {
- OSAID scriptID;
-
- scriptID = kOSANullScript; /* Each time we start a new script we want to */
- /* reinitialize the scriptID. If we are */
- /* correcting a script that had a syntax error, */
- /* we'll want to reuse the same scriptID... */
-
- if ( !CompileScript( scriptStr, &scriptID, result) )
- { /* script compiled okay */
- if ( ExecuteScript( scriptID, result ) ) {
- strcpy(result, "Error executing script");
- return 1;
- }
- else
- return 0;
- }
- else {
- strcpy(result, "Error compiling script");
- return 1;
- }
-
- }
-
- /* CompileScript */
-
- static int CompileScript( char* scriptStr, OSAID *scriptIDPtr, char* result )
- {
- OSErr err;
- OSAError errOSA;
- AEDesc errorDesc = {typeNull, NULL};
- AEDesc textDesc = {typeNull, NULL};
-
- err = AECreateDesc( typeChar, scriptStr, strlen(scriptStr), &textDesc );
-
- if ( err != noErr ) {
- strcpy(result, "Error calling AECreateDesc()");
- return 1;
- }
-
- errOSA = OSACompile( gGenericSC, &textDesc, kOSAModeNull, scriptIDPtr );
-
- err = AEDisposeDesc( &textDesc );
-
- if ( err != noErr ) {
- strcpy(result, "Error calling AEDisposeDesc()");
- return 1;
- }
-
- if ( errOSA == errOSAScriptError )
- {
- GetScriptError( result );
- return 1;
- }
- else if ( errOSA != noErr ) {
- strcpy(result, "Error calling OSACompile()");
- return 1;
- }
-
- /* compiled successfully */
- return 0;
- }
-
-
- /* ExecuteScript */
-
- static int ExecuteScript( OSAID scriptID, char* result )
- {
- OSAID resultID;
- OSAError errOSA;
- AEDesc errorDesc = {typeNull, NULL};
-
- errOSA = OSAExecute( gGenericSC, scriptID, kOSANullScript,
- kOSAModeNull, &resultID );
-
- if ( errOSA == errOSAScriptError )
- {
- GetScriptError( result );
- return 1;
- }
- else if ( errOSA != noErr ) {
- strcpy(result, "Error calling OSAExecute()");
- return 1;
- }
-
- /* If we get here, the script executed successfully. */
- /* Now we'll get the result... */
-
- return GetScriptResults( resultID, result );
- }
-
-
- /* DisplayScriptResults */
-
- static int GetScriptResults( OSAID resultID, char* result)
- {
- OSAError errOSA;
- OSErr err;
- AEDesc resultDesc = {typeNull, NULL};
-
- /* OSADisplay() takes the resultID and builds a typeChar descriptor */
- /* containing a human-readable description of the results. */
- errOSA = OSADisplay( gGenericSC, resultID, typeChar,
- kOSAModeDisplayForHumans, &resultDesc );
-
- /* OSADisplay() will return an error if you attempt to display */
- /* the undisplayable. For example, if your script toggles the */
- /* "warn before emptying" check box, you won't have anything */
- /* useful to display. We'll put up a message if we get an error... */
- if ( errOSA != noErr ) {
- strcpy(result, "Error calling OSADisplay()");
- return 1;
- }
- else
- {
- /* If the call to OSADisplay() was successful, we'll */
- /* convert the descriptor to a string. */
- DescToString( &resultDesc, result );
-
- err = AEDisposeDesc( &resultDesc );
-
- if ( err != noErr ) {
- strcpy(result, "Error calling AEDisposeDesc()");
- return 1;
- }
- else {
- return 0;
- }
- }
- }
-
-
- /* ReportScriptError */
-
- static int GetScriptError( char* result )
- {
- OSAError errOSA;
- OSErr err;
- AEDesc errorDesc = {typeNull, NULL};
-
- /* Retrieve the error message from OSAScriptError() and */
- /* display the message... */
- errOSA = OSAScriptError( gGenericSC, kOSAErrorMessage,
- typeChar, &errorDesc );
-
- if ( errOSA != noErr ) {
- strcpy(result, "Error calling OSAScriptError()");
- return 1;
- }
- DescToString( &errorDesc, result );
-
- err = AEDisposeDesc( &errorDesc );
-
- if ( err != noErr ) {
- strcpy(result, "Error calling AEDisposeDesc()");
- return 1;
- }
- else {
- return 0;
- }
- }
-
-
- /* DescToString */
-
- static int DescToString( AEDesc *textDescPtr, char* result)
- {
- Size len;
-
- if ( textDescPtr->descriptorType != typeChar ) {
- strcpy(result, "Tried to convert a non-typeChar descriptor to a string!!!");
- return 1;
- }
-
- len = GetHandleSize(textDescPtr->dataHandle);
-
- HLock( textDescPtr->dataHandle );
-
- strncpy(result, *(textDescPtr->dataHandle), (unsigned int) len);
-
- HUnlock( textDescPtr->dataHandle );
-
- result[(unsigned int) len] = '\0';
-
- return 0;
- }
-
-
-