Initial revision

This commit is contained in:
Jack Jansen 1998-08-18 14:54:11 +00:00
parent 1d6a6ea1a8
commit 7cc5735ef2
24 changed files with 5316 additions and 0 deletions

View File

@ -0,0 +1,129 @@
"""PythonSlave.py
An application that responds to three types of apple event:
'pyth'/'EXEC': execute direct parameter as Python
'aevt', 'quit': quit
'aevt', 'odoc': perform python scripts
Copyright © 1996, Just van Rossum, Letterror
"""
__version__ = "0.1.3"
import FrameWork
import sys
import traceback
import aetools
import string
import AE
import EasyDialogs
import os
import Qd
from Types import *
from Events import charCodeMask, cmdKey
import MacOS
import Evt
def dummyfunc(): pass
modulefilename = dummyfunc.func_code.co_filename
def Interact(timeout = 50000000): # timeout after 10 days...
AE.AEInteractWithUser(timeout)
class PythonSlave(FrameWork.Application):
def __init__(self):
FrameWork.Application.__init__(self)
AE.AEInstallEventHandler('pyth', 'EXEC', ExecHandler)
AE.AEInstallEventHandler('aevt', 'quit', QuitHandler)
AE.AEInstallEventHandler('aevt', 'odoc', OpenDocumentHandler)
def makeusermenus(self):
self.filemenu = m = FrameWork.Menu(self.menubar, "File")
self._quititem = FrameWork.MenuItem(m, "Quit", "Q", self._quit)
def do_kHighLevelEvent(self, event):
(what, message, when, where, modifiers) = event
try:
AE.AEProcessAppleEvent(event)
except AE.Error, detail:
print "Apple Event was not handled, error:", detail
def do_key(self, event):
(what, message, when, where, modifiers) = event
c = chr(message & charCodeMask)
if modifiers & cmdKey and c == '.':
return
FrameWork.Application.do_key(self, event)
def idle(self, event):
Qd.InitCursor()
def quit(self, *args):
raise self
def getabouttext(self):
return "About PythonSlaveŠ"
def do_about(self, id, item, window, event):
EasyDialogs.Message("PythonSlave " + __version__ + "\rCopyright © 1996, Letterror, JvR")
def ExecHandler(theAppleEvent, theReply):
parameters, args = aetools.unpackevent(theAppleEvent)
if parameters.has_key('----'):
if parameters.has_key('NAME'):
print '--- executing "' + parameters['NAME'] + '" ---'
else:
print '--- executing "<unknown>" ---'
stuff = parameters['----']
MyExec(stuff + "\n") # execute input
print '--- done ---'
return 0
def MyExec(stuff):
stuff = string.splitfields(stuff, '\r') # convert return chars
stuff = string.joinfields(stuff, '\n') # to newline chars
Interact()
saveyield = MacOS.EnableAppswitch(1)
try:
exec stuff in {}
except:
MacOS.EnableAppswitch(saveyield)
traceback.print_exc()
MacOS.EnableAppswitch(saveyield)
def OpenDocumentHandler(theAppleEvent, theReply):
parameters, args = aetools.unpackevent(theAppleEvent)
docs = parameters['----']
if type(docs) <> ListType:
docs = [docs]
for doc in docs:
fss, a = doc.Resolve()
path = fss.as_pathname()
if path <> modulefilename:
MyExecFile(path)
return 0
def MyExecFile(path):
saveyield = MacOS.EnableAppswitch(1)
savewd = os.getcwd()
os.chdir(os.path.split(path)[0])
print '--- Executing file "' + os.path.split(path)[1] + '"'
try:
execfile(path, {"__name__": "__main__"})
except:
traceback.print_exc()
MacOS.EnableAppswitch(saveyield)
MacOS.EnableAppswitch(saveyield)
os.chdir(savewd)
print "--- done ---"
def QuitHandler(theAppleEvent, theReply):
slave.quit()
return 0
slave = PythonSlave()
print "PythonSlave", __version__, "ready."
slave.mainloop()

41
Mac/Contrib/BBPy/README Normal file
View File

@ -0,0 +1,41 @@
"Run as Python" -- a BBEdit extension to make the Python interpreter execute the
contents of the current window.
version 0.2.3, 18 september 1996
contents:
- "Run as Python" -- the extension
- PythonSlave.py -- the "slave" script that handles the AppleEvents
- source -- source code & CW9 project for the extension
quickstart:
- drop "Run as Python" in BBEdit extensions folder
- double-click PythonSlave.py
- start BBEdit
- type some code
- go to Extensions menu: "Run as Python"
- be happy
warning:
since PythonSlave.py runs its own event loop and we have no interface
to SIOUX you *cannot* copy from the console. Duh.
extra feature:
while PythonSlave.py is running you can still double-click Python
documents, they will get executed as if Python was not already running.
bugs:
perhaps
acknowledgements:
- Thanks to Joseph Strout for valuable input and beta testing.
- Thanks to Mark Roseman for providing code that can launch
PythonSlave.py from BBEdit.
Have fun with it!
Please report bugs, or fix 'em. Suggestions are always welcome.
Just van Rossum, Letterror
<just@knoware.nl>

View File

@ -0,0 +1,716 @@
#pragma once
#include <MixedMode.h>
#include <Dialogs.h>
#include <Files.h>
#include <Windows.h>
#include <AppleEvents.h>
#include <StandardFile.h>
#if defined(powerc) || defined (__powerc)
#pragma options align=mac68k
#endif
typedef struct
{
FSSpec spec; // designates file on disk
long key; // reserved for future expansion
char tree; // 0 for absolute, 1 for project, 2 for system
Boolean found; // FALSE if file couldn't be located; if so, all other info is moot
OSType type; // file type of found file
OSType crtr; // signature of found file's creator
short spare0; // reserved for future expansion
long spare1;
} ProjectEntry;
enum
{
kNeitherTree,
kProjectTree,
kSystemTree
};
enum
{
kTHINKCProject,
kTHINKPascalProject,
kCodeWarriorProject
};
// masks for the "flags" argument to new-convention interfaces
#define xfWindowOpen 0x00000001
#define xfWindowChangeable 0x00000002
#define xfHasSelection 0x00000004
#define xfUseDefaults 0x00000008
#define xfIsBBEditLite 0x00000040
#define xfIsBBEditDemo 0x00000080
typedef struct
{
FSSpec spec;
OSType key;
short error_kind;
long line_number;
Str255 message;
} ErrorEntry;
typedef enum
{
kNote = 0,
kError,
kWarning
} ErrorKind;
#define kCurrentExternalVersion 5 // current version of callbacks
// Universal callback interfaces
#if USESROUTINEDESCRIPTORS
#define ExtensionUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ExternalCallbackBlock *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(WindowPtr))))
#define NewExtensionUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ExternalCallbackBlock *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(WindowPtr))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(AppleEvent *))) \
| STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(AppleEvent *))))
#define GetWindowContentsUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Handle))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))))
#define GetSelectionUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long *))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long *))))
#define SetSelectionUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))))
#define GetDocInfoUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(unsigned char *))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short *))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long *))))
#define GetModDateUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))))
#define CopyUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Handle))))
#define PasteUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Handle))))
#define GetLastLineUPPInfo (kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(long))))
#define GetLineNumberUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))))
#define GetLineStartUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))))
#define GetLineEndUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))))
#define GetLinePosUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))))
#define InsertUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(char *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))))
#define DeleteUPPInfo (kPascalStackBased)
#define SetWindowContentsUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle))))
#define ContentsChangedUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))))
#define GetFileTextUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Handle))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(unsigned char *))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(Boolean *))))
#define GetFolderUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short *))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long *))))
#define OpenSeveralUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short *))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(StandardFileReply ***))))
#define CenterDialogUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(DialogPtr))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))))
#define StandardFilterUPPInfo uppModalFilterProcInfo
#define FrameDialogItemUPPInfo uppUserItemProcInfo
#define NewDocumentUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(WindowPtr))))
#define OpenDocumentUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(WindowPtr))))
#define AllocateUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Handle))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Boolean))))
#define FindPatternUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(char *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(char *))) \
| STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(Boolean))))
#define ReportOSErrorUPPInfo (kPascalStackBased)
#define GetPreferenceUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ResType))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short *))))
#define SetPreferenceUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ResType))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short *))))
#define StartProgressUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Boolean))))
#define DoProgressUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))))
#define DoneProgressUPPInfo (kPascalStackBased)
#define GetProjectListUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(FSSpec *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short *))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short *))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ProjectEntry***))))
#define ProjectTextListUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(FSSpec *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle *))))
#define PresetUndoUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))))
#define SetUndoUPPInfo (kPascalStackBased)
#define OpenFileUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(FSSpec *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(WindowPtr *))))
#define PrepareUndoUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long))))
#define CommitUndoUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))))
#define CreateResultsUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Handle))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(WindowPtr *))))
typedef UniversalProcPtr GetWindowContentsProc;
typedef UniversalProcPtr GetSelectionProc;
typedef UniversalProcPtr SetSelectionProc;
typedef UniversalProcPtr GetDocInfoProc;
typedef UniversalProcPtr GetModDateProc;
typedef UniversalProcPtr CopyProc;
typedef UniversalProcPtr PasteProc;
typedef UniversalProcPtr GetLastLineProc;
typedef UniversalProcPtr GetLineNumberProc;
typedef UniversalProcPtr GetLineStartProc;
typedef UniversalProcPtr GetLineEndProc;
typedef UniversalProcPtr GetLinePosProc;
typedef UniversalProcPtr InsertProc;
typedef UniversalProcPtr DeleteProc;
typedef UniversalProcPtr SetWindowContentsProc;
typedef UniversalProcPtr ContentsChangedProc;
typedef UniversalProcPtr GetFileTextProc;
typedef UniversalProcPtr GetFolderProc;
typedef UniversalProcPtr OpenSeveralProc;
typedef UniversalProcPtr CenterDialogProc;
typedef UniversalProcPtr StandardFilterProc;
typedef UniversalProcPtr FrameDialogItemProc;
typedef UniversalProcPtr NewDocumentProc;
typedef UniversalProcPtr OpenDocumentProc;
typedef UniversalProcPtr AllocateProc;
typedef UniversalProcPtr FindPatternProc;
typedef UniversalProcPtr ReportOSErrorProc;
typedef UniversalProcPtr GetPreferenceProc;
typedef UniversalProcPtr SetPreferenceProc;
typedef UniversalProcPtr StartProgressProc;
typedef UniversalProcPtr DoProgressProc;
typedef UniversalProcPtr DoneProgressProc;
typedef UniversalProcPtr GetProjectListProc;
typedef UniversalProcPtr ProjectTextListProc;
typedef UniversalProcPtr PresetUndoProc;
typedef UniversalProcPtr SetUndoProc;
typedef UniversalProcPtr OpenFileProc;
typedef UniversalProcPtr PrepareUndoProc;
typedef UniversalProcPtr CommitUndoProc;
typedef UniversalProcPtr CreateResultsProc;
#define CallGetWindowContents(proc, w) \
(Handle)(CallUniversalProc(proc, GetWindowContentsUPPInfo, (w)))
#define CallGetSelection(proc, selStart, selEnd, firstChar) \
(CallUniversalProc(proc, GetSelectionUPPInfo, (selStart), (selEnd), (firstChar)))
#define CallSetSelection(proc, selStart, selEnd, firstChar) \
(CallUniversalProc(proc, SetSelectionUPPInfo, (selStart), (selEnd), (firstChar)))
#define CallGetDocInfo(proc, w, name, vRefNum, dirID) \
(CallUniversalProc(proc, GetDocInfoUPPInfo, (w), (name), (vRefNum), (dirID)))
#define CallGetModDate(proc, w) \
(CallUniversalProc(proc, GetModDateUPPInfo, (w)))
#define CallCopy(proc) \
(Handle)(CallUniversalProc(proc, CopyUPPInfo))
#define CallPaste(proc, h) \
(CallUniversalProc(proc, PasteUPPInfo, (h)))
#define CallGetLastLine(proc) \
(CallUniversalProc(proc, GetLastLineUPPInfo))
#define CallGetLineNumber(proc, sel) \
(CallUniversalProc(proc, GetLineNumberUPPInfo, (sel)))
#define CallGetLineStart(proc, sel) \
(CallUniversalProc(proc, GetLineStartUPPInfo, (sel)))
#define CallGetLineEnd(proc, sel) \
(CallUniversalProc(proc, GetLineEndUPPInfo, (sel)))
#define CallGetLinePos(proc, sel) \
(CallUniversalProc(proc, GetLinePosUPPInfo, (sel)))
#define CallInsert(proc, text, len) \
(CallUniversalProc(proc, InsertUPPInfo, (text), (len)))
#define CallDelete(proc) \
(CallUniversalProc(proc, DeleteUPPInfo))
#define CallSetWindowContents(proc, w, h) \
(CallUniversalProc(proc, SetWindowContentsUPPInfo, (w), (h)))
#define CallContentsChanged(proc, w) \
(CallUniversalProc(proc, ContentsChangedUPPInfo, (w)))
#define CallGetFileText(proc, vRefNum, dirID, name, canDispose) \
(Handle)(CallUniversalProc(proc, GetFileTextUPPInfo, (vRefNum), (dirID), (name), (canDispose)))
#define CallGetFolder(proc, prompt, vRefNum, dirID) \
(Boolean)(CallUniversalProc(proc, GetFolderUPPInfo, (prompt), (vRefNum), (dirID)))
#define CallOpenSeveral(proc, sort, file_count, files) \
(Boolean)(CallUniversalProc(proc, OpenSeveralUPPInfo, (sort), (file_count), (files)))
#define CallCenterDialog(proc, dialogID) \
(DialogPtr)(CallUniversalProc(proc, CenterDialogUPPInfo, (dialogID)))
#define CallStandardFilter(proc, d, event, item) \
CallModalFilterProc(proc, (d), (event), (item))
#define CallFrameDialogItem(proc, d, item) \
CallUserItemProc(proc, (d), (item))
#define CallNewDocument(proc) \
(WindowPtr)(CallUniversalProc(proc, NewDocumentUPPInfo))
#define CallOpenDocument(proc) \
(WindowPtr)(CallUniversalProc(proc, OpenDocumentUPPInfo))
#define CallAllocate(proc, size, clear) \
(Handle)(CallUniversalProc(proc, AllocateUPPInfo, (size), (clear)))
#define CallFindPattern(proc, text, text_len, text_offset, pat, pat_len, case_sens) \
(CallUniversalProc(proc, FindPatternUPPInfo, (text), (text_len), (text_offset), \
(pat), (pat_len), (case_sens)))
#define CallReportOSError(proc, code) \
(CallUniversalProc(proc, ReportOSErrorUPPInfo, (code)))
#define CallGetPreference(proc, prefType, req_len, buffer, act_len) \
(CallUniversalProc(proc, GetPreferenceUPPInfo, (prefType), (req_len), (buffer), (act_len)))
#define CallSetPreference(proc, prefType, req_len, buffer, act_len) \
(CallUniversalProc(proc, SetPreferenceUPPInfo, (prefType), (req_len), (buffer), (act_len)))
#define CallStartProgress(proc, str, total, cancel_allowed) \
(CallUniversalProc(proc, StartProgressUPPInfo, (str), (total), (cancel_allowed)))
#define CallDoProgress(proc, done) \
(Boolean)(CallUniversalProc(proc, DoProgressUPPInfo, (done)))
#define CallDoneProgress(proc) \
(CallUniversalProc(proc, DoneProgressUPPInfo))
#define CallGetProjectList(proc, spec, kind, count, entries) \
(Boolean)(CallUniversalProc(proc, GetProjectListUPPInfo, (spec), (kind), (count), (entries)))
#define CallProjectTextList(proc, spec, text) \
(Boolean)(CallUniversalProc(proc, ProjectTextListUPPInfo, (spec), (text)))
#define CallPresetUndo(proc) \
(Boolean)(CallUniversalProc(proc, PresetUndoUPPInfo))
#define CallSetUndo(proc) \
(CallUniversalProc(proc, SetUndoUPPInfo))
#define CallOpenFile(proc, spec, w) \
(Boolean)(CallUniversalProc(proc, OpenFileUPPInfo, (spec), (w)))
#define CallPrepareUndo(proc, undo_start, undo_end, sel_start, sel_end) \
(Boolean)(CallUniversalProc(proc, PrepareUndoUPPInfo, (undo_start), (undo_end), \
(sel_start), (sel_end)))
#define CallCommitUndo(proc, new_end) \
(CallUniversalProc(proc, CommitUndoUPPInfo, (new_end)))
#define CallCreateResults(proc, title, count, results, w) \
(Boolean)(CallUniversalProc(proc, CreateResultsUPPInfo, (title), (count), (results), (w)))
#else
typedef pascal Handle (*GetWindowContentsProc)(WindowPtr w);
typedef pascal void (*GetSelectionProc)(long *selStart, long *selEnd, long *firstChar);
typedef pascal void (*SetSelectionProc)(long selStart, long selEnd, long firstChar);
typedef pascal void (*GetDocInfoProc)(WindowPtr w, Str255 fName, short *vRefNum, long *dirID);
typedef pascal long (*GetModDateProc)(WindowPtr w);
typedef pascal Handle (*CopyProc)(void);
typedef pascal void (*PasteProc)(Handle pasteText);
typedef pascal long (*GetLastLineProc)(void);
typedef pascal long (*GetLineNumberProc)(long selection);
typedef pascal long (*GetLineStartProc)(long selection);
typedef pascal long (*GetLineEndProc)(long selection);
typedef pascal long (*GetLinePosProc)(long line);
typedef pascal void (*InsertProc)(char *text, long len);
typedef pascal void (*DeleteProc)(void);
typedef pascal void (*SetWindowContentsProc)(WindowPtr w, Handle h);
typedef pascal void (*ContentsChangedProc)(WindowPtr w);
typedef pascal Handle (*GetFileTextProc)(short vRefNum, long dirID, Str255 fName, Boolean *canDispose);
typedef pascal Boolean (*GetFolderProc)(Str255 prompt, short *vRefNum, long *dirID);
typedef pascal Boolean (*OpenSeveralProc)(Boolean sort, short *file_count, StandardFileReply ***files);
typedef pascal DialogPtr (*CenterDialogProc)(short dialogID);
typedef pascal Boolean (*StandardFilterProc)(DialogPtr d, EventRecord *event, short *item);
typedef pascal void (*FrameDialogItemProc)(DialogPtr d, short item);
typedef pascal WindowPtr (*NewDocumentProc)(void);
typedef pascal WindowPtr (*OpenDocumentProc)(void);
typedef pascal Handle (*AllocateProc)(long size, Boolean clear);
typedef pascal long (*FindPatternProc)(char *text, long text_len, long text_offset,
char *pat, long pat_len,
Boolean case_sensitive);
typedef pascal void (*ReportOSErrorProc)(short code);
typedef pascal void (*GetPreferenceProc)(ResType prefType, short req_len, void *buffer, short *act_len);
typedef pascal void (*SetPreferenceProc)(ResType prefType, short req_len, void *buffer, short *act_len);
typedef pascal void (*StartProgressProc)(Str255 str, long total, Boolean cancel_allowed);
typedef pascal Boolean (*DoProgressProc)(long done);
typedef pascal void (*DoneProgressProc)(void);
typedef pascal Boolean (*GetProjectListProc)(FSSpec *spec, short *kind, short *count, ProjectEntry ***entries);
typedef pascal Boolean (*ProjectTextListProc)(FSSpec *spec, Handle *text);
typedef pascal Boolean (*PresetUndoProc)(void);
typedef pascal void (*SetUndoProc)(void);
typedef pascal Boolean (*OpenFileProc)(FSSpec *spec, WindowPtr *w);
typedef pascal Boolean (*PrepareUndoProc)(long undo_start, long undo_end,
long sel_start, long sel_end);
typedef pascal void (*CommitUndoProc)(long new_end);
typedef pascal Boolean (*CreateResultsProc)(Str255 title, short count, Handle results, WindowPtr *w);
#define CallGetWindowContents(proc, w) \
((proc))((w))
#define CallGetSelection(proc, selStart, selEnd, firstChar) \
((proc))((selStart), (selEnd), (firstChar))
#define CallSetSelection(proc, selStart, selEnd, firstChar) \
((proc))((selStart), (selEnd), (firstChar))
#define CallGetDocInfo(proc, w, name, vRefNum, dirID) \
((proc))((w), (name), (vRefNum), (dirID))
#define CallGetModDate(proc, w) \
((proc))((w))
#define CallCopy(proc) \
((proc))()
#define CallPaste(proc, h) \
((proc))((h))
#define CallGetLastLine(proc) \
((proc))()
#define CallGetLineNumber(proc, sel) \
((proc))((sel))
#define CallGetLineStart(proc, sel) \
((proc))((sel))
#define CallGetLineEnd(proc, sel) \
((proc))((sel))
#define CallGetLinePos(proc, sel) \
((proc))((sel))
#define CallInsert(proc, text, len) \
((proc))((text), (len))
#define CallDelete(proc) \
((proc))()
#define CallSetWindowContents(proc, w, h) \
((proc))((w), (h))
#define CallContentsChanged(proc, w) \
((proc))((w))
#define CallGetFileText(proc, vRefNum, dirID, name, canDispose) \
((proc))((vRefNum), (dirID), (name), (canDispose))
#define CallGetFolder(proc, prompt, vRefNum, dirID) \
((proc))((prompt), (vRefNum), (dirID))
#define CallOpenSeveral(proc, sort, file_count, files) \
((proc))((sort), (file_count), (files))
#define CallCenterDialog(proc, dialogID) \
((proc))((dialogID))
#define CallStandardFilter(proc, d, event, item) \
((proc))((d), (event), (item))
#define CallFrameDialogItem(proc, d, item) \
((proc))((d), (item))
#define CallNewDocument(proc) \
((proc))()
#define CallOpenDocument(proc) \
((proc))()
#define CallAllocate(proc, size, clear) \
((proc))((size), (clear))
#define CallFindPattern(proc, text, text_len, text_offset, pat, pat_len, case_sens) \
((proc))((text), (text_len), (text_offset), (pat), (pat_len), (case_sens))
#define CallReportOSError(proc, code) \
((proc))((code))
#define CallGetPreference(proc, prefType, req_len, buffer, act_len) \
((proc))((prefType), (req_len), (buffer), (act_len))
#define CallSetPreference(proc, prefType, req_len, buffer, act_len) \
((proc))((prefType), (req_len), (buffer), (act_len))
#define CallStartProgress(proc, str, total, cancel_allowed) \
((proc))((str), (total), (cancel_allowed))
#define CallDoProgress(proc, done) \
((proc))((done))
#define CallDoneProgress(proc) \
((proc))()
#define CallGetProjectList(proc, spec, kind, count, entries) \
((proc))((spec), (kind), (count), (entries))
#define CallProjectTextList(proc, spec, text) \
((proc))((spec), (text))
#define CallPresetUndo(proc) \
((proc))()
#define CallSetUndo(proc) \
((proc))()
#define CallOpenFile(proc, spec, w) \
((proc))((spec), (w))
#define CallPrepareUndo(proc, undo_start, undo_end, sel_start, sel_end) \
((proc))((undo_start), (undo_end), (sel_start), (sel_end))
#define CallCommitUndo(proc, new_end) \
((proc))((new_end))
#define CallCreateResults(proc, title, count, results, w) \
((proc))((title), (count), (results), (w))
#endif
typedef struct
{
short version;
// version 1 callbacks
GetWindowContentsProc GetWindowContents;
GetSelectionProc GetSelection;
SetSelectionProc SetSelection;
GetDocInfoProc GetDocInfo;
GetModDateProc GetModDate;
CopyProc Copy;
PasteProc Paste;
// version 2 callbacks
/* Text-Editing stuff */
GetLastLineProc GetLastLine;
GetLineNumberProc GetLineNumber;
GetLineStartProc GetLineStart;
GetLineEndProc GetLineEnd;
GetLinePosProc GetLinePos;
InsertProc Insert;
DeleteProc Delete;
/* Getting and Setting window text */
SetWindowContentsProc SetWindowContents;
ContentsChangedProc ContentsChanged;
/* Reading file text */
GetFileTextProc GetFileText;
/* Direct user-interface calls */
GetFolderProc GetFolder;
OpenSeveralProc OpenSeveral;
CenterDialogProc CenterDialog;
StandardFilterProc StandardFilter;
FrameDialogItemProc FrameDialogItem;
NewDocumentProc NewDocument;
OpenDocumentProc OpenDocument;
/* Utility Routines */
AllocateProc Allocate;
FindPatternProc FindPattern;
ReportOSErrorProc ReportOSError;
/* Preference routines */
GetPreferenceProc GetPreference;
SetPreferenceProc SetPreference;
/* Progress routines */
StartProgressProc StartProgress;
DoProgressProc DoProgress;
DoneProgressProc DoneProgress;
// Version 3 callbacks
GetProjectListProc GetProjectList;
ProjectTextListProc ProjectTextList;
// version 4 callbacks
PresetUndoProc PresetUndo;
SetUndoProc SetUndo;
OpenFileProc OpenFile;
// version 5 callbacks
PrepareUndoProc PrepareUndo;
CommitUndoProc CommitUndo;
CreateResultsProc CreateResults;
} ExternalCallbackBlock;
#if defined(powerc) || defined (__powerc)
#pragma options align=reset
#endif
/*
'main' for a BBXT is declared:
pascal void main(ExternalCallbackBlock *callbacks, WindowPtr w); [C]
The 'new' calling convention, which passes more information
and allows scriptability, is this:
pascal OSErr main(ExternalCallbackBlock *callbacks, WindowPtr w, long flags, AppleEvent *event, AppleEvent *reply);
*/

