blob: bf77d6bfd4a4d644e82264ca99d2bd7376a7bfb7 [file] [log] [blame]
Jack Jansen7cc57351998-08-18 14:54:11 +00001/*
2 *
3 * This is a simple module to allow the
4 * user to compile and execute an applescript
5 * which is passed in as a text item.
6 *
7 * Sean Hummel <seanh@prognet.com>
8 * 1/20/98
9 * RealNetworks
10 *
11 * Jay Painter <jpaint@serv.net> <jpaint@gimp.org> <jpaint@real.com>
12 *
13 *
14 */
15
16#include <Resources.h>
17#include <Files.h>
18#include <OSA.h>
19#include <string.h>
20#include "ScriptRunner.h"
21#include <script.h>
22#include <resources.h>
23
Jack Jansencbed91b2001-08-03 13:31:36 +000024#ifdef TARGET_API_MAC_CARBON
25static
26p2cstr(StringPtr p)
27{
28 unsigned char *c = p;
29 int len = c[0];
30 strncpy((char *)c+1, (char *)c, len);
31 c[len] = 0;
32}
Jack Jansen7cc57351998-08-18 14:54:11 +000033
Jack Jansencbed91b2001-08-03 13:31:36 +000034static c2pstr(const char *cc)
35{
36 char *c = (char *)cc; /* Ouch */
37 int len = strlen(c);
38
39 if ( len > 255 ) len = 255;
40 strncpy(c, c+1, len);
41 c[0] = len;
42}
43#endif
Jack Jansen7cc57351998-08-18 14:54:11 +000044
45OSAError LoadScriptingComponent (ComponentInstance * scriptingComponent);
46
47
48/*
49 * store the script as a compile script so that OSA
50 * components may load and execute the script easily
51 */
52OSAError
53CompileAndSave (const char *text,
54 const char *outfile,
55 OSAActiveUPP proc,
56 AEDesc * result)
57{
58
59 OSAError err2 = 0;
60 AEDesc theScript;
61 OSAID compiledScriptID = 0;
62 ComponentInstance scriptingComponent;
63 FSSpec outfilespec;
64 AEDesc theCompiledScript;
65 OSAID scriptid = kOSANullScript;
66 short saveres = 0;
67
68
69
70 /* Initialize theScript here because it is a struct */
71 theScript.dataHandle = NULL;
72 theCompiledScript.dataHandle = NULL;
73
74
75 /* open the component manager */
76 err2 = LoadScriptingComponent (&scriptingComponent);
77 if (err2)
78 return err2; /* <<< Fail quietly?? */
79
80
81 /* construct the AppleEvent Descriptor to contain the text of script */
82 AECreateDesc ('TEXT', text, strlen (text), &theScript);
83
84 err2 = OSACompile (scriptingComponent,
85 &theScript,
86 kOSAModeCompileIntoContext,
87 &scriptid);
88 if (err2)
89 {
90 OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result);
91 goto CleanUp;
92 }
93
94
95 err2 = OSAStore (scriptingComponent,
96 scriptid,
97 typeOSAGenericStorage,
98 kOSAModeCompileIntoContext,
99 &theCompiledScript);
100 if (err2)
101 {
102 OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result);
103 goto CleanUp;
104 }
105
106
107 c2pstr (outfile);
108 FSMakeFSSpec (0, 0, (StringPtr) outfile, &outfilespec);
109 p2cstr ((StringPtr) outfile);
110
111 FSpDelete (&outfilespec);
112
113 FSpCreateResFile (&outfilespec, 'ToyS', 'osas', smRoman);
114
115 saveres = CurResFile ();
116
117 if (saveres)
118 {
119 short myres = 0;
120 myres = FSpOpenResFile (&outfilespec, fsWrPerm);
121
122 UseResFile (myres);
123 AddResource (theCompiledScript.dataHandle, 'scpt', 128, "\p");
124 CloseResFile (myres);
125 UseResFile (saveres);
126 }
127
128
129CleanUp:
130
131 if (theScript.dataHandle)
132 AEDisposeDesc (&theScript);
133
134 if (theCompiledScript.dataHandle)
135 AEDisposeDesc (&theCompiledScript);
136
137 if (scriptid)
138 OSADispose (scriptingComponent, scriptid);
139
140 if (scriptingComponent != 0)
141 CloseComponent (scriptingComponent);
142
143
144 return err2;
145}
146
147
148OSAError
149CompileAndExecute (const char *text,
150 AEDesc * result,
151 OSAActiveUPP proc)
152{
153 OSAError err2 = 0;
154 AEDesc theScript;
155 OSAID compiledScriptID = 0;
156 ComponentInstance scriptingComponent;
157
158
159 /* initialize theScript here because it is a struct */
160 theScript.dataHandle = NULL;
161
162 /* Open the component manager */
163 err2 = LoadScriptingComponent (&scriptingComponent);
164 if (err2)
165 return err2; /* <<< Fail quietly?? */
166
167
168 /* construct the AppleEvent Descriptor to contain the text of script */
169 AECreateDesc ('TEXT', text, strlen (text), &theScript);
170
171
172 err2 = OSASetActiveProc (scriptingComponent, proc, NULL);
173 if (err2)
174 goto CleanUp;
175
176
177 err2 = OSADoScript (scriptingComponent, &theScript, kOSANullScript, 'TEXT', 0, result);
178 if (err2)
179 {
180 OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result);
181 goto CleanUp;
182 }
183
184
185CleanUp:
186
187 if (theScript.dataHandle)
188 AEDisposeDesc (&theScript);
189
190 if (scriptingComponent != 0)
191 CloseComponent (scriptingComponent);
192
193
194 return err2;
195}
196
197
198/*
199 * This routine reads in a saved script file and executes
200 * the script contained within (from a 'scpt' resource.)
201 */
202OSAError
203ExecuteScriptFile (const char *theFilePath,
204 OSAActiveUPP proc,
205 AEDesc * result)
206{
207 OSAError err2;
208 short resRefCon;
209 AEDesc theScript;
210 OSAID compiledScriptID, scriptResultID;
211 ComponentInstance scriptingComponent;
212 FSSpec theFile;
213
214
215 c2pstr (theFilePath);
216 FSMakeFSSpec (0, 0, (StringPtr) theFilePath, &theFile);
217 p2cstr ((StringPtr) theFilePath);
218
219
220 /* open a connection to the OSA */
221 err2 = LoadScriptingComponent (&scriptingComponent);
222 if (err2)
223 return err2; /* <<< Fail quietly?? */
224
225
226 err2 = OSASetActiveProc (scriptingComponent, proc, NULL);
227 if (err2)
228 goto error;
229
230
231 /* now, try and read in the script
232 * Open the script file and get the resource
233 */
234 resRefCon = FSpOpenResFile (&theFile, fsRdPerm);
235 if (resRefCon == -1)
236 return ResError ();
237
238 theScript.dataHandle = Get1IndResource (typeOSAGenericStorage, 1);
239
240 if ((err2 = ResError ()) || (err2 = resNotFound, theScript.dataHandle == NULL))
241 {
242 CloseResFile (resRefCon);
243 return err2;
244 }
245
246 theScript.descriptorType = typeOSAGenericStorage;
247 DetachResource (theScript.dataHandle);
248 CloseResFile (resRefCon);
249 err2 = noErr;
250
251
252 /* give a copy of the script to AppleScript */
253 err2 = OSALoad (scriptingComponent,
254 &theScript,
255 0L,
256 &compiledScriptID);
257 if (err2)
258 goto error;
259
260 AEDisposeDesc (&theScript);
261 theScript.dataHandle = NULL;
262
263
264 err2 = OSAExecute (scriptingComponent,
265 compiledScriptID,
266 kOSANullScript,
267 0,
268 &scriptResultID);
269
270 if (compiledScriptID)
271 OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result);
272
273 if (err2)
274 goto error;
275
276 /* If there was an error, return it. If there was a result, return it. */
277 (void) OSADispose (scriptingComponent, compiledScriptID);
278
279 if (err2)
280 goto error;
281 else
282 goto done;
283
284error:
285 if (theScript.dataHandle)
286 AEDisposeDesc (&theScript);
287
288
289done:
290
291
292 return err2;
293}
294
295
296OSAError
297LoadScriptingComponent (ComponentInstance * scriptingComponent)
298{
299 OSAError err2;
300
301 /* Open a connection to the Open Scripting Architecture */
302 *scriptingComponent = OpenDefaultComponent (kOSAComponentType,
303 kOSAGenericScriptingComponentSubtype);
304
305 err2 = GetComponentInstanceError (*scriptingComponent);
306
307 return err2;
308}