mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	
		
			
	
	
		
			407 lines
		
	
	
	
		
			9.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			407 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) |