View File

@ -0,0 +1,716 @@
#pragma once
#include <MixedMode.h>
#include <Dialogs.h>
#include <Files.h>
#include <Windows.h>
#include <AppleEvents.h>
#include <StandardFile.h>
#if defined(powerc) || defined (__powerc)
#pragma options align=mac68k
#endif
typedef struct
{
FSSpec spec; // designates file on disk
long key; // reserved for future expansion
char tree; // 0 for absolute, 1 for project, 2 for system
Boolean found; // FALSE if file couldn't be located; if so, all other info is moot
OSType type; // file type of found file
OSType crtr; // signature of found file's creator
short spare0; // reserved for future expansion
long spare1;
} ProjectEntry;
enum
{
kNeitherTree,
kProjectTree,
kSystemTree
};
enum
{
kTHINKCProject,
kTHINKPascalProject,
kCodeWarriorProject
};
// masks for the "flags" argument to new-convention interfaces
#define xfWindowOpen 0x00000001
#define xfWindowChangeable 0x00000002
#define xfHasSelection 0x00000004
#define xfUseDefaults 0x00000008
#define xfIsBBEditLite 0x00000040
#define xfIsBBEditDemo 0x00000080
typedef struct
{
FSSpec spec;
OSType key;
short error_kind;
long line_number;
Str255 message;
} ErrorEntry;
typedef enum
{
kNote = 0,
kError,
kWarning
} ErrorKind;
#define kCurrentExternalVersion 5 // current version of callbacks
// Universal callback interfaces
#if USESROUTINEDESCRIPTORS
#define ExtensionUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ExternalCallbackBlock *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(WindowPtr))))
#define NewExtensionUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ExternalCallbackBlock *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(WindowPtr))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(AppleEvent *))) \
| STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(AppleEvent *))))
#define GetWindowContentsUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Handle))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))))
#define GetSelectionUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long *))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long *))))
#define SetSelectionUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))))
#define GetDocInfoUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(unsigned char *))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short *))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long *))))
#define GetModDateUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))))
#define CopyUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Handle))))
#define PasteUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Handle))))
#define GetLastLineUPPInfo (kPascalStackBased | RESULT_SIZE(SIZE_CODE(sizeof(long))))
#define GetLineNumberUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))))
#define GetLineStartUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))))
#define GetLineEndUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))))
#define GetLinePosUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))))
#define InsertUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(char *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))))
#define DeleteUPPInfo (kPascalStackBased)
#define SetWindowContentsUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle))))
#define ContentsChangedUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(WindowPtr))))
#define GetFileTextUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Handle))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(unsigned char *))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(Boolean *))))
#define GetFolderUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short *))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long *))))
#define OpenSeveralUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short *))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(StandardFileReply ***))))
#define CenterDialogUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(DialogPtr))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(short))))
#define StandardFilterUPPInfo uppModalFilterProcInfo
#define FrameDialogItemUPPInfo uppUserItemProcInfo
#define NewDocumentUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(WindowPtr))))
#define OpenDocumentUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(WindowPtr))))
#define AllocateUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Handle))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Boolean))))
#define FindPatternUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(char *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(char *))) \
| STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(Boolean))))
#define ReportOSErrorUPPInfo (kPascalStackBased)
#define GetPreferenceUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ResType))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short *))))
#define SetPreferenceUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(ResType))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(short *))))
#define StartProgressUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Boolean))))
#define DoProgressUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))))
#define DoneProgressUPPInfo (kPascalStackBased)
#define GetProjectListUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(FSSpec *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short *))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(short *))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(ProjectEntry***))))
#define ProjectTextListUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(FSSpec *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle *))))
#define PresetUndoUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))))
#define SetUndoUPPInfo (kPascalStackBased)
#define OpenFileUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(FSSpec *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(WindowPtr *))))
#define PrepareUndoUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long))))
#define CommitUndoUPPInfo (kPascalStackBased \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long))))
#define CreateResultsUPPInfo (kPascalStackBased \
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean))) \
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(unsigned char *))) \
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(short))) \
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Handle))) \
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(WindowPtr *))))
typedef UniversalProcPtr GetWindowContentsProc;
typedef UniversalProcPtr GetSelectionProc;
typedef UniversalProcPtr SetSelectionProc;
typedef UniversalProcPtr GetDocInfoProc;
typedef UniversalProcPtr GetModDateProc;
typedef UniversalProcPtr CopyProc;
typedef UniversalProcPtr PasteProc;
typedef UniversalProcPtr GetLastLineProc;
typedef UniversalProcPtr GetLineNumberProc;
typedef UniversalProcPtr GetLineStartProc;
typedef UniversalProcPtr GetLineEndProc;
typedef UniversalProcPtr GetLinePosProc;
typedef UniversalProcPtr InsertProc;
typedef UniversalProcPtr DeleteProc;
typedef UniversalProcPtr SetWindowContentsProc;
typedef UniversalProcPtr ContentsChangedProc;
typedef UniversalProcPtr GetFileTextProc;
typedef UniversalProcPtr GetFolderProc;
typedef UniversalProcPtr OpenSeveralProc;
typedef UniversalProcPtr CenterDialogProc;
typedef UniversalProcPtr StandardFilterProc;
typedef UniversalProcPtr FrameDialogItemProc;
typedef UniversalProcPtr NewDocumentProc;
typedef UniversalProcPtr OpenDocumentProc;
typedef UniversalProcPtr AllocateProc;
typedef UniversalProcPtr FindPatternProc;
typedef UniversalProcPtr ReportOSErrorProc;
typedef UniversalProcPtr GetPreferenceProc;
typedef UniversalProcPtr SetPreferenceProc;
typedef UniversalProcPtr StartProgressProc;
typedef UniversalProcPtr DoProgressProc;
typedef UniversalProcPtr DoneProgressProc;
typedef UniversalProcPtr GetProjectListProc;
typedef UniversalProcPtr ProjectTextListProc;
typedef UniversalProcPtr PresetUndoProc;
typedef UniversalProcPtr SetUndoProc;
typedef UniversalProcPtr OpenFileProc;
typedef UniversalProcPtr PrepareUndoProc;
typedef UniversalProcPtr CommitUndoProc;
typedef UniversalProcPtr CreateResultsProc;
#define CallGetWindowContents(proc, w) \
(Handle)(CallUniversalProc(proc, GetWindowContentsUPPInfo, (w)))
#define CallGetSelection(proc, selStart, selEnd, firstChar) \
(CallUniversalProc(proc, GetSelectionUPPInfo, (selStart), (selEnd), (firstChar)))
#define CallSetSelection(proc, selStart, selEnd, firstChar) \
(CallUniversalProc(proc, SetSelectionUPPInfo, (selStart), (selEnd), (firstChar)))
#define CallGetDocInfo(proc, w, name, vRefNum, dirID) \
(CallUniversalProc(proc, GetDocInfoUPPInfo, (w), (name), (vRefNum), (dirID)))
#define CallGetModDate(proc, w) \
(CallUniversalProc(proc, GetModDateUPPInfo, (w)))
#define CallCopy(proc) \
(Handle)(CallUniversalProc(proc, CopyUPPInfo))
#define CallPaste(proc, h) \
(CallUniversalProc(proc, PasteUPPInfo, (h)))
#define CallGetLastLine(proc) \
(CallUniversalProc(proc, GetLastLineUPPInfo))
#define CallGetLineNumber(proc, sel) \
(CallUniversalProc(proc, GetLineNumberUPPInfo, (sel)))
#define CallGetLineStart(proc, sel) \
(CallUniversalProc(proc, GetLineStartUPPInfo, (sel)))
#define CallGetLineEnd(proc, sel) \
(CallUniversalProc(proc, GetLineEndUPPInfo, (sel)))
#define CallGetLinePos(proc, sel) \
(CallUniversalProc(proc, GetLinePosUPPInfo, (sel)))
#define CallInsert(proc, text, len) \
(CallUniversalProc(proc, InsertUPPInfo, (text), (len)))
#define CallDelete(proc) \
(CallUniversalProc(proc, DeleteUPPInfo))
#define CallSetWindowContents(proc, w, h) \
(CallUniversalProc(proc, SetWindowContentsUPPInfo, (w), (h)))
#define CallContentsChanged(proc, w) \
(CallUniversalProc(proc, ContentsChangedUPPInfo, (w)))
#define CallGetFileText(proc, vRefNum, dirID, name, canDispose) \
(Handle)(CallUniversalProc(proc, GetFileTextUPPInfo, (vRefNum), (dirID), (name), (canDispose)))
#define CallGetFolder(proc, prompt, vRefNum, dirID) \
(Boolean)(CallUniversalProc(proc, GetFolderUPPInfo, (prompt), (vRefNum), (dirID)))
#define CallOpenSeveral(proc, sort, file_count, files) \
(Boolean)(CallUniversalProc(proc, OpenSeveralUPPInfo, (sort), (file_count), (files)))
#define CallCenterDialog(proc, dialogID) \
(DialogPtr)(CallUniversalProc(proc, CenterDialogUPPInfo, (dialogID)))
#define CallStandardFilter(proc, d, event, item) \
CallModalFilterProc(proc, (d), (event), (item))
#define CallFrameDialogItem(proc, d, item) \
CallUserItemProc(proc, (d), (item))
#define CallNewDocument(proc) \
(WindowPtr)(CallUniversalProc(proc, NewDocumentUPPInfo))
#define CallOpenDocument(proc) \
(WindowPtr)(CallUniversalProc(proc, OpenDocumentUPPInfo))
#define CallAllocate(proc, size, clear) \
(Handle)(CallUniversalProc(proc, AllocateUPPInfo, (size), (clear)))
#define CallFindPattern(proc, text, text_len, text_offset, pat, pat_len, case_sens) \
(CallUniversalProc(proc, FindPatternUPPInfo, (text), (text_len), (text_offset), \
(pat), (pat_len), (case_sens)))
#define CallReportOSError(proc, code) \
(CallUniversalProc(proc, ReportOSErrorUPPInfo, (code)))
#define CallGetPreference(proc, prefType, req_len, buffer, act_len) \
(CallUniversalProc(proc, GetPreferenceUPPInfo, (prefType), (req_len), (buffer), (act_len)))
#define CallSetPreference(proc, prefType, req_len, buffer, act_len) \
(CallUniversalProc(proc, SetPreferenceUPPInfo, (prefType), (req_len), (buffer), (act_len)))
#define CallStartProgress(proc, str, total, cancel_allowed) \
(CallUniversalProc(proc, StartProgressUPPInfo, (str), (total), (cancel_allowed)))
#define CallDoProgress(proc, done) \
(Boolean)(CallUniversalProc(proc, DoProgressUPPInfo, (done)))
#define CallDoneProgress(proc) \
(CallUniversalProc(proc, DoneProgressUPPInfo))
#define CallGetProjectList(proc, spec, kind, count, entries) \
(Boolean)(CallUniversalProc(proc, GetProjectListUPPInfo, (spec), (kind), (count), (entries)))
#define CallProjectTextList(proc, spec, text) \
(Boolean)(CallUniversalProc(proc, ProjectTextListUPPInfo, (spec), (text)))
#define CallPresetUndo(proc) \
(Boolean)(CallUniversalProc(proc, PresetUndoUPPInfo))
#define CallSetUndo(proc) \
(CallUniversalProc(proc, SetUndoUPPInfo))
#define CallOpenFile(proc, spec, w) \
(Boolean)(CallUniversalProc(proc, OpenFileUPPInfo, (spec), (w)))
#define CallPrepareUndo(proc, undo_start, undo_end, sel_start, sel_end) \
(Boolean)(CallUniversalProc(proc, PrepareUndoUPPInfo, (undo_start), (undo_end), \
(sel_start), (sel_end)))
#define CallCommitUndo(proc, new_end) \
(CallUniversalProc(proc, CommitUndoUPPInfo, (new_end)))
#define CallCreateResults(proc, title, count, results, w) \
(Boolean)(CallUniversalProc(proc, CreateResultsUPPInfo, (title), (count), (results), (w)))
#else
typedef pascal Handle (*GetWindowContentsProc)(WindowPtr w);
typedef pascal void (*GetSelectionProc)(long *selStart, long *selEnd, long *firstChar);
typedef pascal void (*SetSelectionProc)(long selStart, long selEnd, long firstChar);
typedef pascal void (*GetDocInfoProc)(WindowPtr w, Str255 fName, short *vRefNum, long *dirID);
typedef pascal long (*GetModDateProc)(WindowPtr w);
typedef pascal Handle (*CopyProc)(void);
typedef pascal void (*PasteProc)(Handle pasteText);
typedef pascal long (*GetLastLineProc)(void);
typedef pascal long (*GetLineNumberProc)(long selection);
typedef pascal long (*GetLineStartProc)(long selection);
typedef pascal long (*GetLineEndProc)(long selection);
typedef pascal long (*GetLinePosProc)(long line);
typedef pascal void (*InsertProc)(char *text, long len);
typedef pascal void (*DeleteProc)(void);
typedef pascal void (*SetWindowContentsProc)(WindowPtr w, Handle h);
typedef pascal void (*ContentsChangedProc)(WindowPtr w);
typedef pascal Handle (*GetFileTextProc)(short vRefNum, long dirID, Str255 fName, Boolean *canDispose);
typedef pascal Boolean (*GetFolderProc)(Str255 prompt, short *vRefNum, long *dirID);
typedef pascal Boolean (*OpenSeveralProc)(Boolean sort, short *file_count, StandardFileReply ***files);
typedef pascal DialogPtr (*CenterDialogProc)(short dialogID);
typedef pascal Boolean (*StandardFilterProc)(DialogPtr d, EventRecord *event, short *item);
typedef pascal void (*FrameDialogItemProc)(DialogPtr d, short item);
typedef pascal WindowPtr (*NewDocumentProc)(void);
typedef pascal WindowPtr (*OpenDocumentProc)(void);
typedef pascal Handle (*AllocateProc)(long size, Boolean clear);
typedef pascal long (*FindPatternProc)(char *text, long text_len, long text_offset,
char *pat, long pat_len,
Boolean case_sensitive);
typedef pascal void (*ReportOSErrorProc)(short code);
typedef pascal void (*GetPreferenceProc)(ResType prefType, short req_len, void *buffer, short *act_len);
typedef pascal void (*SetPreferenceProc)(ResType prefType, short req_len, void *buffer, short *act_len);
typedef pascal void (*StartProgressProc)(Str255 str, long total, Boolean cancel_allowed);
typedef pascal Boolean (*DoProgressProc)(long done);
typedef pascal void (*DoneProgressProc)(void);
typedef pascal Boolean (*GetProjectListProc)(FSSpec *spec, short *kind, short *count, ProjectEntry ***entries);
typedef pascal Boolean (*ProjectTextListProc)(FSSpec *spec, Handle *text);
typedef pascal Boolean (*PresetUndoProc)(void);
typedef pascal void (*SetUndoProc)(void);
typedef pascal Boolean (*OpenFileProc)(FSSpec *spec, WindowPtr *w);
typedef pascal Boolean (*PrepareUndoProc)(long undo_start, long undo_end,
long sel_start, long sel_end);
typedef pascal void (*CommitUndoProc)(long new_end);
typedef pascal Boolean (*CreateResultsProc)(Str255 title, short count, Handle results, WindowPtr *w);
#define CallGetWindowContents(proc, w) \
((proc))((w))
#define CallGetSelection(proc, selStart, selEnd, firstChar) \
((proc))((selStart), (selEnd), (firstChar))
#define CallSetSelection(proc, selStart, selEnd, firstChar) \
((proc))((selStart), (selEnd), (firstChar))
#define CallGetDocInfo(proc, w, name, vRefNum, dirID) \
((proc))((w), (name), (vRefNum), (dirID))
#define CallGetModDate(proc, w) \
((proc))((w))
#define CallCopy(proc) \
((proc))()
#define CallPaste(proc, h) \
((proc))((h))
#define CallGetLastLine(proc) \
((proc))()
#define CallGetLineNumber(proc, sel) \
((proc))((sel))
#define CallGetLineStart(proc, sel) \
((proc))((sel))
#define CallGetLineEnd(proc, sel) \
((proc))((sel))
#define CallGetLinePos(proc, sel) \
((proc))((sel))
#define CallInsert(proc, text, len) \
((proc))((text), (len))
#define CallDelete(proc) \
((proc))()
#define CallSetWindowContents(proc, w, h) \
((proc))((w), (h))
#define CallContentsChanged(proc, w) \
((proc))((w))
#define CallGetFileText(proc, vRefNum, dirID, name, canDispose) \
((proc))((vRefNum), (dirID), (name), (canDispose))
#define CallGetFolder(proc, prompt, vRefNum, dirID) \
((proc))((prompt), (vRefNum), (dirID))
#define CallOpenSeveral(proc, sort, file_count, files) \
((proc))((sort), (file_count), (files))
#define CallCenterDialog(proc, dialogID) \
((proc))((dialogID))
#define CallStandardFilter(proc, d, event, item) \
((proc))((d), (event), (item))
#define CallFrameDialogItem(proc, d, item) \
((proc))((d), (item))
#define CallNewDocument(proc) \
((proc))()
#define CallOpenDocument(proc) \
((proc))()
#define CallAllocate(proc, size, clear) \
((proc))((size), (clear))
#define CallFindPattern(proc, text, text_len, text_offset, pat, pat_len, case_sens) \
((proc))((text), (text_len), (text_offset), (pat), (pat_len), (case_sens))
#define CallReportOSError(proc, code) \
((proc))((code))
#define CallGetPreference(proc, prefType, req_len, buffer, act_len) \
((proc))((prefType), (req_len), (buffer), (act_len))
#define CallSetPreference(proc, prefType, req_len, buffer, act_len) \
((proc))((prefType), (req_len), (buffer), (act_len))
#define CallStartProgress(proc, str, total, cancel_allowed) \
((proc))((str), (total), (cancel_allowed))
#define CallDoProgress(proc, done) \
((proc))((done))
#define CallDoneProgress(proc) \
((proc))()
#define CallGetProjectList(proc, spec, kind, count, entries) \
((proc))((spec), (kind), (count), (entries))
#define CallProjectTextList(proc, spec, text) \
((proc))((spec), (text))
#define CallPresetUndo(proc) \
((proc))()
#define CallSetUndo(proc) \
((proc))()
#define CallOpenFile(proc, spec, w) \
((proc))((spec), (w))
#define CallPrepareUndo(proc, undo_start, undo_end, sel_start, sel_end) \
((proc))((undo_start), (undo_end), (sel_start), (sel_end))
#define CallCommitUndo(proc, new_end) \
((proc))((new_end))
#define CallCreateResults(proc, title, count, results, w) \
((proc))((title), (count), (results), (w))
#endif
typedef struct
{
short version;
// version 1 callbacks
GetWindowContentsProc GetWindowContents;
GetSelectionProc GetSelection;
SetSelectionProc SetSelection;
GetDocInfoProc GetDocInfo;
GetModDateProc GetModDate;
CopyProc Copy;
PasteProc Paste;
// version 2 callbacks
/* Text-Editing stuff */
GetLastLineProc GetLastLine;
GetLineNumberProc GetLineNumber;
GetLineStartProc GetLineStart;
GetLineEndProc GetLineEnd;
GetLinePosProc GetLinePos;
InsertProc Insert;
DeleteProc Delete;
/* Getting and Setting window text */
SetWindowContentsProc SetWindowContents;
ContentsChangedProc ContentsChanged;
/* Reading file text */
GetFileTextProc GetFileText;
/* Direct user-interface calls */
GetFolderProc GetFolder;
OpenSeveralProc OpenSeveral;
CenterDialogProc CenterDialog;
StandardFilterProc StandardFilter;
FrameDialogItemProc FrameDialogItem;
NewDocumentProc NewDocument;
OpenDocumentProc OpenDocument;
/* Utility Routines */
AllocateProc Allocate;
FindPatternProc FindPattern;
ReportOSErrorProc ReportOSError;
/* Preference routines */
GetPreferenceProc GetPreference;
SetPreferenceProc SetPreference;
/* Progress routines */
StartProgressProc StartProgress;
DoProgressProc DoProgress;
DoneProgressProc DoneProgress;
// Version 3 callbacks
GetProjectListProc GetProjectList;
ProjectTextListProc ProjectTextList;
// version 4 callbacks
PresetUndoProc PresetUndo;
SetUndoProc SetUndo;
OpenFileProc OpenFile;
// version 5 callbacks
PrepareUndoProc PrepareUndo;
CommitUndoProc CommitUndo;
CreateResultsProc CreateResults;
} ExternalCallbackBlock;
#if defined(powerc) || defined (__powerc)
#pragma options align=reset
#endif
/*
'main' for a BBXT is declared:
pascal void main(ExternalCallbackBlock *callbacks, WindowPtr w); [C]
The 'new' calling convention, which passes more information
and allows scriptability, is this:
pascal OSErr main(ExternalCallbackBlock *callbacks, WindowPtr w, long flags, AppleEvent *event, AppleEvent *reply);
*/

