mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 02:15:10 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			406 lines
		
	
	
	
		
			9.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			406 lines
		
	
	
	
		
			9.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """
 | |
| 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)
 | 
