Important: The information in this document is obsolete and should not be used for new development.
Compiling and Executing Source Data
This section describes how you can use scripting component routines to obtain source data from users, compile the source data, and execute the compiled script. To create and execute a script using the Script Editor application, a user can type the script, then click the Run button to execute it. Your application can provide similar capabilities.To allow users to write a new script and then execute it, your application must use scripting component routines to compile and execute the source data. To compile source data in a new script with a new script ID, pass the constant
kOSANullScript
(rather than an existing script ID) in the last parameter of theOSACompile
function. This causesOSACompile
to return a new script ID in the same parameter.To execute a compiled script, your application must specify, in addition to the script ID for the compiled script, a script context: either the corresponding scripting component's default context or a script ID for the global context created by that scripting component. Script contexts maintain state information for the execution of scripts. Your application can use script contexts to control the binding of variables used in scripts that it executes. For example, if your application saves its own global context and reuses it every time a script is executed, the binding of variables used in the script is maintained after the user restarts the computer. If your application does not specify a script context, the AppleScript component uses a single default context whenever it executes the script. A scripting component's default context binds the variables used in the script only until the user quits the application.
To specify a scripting component's default context, pass the constant
kOSANullScript
in the third parameter of theOSAExecute
function; to specify some other global context, pass its script ID in the third parameter.The
MyDoNewScript
procedure in Listing 10-2 allows a user to type a script in the appropriate scripting language, then compiles the script, executes the compiled script using a global context provided by the application, and displays the result to the user.The
MyDoNewScript
procedure begins by calling theOSAScriptingComponentName
function to obtain the name of the scripting component specified bygScriptingComponent
. This name is passed to the application-defined functionMyGetUserScriptText
.
The
- Note
- If you are using the generic scripting component, you can use the
OSAGetDefaultComponent
function to get the subtype code for the default scripting component (that is, the scripting component used by the generic scripting component for new scripts). You can then get an instance of the default scripting component by passing its subtype code toOSAGetScriptingComponent
. Finally, you can pass that instance toOSAScriptingComponentName
to obtain the default scripting component's name. For more information about the default scripting component and routines you can use with the generic scripting component, see "Generic Scripting Component Routines," which begins on page 10-83.MyGetUserScriptText
function displays the name of the scripting language to use in a script-editing window or message box that allows the user to type and execute a new script. After it obtains the source data for the new script, theMyDoNewScript
procedure sets thescriptID
variable tokOSANullScript
. The procedure then passes the source data andscriptID
to theOSACompile
function. When the script ID passed toOSACompile
iskOSANullScript
,OSACompile
returns, in the same parameter, a new script ID for the resulting compiled script. TheMyDoNewScript
procedure then passes the new script ID to theOSAExecute
function.In addition to a component instance and the script ID for the compiled script to be executed,
OSAExecute
takes a script ID for a script context and a parameter that contains the mode flags, if any, for script execution. In Listing 10-2, the script ID passed toOSAExecute
for the script context isgContext
, a global context provided by the application. The constant kOSAModeNull in the next parameter indicates that no mode flags are set for script execution.Listing 10-2 A routine that compiles and executes source data
PROCEDURE MyDoNewScript; VAR componentName, scriptText, resultText: AEDesc; scriptID, resultID: OSAID; myOSAErr, ignoreErr: OSAError; BEGIN {get the scripting component's name so you can show } { the user which scripting language to use} myOSAErr := OSAScriptingComponentName(gScriptingComponent, componentName); IF myOSAErr = noErr THEN BEGIN {get the user's script text, then compile it} MyGetUserScriptText(componentName, scriptText); {to create a new compiled script using the user's script } { text, pass kOSANullScript to OSACompile as the script ID } { for the script to be compiled} scriptID := kOSANullScript; myOSAErr := OSACompile(gScriptingComponent, scriptText, kOSAModeNull, scriptID); ignoreErr := AEDisposeDesc(scriptText); END; IF myOSAErr = noErr THEN BEGIN {execute the script in a global context} myOSAErr := OSAExecute(gScriptingComponent, scriptID, gContext, kOSAModeNull, resultID); ignoreErr := OSADispose(gScriptingComponent, scriptID); IF myOSAErr = noErr THEN BEGIN {convert the script value returned by OSAExecute to } { text that can be displayed to the user} myOSAErr := OSADisplay(gScriptingComponent, resultID, typeChar, kOSAModeNull, resultText); ignoreErr := OSADispose(gScriptingComponent, resultID); {show result to user} MyShowUserResult(resultText); ignoreErr := AEDisposeDesc(resultText); END; END; IF myOSAErr = errOSAScriptError THEN MyGetScriptErrorInfo; END;If script execution is successful, theMyDoNewScript
procedure passes the script ID for the resulting script value to theOSADisplay
function and calls theMyShowUserResult
procedure to display the script value to the user. It also disposes of the script data for the compiled script. IfOSAExecute
orOSACompile
returns the result codeerrOSAScriptError
, theMyDoNewScript
procedure calls theMyGetScriptErrorInfo
procedure shown in Listing 10-3, which uses theOSAScriptError
function to obtain more information about the error.Whenever a scripting component routine returns the result code
errOSAScriptError
, you can useOSAScriptError
to obtain more information about the error. The second parameter of theOSAScriptError
function is a constant that specifies the kind of error information to be returned, and the third parameter is the descriptor type for the descriptor record in which the additional error information will be returned.The
MyGetScriptErrorInfo
procedure in Listing 10-3 callsOSAScriptError
three times: once to obtain an error number for either a system error or a scripting component error, once to obtain a text description of the error, and once to obtain error-range information. (For more information about specifying descriptor types forOSAScriptError
, see page 10-36.) Finally, theMyGetScriptErrorInfo
procedure extracts the starting and ending positions of the error range in the source data and calls the application-defined procedureMyIndicateError
to display the error information to the user. Note that your application is responsible for disposing of any descriptor records that are created.You should use the
OSACompile
andOSAExecute
functions as shown in Listing 10-2 if you expect the user to execute the compiled script several times or manipulate it in some other way. If you want to compile and execute a script just one time and don't need to keep the compiled script in memory after it has been executed, you can use eitherOSACompileExecute
orOSADoScript
if these functions are supported by the scripting component you specify.The
OSACompileExecute
function takes a component instance, a descriptor record for the source data to be compiled and executed, a context ID, and amodeFlags
parameter. It executes the resulting compiled script, disposes of the compiled script, and returns the script ID for the resulting script value.The
OSADoScript
function takes a component instance, a descriptor record for source data, a context ID, a text descriptor type, and amodeFlags
parameter. It compiles and executes the script, returns a descriptor record for the text that corresponds to the resulting script value, and disposes of both the compiled script and the script value.Listing 10-3 A procedure that uses
OSAScriptError
to get information about an execution error
PROCEDURE MyGetScriptErrorInfo; TYPE OSErrPtr = ^OSErr; OSErrHandle = ^OSErrPtr; VAR errorMessage: Handle; startPos, endPos: Integer; desc, recordDesc: AEDesc; actualType: DescType; actualSize: Size; scriptErr, myErr, ignoreErr: OSErr; myOSAErr: OSAError; BEGIN myOSAErr := OSAScriptError(gScriptingComponent, kOSAErrorNumber, typeShortInteger, desc); scriptErr := OSErrHandle(desc.dataHandle)^^; ignoreErr := AEDisposeDesc(desc); myOSAErr := OSAScriptError(gScriptingComponent, kOSAErrorMessage, typeChar, desc); errorMessage := desc.dataHandle; myOSAErr := OSAScriptError(gScriptingComponent, kOSAErrorRange, typeOSAErrorRange, desc); myErr := AECoerceDesc (desc, typeAERecord, recordDesc); ignoreErr := AEDisposeDesc(desc); myErr := AEGetKeyPtr(recordDesc, keySourceStart, typeShortInteger, actualType, Ptr(@startPos), sizeOf(startPos), actualSize); myErr := AEGetKeyPtr(recordDesc, keySourceEnd, typeShortInteger, actualType, Ptr(@endPos), sizeOf(endPos), actualSize); ignoreErr := AEDisposeDesc(recordDesc); MyIndicateError(scriptErr, errorMessage, startPos, endPos); {add your own error checking} END;