View File

@ -0,0 +1,17 @@
/* BBPython
A simple menu command to send the contents of a window to the Python interpreter
copyright © 1996 Just van Rossum, Letterror: just@knoware.nl
All Rights Reserved
*/
#include <MacHeaders68K>
#include <A4Stuff.h>
#include <SetUpA4.h> // for global variables, multiple segments, etc.
#include "ExternalInterface.h"
#include <Memory.h>
extern OSErr SendTextAsAE(ExternalCallbackBlock *callbacks, Ptr theText, long theSize, Str255 windowTitle);
extern OSErr LaunchPythonSlave(FSSpec * docSpec);
extern Boolean GetPythonSlaveSpec(FSSpec * docSpec);

View File

@ -0,0 +1,15 @@
(This file must be converted with BinHex 4.0)
:#8*#8(NZFR0bB`"bFh*M8P0&4!#3#!*eepN!N!3"!!!!!I-!!!$c!!!!JJ$l!&`
"6F!#!!X!N!@N!$3!a!"N"J#3"U3!I!P#3P"j,R*cFQ0ZG'9bCQ&MC5jSF(*U,QK
aH(PiHA0X!!"3BA*d8dP8)3#3',&VJKm!N!B#G@jMC@`!N!8j!%i!63#H"!T%Efl
9G#"6BACP!*!&$!"1!#`"GBJh8f&fC5"MD'&ZCf9c)(4[)(4SC5"0CA4bEhGPFQY
c)%4[Bh9YC@jd)0*H-0-JBQ9QEh*P)&ia2`)!N!8-!"F!,!!hS!)!!J#3$)%%!!%
!!!!1!#J!+!#-!C!!!)"996!+!!!!"!!!!N%!!!#!!!-!N!9!!33!9!&8"!0CCA-
!N!C!!+S!9!$k"!*1E`#3"3J!2!!f!95)2Y*3HA4SEfj6E'&fC5j`HG-JDA-JEQp
d)(*eEQjTEQFX)!ehEh9XC#"jEh8JE'PVC5"dEb"XEf0KG'8JDA3r!*!&#!!+!#J
!+U!#!!%!!!!'!3!!8J#3"8F!)b!!!!!'GM!Z-Lic1AB`,M)Z-b#T)%TeFh3JGQ&
Z)&*[Fh0eE5![)%aPG(4PFR*[FL`J2'TeFh4!E'9dG'9bFQpb,QjX2J!!!3!!!!(
c!!!!m`!!!)))r"0%*d`!!!!F!))!"(CPFR-!!!!U4%P86!!!!$C"6&*8!!!!3N*
#@%B!!!"13N*B5`!!!&S!!Irr!!!!U!Mm%I`!J2rr!!!!'J#3"B$rr`#3#B$rr`!
!!")!N!@!rrm!!!#H!*!%red:

View File

@ -0,0 +1,94 @@
/*
* Launch the PythonSlave.py script.
* This works exactly as if you'd double clicked on the file in the Finder, which
* not surprisingly is how its implemented (via the AppleEvents route of course).
*
* Largely based on code submitted by Mark Roseman <roseman@cpsc.ucalgary.ca>
* Thanks!
*/
#include "BBPy.h"
pascal Boolean MyFileFilter(CInfoPBPtr PB);
FileFilterUPP gMyFileFilterUPP = NULL;
Boolean GetPythonSlaveSpec(FSSpec * docSpec) {
StandardFileReply reply;
SFTypeList typeList;
typeList[0] = 'TEXT';
//if (!gMyFileFilterUPP)
gMyFileFilterUPP = NewFileFilterProc( MyFileFilter );
StandardGetFile(gMyFileFilterUPP, 0, typeList, &reply);
DisposePtr((Ptr)gMyFileFilterUPP);
if(!reply.sfGood)
return 0; /* user cancelled */
docSpec->vRefNum = reply.sfFile.vRefNum;
docSpec->parID = reply.sfFile.parID;
BlockMove(reply.sfFile.name, docSpec->name, 64);
return 1;
}
pascal Boolean MyFileFilter(CInfoPBPtr PB) {
OSType fType; /* file type */
OSType fCreator; /* file creator */
fType =((HParmBlkPtr)PB)->fileParam.ioFlFndrInfo.fdType;
fCreator = ((HParmBlkPtr)PB)->fileParam.ioFlFndrInfo.fdCreator;
if (fType == 'TEXT' &&
fCreator == 'Pyth')
return 0;
return 1;
}
OSErr LaunchPythonSlave(FSSpec * docSpec) {
OSErr err;
FSSpec dirSpec;
AEAddressDesc finderAddress;
AppleEvent theEvent, theReply;
OSType finderSig = 'MACS';
AliasHandle DirAlias, FileAlias;
AEDesc fileList;
AEDesc aeDirDesc, listElem;
err = AECreateDesc(typeApplSignature, (Ptr)&finderSig, 4, &finderAddress);
if(err != noErr) return err;
err = AECreateAppleEvent('FNDR', 'sope', &finderAddress,
kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
if(err != noErr) return err;
FSMakeFSSpec(docSpec->vRefNum, docSpec->parID, NULL, &dirSpec);
NewAlias(NULL, &dirSpec, &DirAlias);
NewAlias(NULL, docSpec, &FileAlias);
err = AECreateList(NULL, 0, 0, &fileList);
HLock((Handle)DirAlias);
AECreateDesc(typeAlias, (Ptr)*DirAlias, GetHandleSize((Handle)DirAlias), &aeDirDesc);
HUnlock((Handle)DirAlias);
if ((err = AEPutParamDesc(&theEvent, keyDirectObject, &aeDirDesc)) == noErr) {
AEDisposeDesc(&aeDirDesc);
HLock((Handle)FileAlias);
AECreateDesc(typeAlias, (Ptr)*FileAlias, GetHandleSize((Handle)FileAlias), &listElem);
HLock((Handle)FileAlias);
err = AEPutDesc(&fileList, 0, &listElem);
}
AEDisposeDesc(&listElem);
err = AEPutParamDesc(&theEvent, 'fsel', &fileList);
AEDisposeDesc(&fileList);
err = AESend(&theEvent, &theReply, kAENoReply+kAENeverInteract,
kAENormalPriority, kAEDefaultTimeout, 0L, 0L);
if(err != noErr) return err;
err = AEDisposeDesc(&theEvent);
if(err != noErr) return err;
err = AEDisposeDesc(&theReply);
return err;
}

View File

@ -0,0 +1,94 @@
/*
* Launch the PythonSlave.py script.
* This works exactly as if you'd double clicked on the file in the Finder, which
* not surprisingly is how its implemented (via the AppleEvents route of course).
*
* Largely based on code submitted by Mark Roseman <roseman@cpsc.ucalgary.ca>
* Thanks!
*/
#include "BBPy.h"
pascal Boolean MyFileFilter(CInfoPBPtr PB);
FileFilterUPP gMyFileFilterUPP = NULL;
Boolean GetPythonSlaveSpec(FSSpec * docSpec) {
StandardFileReply reply;
SFTypeList typeList;
typeList[0] = 'TEXT';
//if (!gMyFileFilterUPP)
gMyFileFilterUPP = NewFileFilterProc( MyFileFilter );
StandardGetFile(gMyFileFilterUPP, 0, typeList, &reply);
DisposePtr((Ptr)gMyFileFilterUPP);
if(!reply.sfGood)
return 0; /* user cancelled */
docSpec->vRefNum = reply.sfFile.vRefNum;
docSpec->parID = reply.sfFile.parID;
BlockMove(reply.sfFile.name, docSpec->name, 64);
return 1;
}
pascal Boolean MyFileFilter(CInfoPBPtr PB) {
OSType fType; /* file type */
OSType fCreator; /* file creator */
fType =((HParmBlkPtr)PB)->fileParam.ioFlFndrInfo.fdType;
fCreator = ((HParmBlkPtr)PB)->fileParam.ioFlFndrInfo.fdCreator;
if (fType == 'TEXT' &&
fCreator == 'Pyth')
return 0;
return 1;
}
OSErr LaunchPythonSlave(FSSpec * docSpec) {
OSErr err;
FSSpec dirSpec;
AEAddressDesc finderAddress;
AppleEvent theEvent, theReply;
OSType finderSig = 'MACS';
AliasHandle DirAlias, FileAlias;
AEDesc fileList;
AEDesc aeDirDesc, listElem;
err = AECreateDesc(typeApplSignature, (Ptr)&finderSig, 4, &finderAddress);
if(err != noErr) return err;
err = AECreateAppleEvent('FNDR', 'sope', &finderAddress,
kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
if(err != noErr) return err;
FSMakeFSSpec(docSpec->vRefNum, docSpec->parID, NULL, &dirSpec);
NewAlias(NULL, &dirSpec, &DirAlias);
NewAlias(NULL, docSpec, &FileAlias);
err = AECreateList(NULL, 0, 0, &fileList);
HLock((Handle)DirAlias);
AECreateDesc(typeAlias, (Ptr)*DirAlias, GetHandleSize((Handle)DirAlias), &aeDirDesc);
HUnlock((Handle)DirAlias);
if ((err = AEPutParamDesc(&theEvent, keyDirectObject, &aeDirDesc)) == noErr) {
AEDisposeDesc(&aeDirDesc);
HLock((Handle)FileAlias);
AECreateDesc(typeAlias, (Ptr)*FileAlias, GetHandleSize((Handle)FileAlias), &listElem);
HLock((Handle)FileAlias);
err = AEPutDesc(&fileList, 0, &listElem);
}
AEDisposeDesc(&listElem);
err = AEPutParamDesc(&theEvent, 'fsel', &fileList);
AEDisposeDesc(&fileList);
err = AESend(&theEvent, &theReply, kAENoReply+kAENeverInteract,
kAENormalPriority, kAEDefaultTimeout, 0L, 0L);
if(err != noErr) return err;
err = AEDisposeDesc(&theEvent);
if(err != noErr) return err;
err = AEDisposeDesc(&theReply);
return err;
}

View File

@ -0,0 +1,104 @@
/* BBPython
A simple menu command to send the contents of a window to the Python interpreter
copyright © 1996 Just van Rossum, Letterror: just@knoware.nl
All Rights Reserved
*/
#include "BBPy.h"
OSErr SendTextAsAE(ExternalCallbackBlock *callbacks, Ptr theText, long theSize, Str255 windowTitle)
{
OSErr err;
AEDesc theEvent;
AEAddressDesc theTarget;
AppleEvent theReply;
AEDesc theTextDesc;
AEDesc theNameDesc;
OSType pythonSig = 'Pyth';
FSSpec docSpec;
short itemHit;
long time;
EventRecord theDummyEvent;
/* initialize AE descriptor for python's signature */
err = AECreateDesc (typeApplSignature, &pythonSig, sizeof(OSType), &theTarget);
if(err != noErr) return err;
/* initialize AE descriptor for the title of our window */
err = AECreateDesc (typeChar, &windowTitle[1], windowTitle[0], &theNameDesc);
if(err != noErr) return err;
/* initialize AE descriptor for the content of our window */
err = AECreateDesc ('TEXT', theText, theSize, &theTextDesc);
if(err != noErr) return err;
/* initialize AppleEvent */
err = AECreateAppleEvent ('pyth', 'EXEC', &theTarget, kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
if(err != noErr) return err;
/* add the content of our window to the AppleEvent */
err = AEPutParamDesc (&theEvent, keyDirectObject, &theTextDesc);
if(err != noErr) return err;
/* add the title of our window to the AppleEvent */
err = AEPutParamDesc (&theEvent, 'NAME', &theNameDesc);
if(err != noErr) return err;
/* send the AppleEvent */
err = AESend (&theEvent, &theReply, kAEWaitReply, kAEHighPriority, kNoTimeOut, NULL, NULL);
if(err == connectionInvalid) {
// launch PythonSlave.py
itemHit = Alert(128, NULL);
if(itemHit == 2) return noErr; /* user cancelled */
if( ! GetPythonSlaveSpec(&docSpec) )
return noErr; /* user cancelled */
err = LaunchPythonSlave(&docSpec);
if(err != noErr) return err;
} else if(err != noErr)
return err;
/* clean up */
err = AEDisposeDesc (&theTarget);
if(err != noErr) return err;
err = AEDisposeDesc (&theNameDesc);
if(err != noErr) return err;
err = AEDisposeDesc (&theTextDesc);
if(err != noErr) return err;
err = AEDisposeDesc (&theEvent);
if(err != noErr) return err;
err = AEDisposeDesc (&theReply);
if(err != noErr) return err;
/* everything is cool */
return noErr;
}
pascal void main(ExternalCallbackBlock *callbacks, WindowPtr theWindow)
{
long oldA4;
OSErr err;
Handle windowContents;
Str255 windowTitle;
//RememberA0(); /* Can't find header file for this. Seems to work anyway. */
oldA4 = SetUpA4();
GetWTitle(theWindow, windowTitle);
windowContents = callbacks->GetWindowContents(theWindow);
HLock(windowContents);
err = SendTextAsAE(callbacks, *windowContents, GetHandleSize(windowContents), windowTitle);
if(err != noErr) callbacks->ReportOSError(err);
HUnlock(windowContents);
RestoreA4(oldA4);
}

View File

@ -0,0 +1,25 @@
'''
Minimal test module
'''#
import sys
import PythonScript
SIGNATURE = 'MACS'
TIMEOUT = 10*60*60
PythonScript.PsScript(SIGNATURE, TIMEOUT)
p = PythonScript.PyScript
ev = PythonScript.PsEvents
pc = PythonScript.PsClass
pp = PythonScript.PsProperties
startup = str(p(ev.Get, pc.Desktopobject(1).Startup_disk().Name()))
print 'startup',startup, type(startup)
print p(ev.Get, pc.Disk(startup).Folder(7).File(1).Name())
print p(ev.Get, pc.Disk(1).Name())
print p(ev.Get, pc.Disk('every').Name())
print p(ev.Make, None, New='Alias_file', At=pp.Desktop(''), To=pp.System_folder(1))
sys.exit(1)

View File

@ -0,0 +1,301 @@
"""
Python script a module to comunicate with apple events
v 0.1a2
v.0.2 16 april 1998
"""
import sys
import getaete
import baetools
import baetypes
import AE
import AppleEvents
import macfs
from types import *
#from aetypes import InstanceType
from aepack import AEDescType
ordinal = {
'every': 'all ',
'first' : 'firs',
'last' : 'last',
'any' : 'any ',
'middle' : 'midd'}
Error = 'PythonScript.Error'
class PsEvents:
pass
class PsClasses:
def __getattr__(self, name):
try:
return DCItem(name, self)
except:
pass
def __repr__(self):
if self.form != 'prop':
t = type(self.seld)
if t == StringType:
self.form = 'name'
elif baetypes.IsRange(self.seld):
self.form = 'rang'
elif baetypes.IsComparison(self.seld) or baetypes.IsLogical(self.seld):
self.form = 'test'
elif t == TupleType:
# Breakout: specify both form and seld in a tuple
# (if you want ID or rele or somesuch)
self.form, self.seld = self.seld
elif t == IntType:
self.form = 'indx'
else:
pass
if self.seld in ordinal.keys():
self.seld = baetypes.Ordinal(ordinal[self.seld])
self.form = 'indx'
s = "baetypes.ObjectSpecifier(%s, %s, %s" % (`self.want`, `self.form`, `self.seld`)
if `self.fr`:
s = s + ", %s)" % `self.fr`
else:
s = s + ")"
return s
def __str__(self):
return self.want
def template(self, seld=None, fr=None):
self.seld = seld
self.fr = fr
def template1(self, which, fr=None):
self.want = 'prop'
self.form = 'prop'
self.fr = fr
class DCItem:
def __init__(self, comp, fr):
self.compclass = comp
self.fr = fr
def __call__(self, which=None):
if which:
self.compclass = eval('PsClass.%s' % self.compclass)
else:
try:
self.compclass = eval('PsProperties.%s' % self.compclass)
except AttributeError:
self.compclass = eval('PsClass.%s' % self.compclass)
return self.compclass(which, self.fr)
class PsClass:
pass
class PsProperties:
pass
class PsEnumerations:
pass
def PsScript(sig=None, Timeout=0, Ignoring=0):
elements = {}
if sig:
target, sig = Signature(sig)
pyscript = getaete.Getaete(sig)
else:
target, sig = Signature('Pyth')
pyscript = getaete.Getaete()
setattr(PyScript, 'timeout', Timeout)
setattr(PyScript, 'ignoring', Ignoring)
setattr(PyScript, 'target', target)
for key, value in pyscript[0].items():
setattr(PsEvents, key, value)
for key, value in pyscript[1].items():
CreateClass(key, 'PsClasses', value)
for val in value[2]:
CreateProperty(val[0], 'PsClasses', `val[1]`)
if value[3]:
for val in value[3]:
if val[0] not in elements.keys():
elements[val[0]] = val[1]
elif len(val[1]) > len(elements[val[0]]):
elements[val[0]] = val[1]
for key, value in pyscript[2].items():
for val in value:
setattr(PsEnumerations, val[0], val[1])
def CreateClass(newClassName, superClassName, value):
parentDict = PsClass.__dict__
exec "class %s(%s): pass" % (newClassName, superClassName) in \
globals(), parentDict
newClassObj = parentDict[newClassName]
newClassObj.__init__ = template
exec "setattr(newClassObj, 'want', %s)" % `value[0]`
if value[2] and value[2][0][0] == 'every':
exec "setattr(newClassObj, 'plur', 1)"
def CreateProperty(newClassName, superClassName, value):
parentDict = PsProperties.__dict__
exec "class %s(%s): pass" % (newClassName, superClassName) in \
globals(), parentDict
newClassObj = parentDict[newClassName]
if newClassName == 'Every':
value = "baetypes.mkOrdinal('every')"
newClassObj.__init__ = template1
exec "setattr(newClassObj, 'seld', %s)" % value
def Signature(signature):
if type(signature) == AEDescType:
target = signature
elif type(signature) == InstanceType and hasattr(signature, '__aepack__'):
target = signature.__aepack__()
elif type(signature) == StringType:
if len(signature) == 4:
target = AE.AECreateDesc(AppleEvents.typeApplSignature, signature)
target_signature = signature
else:
#This should ready be made persistant, so PythonScript 'remembered' where applications were
fss, ok = macfs.PromptGetFile('Find the aplication %s' % signature, 'APPL')
if ok:
target_signature = fss.GetCreatorType()[0]
target = AE.AECreateDesc(AppleEvents.typeApplSignature, target_signature)
else:
raise TypeError, "signature should be 4-char string or AEDesc"
return target, target_signature
class PyScript(PsEvents):
def __init__(self, name, obj=None, **args):
desc, code, subcode, rply, message, keywds = name
# print 'code', code
# print 'subcode', subcode
# print 'rply', rply
# print 'message', message
# print 'keywds', keywds
# print 'name', name
# print 'obj', obj
# print 'args', args
self.code = code
self.subcode = subcode
self.attributes ={}
self.arguments = {}
if keywds:
self.arguments = self.keyargs(keywds, args)
self.arguments['----'] = self.keyfms(message[0], obj)
##XXXX Eudora needs this XXXX##
if self.arguments['----'] == None:
del self.arguments['----']
# print 'arguments', self.arguments
if self.ignoring or rply[0] == 'null':
self.send_flags = AppleEvents.kAENoReply
else:
self.send_flags = AppleEvents.kAEWaitReply
self.send_priority = AppleEvents.kAENormalPriority
if self.timeout:
self.send_timeout = self.timeout
else:
self.send_timeout = AppleEvents.kAEDefaultTimeout
def keyargs(self, ats, args):
# print 'keyargs', ats, args
output = {}
for arg in args.keys():
for at in ats:
if at[0] == arg:
output[at[1]] = self.keyfms(at[2][0], args[arg])
return output
def keyfms(self, key, value):
# print 'keyfms', 'key', key, `value`
if key == 'obj ' or key == 'insl':
return eval(`value`)
elif key == 'TEXT':
return value
elif key == 'null':
return
elif key == 'bool':
return baetypes.mkboolean(value)
elif key == 'type':
try:
val = eval('PsClass.%s()' % value)
return baetypes.mktype(str(val))
except:
return baetypes.mktype(value)
else:
print "I don't know what to put here -- script.keyargs"
print key, `value`
sys.exit[1]
def newevent(self, code, subcode, parameters = {}, attributes = {}):
"""Create a complete structure for an apple event"""
# print code, subcode, parameters, attributes
event = AE.AECreateAppleEvent(code, subcode, self.target,
AppleEvents.kAutoGenerateReturnID, AppleEvents.kAnyTransactionID)
baetools.packevent(event, parameters, attributes)
return event
def sendevent(self, event):
"""Send a pre-created appleevent, await the reply and unpack it"""
reply = event.AESend(self.send_flags, self.send_priority,
self.send_timeout)
parameters, attributes = baetools.unpackevent(reply)
return reply, parameters, attributes
def send(self, code, subcode, parameters = {}, attributes = {}):
"""Send an appleevent given code/subcode/pars/attrs and unpack the reply"""
# print code, subcode, parameters, attributes
return self.sendevent(self.newevent(code, subcode, parameters, attributes))
def __str__(self):
_reply, _arguments, _attributes = self.send(self.code, self.subcode, self.arguments, self.attributes)
if _arguments.has_key('errn'):
raise baetools.Error, baetools.decodeerror(_arguments)
# XXXX Optionally decode result
if _arguments.has_key('----'):
return str(_arguments['----'])
else:
return
def test():
Simp = 'Hermit:Applications:SimpleText'
PsScript('MACS', Timeout=60*60*3)
# PsScript('CSOm', Timeout=60*60*3)
# PsScript('', Timeout=60*60*3)
# PyScript('macsoup')
ev = PsEvents
ps = PsClass
# print PsProperties.__dict__
# y = script(ev.Open, File('Hermit:Desktop Folder:Lincolnshire Imp'), using=Application_file(Simp))
# print baetypes.NProperty('prop', 'prop', 'pnam', baetypes.ObjectSpecifier('cdis', 'indx', 1, None))
# y = PyScript(ev.Get, Disk("Hermit").Folder(7).File(1).Name())
# y = PyScript(ev.Get, Disk("Hermit").Size(), As='Integer')
# y = PyScript(ev.Get, ps.Desktopobject(1).Startup_disk())
# y = PyScript(ev.Get, Mailbox(1).File(), as='TEXT')
# print 'y', y, type(y)
if __name__ == '__main__':
test()
# sys.exit(1)

View File

@ -0,0 +1,86 @@
PythonScript
------------
v0.5 beta 1 24/04/98
author: Bill Bedford, <billb@mousa.demon.co.uk>
This suite of modules is a first attempt at writing a more user friendly
python/appleevent interface. The files in the suite are:
PythonScript
------------
Loads three dictionaries generated by getaete into __dict__'s of three
classes and thus gives us direct assess to all the methods in the aete.
Each method now contains all the information needed to build apple events.
The general usage is
>>>PythonScript.PsScript(SIGNATURE, TIMEOUT, IGNORING)
where
SIGNATURE is the target application
TIMEOUT is in ticks
and IGNORING is a boolean and determines whether the script waits for a reply
from the target before going on to the next event
>>>PythonScript.PyScript(Event, Object, keywdarg1..., keywdarg2...etc)
Object is a appleevent object specifier and is of the form
PythonScript.PsClass.Class1(arg).Class2(arg)Š.Property()
All applescript event, class and property names are capitalised to
distinguish them from python methods.
getaete
-------
Reads the aete of the target application and returns it as a list of three
dictionaries, which represent all the events, properties and enumeration in
the aete. (the fourth dictionary, comparisons, has never been implemented
in applescript so I have not used it) It also reads the applescript aeut
and adds any suites that are missing (ie where the application author has
set his suite to inherit from the aeut.) and the applescript suite, which
gives the language methods
printaete
---------
Produces a text file with the aete set out in a human readable form,
similar to the Open Dictionary command in the applescript editor.
baetools, baepack, baetypes
---------------------------
These are direct equivalents of aetools, aepack, aetypes in the standard
distribution. Some methods and classes have been enhanced others are
redundant
PyScriptTest, testeudora
------------------------
A couple of test scripts. Testeudora is an updated version of the one in
the standard distribution.
Still To Do (in no particular order)
-----------
These modules are much slower than applescript. I believe they could be
made faster by rewriting the aete parser in getaete and/or by putting in
some form of persistent storage so that the class dictionaries can be cached.
The parsing of the appleevent replies need rewriting.
Support for the use of scripting additions.
A Python aeut needs to be written, much of the applescript one is redundant
in python.
Probably a few other things I haven't thought of yet.

View File

@ -0,0 +1,385 @@
"""Tools for use in AppleEvent clients and servers:
conversion between AE types and python types
pack(x) converts a Python object to an AEDesc object
unpack(desc) does the reverse
coerce(x, wanted_sample) coerces a python object to another python object
"""
#
# This code was originally written by Guido, and modified/extended by Jack
# to include the various types that were missing. The reference used is
# Apple Event Registry, chapter 9.
#
import struct
import string
import types
from string import strip
from types import *
import AE
from AppleEvents import *
from AERegistry import *
from AEObjects import *
import MacOS
import macfs
import StringIO
import baetypes
from baetypes import mkenum, mktype
import calldll
OSL = calldll.getlibrary('ObjectSupportLib')
# These ones seem to be missing from AppleEvents
# (they're in AERegistry.h)
#typeColorTable = 'clrt'
#typeDrawingArea = 'cdrw'
#typePixelMap = 'cpix'
#typePixelMapMinus = 'tpmm'
#typeRotation = 'trot'
#typeTextStyles = 'tsty'
#typeStyledText = 'STXT'
#typeAEText = 'tTXT'
#typeEnumeration = 'enum'
#
# Some AE types are immedeately coerced into something
# we like better (and which is equivalent)
#
unpacker_coercions = {
typeComp : typeExtended,
typeColorTable : typeAEList,
typeDrawingArea : typeAERecord,
typeFixed : typeExtended,
typeFloat : typeExtended,
typePixelMap : typeAERecord,
typeRotation : typeAERecord,
typeStyledText : typeAERecord,
typeTextStyles : typeAERecord,
};
#
# Some python types we need in the packer:
#
AEDescType = type(AE.AECreateDesc('TEXT', ''))
_sample_fss = macfs.FSSpec(':')
_sample_alias = _sample_fss.NewAliasMinimal()
FSSType = type(_sample_fss)
AliasType = type(_sample_alias)
def pack(x, forcetype = None):
"""Pack a python object into an AE descriptor"""
# print 'aepack', x, type(x), forcetype
# if type(x) == TupleType:
# forcetype, x = x
if forcetype:
print x, forcetype
if type(x) is StringType:
return AE.AECreateDesc(forcetype, x)
else:
return pack(x).AECoerceDesc(forcetype)
if x == None:
return AE.AECreateDesc('null', '')
t = type(x)
if t == AEDescType:
return x
if t == FSSType:
return AE.AECreateDesc('fss ', x.data)
if t == AliasType:
return AE.AECreateDesc('alis', x.data)
if t == IntType:
return AE.AECreateDesc('long', struct.pack('l', x))
if t == FloatType:
#
# XXXX (note by Guido) Weird thing -- Think C's "double" is 10 bytes, but
# struct.pack('d') return 12 bytes (and struct.unpack requires
# them, too). The first 2 bytes seem to be repeated...
# Probably an alignment problem
# XXXX (note by Jack) haven't checked this under MW
#
# return AE.AECreateDesc('exte', struct.pack('d', x)[2:])
return AE.AECreateDesc('exte', struct.pack('d', x))
if t == StringType:
return AE.AECreateDesc('TEXT', x)
if t == ListType:
list = AE.AECreateList('', 0)
for item in x:
list.AEPutDesc(0, pack(item))
return list
if t == DictionaryType:
record = AE.AECreateList('', 1)
for key, value in x.items():
record.AEPutParamDesc(key, pack(value))
return record
if t == InstanceType and hasattr(x, '__aepack__'):
return x.__aepack__()
return AE.AECreateDesc('TEXT', repr(x)) # Copout
def unpack(desc):
"""Unpack an AE descriptor to a python object"""
t = desc.type
# print t
if unpacker_coercions.has_key(t):
desc = desc.AECoerceDesc(unpacker_coercions[t])
t = desc.type # This is a guess by Jack....
if t == typeAEList:
l = []
for i in range(desc.AECountItems()):
keyword, item = desc.AEGetNthDesc(i+1, '****')
l.append(unpack(item))
return l
if t == typeAERecord:
d = {}
for i in range(desc.AECountItems()):
keyword, item = desc.AEGetNthDesc(i+1, '****')
d[keyword] = unpack(item)
return d
if t == typeAEText:
record = desc.AECoerceDesc('reco')
return mkaetext(unpack(record))
if t == typeAlias:
return macfs.RawAlias(desc.data)
# typeAppleEvent returned as unknown
if t == typeBoolean:
return struct.unpack('b', desc.data)[0]
if t == typeChar:
return desc.data
# typeColorTable coerced to typeAEList
# typeComp coerced to extended
# typeData returned as unknown
# typeDrawingArea coerced to typeAERecord
if t == typeEnumeration:
return mkenum(desc.data)
# typeEPS returned as unknown
if t == typeExtended:
# print desc, type(desc), len(desc)
data = desc.data
# print `data[:8]`, type(data), len(data[:8])
# print struct.unpack('=d', data[:8])[0]
# print string.atoi(data), type(data), len(data)
# print struct.calcsize(data)
# XXX See corresponding note for pack()
# return struct.unpack('d', data[:2] + data)[0]
return struct.unpack('d', data[:8])[0]
if t == typeFalse:
return 0
# typeFixed coerced to extended
# typeFloat coerced to extended
if t == typeFSS:
return macfs.RawFSSpec(desc.data)
if t == typeInsertionLoc:
record = desc.AECoerceDesc('reco')
return mkinsertionloc(unpack(record))
# typeInteger equal to typeLongInteger
if t == typeIntlText:
script, language = struct.unpack('hh', desc.data[:4])
return baetypes.IntlText(script, language, desc.data[4:])
if t == typeIntlWritingCode:
script, language = struct.unpack('hh', desc.data)
return baetypes.IntlWritingCode(script, language)
if t == typeKeyword:
return mkkeyword(desc.data)
# typeLongFloat is equal to typeFloat
if t == typeLongInteger:
# print t, struct.unpack('l', desc.data)
return struct.unpack('l', desc.data)[0]
if t == typeNull:
return None
if t == typeMagnitude:
v = struct.unpack('l', desc.data)
if v < 0:
v = 0x100000000L + v
return v
if t == typeObjectSpecifier:
import Res
# print desc, type(desc)
# print desc.__members__
# print desc.data, desc.type
# print unpack(desc)
# getOSL = calldll.newcall(OSL.AEResolve, 'OSErr', 'InHandle', 'InShort')#, 'InString')
# print 'OSL', getOSL(rdesc, 0)#, desc.data)
record = desc.AECoerceDesc('reco')
# print record
return mkobject(unpack(record))
# typePict returned as unknown
# typePixelMap coerced to typeAERecord
# typePixelMapMinus returned as unknown
# typeProcessSerialNumber returned as unknown
if t == typeQDPoint:
v, h = struct.unpack('hh', desc.data)
return baetypes.QDPoint(v, h)
if t == typeQDRectangle:
v0, h0, v1, h1 = struct.unpack('hhhh', desc.data)
return baetypes.QDRectangle(v0, h0, v1, h1)
if t == typeRGBColor:
r, g, b = struct.unpack('hhh', desc.data)
return baetypes.RGBColor(r, g, b)
# typeRotation coerced to typeAERecord
# typeScrapStyles returned as unknown
# typeSessionID returned as unknown
if t == typeShortFloat:
return struct.unpack('f', desc.data)[0]
if t == typeShortInteger:
# print t, desc.data
# print struct.unpack('h', desc.data)[0]
return struct.unpack('h', desc.data)[0]
# typeSMFloat identical to typeShortFloat
# typeSMInt indetical to typeShortInt
# typeStyledText coerced to typeAERecord
if t == typeTargetID:
return mktargetid(desc.data)
# typeTextStyles coerced to typeAERecord
# typeTIFF returned as unknown
if t == typeTrue:
return 1
if t == typeType:
# print t, desc.data
return mktype(desc.data)
#
# The following are special
#
if t == 'rang':
record = desc.AECoerceDesc('reco')
return mkrange(unpack(record))
if t == 'cmpd':
record = desc.AECoerceDesc('reco')
return mkcomparison(unpack(record))
if t == 'logi':
record = desc.AECoerceDesc('reco')
return mklogical(unpack(record))
return mkunknown(desc.type, desc.data)
def coerce(data, egdata):
"""Coerce a python object to another type using the AE coercers"""
pdata = pack(data)
pegdata = pack(egdata)
pdata = pdata.AECoerceDesc(pegdata.type)
return unpack(pdata)
#
# Helper routines for unpack
#
def mktargetid(data):
sessionID = getlong(data[:4])
name = mkppcportrec(data[4:4+72])
location = mklocationnamerec(data[76:76+36])
rcvrName = mkppcportrec(data[112:112+72])
return sessionID, name, location, rcvrName
def mkppcportrec(rec):
namescript = getword(rec[:2])
name = getpstr(rec[2:2+33])
portkind = getword(rec[36:38])
if portkind == 1:
ctor = rec[38:42]
type = rec[42:46]
identity = (ctor, type)
else:
identity = getpstr(rec[38:38+33])
return namescript, name, portkind, identity
def mklocationnamerec(rec):
kind = getword(rec[:2])
stuff = rec[2:]
if kind == 0: stuff = None
if kind == 2: stuff = getpstr(stuff)
return kind, stuff
def mkunknown(type, data):
return baetypes.Unknown(type, data)
def getpstr(s):
return s[1:1+ord(s[0])]
def getlong(s):
return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
def getword(s):
return (ord(s[0])<<8) | (ord(s[1])<<0)
def mkkeyword(keyword):
return baetypes.Keyword(keyword)
def mkrange(dict):
return baetypes.Range(dict['star'], dict['stop'])
def mkcomparison(dict):
return baetypes.Comparison(dict['obj1'], dict['relo'].enum, dict['obj2'])
def mklogical(dict):
return baetypes.Logical(dict['logc'], dict['term'])
def mkstyledtext(dict):
return baetypes.StyledText(dict['ksty'], dict['ktxt'])
def mkaetext(dict):
return baetypes.AEText(dict[keyAEScriptTag], dict[keyAEStyles], dict[keyAEText])
def mkinsertionloc(dict):
return baetypes.InsertionLoc(dict[keyAEObject], dict[keyAEPosition])
def mkobject(dict):
want = dict['want'].type
form = dict['form'].enum
seld = dict['seld']
fr = dict['from']
if form in ('name', 'indx', 'rang', 'test'):
if want == 'text': return baetypes.Text(seld, fr)
if want == 'cha ': return baetypes.Character(seld, fr)
if want == 'cwor': return baetypes.Word(seld, fr)
if want == 'clin': return baetypes.Line(seld, fr)
if want == 'cpar': return baetypes.Paragraph(seld, fr)
if want == 'cwin': return baetypes.Window(seld, fr)
if want == 'docu': return baetypes.Document(seld, fr)
if want == 'file': return baetypes.File(seld, fr)
if want == 'cins': return baetypes.InsertionPoint(seld, fr)
if want == 'prop' and form == 'prop' and baetypes.IsType(seld):
return baetypes.Property(seld.type, fr)
return baetypes.ObjectSpecifier(want, form, seld, fr)
def _test():
"""Test program. Pack and unpack various things"""
objs = [
'a string',
12,
12.0,
None,
['a', 'list', 'of', 'strings'],
{'key1': 'value1', 'key2':'value2'},
macfs.FSSpec(':'),
macfs.FSSpec(':').NewAliasMinimal(),
baetypes.Enum('enum'),
baetypes.Type('type'),
baetypes.Keyword('kwrd'),
baetypes.Range(1, 10),
baetypes.Comparison(1, '< ', 10),
baetypes.Logical('not ', 1),
# Cannot do StyledText
# Cannot do AEText
baetypes.IntlText(0, 0, 'international text'),
baetypes.IntlWritingCode(0,0),
baetypes.QDPoint(50,100),
baetypes.QDRectangle(50,100,150,200),
baetypes.RGBColor(0x7000, 0x6000, 0x5000),
baetypes.Unknown('xxxx', 'unknown type data'),
baetypes.Character(1),
baetypes.Character(2, baetypes.Line(2)),
]
for o in objs:
print 'BEFORE', o, `o`
print type(o)
packed = pack(o)
unpacked = unpack(packed)
print 'AFTER ', unpacked, `unpacked`
import sys
sys.exit(1)
if __name__ == '__main__':
_test()

View File

@ -0,0 +1,263 @@
"""Tools for use in AppleEvent clients and servers.
pack(x) converts a Python object to an AEDesc object
unpack(desc) does the reverse
packevent(event, parameters, attributes) sets params and attrs in an AEAppleEvent record
unpackevent(event) returns the parameters and attributes from an AEAppleEvent record
Plus... Lots of classes and routines that help representing AE objects,
ranges, conditionals, logicals, etc., so you can write, e.g.:
x = Character(1, Document("foobar"))
and pack(x) will create an AE object reference equivalent to AppleScript's
character 1 of document "foobar"
Some of the stuff that appears to be exported from this module comes from other
files: the pack stuff from aepack, the objects from aetypes.
"""
from types import *
import AE
import AppleEvents
import MacOS
import sys
from baetypes import *
from baepack import pack, unpack, coerce, AEDescType
Error = 'baetools.Error'
# Special code to unpack an AppleEvent (which is *not* a disguised record!)
# Note by Jack: No??!? If I read the docs correctly it *is*....
aekeywords = [
'tran',
'rtid',
'evcl',
'evid',
'addr',
'optk',
'timo',
'inte', # this attribute is read only - will be set in AESend
'esrc', # this attribute is read only
'miss', # this attribute is read only
'from' # new in 1.0.1
]
def missed(ae):
try:
desc = ae.AEGetAttributeDesc('miss', 'keyw')
except AE.Error, msg:
return None
return desc.data
def unpackevent(ae):
parameters = {}
while 1:
key = missed(ae)
if not key: break
parameters[key] = unpack(ae.AEGetParamDesc(key, '****'))
attributes = {}
for key in aekeywords:
try:
desc = ae.AEGetAttributeDesc(key, '****')
except (AE.Error, MacOS.Error), msg:
if msg[0] != -1701 and msg[0] != -1704:
raise sys.exc_type, sys.exc_value
continue
attributes[key] = unpack(desc)
return parameters, attributes
def packevent(ae, parameters = {}, attributes = {}):
for key, value in parameters.items():
ae.AEPutParamDesc(key, pack(value))
for key, value in attributes.items():
ae.AEPutAttributeDesc(key, pack(value))
#
# Support routine for automatically generated Suite interfaces
# These routines are also useable for the reverse function.
#
def keysubst(arguments, keydict):
"""Replace long name keys by their 4-char counterparts, and check"""
ok = keydict.values()
for k in arguments.keys():
if keydict.has_key(k):
v = arguments[k]
del arguments[k]
arguments[keydict[k]] = v
elif k != '----' and k not in ok:
raise TypeError, 'Unknown keyword argument: %s'%k
def enumsubst(arguments, key, edict):
"""Substitute a single enum keyword argument, if it occurs"""
if not arguments.has_key(key):
return
v = arguments[key]
ok = edict.values()
if edict.has_key(v):
arguments[key] = edict[v]
elif not v in ok:
raise TypeError, 'Unknown enumerator: %s'%v
def decodeerror(arguments):
"""Create the 'best' argument for a raise MacOS.Error"""
errn = arguments['errn']
err_a1 = errn
if arguments.has_key('errs'):
err_a2 = arguments['errs']
else:
err_a2 = MacOS.GetErrorString(errn)
if arguments.has_key('erob'):
err_a3 = arguments['erob']
else:
err_a3 = None
return (err_a1, err_a2, err_a3)
class TalkTo:
"""An AE connection to an application"""
def __init__(self, signature, start=0, timeout=0):
"""Create a communication channel with a particular application.
Addressing the application is done by specifying either a
4-byte signature, an AEDesc or an object that will __aepack__
to an AEDesc.
"""
self.target_signature = None
if type(signature) == AEDescType:
self.target = signature
elif type(signature) == InstanceType and hasattr(signature, '__aepack__'):
self.target = signature.__aepack__()
elif type(signature) == StringType and len(signature) == 4:
self.target = AE.AECreateDesc(AppleEvents.typeApplSignature, signature)
self.target_signature = signature
else:
raise TypeError, "signature should be 4-char string or AEDesc"
self.send_flags = AppleEvents.kAEWaitReply
self.send_priority = AppleEvents.kAENormalPriority
if timeout:
self.send_timeout = timeout
else:
self.send_timeout = AppleEvents.kAEDefaultTimeout
if start:
self.start()
def start(self):
"""Start the application, if it is not running yet"""
self.send_flags = AppleEvents.kAENoReply
_launch(self.target_signature)
def newevent(self, code, subcode, parameters = {}, attributes = {}):
"""Create a complete structure for an apple event"""
event = AE.AECreateAppleEvent(code, subcode, self.target,
AppleEvents.kAutoGenerateReturnID, AppleEvents.kAnyTransactionID)
# print parameters, attributes
packevent(event, parameters, attributes)
return event
def sendevent(self, event):
"""Send a pre-created appleevent, await the reply and unpack it"""
reply = event.AESend(self.send_flags, self.send_priority,
self.send_timeout)
parameters, attributes = unpackevent(reply)
return reply, parameters, attributes
def send(self, code, subcode, parameters = {}, attributes = {}):
"""Send an appleevent given code/subcode/pars/attrs and unpack the reply"""
return self.sendevent(self.newevent(code, subcode, parameters, attributes))
#
# The following events are somehow "standard" and don't seem to appear in any
# suite...
#
def activate(self):
"""Send 'activate' command"""
self.send('misc', 'actv')
def _get(self, _object, as=None, _attributes={}):
"""_get: get data from an object
Required argument: the object
Keyword argument _attributes: AppleEvent attribute dictionary
Returns: the data
"""
_code = 'core'
_subcode = 'getd'
_arguments = {'----':_object}
if as:
_arguments['rtyp'] = mktype(as)
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise Error, decodeerror(_arguments)
if _arguments.has_key('----'):
return _arguments['----']
# Tiny Finder class, for local use only
class _miniFinder(TalkTo):
def open(self, _object, _attributes={}, **_arguments):
"""open: Open the specified object(s)
Required argument: list of objects to open
Keyword argument _attributes: AppleEvent attribute dictionary
"""
_code = 'aevt'
_subcode = 'odoc'
if _arguments: raise TypeError, 'No optional args expected'
_arguments['----'] = _object
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error, aetools.decodeerror(_arguments)
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
#pass
_finder = _miniFinder('MACS')
def _launch(appfile):
"""Open a file thru the finder. Specify file by name or fsspec"""
_finder.open(_application_file(('ID ', appfile)))
class _application_file(ComponentItem):
"""application file - An application's file on disk"""
want = 'appf'
_application_file._propdict = {
}
_application_file._elemdict = {
}
# Test program
# XXXX Should test more, really...
def test():
target = AE.AECreateDesc('sign', 'quil')
ae = AE.AECreateAppleEvent('aevt', 'oapp', target, -1, 0)
print unpackevent(ae)
raw_input(":")
ae = AE.AECreateAppleEvent('core', 'getd', target, -1, 0)
obj = Character(2, Word(1, Document(1)))
print obj
print repr(obj)
packevent(ae, {'----': obj})
params, attrs = unpackevent(ae)
print params['----']
raw_input(":")
if __name__ == '__main__':
test()
sys.exit(1)

View File

@ -0,0 +1,564 @@
"""aetypes - Python objects representing various AE types."""
from AppleEvents import *
from AERegistry import *
from AEObjects import *
import struct
from types import *
import string
#
# convoluted, since there are cyclic dependencies between this file and
# aetools_convert.
#
def pack(*args):
from aepack import pack
return apply(pack, args)
def IsSubclass(cls, base):
"""Test whether CLASS1 is the same as or a subclass of CLASS2"""
# Loop to optimize for single inheritance
while 1:
if cls is base: return 1
if len(cls.__bases__) <> 1: break
cls = cls.__bases__[0]
# Recurse to cope with multiple inheritance
for c in cls.__bases__:
if IsSubclass(c, base): return 1
return 0
def IsInstance(x, cls):
"""Test whether OBJECT is an instance of (a subclass of) CLASS"""
return type(x) is InstanceType and IsSubclass(x.__class__, cls)
def nice(s):
"""'nice' representation of an object"""
if type(s) is StringType: return repr(s)
else: return str(s)
class Unknown:
"""An uninterpreted AE object"""
def __init__(self, type, data):
self.type = type
self.data = data
def __repr__(self):
return "Unknown(%s, %s)" % (`self.type`, `self.data`)
def __aepack__(self):
return pack(self.data, self.type)
class Enum:
"""An AE enumeration value"""
def __init__(self, enum):
self.enum = "%-4.4s" % str(enum)
def __repr__(self):
return "Enum(%s)" % `self.enum`
def __str__(self):
return string.strip(self.enum)
def __aepack__(self):
return pack(self.enum, typeEnumeration)
def IsEnum(x):
return IsInstance(x, Enum)
def mkenum(enum):
# print enum
if IsEnum(enum): return enum
return Enum(enum)
class Boolean:
"""An AE boolean value"""
def __init__(self, bool):
if bool:
self.bool = "%-4.4s" % str(typeTrue)
else:
self.bool = "%-4.4s" % str(typeFalse)
def __repr__(self):
return "Boolean(%s)" % self.bool
def __str__(self):
return self.bool
def __aepack__(self):
if self.bool == 'true':
return pack('', typeTrue)
else:
return pack('', typeFalse)
def IsBoolean(x):
return IsInstance(x, Boolean)
def mkboolean(bool):
# print bool
if IsBoolean(bool): return bool
return Boolean(bool)
class Type:
"""An AE 4-char typename object"""
def __init__(self, _type):
self.type = "%-4.4s" % str(_type)
def __repr__(self):
return "Type(%s)" % `self.type`
def __str__(self):
return string.strip(self.type)
def __aepack__(self):
# print self.type, typeType
return pack(self.type, typeType)
def IsType(x):
return IsInstance(x, Type)
def mktype(_type):
# Should check for apple ID codes, will allow
if IsType(_type): return _type
if type(_type) <> StringType: return _type
if len(_type) <> 4: return Type(eval('type' + _type))
return Type(_type)
class Keyword:
"""An AE 4-char keyword object"""
def __init__(self, keyword):
self.keyword = "%-4.4s" % str(keyword)
def __repr__(self):
return "Keyword(%s)" % `self.keyword`
def __str__(self):
return string.strip(self.keyword)
def __aepack__(self):
return pack(self.keyword, typeKeyword)
def IsKeyword(x):
return IsInstance(x, Keyword)
class Range:
"""An AE range object"""
def __init__(self, start, stop):
self.start = start
self.stop = stop
def __repr__(self):
return "Range(%s, %s)" % (`self.start`, `self.stop`)
def __str__(self):
return "%s thru %s" % (nice(self.start), nice(self.stop))
def __aepack__(self):
return pack({'star': self.start, 'stop': self.stop}, 'rang')
def IsRange(x):
return IsInstance(x, Range)
class Comparison:
"""An AE Comparison"""
def __init__(self, obj1, relo, obj2):
self.obj1 = obj1
self.relo = "%-4.4s" % str(relo)
self.obj2 = obj2
def __repr__(self):
return "Comparison(%s, %s, %s)" % (`self.obj1`, `self.relo`, `self.obj2`)
def __str__(self):
return "%s %s %s" % (nice(self.obj1), string.strip(self.relo), nice(self.obj2))
def __aepack__(self):
return pack({'obj1': self.obj1,
'relo': mkenum(self.relo),
'obj2': self.obj2},
'cmpd')
def IsComparison(x):
return IsInstance(x, Comparison)
class NComparison(Comparison):
# The class attribute 'relo' must be set in a subclass
def __init__(self, obj1, obj2):
Comparison.__init__(obj1, self.relo, obj2)
class Ordinal:
"""An AE Ordinal"""
def __init__(self, ord):
self.ord = ord
def __repr__(self):
return "baetypes.Ordinal(%s)" % `self.ord`
def __str__(self):
return "%s" % (string.strip(self.ord))
def __aepack__(self):
return pack(self.ord, typeAbsoluteOrdinal)
def IsOrdinal(x):
# print 'IsOrdinal', x, IsInstance(x, Ordinal)
return IsInstance(x, Ordinal)
def mkOrdinal(Ord):
if IsOrdinal(Ord): return Ord
return Ordinal(Ord)
class NOrdinal(Ordinal):
# The class attribute 'abso' must be set in a subclass
def __init__(self ):
# print 'NOrdinal', self.abso
Ordinal.__init__(self, self.abso)
class Logical:
"""An AE logical expression object"""
def __init__(self, logc, term):
self.logc = "%-4.4s" % str(logc)
self.term = term
def __repr__(self):
return "Logical(%s, %s)" % (`self.logc`, `self.term`)
def __str__(self):
if type(self.term) == ListType and len(self.term) == 2:
return "%s %s %s" % (nice(self.term[0]),
string.strip(self.logc),
nice(self.term[1]))
else:
return "%s(%s)" % (string.strip(self.logc), nice(self.term))
def __aepack__(self):
return pack({'logc': mkenum(self.logc), 'term': self.term}, 'logi')
def IsLogical(x):
return IsInstance(x, Logical)
class StyledText:
"""An AE object respresenting text in a certain style"""
def __init__(self, style, text):
self.style = style
self.text = text
def __repr__(self):
return "StyledText(%s, %s)" % (`self.style`, `self.text`)
def __str__(self):
return self.text
def __aepack__(self):
return pack({'ksty': self.style, 'ktxt': self.text}, 'STXT')
def IsStyledText(x):
return IsInstance(x, StyledText)
class AEText:
"""An AE text object with style, script and language specified"""
def __init__(self, script, style, text):
self.script = script
self.style = style
self.text = text
def __repr__(self):
return "AEText(%s, %s, %s)" % (`self.script`, `self.style`, `self.text`)
def __str__(self):
return self.text
def __aepack__(self):
return pack({keyAEScriptTag: self.script, keyAEStyles: self.style,
keyAEText: self.text}, typeAEText)
def IsAEText(x):
return IsInstance(x, AEText)
class IntlText:
"""A text object with script and language specified"""
def __init__(self, script, language, text):
self.script = script
self.language = language
self.text = text
def __repr__(self):
return "IntlText(%s, %s, %s)" % (`self.script`, `self.language`, `self.text`)
def __str__(self):
return self.text
def __aepack__(self):
return pack(struct.pack('hh', self.script, self.language)+self.text,
typeIntlText)
def IsIntlText(x):
return IsInstance(x, IntlText)
class IntlWritingCode:
"""An object representing script and language"""
def __init__(self, script, language):
self.script = script
self.language = language
def __repr__(self):
return "IntlWritingCode(%s, %s)" % (`self.script`, `self.language`)
def __str__(self):
return "script system %d, language %d"%(self.script, self.language)
def __aepack__(self):
return pack(struct.pack('hh', self.script, self.language),
typeIntlWritingCode)
def IsIntlWritingCode(x):
return IsInstance(x, IntlWritingCode)
class QDPoint:
"""A point"""
def __init__(self, v, h):
self.v = v
self.h = h
def __repr__(self):
return "QDPoint(%s, %s)" % (`self.v`, `self.h`)
def __str__(self):
return "(%d, %d)"%(self.v, self.h)
def __aepack__(self):
return pack(struct.pack('hh', self.v, self.h),
typeQDPoint)
def IsQDPoint(x):
return IsInstance(x, QDPoint)
class QDRectangle:
"""A rectangle"""
def __init__(self, v0, h0, v1, h1):
self.v0 = v0
self.h0 = h0
self.v1 = v1
self.h1 = h1
def __repr__(self):
return "QDRectangle(%s, %s, %s, %s)" % (`self.v0`, `self.h0`,
`self.v1`, `self.h1`)
def __str__(self):
return "(%d, %d)-(%d, %d)"%(self.v0, self.h0, self.v1, self.h1)
def __aepack__(self):
return pack(struct.pack('hhhh', self.v0, self.h0, self.v1, self.h1),
typeQDRectangle)
def IsQDRectangle(x):
return IsInstance(x, QDRectangle)
class RGBColor:
"""An RGB color"""
def __init__(self, r, g, b):
self.r = r
self.g = g
self.b = b
def __repr__(self):
return "RGBColor(%s, %s, %s)" % (`self.r`, `self.g`, `self.b`)
def __str__(self):
return "0x%x red, 0x%x green, 0x%x blue"% (self.r, self.g, self.b)
def __aepack__(self):
return pack(struct.pack('hhh', self.r, self.g, self.b),
typeRGBColor)
def IsRGBColor(x):
return IsInstance(x, RGBColor)
class ObjectSpecifier:
"""A class for constructing and manipulation AE object specifiers in python.
An object specifier is actually a record with four fields:
key type description
--- ---- -----------
'want' type 4-char class code of thing we want,
e.g. word, paragraph or property
'form' enum how we specify which 'want' thing(s) we want,
e.g. by index, by range, by name, or by property specifier
'seld' any which thing(s) we want,
e.g. its index, its name, or its property specifier
'from' object the object in which it is contained,
or null, meaning look for it in the application
Note that we don't call this class plain "Object", since that name
is likely to be used by the application.
"""
def __init__(self, want, form, seld, fr = None):
self.want = want
self.form = form
self.seld = seld
self.fr = fr
def __repr__(self):
s = "ObjectSpecifier(%s, %s, %s" % (`self.want`, `self.form`, `self.seld`)
if self.fr:
s = s + ", %s)" % `self.fr`
else:
s = s + ")"
return s
def __aepack__(self):
return pack({'want': mktype(self.want),
'form': mkenum(self.form),
'seld': self.seld,
'from': self.fr},
'obj ')
def IsObjectSpecifier(x):
return IsInstance(x, ObjectSpecifier)
# Backwards compatability, sigh...
class Property(ObjectSpecifier):
def __init__(self, which, fr = None, want='prop'):
ObjectSpecifier.__init__(self, want, 'prop', mktype(which), fr)
def __repr__(self):
if self.fr:
return "Property_r(%s, %s)" % (`self.seld.type`, `self.fr`)
else:
return "Property_r(%s)" % `self.seld.type`
def __str__(self):
if self.fr:
return "Property %s of %s" % (str(self.seld), str(self.fr))
else:
return "Property_s %s" % str(self.seld)
class NProperty(ObjectSpecifier):
# Subclasses *must* self baseclass attributes:
# want is the type of this property
# which is the property name of this property
def __init__(self, want, form, seld, fr = None):
ObjectSpecifier.__init__(self, want, form,
mktype(seld), fr)
class SelectableItem(ObjectSpecifier):
def __init__(self, want, seld, fr = None):
t = type(seld)
if t == StringType:
form = 'name'
elif IsRange(seld):
form = 'rang'
elif IsComparison(seld) or IsLogical(seld):
form = 'test'
elif t == TupleType:
# Breakout: specify both form and seld in a tuple
# (if you want ID or rele or somesuch)
form, seld = seld
else:
form = 'indx'
ObjectSpecifier.__init__(self, want, form, seld, fr)
class ComponentItem(SelectableItem):
# Derived classes *must* set the *class attribute* 'want' to some constant
# Also, dictionaries _propdict and _elemdict must be set to map property
# and element names to the correct classes
def __init__(self, want, which, fr = None):
SelectableItem.__init__(self, want, which, fr)
def __repr__(self):
if not self.fr:
return "%s(%s)" % (self.__class__.__name__, `self.seld`)
return "%s(%s, %s)" % (self.__class__.__name__, `self.seld`, `self.fr`)
def __str__(self):
seld = self.seld
if type(seld) == StringType:
ss = repr(seld)
elif IsRange(seld):
start, stop = seld.start, seld.stop
if type(start) == InstanceType == type(stop) and \
start.__class__ == self.__class__ == stop.__class__:
ss = str(start.seld) + " thru " + str(stop.seld)
else:
ss = str(seld)
else:
ss = str(seld)
s = "%s %s" % (self.__class__.__name__, ss)
if self.fr: s = s + " of %s" % str(self.fr)
return s
# def __getattr__(self, name):
# print name
# if self._elemdict.has_key(name):
# cls = self._elemdict[name]
# return DelayedComponentItem(cls, self)
# if self._propdict.has_key(name):
# cls = self._propdict[name]
# return cls(self)
# raise AttributeError, name
class DelayedComponentItem:
def __init__(self, compclass, fr):
self.compclass = compclass
self.fr = fr
def __call__(self, which):
return self.compclass(which, self.fr)
def __repr__(self):
return "%s(???, %s)" % (self.__class__.__name__, `self.fr`)
def __str__(self):
return "selector for element %s of %s"%(self.__class__.__name__, str(self.fr))
template = """
class %s(ComponentItem): want = '%s'
"""
exec template % ("Text", 'text')
exec template % ("Character", 'cha ')
exec template % ("Word", 'cwor')
exec template % ("Line", 'clin')
exec template % ("paragraph", 'cpar')
exec template % ("Window", 'cwin')
exec template % ("Document", 'docu')
exec template % ("File", 'file')
exec template % ("InsertionPoint", 'cins')

View File

@ -0,0 +1,406 @@
"""
Produces a 3 dictionaries from application aete's
to be read by PythonScript
v.02 january 31, 1998 added support for inheriting suites from aeut
v.03 february 16, 1998 changes to identify
v.04 february 26, 1998 simplified decode
v.05 23/04/98 simplified _launch
"""
import baetools
import macpath
import sys
import os
import MacOS
import StringIO
import types
from MACFS import *
import macfs
import string
from Res import *
import struct
# for testing only
app ='CSOm' #'ezVu'# 'nwSP'#MACS'#
#Restrict the application suites to the dialect we want to use.
LANG = 0 # 0 = English, 1 = French, 11 = Japanese
lang = {0:'English', 1:'French', 11:'Japanese'}
#The following are neaded to open the application aete
kASAppleScriptSuite = 'ascr'
kGetAETE = 'gdte'
attributes = {}
arguments = {}
class AETE(baetools.TalkTo):
pass
def Getaete(app):
try:
data = openaete(app)
except MacOS.Error, msg:
if msg[0] == -609:
_launch(app)
data = openaete(app)
data = decode(data['----'].data)
data = compileaete(data)
return data
def decode(data):
"""Decode an aete into a python data structure"""
f = StringIO.StringIO(data)
aete = generic(getaete, f)
return aete
def simplify(item):
"""Recursively replace singleton tuples by their constituent item"""
if type(item) is types.ListType:
return map(simplify, item)
elif type(item) == types.TupleType and len(item) == 2:
return simplify(item[1])
else:
return item
## Here follows the aete resource decoder.
## It is presented bottom-up instead of top-down because there are direct
## references to the lower-level part-decoders from the high-level part-decoders.
#
def getflag(f, *args):
m = ''
c = f.read(2)
print `c`
if not c:
raise EOFError, 'in getflag' + str(args)
for n in c:
m = m + `ord(n)`
def getbyte(f, *args):
c = f.read(1)
if not c:
raise EOFError, 'in getbyte' + str(args)
return ord(c)
def getword(f, *args):
getalign(f)
s = f.read(2)
if len(s) < 2:
raise EOFError, 'in getword' + str(args)
return (ord(s[0])<<8) | ord(s[1])
def getlong(f, *args):
getalign(f)
s = f.read(4)
if len(s) < 4:
raise EOFError, 'in getlong' + str(args)
return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
def getostype(f, *args):
getalign(f)
s = f.read(4)
if len(s) < 4:
raise EOFError, 'in getostype' + str(args)
return s
def getpstr(f, *args):
c = f.read(1)
if len(c) < 1:
raise EOFError, 'in getpstr[1]' + str(args)
nbytes = ord(c)
if nbytes == 0: return ''
s = f.read(nbytes)
if len(s) < nbytes:
raise EOFError, 'in getpstr[2]' + str(args)
return s
def getalign(f):
if f.tell() & 1:
c = f.read(1)
##if c <> '\0':
## print 'align:', `c`
def getlist(f, description, getitem):
count = getword(f)
list = []
for i in range(count):
list.append(generic(getitem, f))
getalign(f)
return list
def alt_generic(what, f, *args):
print "generic", `what`, args
res = vageneric(what, f, args)
print '->', `res`
return res
def generic(what, f, *args):
if type(what) == types.FunctionType:
return apply(what, (f,) + args)
if type(what) == types.ListType:
record = []
for thing in what:
item = apply(generic, thing[:1] + (f,) + thing[1:])
record.append(item)
return record
return "BAD GENERIC ARGS: %s" % `what`
getdata = [
(getostype, "type"),
(getpstr, "description"),
(getword, "flags")
]
getargument = [
(getpstr, "name"),
(getostype, "keyword"),
(getdata, "what")
]
getevent = [
(getpstr, "name"),
(getpstr, "description"),
(getostype, "suite code"),
(getostype, "event code"),
(getdata, "returns"),
(getdata, "accepts"),
(getlist, "optional arguments", getargument)
]
getproperty = [
(getpstr, "name"),
(getostype, "code"),
(getdata, "what")
]
getelement = [
(getostype, "type"),
(getlist, "keyform", getostype)
]
getclass = [
(getpstr, "name"),
(getostype, "class code"),
(getpstr, "description"),
(getlist, "properties", getproperty),
(getlist, "elements", getelement)
]
getcomparison = [
(getpstr, "operator name"),
(getostype, "operator ID"),
(getpstr, "operator comment"),
]
getenumerator = [
(getpstr, "enumerator name"),
(getostype, "enumerator ID"),
(getpstr, "enumerator comment")
]
getenumeration = [
(getostype, "enumeration ID"),
(getlist, "enumerator", getenumerator)
]
getsuite = [
(getpstr, "suite name"),
(getpstr, "suite description"),
(getostype, "suite ID"),
(getword, "suite level"),
(getword, "suite version"),
(getlist, "events", getevent),
(getlist, "classes", getclass),
(getlist, "comparisons", getcomparison),
(getlist, "enumerations", getenumeration)
]
getaete = [
(getbyte, "major version in BCD"),
(getbyte, "minor version in BCD"),
(getword, "language code"),
(getword, "script code"),
(getlist, "suites", getsuite)
]
def compileaete(aete):
"""Generate dictionary for a full aete resource."""
[major, minor, language, script, suites] = aete
suitedict = {}
gsuites = openaeut()
for gsuite in gsuites:
if gsuite[0] == 'AppleScript Suite':
suite = gsuite
suite = compilesuite(suite)
suitedict[identify(suite[0])] = suite[1:]
for suite in suites:
if language == LANG:
suitecode = suite[2]
if suite[5] == []:
for gsuite in gsuites:
if suitecode == gsuite[2]:
suite = gsuite
suite = compilesuite(suite)
suitedict[identify(suite[0])] = suite[1:]
suitedict = combinesuite(suitedict)
return suitedict
def compilesuite(suite):
"""Generate dictionary for a single suite"""
[name, desc, code, level, version, events, classes, comps, enums] = suite
eventdict ={}
classdict = {}
enumdict ={}
for event in events:
if event[6]:
for ev in event[6]:
ev[0] = identify(ev[:2])
eventdict[identify(event[:2])] = event[1:]
for klass in classes:
if klass[3]:
for kl in klass[3]:
kl[0] = identify(kl[:2])
classdict[identify(klass[:2])] = klass[1:]
for enum in enums:
enumdict[enum[0]] = enum[1]
return name, eventdict, classdict, enumdict
def combinesuite(suite):
"""Combines suite dictionaries to seperate event, class, enumeration dictionaries
"""
suitelist = []
eventDict ={}
classDict ={}
enumDict ={}
for value in suite.values():
for key in value[0].keys():
val = value[0][key]
eventDict[key] = val
for key in value[1].keys():
val = value[1][key]
if key in classDict.keys():
nval = classDict[key][2]
val[2] = val[2] + nval
classDict[key] = val
for key in value[2].keys():
val = value[2][key]
enumDict[key] = val
return eventDict, classDict, enumDict
illegal_ids = [ "for", "in", "from", "and", "or", "not", "print", "class", "return",
"def", "name", 'data' ]
def identify(str):
"""Turn any string into an identifier:
- replace space by _
- remove ',' and '-'
capitalise
"""
if not str[0]:
if str[1] == 'c@#!':
return "Every"
else:
return 'Any'
rv = string.replace(str[0], ' ', '_')
rv = string.replace(rv, '-', '')
rv = string.replace(rv, ',', '')
rv = string.capitalize(rv)
return rv
def openaete(app):
"""open and read the aete of the target application"""
arguments['----'] = LANG
_aete = AETE(app)
_reply, _arguments, _attributes = _aete.send(kASAppleScriptSuite, kGetAETE, arguments, attributes)
if _arguments.has_key('errn'):
raise baetools.Error, baetools.decodeerror(_arguments)
return _arguments
def openaeut():
"""Open and read a aeut file.
XXXXX This has been temporarily hard coded until a Python aeut is written XXXX"""
fullname = dialect
rf = OpenRFPerm(fullname, 0, 1)
try:
UseResFile(rf)
resources = []
for i in range(Count1Resources('aeut')):
res = Get1IndResource('aeut', 1+i)
resources.append(res)
for res in resources:
data = res.data
data = decode(data)[4]
finally:
CloseResFile(rf)
return data
def dialect():
"""find the correct Dialect file"""
dialect = lang[LANG] + " Dialect"
try:
##System 8
vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kScriptingAdditionsFolderType, 0)
fss = macfs.FSSpec((vRefNum, dirID, ''))
fss = fss.as_pathname()
except macfs.error:
##Sytem 7
vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kExtensionFolderType, 0)
fss = macfs.FSSpec((vRefNum, dirID, ''))
fss = fss.as_pathname()
fss = macpath.join(fss, "Scripting Additions")
fss = macpath.join(fss, "Dialect")
fss = macpath.join(fss, dialect)
return fss
#def openosax():
# """Open and read the aetes of osaxen in the scripting additions folder"""
#
# # System 7.x
# aete = []
# vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kExtensionFolderType, 0)
# fss = macfs.FSSpec((vRefNum, dirID, ''))
# fss = fss.as_pathname()
# osax = macpath.join(fss, "Scripting Additions")
# for file in os.listdir(osax):
# fullname = macpath.join(osax, file)
# print fullname
# rf = OpenRFPerm(fullname, 0, 1)
# try:
# UseResFile(rf)
# resources = []
# for i in range(Count1Resources('aete')):
# res = Get1IndResource('aete', 1+i)
# resources.append(res)
# for res in resources:
# data = res.data
# data = decode(data)[4]
# finally:
# CloseResFile(rf)
# aete.append(data)
# print data
#The following should be replaced by direct access to a python 'aeut'
def _launch(appfile):
"""Open a file thru the finder. Specify file by name or fsspec"""
# from PythonScript import PyScript
import baetypes
_finder = AETE('MACS')
parameters ={}
parameters['----'] = eval("baetypes.ObjectSpecifier('%s', '%s', %s)" % ('appf', 'ID ', `appfile`))
_reply, _arguments, _attributes = _finder.send( 'aevt', 'odoc', parameters , attributes = {})
if _arguments.has_key('errn'):
raise baetools.Error, baetools.decodeerror(_arguments)
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
if __name__ == '__main__':
# import profile
# profile.run('Getaete(app)', 'Getaeteprof')
Getaete(app)
# openosax()
# openaete('ascr')
# sys.exit(1)

View File

@ -0,0 +1,346 @@
"""
Produces a human readable file of an application's aete
v.02 january 29, 1998 bug fix Main()
v.03 january 31, 1998 added support for inheriting suites from aeut
v.04 april 16, 1998 Changed identify to match getaete
"""
import aetools
import sys
import MacOS
import StringIO
import types
import macfs
import string
import macpath
from Res import *
# for testing only
app = 'MACS'#CSOm'#'nwSP'#'ezVu'#
#Dialect file hard coded as a tempoary measure
DIALECT = 'Hermit:System Folder:Scripting Additions:Dialects:English Dialect'
#Restrict the application suites to the dialect we want to use.
LANG = 0 # 0 = English, 1 = French, 11 = Japanese
#The following are neaded to open the application aete
kASAppleScriptSuite = 'ascr'
kGetAETE = 'gdte'
attributes = {}
arguments = {}
class AETE(aetools.TalkTo):
pass
def Main(appl):
fss, ok = macfs.PromptGetFile('Application to work on', 'FNDR', 'APPL')#
if not ok:
return
app = fss.GetCreatorType()[0]
path = macpath.split(sys.argv[0])[0]
appname = macpath.split(fss.as_pathname())[1]
appname = appname + '.aete'
appname = macpath.join(path, appname)
try:
data = Getaete(app)
except MacOS.Error, msg:
if msg[0] == -609:
_launch(app)
data = Getaete(app)
# print data
data = decode(data['----'].data)
data = compileaete(data, appname)
def decode(data):
"""Decode an aete into a python data structure"""
f = StringIO.StringIO(data)
aete = generic(getaete, f)
aete = simplify(aete)
return aete
def simplify(item):
"""Recursively replace singleton tuples by their constituent item"""
if type(item) is types.ListType:
return map(simplify, item)
elif type(item) == types.TupleType and len(item) == 2:
return simplify(item[1])
else:
return item
## Here follows the aete resource decoder.
## It is presented bottom-up instead of top-down because there are direct
## references to the lower-level part-decoders from the high-level part-decoders.
#
def getbyte(f, *args):
c = f.read(1)
if not c:
raise EOFError, 'in getbyte' + str(args)
return ord(c)
def getword(f, *args):
getalign(f)
s = f.read(2)
if len(s) < 2:
raise EOFError, 'in getword' + str(args)
return (ord(s[0])<<8) | ord(s[1])
def getlong(f, *args):
getalign(f)
s = f.read(4)
if len(s) < 4:
raise EOFError, 'in getlong' + str(args)
return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])
def getostype(f, *args):
getalign(f)
s = f.read(4)
if len(s) < 4:
raise EOFError, 'in getostype' + str(args)
return s
def getpstr(f, *args):
c = f.read(1)
if len(c) < 1:
raise EOFError, 'in getpstr[1]' + str(args)
nbytes = ord(c)
if nbytes == 0: return ''
s = f.read(nbytes)
if len(s) < nbytes:
raise EOFError, 'in getpstr[2]' + str(args)
return s
def getalign(f):
if f.tell() & 1:
c = f.read(1)
##if c <> '\0':
## print 'align:', `c`
def getlist(f, description, getitem):
count = getword(f)
list = []
for i in range(count):
list.append(generic(getitem, f))
getalign(f)
return list
def alt_generic(what, f, *args):
print "generic", `what`, args
res = vageneric(what, f, args)
print '->', `res`
return res
def generic(what, f, *args):
if type(what) == types.FunctionType:
return apply(what, (f,) + args)
if type(what) == types.ListType:
record = []
for thing in what:
# print thing
item = apply(generic, thing[:1] + (f,) + thing[1:])
record.append((thing[1], item))
return record
return "BAD GENERIC ARGS: %s" % `what`
getdata = [
(getostype, "type"),
(getpstr, "description"),
(getword, "flags")
]
getargument = [
(getpstr, "name"),
(getostype, "keyword"),
(getdata, "what")
]
getevent = [
(getpstr, "name"),
(getpstr, "description"),
(getostype, "suite code"),
(getostype, "event code"),
(getdata, "returns"),
(getdata, "accepts"),
(getlist, "optional arguments", getargument)
]
getproperty = [
(getpstr, "name"),
(getostype, "code"),
(getdata, "what")
]
getelement = [
(getostype, "type"),
(getlist, "keyform", getostype)
]
getclass = [
(getpstr, "name"),
(getostype, "class code"),
(getpstr, "description"),
(getlist, "properties", getproperty),
(getlist, "elements", getelement)
]
getcomparison = [
(getpstr, "operator name"),
(getostype, "operator ID"),
(getpstr, "operator comment"),
]
getenumerator = [
(getpstr, "enumerator name"),
(getostype, "enumerator ID"),
(getpstr, "enumerator comment")
]
getenumeration = [
(getostype, "enumeration ID"),
(getlist, "enumerator", getenumerator)
]
getsuite = [
(getpstr, "suite name"),
(getpstr, "suite description"),
(getostype, "suite ID"),
(getword, "suite level"),
(getword, "suite version"),
(getlist, "events", getevent),
(getlist, "classes", getclass),
(getlist, "comparisons", getcomparison),
(getlist, "enumerations", getenumeration)
]
getaete = [
(getword, "major/minor version in BCD"),
(getword, "language code"),
(getword, "script code"),
(getlist, "suites", getsuite)
]
def compileaete(aete, appname):
"""Generate dictionary file for a full aete resource."""
[version, language, script, suites] = aete
major, minor = divmod(version, 256)
fp = open(appname, 'w')
fp.write('%s:\n' % (appname))
fp.write("AETE resource version %d/%d, language %d, script %d\n" % \
(major, minor, language, script))
fp.write('\n\n')
gsuites = openaeut()
for suite in suites:
if language == LANG:
suitecode = suite[2]
if suite[5] == []:
for gsuite in gsuites:
if suitecode == gsuite[2]:
suite = gsuite
[name, desc, code, level, version, events, classes, comps, enums] = suite
fp.write('\n%s Suite: %s\n' % (name, desc))
fp.write('\n\tEvents:\n')
for event in events:
fp.write('\n\t%s: %s\n' % (identify(event[0]), event[1]))
fp.write('\t\t%s: %s -- %s\n' % (identify(event[0]), event[5][1], event[5][0]))
fp.write('\t\tResult: %s -- %s\n' % (event[4][1], event[4][0]))
for ev in event[6]:
fp.write('\t\t\t%s: %s -- %s\n' % (identify(ev[0]), ev[2][0], ev[2][1]))
fp.write('\n\tClasses')
for klass in classes:
fp.write('\n\t%s: %s\n' % (identify(klass[0]), klass[2]))
if klass[3]:
if not klass[3][0][0]: continue
fp.write('\t\tProperties\n')
for cl in klass[3]:
fp.write('\t\t\t%s: %s -- %s\n' % (identify(cl[0]), cl[2][1], cl[2][0]))#,, cl[3][3][1]))
if klass[4]:
fp.write('\n\t\t\tElements\n')
for cl in klass[4]:
fp.write('\t\t\t\t%s: %s\n' % (identify(cl[0]), cl[1]))
illegal_ids = [ "for", "in", "from", "and", "or", "not", "print", "class", "return",
"def", "name" ]
def identify(str):
"""Turn any string into an identifier:
- replace space by _
- prepend _ if the result is a python keyword
"""
rv = string.replace(str, ' ', '_')
rv = string.replace(rv, '-', '')
rv = string.replace(rv, ',', '')
rv = string.capitalize(rv)
return rv
def Getaete(app):
'''Read the target aete'''
arguments['----'] = LANG
_aete = AETE(app)
_reply, _arguments, _attributes = _aete.send('ascr', 'gdte', arguments, attributes)
if _arguments.has_key('errn'):
raise aetools.Error, aetools.decodeerror(_arguments)
return _arguments
def openaeut():
"""Open and read a aeut file.
XXXXX This has been temporarily hard coded until a Python aeut is written XXXX"""
fullname = DIALECT
rf = OpenRFPerm(fullname, 0, 1)
try:
UseResFile(rf)
resources = []
for i in range(Count1Resources('aeut')):
res = Get1IndResource('aeut', 1+i)
resources.append(res)
for res in resources:
data = res.data
data = decode(data)[3]
finally:
CloseResFile(rf)
return data
#The following should be replaced by direct access to a python 'aeut'
class _miniFinder(aetools.TalkTo):
def open(self, _object, _attributes={}, **_arguments):
"""open: Open the specified object(s)
Required argument: list of objects to open
Keyword argument _attributes: AppleEvent attribute dictionary
"""
_code = 'aevt'
_subcode = 'odoc'
if _arguments: raise TypeError, 'No optional args expected'
_arguments['----'] = _object
_reply, _arguments, _attributes = self.send(_code, _subcode,
_arguments, _attributes)
if _arguments.has_key('errn'):
raise aetools.Error, aetools.decodeerror(_arguments)
# XXXX Optionally decode result
if _arguments.has_key('----'):
return _arguments['----']
_finder = _miniFinder('MACS')
def _launch(appfile):
"""Open a file thru the finder. Specify file by name or fsspec"""
_finder.open(_application_file(('ID ', appfile)))
class _application_file(aetools.ComponentItem):
"""application file - An application's file on disk"""
want = 'appf'
_application_file._propdict = {
}
_application_file._elemdict = {
}
Main(app)
sys.exit(1)

View File

@ -0,0 +1,44 @@
"""A test program that allows us to control Eudora"""
import sys
import MacOS
import PythonScript
# The Creator signature of eudora:
SIGNATURE="CSOm"
TIMEOUT = 10*60*60
def main():
PythonScript.PsScript(SIGNATURE, TIMEOUT)
talker = PythonScript.PyScript
ev = PythonScript.PsEvents
pc = PythonScript.PsClass
while 1:
print 'get, put, name (of first folder), list (foldernames), quit (eudora) or exit (this program) ?'
line = sys.stdin.readline()
try:
if line[0] == 'g':
print 'check'
print talker(ev.Activate)
print talker(ev.Connect, Checking=1)
elif line[0] == 'p':
print talker(ev.Connect, Sending=1)
elif line[0] == 'n':
id = talker(ev.Get, pc.Mail_folder("").Mailbox(1).Name())
print "It is called", id, "\n"
elif line[0] == 'l':
id = talker(ev.Count, pc.Mail_folder(""), Each='Mailbox')
print "There are", id, "mailboxes"
elif line[0] == 'q':
print talker(ev.Quit)
elif line[0] == 'e':
break
except MacOS.Error, arg:
if arg[0] == -609:
print 'Connection invalid, is eudora running?'
else:
print 'MacOS Error:', arg[1]
main()

262
Mac/Contrib/osam/OSAm.c Normal file
View File

@ -0,0 +1,262 @@
/*
*
* 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 "OSAm.h"
#include "ScriptRunner.h"
#include <AppleEvents.h>
/*
* Boiler plate generated from "genmodule.py"
*/
static PyObject *ErrorObject;
static char OSAm_DoCommand__doc__[] = "";
static PyObject *
OSAm_RunCompiledScript (self, args)
PyObject *self;
PyObject *args;
{
char *commandStr = NULL;
char *outpath = NULL;
OSErr myErr;
AEDesc temp;
EventRecord event;
temp.dataHandle = NULL;
if (!PyArg_ParseTuple (args, "s", &commandStr))
return NULL;
myErr = ExecuteScriptFile (commandStr, NULL, &temp);
if (temp.dataHandle != NULL && temp.descriptorType == 'TEXT')
{
char *line;
DescType typeCode;
long dataSize = 0;
HLock (temp.dataHandle);
dataSize = GetHandleSize (temp.dataHandle);
if (dataSize > 0)
{
PyObject *result = PyString_FromStringAndSize ((*temp.dataHandle),
dataSize);
AEDisposeDesc (&temp);
if (!result)
{
printf ("OSAm.error Out of memory.\n");
Py_INCREF (Py_None);
return Py_None;
}
return result;
}
}
if (myErr != noErr)
{
PyErr_Mac (ErrorObject, myErr);
return NULL;
}
Py_INCREF (Py_None);
return Py_None;
}
static PyObject *
OSAm_CompileAndSave (self, args)
PyObject *self;
PyObject *args;
{
char *commandStr = NULL;
char *outpath = NULL;
OSErr myErr;
AEDesc temp;
EventRecord event;
temp.dataHandle = NULL;
if (!PyArg_ParseTuple (args, "ss", &commandStr, &outpath))
return NULL;
myErr = CompileAndSave (commandStr, outpath, NULL, &temp);
if (temp.dataHandle != NULL && temp.descriptorType == 'TEXT')
{
char *line;
DescType typeCode;
long dataSize = 0;
HLock (temp.dataHandle);
dataSize = GetHandleSize (temp.dataHandle);
if (dataSize > 0)
{
PyObject *result = PyString_FromStringAndSize ((*temp.dataHandle),
dataSize);
AEDisposeDesc (&temp);
if (!result)
{
printf ("OSAm.error Out of memory.\n");
Py_INCREF (Py_None);
return Py_None;
}
return result;
}
}
if (myErr != noErr)
{
PyErr_Mac (ErrorObject, myErr);
return NULL;
}
Py_INCREF (Py_None);
return Py_None;
}
static PyObject *
OSAm_CompileAndExecute (self, args)
PyObject *self;
PyObject *args;
{
char *commandStr;
OSErr myErr;
AEDesc temp;
EventRecord event;
temp.dataHandle = NULL;
if (!PyArg_ParseTuple (args, "s", &commandStr))
return NULL;
myErr = CompileAndExecute (commandStr, &temp, NULL);
if (temp.dataHandle != NULL && temp.descriptorType == 'TEXT')
{
char *line;
DescType typeCode;
long dataSize = 0;
HLock (temp.dataHandle);
dataSize = GetHandleSize (temp.dataHandle);
if (dataSize > 0)
{
PyObject *result = PyString_FromStringAndSize ((*temp.dataHandle),
dataSize);
AEDisposeDesc (&temp);
if (!result)
{
printf ("OSAm.error Out of memory.\n");
Py_INCREF (Py_None);
return Py_None;
}
return result;
}
}
if (myErr != noErr)
{
PyErr_Mac (ErrorObject, myErr);
return NULL;
}
Py_INCREF (Py_None);
return Py_None;
}
/*
* List of methods defined in the module
*/
static struct PyMethodDef OSAm_methods[] =
{
{"CompileAndExecute",
(PyCFunction) OSAm_CompileAndExecute,
METH_VARARGS,
OSAm_DoCommand__doc__},
{"CompileAndSave",
(PyCFunction) OSAm_CompileAndSave,
METH_VARARGS,
OSAm_DoCommand__doc__},
{"RunCompiledScript",
(PyCFunction) OSAm_RunCompiledScript,
METH_VARARGS,
OSAm_DoCommand__doc__},
{NULL, (PyCFunction) NULL, 0, NULL}
};
static char OSAm_module_documentation[] = "";
/*
* PYTHON Module Initalization
*/
void
initOSAm ()
{
PyObject *m, *d;
/* Create the module and add the functions */
m = Py_InitModule4 ("OSAm",
OSAm_methods,
OSAm_module_documentation,
(PyObject *) NULL, PYTHON_API_VERSION);
/* Add some symbolic constants to the module */
d = PyModule_GetDict (m);
ErrorObject = PyString_FromString ("OSAm.error");
PyDict_SetItemString (d, "error", ErrorObject);
/* Check for errors */
if (PyErr_Occurred ())
Py_FatalError ("can't initialize module OSAm");
}

View File

@ -0,0 +1 @@
initOSAm

30
Mac/Contrib/osam/OSAm.h Normal file
View File

@ -0,0 +1,30 @@
/*
*
* 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>
*
*
*/
#pragma once
/* Python API */
#include "Python.h"
#include "macglue.h"
/* Macintosh API */
#include <Types.h>
#include <AppleEvents.h>
#include <Processes.h>
#include <Files.h>
#include <Gestalt.h>
#include <Events.h>

View File

@ -0,0 +1,358 @@
(This file must be converted with BinHex 4.0)
:#%p63@dZF(*U!%e08(*$9dP&!3!!!-f(!*!%llTMEfpX!!!!!`!!!5J!!--A!!$
%2`!!#8J!!!"M!3)"!*!*3fpNC9GKFR*TEh)J8(*[DQ9MG!#3lJ3!N!N'!3$rr`#
3#2rr!C!&!*!%(J%"!*!)QCN!!$rr2rmrr`%!!!%!#3CYEfjKBfm!N"`%!#J!#J(
#!S!!+!!+!F)#J!#3%!%!!!%!V!&A!4N#HJ$J!!#XC3!!IV-!!!#4!!!!S!!!$1S
!!"!!N!54!'*KFf9XD@jP3DmM*@3!)MSJEA8"!!!'!3!!"`%!!!J"!!!*!3!!#J%
!!!X"!!!$!!!!"`!!!#3"!!!!!3!!#`)!!!-#!!!'!J!!"`)!!!J#!!!*!J!!#J)
!!!X!!!!(!!!!*!)!!!!#!!!,!!!!33!!!'!!!!0T!!!%!*!%33"K!*!%!@%!N!3
"B3#3"!&K!*!(!3!!!!)!!!!$!!!!"!!!!!8!!!!'!*"d!3!!!`!!!!8!!!!N!3!
!!!%!!!P#Tb!%!!%"!!!"!3!"!!!"!3%!N!S%!*!*"J%!rrm!N!Mrr`'3"3#3""i
"!3#3#*QC!!!rrcrr2rm"!!!"!!N'E@pZB@0[!*!F"!!S!!S"`J+!!#J!#J(#!S!
!N"!"!!!"!&J!VJ$&!KS"0`!!V'8!!"fdH(JZ3dC00MK,1P"bEfTPBh3J6@PcB`"
iH#j$4Ndf1%Xk4@4TG'pb!(Ki,N0'66Bi5cT'Efjd!(Ki,N0'66Bi5cT3FQpUC@0
d)%9iG(*KF`"iH#j$4Ndf1%Xk3h9cG'pY)%YPHAG[FQ4c!(Ki,N0'66Bi5cT"Bf0
PFh-J8'&dD(-!H(JZ3dC00MK,1N*eD@aN)%9iG(*KF`"iH#j$4Ndf1%Xk0MK,)%0
[C'9(C@i!H(JZ3dC00MK,1MBi5b"%DA0KFh0PE@*XCA)!H(JZ3dC00MK,1MBi5b"
-D@jVCA)!H(JZ3dC00MK,1MBi5b"3FQpUC@0d!(Ki,N0'66Bi5cT$,d-V+b"$Efe
`D@aPFJ"iH#j$4Ndf1%Xk3bp$+bXJ9f&bEQPZCh-!H(JZ3dC00MK,1N0'66Bi5`"
iH#j$4Ndf1%Xk8'&cBf&X)%0[EA"TE'9b!(Ki,N0'66Bi5cT3BA0MB@`J9f&bEQP
ZCh-!H(JZ3dC00MK,1P"33b"$Ef4P4f9Z!(Ki,N0'66Bi5cT38%-J4'PcBA0cC@e
LE'9b!(Ki,N0'66Bi5cT38%-J6'PZDf9b!(Ki,N0'66Bi5cT38%-J8%9'!(Ki,N0
'66Bi5cT38%-J8(*[DQ9MG!"iH#j$4Ndf1%Xk8&"$3A0Y)&"KEQ9X!(Ki,N0'66B
i5cT5CASJ3fpYF'PXCA)!H(JZ3dC00MK,1P4KFQGPG#"6CA4dD@jRF`"iH#j$4Nd
f1%Xk4QPXC5"0BA"`D@jRF`"iH#j`F'-k8(*[DQ9MG#"0DA0M!(Ki,R"`BcT&C'P
dEh)!H(JZF("M1NC[ER3!H(JZF("M1P"bEfTPBh3J4AKdFQ&c!(Ki,R"`BcT$GA0
dEfdJ5f9jGfpbC(-!H(JZF("M1N&MBf9cFb"3BA4SF`"iH#j`F'-k3R9TE'3J4AK
dFQ&c!(Ki,R"`BcSf1%XJ3fpNC8GPEJ"iH#j`F'-k0MK,)%4TFf&cFf9YBQaPFJ"
iH#j`F'-k0MK,)%aTEQYPFJ"iH#j`F'-k0MK,)&"bEfTPBh3!H(JZF("M1N-[3bX
V)%0[EA"TE'9b!(Ki,R"`BcT$,d-V+b"ABA*ZD@jRF`"iH#j`F'-k3dC00MK,!(K
i,R"`BcT3BA0MB@`J3fpYF'PXCA)!H(JZF("M1P"KFf0KE#"ABA*ZD@jRF`"iH#j
`F'-k8&"$)%0[C'9(C@i!H(JZF("M1P"33b"%DA0KFh0PE@*XCA)!H(JZF("M1P"
33b"-D@jVCA)!H(JZF("M1P"33b"348B!H(JZF("M1P"33b"3FQpUC@0d!(Ki,R"
`BcT38%0"FfdJ8'&ZC@`!H(JZF("M1P*PHL"$Efe`D@aPFJ"iH#j`F'-k9'&bCf9
d)&0PG(4TEQGc!(Ki,R"`BcT'D@aP)%eKF("TEQGc!&"bEfTPBh3J4QPXC5"-DA0
d!(Ki,N0'66Bi5cT*8L"2F(4TE@PkCA)!H(JZ3dC00MK,1NeKBdp6)%ePFQGP)&"
KEQ9X!(Ki,R"`BcT*8L"2F(4TE@PkCA)!H(JZF("M1NeKBdp6)%ePFQGP)&"KEQ9
X!(Ki,N0'66Bi5cT%C@*eCfGPFL"8BA*RCA3!H(JZ3dC00MK,1NC88#"3B@jPE!"
iH#j$4Ndf1%Xk5Q&fB5"-B@jRG@&RC3"iH#j$4Ndf1%Xk5Q&fB5"2GA4`GA3!H(J
Z3dC00MK,1NTKGQ%J8(*[DQ9MG!"iH#j$4Ndf1%Xk5Q&fB84[Bb"3FQpUC@0d!(K
i,N0'66Bi5cTAD@j53b"$Efe`D@aPFJ"iH#j$4Ndf1%XkH$Jf)%0[C'9(C@i!H(J
Z3dC00MK,1RJi0L"&H'0PF(4TEfjc)&"KEQ9X!(Ki,N0'66Bi5cTi1$BJ6'PZDf9
b!(Ki,N0'66Bi5cTi1$BJ8(*[DQ9MG!"iH#j`F'-k4'9LG@GRCA)J9'&bCf9d!(K
i,R"`BcT'9&!J8'&ZC@`!H(JZF("M1NTKGQ%J6'&ZCh9KCf8!H(JZF("M1NTKGQ%
J6h9dF(9d!(Ki,R"`BcT+BACK)&"bEfTPBh3!H(JZF("M1NTKGQ&%Ef-J8(*[DQ9
MG!"iH#j`F'-k9fPZ8N-J3fpYF'PXCA)!H(JZF("M1RJi0L"$Ef4P4f9Z!(Ki,R"
`BcTi1$BJ4AKMCA"dD@pZFb"3B@jPE!"iH#j`F'-kH$Jf)%aTEQYPFJ"iH#j`F'-
kH$Jf)&"bEfTPBh3!6e0"E5j$4Ndf1%Xk3h9cG'pY)%YPHAG[FQ4c!%p63@dZ3dC
00MK,1N&MBf9cFb"3BA4SF`"28d&Y,N0'66Bi5cT8BA*RCA3J8f9dG'PZCh-!6e0
"E5j$4Ndf1%Xk4QPXC5"0BA"`D@jRF`"28d&Y,N0'66Bi5cT#G@PXC#"&H(4bBA-
!6e0"E5j$4Ndf1%Xk4'9LG@GRCA)J9'&bCf9d!%p63@dZ3dC00MK,1MBi5b"$Ef4
P4f9Z!%p63@dZ3dC00MK,1MBi5b"%DA0KFh0PE@*XCA)!6e0"E5j$4Ndf1%Xk0MK
,)%aTEQYPFJ"28d&Y,N0'66Bi5cSf1%XJ8(*[DQ9MG!"28d&Y,N0'66Bi5cT$,d-
V+b"$Efe`D@aPFJ"28d&Y,N0'66Bi5cT$,d-V+b"ABA*ZD@jRF`"28d&Y,N0'66B
i5cT$4Ndf1%X!6e0"E5j$4Ndf1%Xk4P43)&"KEQ9X!%p63@dZ3dC00MK,1NP5)%p
`G'PYDATPFJ"28d&Y,N0'66Bi5cT+BACK)%aKEQGeB@GP!%p63@dZ3dC00MK,1NT
KGQ%J6h9dF(9d!%p63@dZ3dC00MK,1NTKGQ%J8(*[DQ9MG!"28d&Y,N0'66Bi5cT
+BACK4'pM)&"bEfTPBh3!6e0"E5j$4Ndf1%Xk6@&M6e-J6@9bCf8J8'&ZC@`!6e0
"E5j$4Ndf1%Xk8'&cBf&X)%0[EA"TE'9b!%p63@dZ3dC00MK,1P"KFf0KE#"ABA*
ZD@jRF`"28d&Y,N0'66Bi5cT38%-J3fpNC8GPEJ"28d&Y,N0'66Bi5cT38%-J4'P
cBA0cC@eLE'9b!%p63@dZ3dC00MK,1P"33b"-D@jVCA)!6e0"E5j$4Ndf1%Xk8&"
$)&"&4J"28d&Y,N0'66Bi5cT38%-J8(*[DQ9MG!"28d&Y,N0'66Bi5cT38%0"Ffd
J8'&ZC@`!6e0"E5j$4Ndf1%Xk8Q9k)%0[EA"TE'9b!%p63@dZ3dC00MK,1PGTEP*
$)%0[EA"TE'9b!%p63@dZ3dC00MK,1RJi0L"$Ef4P4f9Z!%p63@dZ3dC00MK,1RJ
i0L"&H'0PF(4TEfjc)&"KEQ9X!%p63@dZ3dC00MK,1RJi0L"-D@jVCA)!6e0"E5j
$4Ndf1%XkH$Jf)&"bEfTPBh3!6e0"E5j`F'-k3h9cG'pY)%YPHAG[FQ4c!%p63@d
ZF("M1N&MBf9cFb"3BA4SF`"28d&Y,R"`BcT8BA*RCA3J8f9dG'PZCh-!6e0"E5j
`F'-k4QPXC5"0BA"`D@jRF`"28d&Y,R"`BcT#G@PXC#"&H(4bBA-!6e0"E5j`F'-
k4'9LG@GRCA)J9'&bCf9d!%p63@dZF("M1MBi5b"$Ef4P4f9Z!%p63@dZF("M1MB
i5b"%DA0KFh0PE@*XCA)!6e0"E5j`F'-k0MK,)%aTEQYPFJ"28d&Y,R"`BcSf1%X
J8(*[DQ9MG!"28d&Y,R"`BcT$,d-V+b"$Efe`D@aPFJ"28d&Y,R"`BcT$,d-V+b"
ABA*ZD@jRF`"28d&Y,R"`BcT$4Ndf1%X!6e0"E5j`F'-k4P43)&"KEQ9X!%p63@d
ZF("M1NP5)%p`G'PYDATPFJ"28d&Y,R"`BcT+BACK)%aKEQGeB@GP!%p63@dZF("
M1NTKGQ%J6h9dF(9d!%p63@dZF("M1NTKGQ%J8(*[DQ9MG!"28d&Y,R"`BcT+BAC
K4'pM)&"bEfTPBh3!6e0"E5j`F'-k6@&M6e-J6@9bCf8J8'&ZC@`!6e0"E5j`F'-
k8'&cBf&X)%0[EA"TE'9b!%p63@dZF("M1P"KFf0KE#"ABA*ZD@jRF`"28d&Y,R"
`BcT38%-J3fpNC8GPEJ"28d&Y,R"`BcT38%-J4'PcBA0cC@eLE'9b!%p63@dZF("
M1P"33b"-D@jVCA)!6e0"E5j`F'-k8&"$)&"&4J"28d&Y,R"`BcT38%-J8(*[DQ9
MG!"28d&Y,R"`BcT38%0"FfdJ8'&ZC@`!6e0"E5j`F'-k8Q9k)%0[EA"TE'9b!%p
63@dZF("M1PGTEP*$)%0[EA"TE'9b!%p63@dZF("M1RJi0L"$Ef4P4f9Z!%p63@d
ZF("M1RJi0L"&H'0PF(4TEfjc)&"KEQ9X!%p63@dZF("M1RJi0L"-D@jVCA)!6e0
"E5j`F'-kH$Jf)&"bEfTPBh3!N2m!N2m!N2m!N#%"!*!(&`!!!!)!N!FS!!!!!`#
3"cF!!!!%!*!(8!!!!!8!N!GU!!!!"J#3"i%!!!!(!*!(Q!!!!!J!N!HZ!!!!#3#
3"mN!!!!+!*!(hJ!!!!X!N!Id!!!!$!#3"J%0!!!!$3#3"J%Q!!!!$J#3"J%h!!!
!$`#3"J&4!!!!%!#3"J&V!!!!%3#3"J'"!!!!%J#3"J'F!!!!%`#3"J'a!!!!&!#
3"J($!!!!&3#3"J(C!!!!&J#3"J(`!!!!&`#3"J)(!!!!'!#3"J)K!!!!'3#3"J)
j!!!!'J#3"J*0!!!!'`#3"J*E!!!!(!#3"J*R!!!!(3#3"J*p!!!!(J#3"J+8!!!
!(`#3"J+S!!!!)!#3"J+m!!!!)3#3"J,2!!!!)J#3"J,R!!!!)`#3"J,j!!!!*!#
3"J--!!!!*3#3"J-L!!!!*J#3"J-i!!!!*`#3"J0'!!!!+!#3"J0G!!!!+3#3"J0
d!!!!+J#3"J1(!!!!+`#3"J1I!!!!,!#3"J1a!!!!,3#3"J2!!!!!,J#3"J26!!!
!,`#3"J2R!!!!-!#3"J2l!!!!-3#3"J35!!!!-J#3"J3R!!!!-`#3"J3j!!!!0!#
3"J43!!!!03#3"J4X!!!!0J#3"J5!!!!!0`#3"J5C!!!!1!#3"J5c!!!!13#3"J6
(!!!!1J#3"J6I!!!!1`#3"J6e!!!!2!#3"J8-!!!!23#3"J8Q!!!!2J#3"J8r!!!
!2`#3"J99!!!!3!#3"J9d!!!!33#3"J@*!!!!3J#3"J@I!!!!3`#3"J@f!!!!4!#
3"JA(!!!!43#3"JAF!!!!4J#3"JA[!!!!4`#3"JB$!!!!5!#3"JBD!!!!53#3"JB
`!!!!5J#3"JC$!!!!5`#3"JCI!!!!6!#3"JCa!!!!63#3"JD%!!!!6J#3"JDJ!!!
!6`#3"JDj!!!!8!#3"JE9!!!!83#3"JE[!!!!8J#3"JF)!!!!8`#3"JFN!!!!9!#
3"JFm!!!!93#3"JGC!!!!9J#3"JG`!!!!9`#3"JH)!!!!@!#3"JHM!!!!@3#3"JH
q!!!!@J#3"JI4!!!!@`#3"JIR!!!!A!#3"JJ!N!4G!*!'#"S!!!"H!*!'#$)!!!"
I!*!'#%X!!!"J!*!'#'F!!!"K!*!'#)8!!!"L!*!'#+%!!!"M!*!'#,d!!!"N!*!
'#08!!!"P!*!'#2)!!!"Q!*!'#3N!!!"R!*!'#4d!!!"S!*!'#68!!!"T!*!'#8i
!!!"U!*!'#@F!!!"V!*!'#B)!!!"X!*!'#CS!!!"Y!*!'#EX!!!"Z!*!'#G)!!!"
[!*!'#HS!!!"`!*!'#J-!!!"a!*!'#KN!!!"b!*!'#M)!!!"c!*!'#NN!!!"d!*!
'#Pm!!!"e!*!'#RJ!!!"f!*!'#Sd!!!"h!*!'#UF!!!"i!*!'#VX!!!"j!*!'#Y!
!!!"k!*!'#ZJ!!!"l!*!'#`#3"(`!N!B,%!!!!(d!N!B,)`!!!(i!N!B,13!!!(m
!N!B,8!!!!)!!N!B,C3!!!)%!N!B,H`!!!))!N!B,P!!!!)-!N!B,V`!!!)3!N!B
,b!!!!)8!N!B,i3!!!)B!N!B,pJ!!!)F!N!B-%!!!!)J!N!B-*!!!!)N!N!B-03!
!!)S!N!B-5J!!!)X!N!B-B!!!!)`!N!B-GJ!!!)d!N!B-MJ!!!)i!N!B-S`!!!)m
!N!B-`3!!!*!!!*!'$08!!!#4!*#l8`!!!&3!!!"9!!!!9J!!!%i!!!"4!!!!9`!
!!&J!!!"C!!!!63!!!&)!!!"3!!!!@J!!!&X!!!"F!!!!A3!!!&i!!!"I!!!!B!!
!!'%!!!"L!!!!B`!!!'3!!!"P!!!!CJ!!!'F!!!"S!!!!D3!!!%m!!!"U!!!!D`!
!!'`!!!"Y!!!!EJ!!!(8!!!"f!!!!G`!!!(J!!!"`!!!!F`!!!(N!!!"k!!!!H`!
!!'m!!!"d!!!!FJ!!!(`!!!"p!!!!IJ!!!(m!!!#!!!!!J3!!!))!!!#$!!!!K!!
!!)8!!!#'!!!!K`!!!)J!!!#*!!!!LJ!!!)X!!!"a!!!!M!!!!)d!!!#1!!!!M`!
!!*!!!!!!-J!!!!F!!!!)!!!!#3!!!!S!!!!&!!!!"J!!!!X!!!!-!!!!$3!!!!3
!!!!h!!!!!3!!!"J!!!!#!!!!1!!!!$-!!!!j!!!!1J!!!$X!!!!m!!!!0!!!!!i
!!!!2!!!!%!!!!"%!!!!5!!!!%`!!!"3!!!!9!!!!!`#3"aB!!!!A!!!!23!!!$i
!!!!r!!!!3!!!!%%!!!!J!!!!)3!!!#)!!!!M!!!!(J!!!"m!!!!N!!!!*3!!!#B
!!!!G!!!!3J!!!"S!!!!a!!!!'`!!!%-!!!!e!!!!4!!!!%8!!!"'!!!!4`!!!$B
!!!!R!!!!+!!!!#N!!!!U!!!!+`!!!#`!!!!Y!!!!,J!!!"`!!!!C!!!!,`!!!$!
!!!")!!!!53!!!%S!!!",!!!!6!#323%!!!!#8Np29!#3$!*(8P93!*!(!3G6Eh9
bBf9c!!!!!dC*6%8#!!!(4NP-43)!!!K'58a&!J!!#8G599!!N!F##8aTBR*KFQP
PF`!!!!9'58a&!J!!!dC*6%8"!!!$4NP-43)!!!C'58a&!J!!#dC*6%8#!!!+!!"
!"V%#8!#3$!&*%A!!N#-r!!!!3!!!!dd!!!3!N!3r!#"LBA0PE'PZC5`JBQmJG+K
[E5`!"J%!N!F"!*!*!3#3"LF!!!!S!!!!+3!!!#S!!!!F!!!!13!!!$i!!!!H!!!
!#`!!!"-!!!!G!!!!)J!!!%!!!!!1!!!!*3!!!#X!!!!X!!!!,3!!!#%!!!!Q!!!
!*!!!!$m!!!!Z!!!!$!!!!"3!!!!#!!!!(`!!!#!!!!!0!!!!#3!!!!8!!!!2!!!
!&3!!!"!!!!!@!!!!%3!!!$S!!!!i!!!!1`!!!$d!!!![!!!!-!!!!")!!!!C!!!
!-J!!!$-!!!!d!!!!03!!!$B!!!!A!!!!0`!!!"X!!!!'!!!!#J!!!$%!!!!m!!!
!!3!!!#-!!!!B!*!("!!!!!F!!!!)!!!!'J!!!!-!N)-"!!!!!J!!!!-!!!!%!!!
!"3!!!!B!N(B#1`!!!#S!N!B#4J!!!#X!N!B#8J!!!#`!N!B#B3!!!#d!N!B#F!!
!!#i!N!B#G`!!!#m!N!B#K!!!!$!!N!B#P!!!!$%!N!B#T!!!!$)!N!B#X3!!!$-
!N!B#[3!!!$3!N!B#cJ!!!$8!N!B#f3!!!$B!N!B#i3!!!$F!N!B#l3!!!$J!N!B
#qJ!!!$N!N!B$"J!!!$S!N!B$&`!!!$X!N!B$(J!!!$`!N!B$*`!!!$d!N!B$0J!
!!$i!N!B$2`!!!$m!N"%$!!#CQ3#3"(rr!*!%Irm!N!4rr`!!!!%"!!!"!3!"!!F
ZP5!!N!X"!!!!!J!!!!-!!!!%!!!!"3!!!!B!N(8(!3!"!3!"!3!!!!%!!!`!N!F
@EAGPFQYcAh"XG@GTEPpMEfjQD@FZD!#3#`%"!!%!N!i"!3%!!!%"!!%!!3%"!!!
"!3!"!!3!N!d"!3%!N"%"!!!!!J!!!!-!!!!%!!!!"3!!!!B!N(6r!*!(!`!!QCN
!N!4rr`#3"(rr!*!%Irm!!!!'!3%!!3%!!!!"!3%!!!!"!!!!!3#3"!F"!!%"!!%
"!!!!!3!!$!#3"aCYGf9bDh0IF'aeCfPZAf0[EQCTCbjS!*!,!3#3%3-!!!p+BAC
K3faKFh0PFbjUBA)!N""D59!J69GD8!#3"3%!$J#3"`%!N!3+99"*,R"bC@CTH!#
3&J%!N!8"!!%!N!m#!!%!(!#3'33!N!d$!!!25Q&fB80XBA0cCA-ZDQ&b!*!3@NP
3)%eA@P!!N!8"!!i!N!F"!*!%#P9355j`FQ9QDAJ!N"B"!*!&!3!"!!!!!`!!!!S
!!!!$!!!!#,&Q2'crrjJ%!*$r!*$r!*!A!J#3$!-#!3%"!!!"!3-"!*!*"3%!!!-
!!3#3$JJ!!!!#!!)!!!!&"!!!!`!"!!%k!*$r!*$r!!%!!!$rN!3!!!!#!!%!!6U
3"!#3r`#3r3%!!!$rN!3!!!!%!!)!!6T0CA4bEhGPFQYc)&0dB@jNBA*N)%aTBR*
KFRNk690-)%-k!*$r!*$H!3!!!2q3"%!!!!%!!J!"1NeKBdp6)&0eF("[FR3k!*$
r!*$b!3!!!2q3"%!!!!)!"3%!!!%!N2m!!!!"!!!*6@9bCf8J6h9d!*!f2j!%39"
36!!"!3!!"%4-4eKMDfPN8(*[DPG68%-!!J#3$!-#!!%"!!!"!3-"!*!*!J!!!!)
!!J#3*`)!N#%&!3!!!`!"!*!)H(JZ3dC00MK,!&0[GA*MCA-!6'PLFQ&bD@9c!(K
iE@pNG@aP,Q-!H(JZ3dC00MK,,V8ZCAK`!%e66#"6D%aTBP*eER4TE@9$4Ndf1%X
Z6'PL!&"jG'K[EN0[FQ9$4Ndf1%X!H(JZF("M!(Ki,R"`Bbke,Q9iF!"08d`J8fK
-D@*5G@jdD@eP,NaTBJ"3HA4SEfj$Eh*P8&"$!$TiH#j$4Ndf1%XZFfaL!%aTBL"
*EA"[FR3J0MK,!%e39b"*EA"[FR3J0MK,!%*KE'a[EfiJ5'9XF!"09b"$,d-V+b!
f1%X!69FJ8'&cBf&X)$Bi5`"09b"5CAS!8%9')%PYF'pbG#!f1'X!1RKi,R"`Bbj
cE')!6'PL)%PYF'pbG#"38%-!69FJ3bp$+bXJ8&"$!%eA)&"KFf0KE#"38%-!8&"
$3A0Y!&K$6dC')%PYF'pbG#"38%-!8%9')%PYF'pbG#"38%-!H(JZF(*U,Q9iF!"
3HA4SEfj$Eh*P!$T0Ef4eE'9c1RKiE@pNG@aP,Q-!1RKi,R"bDLjPH(!!1P"jG'K
[EN0[FQ8!6@&M6e-J0MK,)%aTEQYPFJ"0B@028b"38%-J6'PZDf9b!%0eFh4[E5"
,CAPhEh*NF`""Bf0PFh-J8'&dD(-!9'&bCf9d)&0PG(4TEQGc!%CTE'8J6@&`F'P
ZCh-!3R9TE'3J4AKdFQ&c!%4PBR9RCf9b)&4KFQGPG!!f1%XJ3fpNC8GPEJ!f1%X
J4'PcBA0cC@eLE'9b!$Bi5b"-D@jVCA)!0MK,)&"bEfTPBh3!3bp$+bXJ3fpYF'P
XCA)!3bp$+bXJ9f&bEQPZCh-!3dC00MK,!%P5)%p`G'PYDATPFJ"3BA0MB@`J3fp
YF'PXCA)!8'&cBf&X)&GKFQjTEQGc!&*PHL"$Efe`D@aPFJ"38%-J3fpNC8GPEJ"
38%-J4'PcBA0cC@eLE'9b!&"33b"-D@jVCA)!8&"$)&"&4J"38%-J8(*[DQ9MG!"
38%0"FfdJ8'&ZC@`!6e0"E5j$4Ndf1%X!1Np63@dZ3dC00MK,,R0XBJ"28d&Y,Q-
!6e0"E5jPH(!!8f0bDA"d8R9ZEQ9b,Q-!6e0"E5j`F'-!1Np63@dZF("M,R0XBJ"
*ER4PFQCKBf9-D@)!3A"`E'96Bh*TF(4-D@)!N*X#!!!!13%!!!)!N!N%!!%!!!!
kX@Bm2[rrk')!N2m!N2`q!J!!!J#3#33!!3!!!$qaCM`rrrqE$`#3r`#3qJJ!!!!
#!!)!!!!&"!!!"!!"!!%k!*$r!*$r!!%!!!$rN!3!!!!#!!%!!6U3"!#3r`#3r3%
!!!$rN!3!!!!%!!)!!6T0CA4bEhGPFQYc)&0dB@jNBA*N)%aTBR*KFRNk690-)%-
k!*$r!*$H!3!!!2q3"%!!!!)!!J!"1NeKBdp6)&0eF("[FR3k!*$r!*$b!3!!!2q
3"%!!!!-!"3%!!!%!N2m!!!!*!!!!B5j[GA3!N$SrN!4"8&"-!!!"J&L!!*"#2j!
%!*!*93'3!!%*!RX!N!i"J!#36`%!!!P0CA*RC5"2GA3!N$BrN!4"8&"-!!%"!!!
%4%a(@'0VD@43FQpU9e033`!#!!!!!J!#!*!R!J#3)3%!N$3"!*!BC'9QD@jPC#"
[FL"TFb!!!3%"!*!*!3%"!*!*!J!!#Nj26N&045j&@%8!N"C!!*!%"!#3"!3!!!3
!N!3%!&8"N!!"#3*l!*!,!J!!#Nj26N&045j&@%8!N"C!!*!%"!#3"!3!!!3!N!3
%!&8"N!!"#3*l!*!@2j!%39"36!!"!3!!"%4-4eKMDfPN8(*[DPG68%-!"3%!!!-
!!3#3#%8"!!!'!!!!!J!"!"`!N"X$!!)!+!#3(`%!N!F+!!!!!J#3"a)!!!!$!*!
((!!!!!3!N!FR!!!!"3#3"cF!!!!'!*!(8J!!!!F!N!GM!!!!#!#3"fS!!!!*!*!
(G`!!!!S!N!H-!!!!#`#3"jS!!!!-!*!(U3!!!!d!N!Hi!!!!$J#3"mF!!!!2!*!
(e!!!!"!!N!IK!!!!%3#3"qm!!!!5!*!(pJ!!!"-!N!B""3!!!"3!N!B"%3!!!"8
!N!B")!!!!"B!N!B",3!!!"F!N!B"1`!!!"J!N!B"3J!!!"N!N!B"8`!!!"S!N!B
"BJ!!!"X!N!B"E3!!!"`!N!B"H!!!!"d!N!B"M!!!!"i!N!B"Q!!!!"m!N!B"T!!
!!#!!N!B"Y3!!!#%!N!B"aJ!!!#)!N!B"eJ!!!#-!N!B"i`!!!#3!N!B"m`!!!#8
!N!B#!3!!!#B!N!B#$J!!!#F!N!B#(J!!!#J!N!B#+J!!!#N!N!B#1`!!!#S!N!B
#4J!!!#X!N!B#8J!!!#`!N!B#B3!!!#d!N!B#F!!!!#i!N!B#G`!!!#m!N!B#K!!
!!$!!N!B#P!!!!$%!N!B#T!!!!$)!N!B#X3!!!$-!N!B#[3!!!$3!N!B#cJ!!!$8
!N!B#f3!!!$B!N!B#i3!!!$F!N!B#l3!!!$J!N!B#qJ!!!$N!N!B$"J!!!$S!N!B
$&`!!!$X!N!B$(J!!!$`!N!B$*`!!!$d!N!B$0J!!!$i!N!B$2`!!!$m!N!B$63!
!!%!!N!B$@J!!!%%!N2m!N)N"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!
"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!C"`!!6@&M6e-
J0MK,)%aTEQYPFJ#3r`#3r`#3mNp63@dZ3dC00MK,!*$f!3!"1J#3r`#3r`#3"J%
!!3#3r`#3r`#3"`N!"!p28d&Y,N0'66Bi5bjcE')!N$"3HA4SFfKXBJ#35$q3"!#
3#98"N!!"#3*l!*!8!3#35J3!!3#3$J%!)!#3r`!!AepTEQPdD@&XDATP!*!eAh0
dBA*d!*!jAepdCA*YD@jKG'8!N$J"!!%!N2m!N2m!N2m!N#`9!3%!N!8$!*$r!*!
,!3#3"!J!N2m!N2m!N!4%4Na8$dePG(*[Gf9bDh-J5Q&fB3#3-%PZG'9bEQ9d)%9
iF'a[FQ9b!*$r!*$d4%C-9!#3r`!!"`%"!*!%!3#31fPZDA4iD@jTG(Ki!*"f#!!
"!*!)-XJ!!$,)!!!bb!CcG'4hD@i!N2`(!!"0B@028b"38%-J6'PZDf9b!*$r!*$
r!*$b6e0"E5j`F'-!N2N"!!%k!*$r!*$r!*!F!J'3"3!"!*!&690*43#3r`#3r`!
!D(4dF$S[,fTKGQ%ZFh9Z,Q0[E5p`FQpNG@0dFbpUC'X[-5ia,f4[Bh-[BA"T,`#
3d`8!!3aiH'e[C(9XC5jcE')!N"03@94)FfKXBJ#3F3%rN!3!N!F#!&!!!3!"!!%
!!3#3r`!8*d024%8R)#G%394"*b!R8%P$9#F!N1`%!!%!N%%#!!3!N%J"!!%!!!-
!!!!'!J%!N!8"!!)$!*!-!30Z!*!'!3!!"J!!!"`#!3#3"3%!!3-!N!`"!*!)!3!
!"`!!!$X#!3#3"3%!!3%!N!`"!*!)!3!!#!!!!$`#!3#3"3%!!3%!N!`"!*!)!3!
!#3!!!$d#!3#3"3%!!3%!N!`"!*!)!3!!#J!!!%!#!3#3"3%!!3-!N!`"!*!)!3!
!#`!!!%%#!3#3"3%!!3-!N!`"!*!3!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!
%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$
rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%
!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!
"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#
3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!
%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N"Mrr`#3)!%"!!$rN!3!N#!"!3!!rj!%!*!
C!3!"!*$r!*$r!*!9!3#3'3)!!!T16dj"688Z49K&!*!@3!#3"!3!N!3%!!!%!*!
%"!"9!C!!!3N#H`#3$3)!!!!J!!!!)3!#!!C0B@028b"38%-J6'PZDf9b!*!4'N&
38%`!N%"J!!!!3A"`E!#33'!!!!"068a#!*!J6'PL)%PYF'pbG#"38%-!N"C08%a
'!*!J6'PL)%PYF'pbG#"38%-!N"C09d0%!*"!B!!!!&*68N-!N%"J!!!!9%9B9#j
LD!"MbUY3!!-`b!!8VG!!!!&q!FUV8!!8CF!!!!,@3Q&XE'p[EL")C@a`!*!'(33
"bUZ!!"4P`!'(PY3!N!4849K8,Q-!N"j09b"$,d-V+b"38%-!N"K849K8,Q-V+`#
3(%eA)%-[3bXV)&"33`#3'&4&@&3ZBf-!N"e09b"$,d-V+b"38%-!N"K849K8,Q0
`!*!G69FJ3bp$+bXJ8&"$!*!B9%9B9#jMF(!!N"a09b"$,d-V+b"38%-!N"K849K
8,Q9iF!#33&4&@&3ZD!#3(NeA)%-[3bXV)&"33`#3&"!!!!"849K8,R!!N"j09b"
3BA0MB@`J8&"$!*!A9%9B9#j`BA-!N"a09b"3BA0MB@`J8&"$!*!A9%9B9#j`BfJ
!N"a09b"$,d-V+b"38%-!N"5!!!!!9%9B9#j`BfJV+`#3'NeA)%-[3bXV)&"33`#
3&)!!!!"849K8,R)!N"j09b"5CAS!N"j849K8,R-!D'2+Ue!!!c$)!"5Yd!!!!Ai
"bUY3!"4P`!!!!YC38%0"Ffd!EL")C@`!N!BG"!(+Ui!!&'A!!BH@e!#3"&K$6dB
!N#"B3dp'4L"*EA"[FR3J8&"$!*!8C'pMG3#33'!!!!"bFh*M!*"!B!!!!(0SE')
!N#"348BJ5@e`Eh*d)&"33`#3&R0dG@)!N#"348BJ5@e`Eh*d)&"33`#3'LjNEf-
!N$a3!!!!6@&M6e-J0MK,)%aTEQYPFJ#3%4T"8&"-!*"!B!!!!%&`F'`!N%"J!!!
!68e-3J#3)%aTBL"*EA"[FR3J0MK,!*!@69"-4J#3)%aTBL"*EA"[FR3J0MK,!*!
@69G$4!#33'!!!!"23NSJ!*!J69"A)%PYF'pbG#!f1%X!N"C58e*$!*"!B!!!!&4
&@&3ZBQJ!BmUV8!!$--J!&+h3!!!"IJ(+Ue!!&'A!!!!#eN*KE'a[EfiJ5'9XF!#
3"Kd%!FUVJ!!8CF!"KjE8!*!%9%9B9#jM!*!H69FJ3bp$+bXJ0MK,!*!B9%9B9#j
M+bX!N"a09b"$,d-V+b!f1%X!N"K849K8,Q0M!*!G69FJ3bp$+bXJ0MK,!*!B9%9
B9#jMF!#3(8eA)%-[3bXV)$Bi5`#3'&4&@&3ZBh"`!*!F69FJ3bp$+bXJ0MK,!*!
B9%9B9#jPH(!!bUY3!!-`b!!8VG!!!!&q!FUV8!!8CF!!!!,@!-FUG!aiUi!"bUj
%!"199!!!(33"bUZ!!"4P`!'(SM`!N!4849K8,QJ!N"j09b"$,d-V+b!f1%X!N"3
3!!!!9%9B9#j`!*!H69FJ8'&cBf&X)$Bi5`#3&e4&@&3ZF'&c!*!F69FJ8'&cBf&
X)$Bi5`#3&e4&@&3ZF'0S!*!F69FJ3bp$+bXJ0MK,!*!8J!!!!&4&@&3ZF'0S+bX
!N"T09b"$,d-V+b!f1%X!N"5!!!!!9%9B9#jb!*!H69FJ8Q9k!*!H9%9B9#jcC@F
!bUY3!!-`b!!8VG!!!!&q!FUV8!!8CF!!!!,@!-FUG!aiUi!"bUj%!"199!!!(33
"bUZ!!"4P`!'(SM`!N!4NEf0e!*"!B!!!!(*cFQ-!N%"J!!!!FfKXBJ#3)&"&4L"
*EA"[FR3J0MKV!*!@Fh4eBJ#3)&"&4L"*EA"[FR3J0MKV!*!D,Q4[B`#32&!!!!"
AD@ic-L"i1$BJ6'PZDf9b!*!4#94&@&3ZB`#3(NeA)%-[3bXV)(Ji0J#3'&4&@&3
ZBbXV!*!F69FJ3bp$+bXJH$Jf!*!B9%9B9#jMF!#3(8eA)%-[3bXV)(Ji0J#3'&4
&@&3ZBh"`!*!F69FJ3bp$+bXJH$Jf!*!B9%9B9#j`BfJ!N"a09b"$,d-V+b"i1$B
!N"5!!!!!9%9B9#j`BfJV+`#3'NeA)%-[3bXV)(Ji0J#3&)!!!!"849K8,R*M!*!
G69FJ9fPZ8N-!N#!ZE'PL!*!F6'PL)%PYF'pbG#"i1$B!N"SZEf*U!*!F6f*U)%P
YF'pbG#"i1$B!N"C03b"-D@jVCA)!N"J)68e$5!#34&4&@&3ZB`#3(Ne$)%-[3bX
V!*!F9%9B9#jME(-!N"a03b"$E'&cFb"$Efe`D@aPFJ#3$i!!!!"849K8,Q4PCJ#
33&4&@&3ZC'pM!*!m%!!!!&4&@&3ZD!#32K!!!!"849K8,R"MD!#3(%e$)%-[3bX
V!*!BJ!!!!&4&@&3ZG(-!N%&1EfjP!*!G!8e08()!N%"!!!!!6@&M6e-J6@9bCf8
!N"B(39"36!#33'!!!!""F("X!*"!B!!!!&*68N-!N%"J!!!!9%9B9#jLD!#3(8*
KE'a[EfiJ5'9XF!#3'&4&@&3ZFJ#3(P*PHJ#3)A*cFQ-!N%"J!!!!FfKXBJ#3433
!N"!"!*$r!*"%AepcG'&bG!#3I!%!!3#3r`#3r`#3r`#3,"8"!3#3"3-!N2m!N!X
"!*!%#!#3r`#3r`#3"%4'6&326@9dFQphCA*VFb"+BACK!*!`5@jdCA*ZCA3J4AK
`E'pbCA)!N2m!N24%4Na8!*$r!!!#!C!&!!%!N!908dP&!*$r!*$r!!"SG(4`1Lm
[DQ&fB5jcG@iZBfpY,h"bEf4eBh4c,fTNDbma,M%[C'pMFbpKF'N[!*$6"`%"!*!
%!9pID@jTG'PKE'PkC3#3EepIG'9bAepdCA*YD@jKG'8!N$%)!!%!N!JkMJ!!1Si
!!$U1!*$r!*!%"3!"$%p63@dZF("M,R0XBJ#3%e"jG'KcD'aL!*"a!6q3"!#3"`)
!8!!"!!%!!3!"!*$r!"3R3dp%45FJ*d4"9%%R)#G35808*`#3l!3!!3#333)!"!#
35!%!!J!!!`!!!!S#!3#3"3%!!3-!N!`"!fi!N!B#!!!'!!!!(!)"!*!&!3!"!`#
3$!%!N!J#!!!(!!!!1`)"!*!&!3!"!3#3$!%!N!J#!!!)!!!!2!)"!*!&!3!"!3#
3$!%!N!J#!!!*!!!!23)"!*!&!3!"!3#3$!%!N!J#!!!+!!!!3!)"!*!&!3!"!`#
3$!%!N!J#!!!,!!!!33)"!*!&!3!"!`#3$!%!N"!"!3!!rj!%!*!J!3%!!2q3"!#
3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!
%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$
rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%
!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!
"!3!!rj!%!*!J!3%!!2q3"!#3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#
3)!%"!!$rN!3!N#!"!3!!rj!%!*!J!3%!!2q3"!#3r`#3&d4'6&3!N2m!!!)"N!8
!!3#3"8e6588!N2m!N2m!!'KdG(!k,bpUBACK,R0eELjMEfd[F(*[C(9MG(-[DQ4
V,c%Z-5pNEf0c,f&`D5m!N0-%!!%!N%%#!!3!N%J"!*!%&`!!!#)!!`#3"5-!#!#
3"53!"`#3"58!!J#3"5B!"3#3"5F!!3#3"5J!"J#3"5N!!3#3"5S!"`#3"5X!#3#
3"5`!$!#3"5d!"!#3"5i!"!#3"5m!!3#3"6!!$J#3"6%!!J#3"6)!!J#3"6-!!`#
3"63!!3#3"68!"`#3"6B!#!#3"6F!"3#3"6J!!J!!!!)!"NeKBdp6)&"33b"-D@j
VCA)!N"%D39"36!#33'!!!!""F("X!*"!B!!!!%e06%)!N#"-D@)J5@e`Eh*d)&"
33`#3&Ne36%B!N#"-D@)J5@e`Eh*d)&"33`#3&NeA3d3!N%"J!!!!8P053`#33'!
!!!"849K8,Q*S!'2&ET!!!!-`b!!8VH!!!!&j!F9ZN!!!&'A3!!!#eN*KE'a[Efi
J5'9XF!#3"L@a!F9Z`!!8CG!"JPD8!*!%9%9B9#jM!*!H69FJ3bp$+bXJ8&"$!*!
B9%9B9#jM+bX!N"a09b"$,d-V+b"38%-!N"K849K8,Q0M!*!G69FJ3bp$+bXJ8&"
$!*!B9%9B9#jMF!#3(8eA)%-[3bXV)&"33`#3'&4&@&3ZBh"`!*!F69FJ3bp$+bX
J8&"$!*!B9%9B9#jPH(!!a@k3!!!$--J!&+hJ!!!"H3(&ET!!!"4Pd!!!!YB!8Q9
kYLKZ`!(&FB3!N!BPX3(&EX!!&'A3!B*Kr!#3"&4&@&3ZD!#3(NeA)%-[3bXV)&"
33`#3&"!!!!"849K8,R!!N"j09b"3BA0MB@`J8&"$!*!A9%9B9#j`BA-!N"a09b"
3BA0MB@`J8&"$!*!A9%9B9#j`BfJ!N"a09b"$,d-V+b"38%-!N"5!!!!!9%9B9#j
`BfJV+`#3'NeA)%-[3bXV)&"33`#3&)!!!!"849K8,R)!N"j09b"5CAS!N"j849K
8,R-!D'2&ET!!!!-`b!!8VH!!!!&j!F9ZN!!!&'A3!!!#eP"33d&cE3"Z)%KPE!#
3"L@a!F9Z`!!8CG!"JPD8!*!%@%024J#3)&K$6dC')%PYF'pbG#"38%-!N"4NEf0
e!*"!B!!!!(*cFQ-!N%"J!!!!FfKXBJ#3)&"&4L"*EA"[FR3J8&"$!*!@Fh4eBJ#
3)&"&4L"*EA"[FR3J8&"$!*!D,Q4[B`#32&!!!!"0B@028b!f1%XJ6'PZDf9b!*!
4'N&38%`!N%"J!!!!3A"`E!#33'!!!!"068a#!*!J6'PL)%PYF'pbG#!f1%X!N"C
08%a'!*!J6'PL)%PYF'pbG#!f1%X!N"C09d0%!*"!B!!!!%p#5L!!N#"08&FJ5@e
`Eh*d)$Bi5`#3&P*68N-!N%"J!!!!9%9B9#jLD!"MhJ!#&,a!J*S+!80Uj3%j9'm
!!!!"!*!%!80#B@aXEfpZ)%KPE(!!bJ&U!)J"194Z!80Uj!!j!@K-FJ#3"&4&@&3
ZB`#3(NeA)%-[3bXV)$Bi5`#3'&4&@&3ZBbXV!*!F69FJ3bp$+bXJ0MK,!*!B9%9
B9#jMB`#3(8eA)%-[3bXV)$Bi5`#3'&4&@&3ZBh!!N"e09b"$,d-V+b!f1%X!N"K
849K8,Q0`F!#3(%eA)%-[3bXV)$Bi5`#3'&4&@&3ZCAK`!,a!J*S+!6PAl`&$Bpm
!N!J"3f2H)!3!1J%k,S!"1&!L!3!!!!&$Bpi"19IZ!Hi!N!B4!*!&9%9B9#jS!*!
H69FJ3bp$+bXJ0MK,!*!8%!!!!&4&@&3ZF!#3(NeA)&"KFf0KE#!f1%X!N"G849K
8,R"KF`#3(%eA)&"KFf0KE#!f1%X!N"G849K8,R"MD!#3(%eA)%-[3bXV)$Bi5`#
3&)!!!!"849K8,R"MD#XV!*!D69FJ3bp$+bXJ0MK,!*!8J!!!!&4&@&3ZFJ#3(Ne
A)&*PHJ#3(P4&@&3ZFf9R!,a!J*S+!6PAl`&$Bpm!N!J"3f2H)!3!1J%k,S!"1&!
L!3!!!!&$Bpi"19IZ!Hi!N!B4!*!&C'pMG3#33'!!!!"bFh*M!*"!B!!!!(0SE')
!N#"348BJ5@e`Eh*d)$BiD`#3&R0dG@)!N#"348BJ5@e`Eh*d)$BiD`#3'LjNEf-
!N$a3!!!!9fPZ-c)JH$Jf)%aTEQYPFJ#3%3P849K8,Q-!N"j09b"$,d-V+b"i1$B
!N"K849K8,Q-V+`#3(%eA)%-[3bXV)(Ji0J#3'&4&@&3ZBh!!N"e09b"$,d-V+b"
i1$B!N"K849K8,Q0`F!#3(%eA)%-[3bXV)(Ji0J#3'&4&@&3ZF'0S!*!F69FJ3bp
$+bXJH$Jf!*!8J!!!!&4&@&3ZF'0S+bX!N"T09b"$,d-V+b"i1$B!N"5!!!!!9%9
B9#jbB`#3(8eA)&GTEP*$!*!J,QaTBJ#3(%aTBL"*EA"[FR3JH$Jf!*!D,QpLDJ#
3(%pLDL"*EA"[FR3JH$Jf!*!@68-J6'PZDf9b!*!B#%e03dJ!N%4849K8,Q-!N"j
03b"$,d-V+`#3(&4&@&3ZBfac!*!F68-J3faKFh-J3fpYF'PXCA)!N!q!!!!!9%9
B9#jNC@B!N%"849K8,Q4[B`#32"!!!!"849K8,QJ!N$i3!!!!9%9B9#j`BfJ!N"a
03b"$,d-V+`#3')!!!!"849K8,R4c!*""6QpZC3#3(3&069"b!*"!3!!!!%eKBdp
6)%ePFQGP!*!@"d&38%`!N%"J!!!!3A"`E!#33'!!!!"58e*$!*"!B!!!!&4&@&3
ZBQJ!N"e#B@aXEfpZ)%KPE(!!N"K849K8,R)!N"j5CAS!N#&bFh*M!*"!B!!!!(0
SE')!N%B$[`!!%!"YFh4b!*!1%lm!!!H!EA0dE!#3$KXr!!!#J'ecG'i!N!i"`!!
!!#KYFh4T!*!1-GB!!!3!EA0dFJ!!!qJ!N!T'S3!!")"YFh4X!!!$k!#3#Kkr!!!
"J'ecG'i!!!2S!*!+!bF!!!!+F(*PCJ#Ja-S!!!!"!*!'!c%!!!!`F(*PCJ#J[K3
!!!!#!*!'!f%!!!"+F(*PCJ#J,r`!!!!$!*!'!kX!!!!8F(*PCJ#JMdd!!!!%!*!
'4Q%!!!"!EA4cE!!!!!%!N!T[(3!!"D"YG("X!!!!!3#3#J(S!!!!('edE'm!!!!
"!*!+!J3!!!!3EA4`D3!!!!%!N!S"+!!!!!T`FQ9Q!+$U+`!!!"S!N!B"-J!!!$"
`FQ9Q!+!%S3!!!"X!N!B"BJ!!!%T`FQ9Q!+!K$!!!!"`!N!B"V!!!!"4`FQ9Q!+$
k[J!!!"d!N!BNSJ!!!#"YG(0X!!!!!J#3#U(&!!!&S'edF'`!!!!#!*!+!K3!!!!
FEA4XE`!!!!)!N!S#-!!!!""YG("T!!!!!J#3#MA@!!!%0'edCf`!!!2S!*!+*6S
!!!)XEA"cD3!!!qJ!N!SG[`!!!-"36(0d!+!$I!!!!$-!N!B#3!!!!#KYFh4T!!!
$k!#3#J*S!!!!N!"YG("c!!!!!3#3#L!r!!!!N!"YG("c!!!!!J#3#RHK!!!!$'e
KE'`!N!kY#`!!!,aYBA"X!*!1)l!!!!!DF(*PCJ!rkbJ!!!"1!*!'*j`!!!K3F(*
PCJ"!$`-!!!"2!*!'6%%!!!B-F(*PCJ"!#r!!!!"3!*!'VFF!!"CiF(*PCJ"!2@%
!!!"4!*!',q`!!!%(F(*PCJ"!0B!!!!"5!*!'8Nd!!!))F(*PCJ!rk"i!!!"6!*!
')mS!!!!BF(*PCJ!rMGB!!!"8!*!'!a!!!!!+F(*PCJ!r@[m!!!"9!*!')q)!!!!
1F(*PCJ!rQAX!!!"@!*!'9&8!!!%'F(*PCJ!rJFX!!!"A!*!')r!!!!!mF(*PCJ!
r8%J!!!"B!*!'*-)!!!!1F(*PCJ!rcC)!!!"C!*!'99X!!!(DF(*PCJ!r9+8!!!"
D!*!'9c8!!!-bF(*PCJ!rA'`!!!"E!*!'!aS!!!!-F(*PCJ!rm0N!!!"F!*!'@QF
!!!%3F(*PCJ!rK!J!!!"G!*!'*0!!!!!bF(*PCJ"!3BS!!!"H!*!'@hF!!!93F(*
PCJ"!'Zi!!!"I!*!'D-8!!!-5F(*PCJ"!,N`!!!"J!*!'-2-!!!"LF(*PCJ!rZ@S
!!!"K!*!'*3)!!!!iF(*PCJ"!(Z)!!!"L!*!'-98!!!!0F(*PCJ!rY68!!!"M!*!
'-@)!!!!8F(*PCJ!rrHB!!!"N!*!')[-!!!!+F(*PCJ"!*4X!!!"P!*!'B-F!!!$
%F(*PCJ"!6f!!!!"Q!*!'BBX!!!%BF(*PCJ!r8CN!!!"R!*!'DpF!!!#SF(*PCJ"
!5ZS!!!"S!*!'-AB!!!!ZF(*PCJ!rCL!!!!"T!*!'E(m!!!)-F(*PCJ!rdYd!!!"
U!*!'-D3!!!!LF(*PCJ!rffm!!!"V!*!'-FB!!!!3F(*PCJ!rIMJ!!!"X!*!'48i
!!!!DF(*PCJ!re$F!!!"Y!*!'ESX!!!#5F(*PCJ!rT`#3"'i!N!C&MJ!!!%T`FQ9
Q!%!PP!!!!'m!N!BKi`!!!"T`FQ9Q!$q4R`!!!(!!N!Bk#J!!#&"`FQ9Q!%!PI`!
!!(%!N!CLS`!!"Ja`FQ9Q!$p[*`!!!()!N!ChV3!!&RK`FQ9Q!%!NAJ!!!(-!N!C
#@J!!!3G`FQ9Q!$ppZJ!!!(3!N!Ce*`!!!JK`FQ9Q!%!$%!!!!(8!N!BHT`!!!"K
`FQ9Q!$qq5`!!!(B!N!BKr3!!!!T`FQ9Q!%!9T3!!!(F!N!BLR`!!!!j`FQ9Q!$r
CV3!!!(J!N!C$B3!!!3C`FQ9Q!$r8CJ!!!(N!N!BLV3!!!$a`FQ9Q!%!MP!!!!(S
!N!BLr3!!!!j`FQ9Q!$qhFJ!!!(X!N!D1*3!!!GT`FQ9Q!$pd93!!!(`!N!D2r`!
!!c*`FQ9Q!%"41`!!!(d!N!BM#`!!!!a`FQ9Q!$r@)!!!!(i!N!D6-3!!!4"`FQ9
Q!$qC@!!!!(m!N!BN,!!!!$*`FQ9Q!%!DXJ!!!)!!N!D833!!"9"`FQ9Q!%"IJ3!
!!)%!N!DCN3!!!a*`FQ9Q!$r)Z3!!!))!N!C%C`!!!'*`FQ9Q!$qkI!!!!)-!N!B
NAJ!!!$K`FQ9Q!$qX'`!!!)3!N!BRCJ!!!!e`FQ9Q!$qk(J!!!)8!N!BRF`!!!"4
`FQ9Q!$qEi3!!!)B!N!BLk3!!!!T`FQ9Q!%"(#3!!!)F!N!DFS`!!!-4`FQ9Q!%!
Vh`!!!)J!N!DGC`!!!4K`FQ9Q!$rP`!!!!)N!N!DHI`!!!+K`FQ9Q!%!`-J!!!)S
!N!C%b3!!!#j`FQ9Q!$qiXJ!!!)X!N!DI*`!!!Ja`FQ9Q!%!Y3!!!!)`!N!C%p`!
!!#*`FQ9Q!%!r(J!!!)d!N!BRK`!!!""`FQ9Q!$pS)J!!!)i!N!C&'3!!!"T`FQ9
Q!%!J1`!!!)m!N!DK-`!!!**`FQ9Q!$paGJ!!!*!!!*!'4GJ!!!"+F(*PCJ!rGJ8
!!!#4!*!%H3N!!!:

View File

@ -0,0 +1,289 @@
/*
*
* 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;
}

View File

@ -0,0 +1,30 @@
/*
*
* 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>
*
*
*/
#pragma once
#include <OSA.h>
OSAError CompileAndExecute (const char *text,
AEDesc *result,
OSAActiveUPP proc);
OSAError CompileAndSave (const char *text,
const char *outfile,
OSAActiveUPP proc,
AEDesc *result);
OSAError ExecuteScriptFile (const char *theFile,
OSAActiveUPP proc,
AEDesc *result);