2 gensuitemodule - Generate an AE suite module from an aete/aeut resource
6 Reading and understanding this code is left as an exercise to the reader.
18 from Carbon
.Res
import *
21 fss
, ok
= macfs
.PromptGetFile('Select file with aeut/aete resource:')
24 processfile(fss
.as_pathname())
26 def processfile(fullname
):
27 """Process all resources in a single file"""
30 rf
= OpenRFPerm(fullname
, 0, 1)
34 for i
in range(Count1Resources('aete')):
35 res
= Get1IndResource('aete', 1+i
)
37 for i
in range(Count1Resources('aeut')):
38 res
= Get1IndResource('aeut', 1+i
)
40 print "\nLISTING aete+aeut RESOURCES IN", `fullname`
43 print "decoding", res
.GetResInfo(), "..."
46 aetelist
.append((aete
, res
.GetResInfo()))
51 # switch back (needed for dialogs in Python)
53 compileaetelist(aetelist
, fullname
)
55 def compileaetelist(aetelist
, fullname
):
56 for aete
, resinfo
in aetelist
:
57 compileaete(aete
, resinfo
, fullname
)
60 """Decode a resource into a python data structure"""
61 f
= StringIO
.StringIO(data
)
62 aete
= generic(getaete
, f
)
65 unprocessed
= len(f
.read())
68 sys
.stderr
.write("%d processed + %d unprocessed = %d total\n" %
69 (processed
, unprocessed
, total
))
73 """Recursively replace singleton tuples by their constituent item"""
74 if type(item
) is types
.ListType
:
75 return map(simplify
, item
)
76 elif type(item
) == types
.TupleType
and len(item
) == 2:
77 return simplify(item
[1])
82 # Here follows the aete resource decoder.
83 # It is presented bottom-up instead of top-down because there are direct
84 # references to the lower-level part-decoders from the high-level part-decoders.
86 def getbyte(f
, *args
):
89 raise EOFError, 'in getbyte' + str(args
)
92 def getword(f
, *args
):
96 raise EOFError, 'in getword' + str(args
)
97 return (ord(s
[0])<<8) |
ord(s
[1])
99 def getlong(f
, *args
):
103 raise EOFError, 'in getlong' + str(args
)
104 return (ord(s
[0])<<24) |
(ord(s
[1])<<16) |
(ord(s
[2])<<8) |
ord(s
[3])
106 def getostype(f
, *args
):
110 raise EOFError, 'in getostype' + str(args
)
113 def getpstr(f
, *args
):
116 raise EOFError, 'in getpstr[1]' + str(args
)
118 if nbytes
== 0: return ''
121 raise EOFError, 'in getpstr[2]' + str(args
)
128 ## print 'align:', `c`
130 def getlist(f
, description
, getitem
):
133 for i
in range(count
):
134 list.append(generic(getitem
, f
))
138 def alt_generic(what
, f
, *args
):
139 print "generic", `what`
, args
140 res
= vageneric(what
, f
, args
)
144 def generic(what
, f
, *args
):
145 if type(what
) == types
.FunctionType
:
146 return apply(what
, (f
,) + args
)
147 if type(what
) == types
.ListType
:
150 item
= apply(generic
, thing
[:1] + (f
,) + thing
[1:])
151 record
.append((thing
[1], item
))
153 return "BAD GENERIC ARGS: %s" % `what`
157 (getpstr
, "description"),
162 (getostype
, "keyword"),
167 (getpstr
, "description"),
168 (getostype
, "suite code"),
169 (getostype
, "event code"),
170 (getdata
, "returns"),
171 (getdata
, "accepts"),
172 (getlist
, "optional arguments", getargument
)
181 (getlist
, "keyform", getostype
)
185 (getostype
, "class code"),
186 (getpstr
, "description"),
187 (getlist
, "properties", getproperty
),
188 (getlist
, "elements", getelement
)
191 (getpstr
, "operator name"),
192 (getostype
, "operator ID"),
193 (getpstr
, "operator comment"),
196 (getpstr
, "enumerator name"),
197 (getostype
, "enumerator ID"),
198 (getpstr
, "enumerator comment")
201 (getostype
, "enumeration ID"),
202 (getlist
, "enumerator", getenumerator
)
205 (getpstr
, "suite name"),
206 (getpstr
, "suite description"),
207 (getostype
, "suite ID"),
208 (getword
, "suite level"),
209 (getword
, "suite version"),
210 (getlist
, "events", getevent
),
211 (getlist
, "classes", getclass
),
212 (getlist
, "comparisons", getcomparison
),
213 (getlist
, "enumerations", getenumeration
)
216 (getword
, "major/minor version in BCD"),
217 (getword
, "language code"),
218 (getword
, "script code"),
219 (getlist
, "suites", getsuite
)
222 def compileaete(aete
, resinfo
, fname
):
223 """Generate code for a full aete resource. fname passed for doc purposes"""
224 [version
, language
, script
, suites
] = aete
225 major
, minor
= divmod(version
, 256)
226 fss
= macfs
.FSSpec(fname
)
227 creatorsignature
, dummy
= fss
.GetCreatorType()
228 packagename
= identify(os
.path
.basename(fname
))
230 packagename
= packagename
+'_lang%d'%language
232 packagename
= packagename
+'_script%d'%script
233 if len(packagename
) > 27:
234 packagename
= packagename
[:27]
235 macfs
.SetFolder(os
.path
.join(sys
.prefix
, ':Mac:Lib:lib-scriptpackages'))
236 fss
, ok
= macfs
.GetDirectory('Package folder for %s'%packagename
)
239 pathname
= fss
.as_pathname()
240 packagename
= os
.path
.split(os
.path
.normpath(pathname
))[1]
241 fss
, ok
= macfs
.GetDirectory('Package folder for base suite (usually StdSuites)')
243 dirname
, basepkgname
= os
.path
.split(os
.path
.normpath(fss
.as_pathname()))
244 if not dirname
in sys
.path
:
245 sys
.path
.insert(0, dirname
)
246 basepackage
= __import__(basepkgname
)
249 macfs
.SetFolder(pathname
)
254 code
, suite
, fss
, modname
, precompinfo
= precompilesuite(suite
, basepackage
)
257 allprecompinfo
= allprecompinfo
+ precompinfo
258 suiteinfo
= suite
, fss
, modname
259 suitelist
.append((code
, modname
))
260 allsuites
.append(suiteinfo
)
261 for suiteinfo
in allsuites
:
262 compilesuite(suiteinfo
, major
, minor
, language
, script
, fname
, basepackage
, allprecompinfo
)
263 fss
, ok
= macfs
.StandardPutFile('Package module', '__init__.py')
266 fp
= open(fss
.as_pathname(), 'w')
267 fss
.SetCreatorType('Pyth', 'TEXT')
269 fp
.write("Package generated from %s\n"%fname
)
270 fp
.write("Resource %s resid %d %s\n"%(resinfo
[1], resinfo
[0], resinfo
[2]))
272 fp
.write('import aetools\n')
273 fp
.write('Error = aetools.Error\n')
274 for code
, modname
in suitelist
:
275 fp
.write("import %s\n" % modname
)
276 fp
.write("\n\n_code_to_module = {\n")
277 for code
, modname
in suitelist
:
278 fp
.write("\t'%s' : %s,\n"%(code
, modname
))
280 fp
.write("\n\n_code_to_fullname = {\n")
281 for code
, modname
in suitelist
:
282 fp
.write("\t'%s' : ('%s.%s', '%s'),\n"%(code
, packagename
, modname
, modname
))
284 for code
, modname
in suitelist
:
285 fp
.write("from %s import *\n"%modname
)
287 fp
.write("\n\nclass %s(%s_Events"%(packagename
, suitelist
[0][1]))
288 for code
, modname
in suitelist
[1:]:
289 fp
.write(",\n\t\t%s_Events"%modname
)
290 fp
.write(",\n\t\taetools.TalkTo):\n")
291 fp
.write("\t_signature = '%s'\n\n"%creatorsignature
)
294 def precompilesuite(suite
, basepackage
=None):
295 """Parse a single suite without generating the output. This step is needed
296 so we can resolve recursive references by suites to enums/comps/etc declared
298 [name
, desc
, code
, level
, version
, events
, classes
, comps
, enums
] = suite
300 modname
= identify(name
)
301 if len(modname
) > 28:
302 modname
= modname
[:27]
303 fss
, ok
= macfs
.StandardPutFile('Python output file', modname
+'.py')
305 return None, None, None, None, None
307 pathname
= fss
.as_pathname()
308 modname
= os
.path
.splitext(os
.path
.split(pathname
)[1])[0]
310 if basepackage
and basepackage
._code
_to
_module
.has_key(code
):
311 # We are an extension of a baseclass (usually an application extending
312 # Standard_Suite or so). Import everything from our base module
313 basemodule
= basepackage
._code
_to
_module
[code
]
315 # We are not an extension.
320 findenumsinevent(event
, enumsneeded
)
322 objc
= ObjectCompiler(None, basemodule
)
324 objc
.compileclass(cls
)
326 objc
.fillclasspropsandelems(cls
)
328 objc
.compilecomparison(comp
)
330 objc
.compileenumeration(enum
)
332 for enum
in enumsneeded
.keys():
333 objc
.checkforenum(enum
)
337 precompinfo
= objc
.getprecompinfo(modname
)
339 return code
, suite
, fss
, modname
, precompinfo
341 def compilesuite((suite
, fss
, modname
), major
, minor
, language
, script
, fname
, basepackage
, precompinfo
):
342 """Generate code for a single suite"""
343 [name
, desc
, code
, level
, version
, events
, classes
, comps
, enums
] = suite
345 pathname
= fss
.as_pathname()
346 fp
= open(fss
.as_pathname(), 'w')
347 fss
.SetCreatorType('Pyth', 'TEXT')
349 fp
.write('"""Suite %s: %s\n' % (name
, desc
))
350 fp
.write("Level %d, version %d\n\n" % (level
, version
))
351 fp
.write("Generated from %s\n"%fname
)
352 fp
.write("AETE/AEUT resource version %d/%d, language %d, script %d\n" % \
353 (major
, minor
, language
, script
))
356 fp
.write('import aetools\n')
357 fp
.write('import MacOS\n\n')
358 fp
.write("_code = %s\n\n"% `code`
)
359 if basepackage
and basepackage
._code
_to
_module
.has_key(code
):
360 # We are an extension of a baseclass (usually an application extending
361 # Standard_Suite or so). Import everything from our base module
362 fp
.write('from %s import *\n'%basepackage
._code
_to
_fullname
[code
][0])
363 basemodule
= basepackage
._code
_to
_module
[code
]
364 elif basepackage
and basepackage
._code
_to
_module
.has_key(code
.lower()):
365 # This is needed by CodeWarrior and some others.
366 fp
.write('from %s import *\n'%basepackage
._code
_to
_fullname
[code
.lower()][0])
367 basemodule
= basepackage
._code
_to
_module
[code
.lower()]
369 # We are not an extension.
371 compileclassheader(fp
, modname
, basemodule
)
376 compileevent(fp
, event
, enumsneeded
)
378 fp
.write("\tpass\n\n")
380 objc
= ObjectCompiler(fp
, basemodule
, precompinfo
)
382 objc
.compileclass(cls
)
384 objc
.fillclasspropsandelems(cls
)
386 objc
.compilecomparison(comp
)
388 objc
.compileenumeration(enum
)
390 for enum
in enumsneeded
.keys():
391 objc
.checkforenum(enum
)
397 def compileclassheader(fp
, name
, module
=None):
398 """Generate class boilerplate"""
399 classname
= '%s_Events'%name
401 modshortname
= string
.split(module
.__name
__, '.')[-1]
402 baseclassname
= '%s_Events'%modshortname
403 fp
.write("class %s(%s):\n\n"%(classname
, baseclassname
))
405 fp
.write("class %s:\n\n"%classname
)
407 def compileevent(fp
, event
, enumsneeded
):
408 """Generate code for a single event"""
409 [name
, desc
, code
, subcode
, returns
, accepts
, arguments
] = event
410 funcname
= identify(name
)
412 # generate name->keyword map
415 fp
.write("\t_argmap_%s = {\n"%funcname
)
417 fp
.write("\t\t%s : %s,\n"%(`
identify(a
[0])`
, `a
[1]`
))
421 # Generate function header
423 has_arg
= (not is_null(accepts
))
424 opt_arg
= (has_arg
and is_optional(accepts
))
426 fp
.write("\tdef %s(self, "%funcname
)
429 fp
.write("_object, ") # Include direct object, if it has one
431 fp
.write("_object=None, ") # Also include if it is optional
433 fp
.write("_no_object=None, ") # For argument checking
434 fp
.write("_attributes={}, **_arguments):\n") # include attribute dict and args
436 # Generate doc string (important, since it may be the only
437 # available documentation, due to our name-remaping)
439 fp
.write('\t\t"""%s: %s\n'%(name
, desc
))
441 fp
.write("\t\tRequired argument: %s\n"%getdatadoc
(accepts
))
443 fp
.write("\t\tOptional argument: %s\n"%getdatadoc
(accepts
))
444 for arg
in arguments
:
445 fp
.write("\t\tKeyword argument %s: %s\n"%(identify(arg
[0]),
447 fp
.write("\t\tKeyword argument _attributes: AppleEvent attribute dictionary\n")
448 if not is_null(returns
):
449 fp
.write("\t\tReturns: %s\n"%getdatadoc
(returns
))
450 fp
.write('\t\t"""\n')
452 # Fiddle the args so everything ends up in 'arguments' dictionary
454 fp
.write("\t\t_code = %s\n"% `code`
)
455 fp
.write("\t\t_subcode = %s\n\n"% `subcode`
)
457 # Do keyword name substitution
460 fp
.write("\t\taetools.keysubst(_arguments, self._argmap_%s)\n"%funcname
)
462 fp
.write("\t\tif _arguments: raise TypeError, 'No optional args expected'\n")
464 # Stuff required arg (if there is one) into arguments
467 fp
.write("\t\t_arguments['----'] = _object\n")
469 fp
.write("\t\tif _object:\n")
470 fp
.write("\t\t\t_arguments['----'] = _object\n")
472 fp
.write("\t\tif _no_object != None: raise TypeError, 'No direct arg expected'\n")
475 # Do enum-name substitution
482 fp
.write("\t\taetools.enumsubst(_arguments, %s, _Enum_%s)\n" %
483 (`kname`
, identify(ename
)))
484 enumsneeded
[ename
] = 1
489 fp
.write("\t\t_reply, _arguments, _attributes = self.send(_code, _subcode,\n")
490 fp
.write("\t\t\t\t_arguments, _attributes)\n")
494 fp
.write("\t\tif _arguments.has_key('errn'):\n")
495 fp
.write("\t\t\traise aetools.Error, aetools.decodeerror(_arguments)\n")
496 fp
.write("\t\t# XXXX Optionally decode result\n")
500 fp
.write("\t\tif _arguments.has_key('----'):\n")
502 fp
.write("\t\t\t# XXXX Should do enum remapping here...\n")
503 fp
.write("\t\t\treturn _arguments['----']\n")
506 # print "\n# Command %s -- %s (%s, %s)" % (`name`, `desc`, `code`, `subcode`)
507 # print "# returns", compiledata(returns)
508 # print "# accepts", compiledata(accepts)
509 # for arg in arguments:
510 # compileargument(arg)
512 def compileargument(arg
):
513 [name
, keyword
, what
] = arg
514 print "# %s (%s)" % (name
, `keyword`
), compiledata(what
)
516 def findenumsinevent(event
, enumsneeded
):
517 """Find all enums for a single event"""
518 [name
, desc
, code
, subcode
, returns
, accepts
, arguments
] = event
523 enumsneeded
[ename
] = 1
526 # This class stores the code<->name translations for a single module. It is used
527 # to keep the information while we're compiling the module, but we also keep these objects
528 # around so if one suite refers to, say, an enum in another suite we know where to
529 # find it. Finally, if we really can't find a code, the user can add modules by
532 class CodeNameMapper
:
547 self
.modulename
= None
548 self
.star_imported
= 0
550 def addnamecode(self
, type, name
, code
):
551 self
.name2code
[type][name
] = code
552 if not self
.code2name
[type].has_key(code
):
553 self
.code2name
[type][code
] = name
555 def hasname(self
, type, name
):
556 return self
.name2code
[type].has_key(name
)
558 def hascode(self
, type, code
):
559 return self
.code2name
[type].has_key(code
)
561 def findcodename(self
, type, code
):
562 if not self
.hascode(type, code
):
563 return None, None, None
564 name
= self
.code2name
[type][code
]
565 if self
.modulename
and not self
.star_imported
:
566 qualname
= '%s.%s'%(self
.modulename
, name
)
569 return name
, qualname
, self
.modulename
571 def getall(self
, type):
572 return self
.code2name
[type].items()
574 def addmodule(self
, module
, name
, star_imported
):
575 self
.modulename
= name
576 self
.star_imported
= star_imported
577 for code
, name
in module
._propdeclarations
.items():
578 self
.addnamecode('property', name
, code
)
579 for code
, name
in module
._classdeclarations
.items():
580 self
.addnamecode('class', name
, code
)
581 for code
in module
._enumdeclarations
.keys():
582 self
.addnamecode('enum', '_Enum_'+identify(code
), code
)
583 for code
, name
in module
._compdeclarations
.items():
584 self
.addnamecode('comparison', name
, code
)
586 def prepareforexport(self
, name
=None):
587 if not self
.modulename
:
588 self
.modulename
= name
591 class ObjectCompiler
:
592 def __init__(self
, fp
, basesuite
=None, othernamemappers
=None):
594 self
.basesuite
= basesuite
595 self
.namemappers
= [CodeNameMapper()]
597 self
.othernamemappers
= othernamemappers
[:]
599 self
.othernamemappers
= []
601 basemapper
= CodeNameMapper()
602 basemapper
.addmodule(basesuite
, '', 1)
603 self
.namemappers
.append(basemapper
)
605 def getprecompinfo(self
, modname
):
607 for mapper
in self
.namemappers
:
608 emapper
= mapper
.prepareforexport(modname
)
613 def findcodename(self
, type, code
):
615 # First try: check whether we already know about this code.
616 for mapper
in self
.namemappers
:
617 if mapper
.hascode(type, code
):
618 return mapper
.findcodename(type, code
)
619 # Second try: maybe one of the other modules knows about it.
620 for mapper
in self
.othernamemappers
:
621 if mapper
.hascode(type, code
):
622 self
.othernamemappers
.remove(mapper
)
623 self
.namemappers
.append(mapper
)
625 self
.fp
.write("import %s\n"%mapper
.modulename
)
628 # If all this has failed we ask the user for a guess on where it could
631 m
= self
.askdefinitionmodule(type, code
)
634 if not m
: return None, None, None
635 mapper
= CodeNameMapper()
636 mapper
.addmodule(m
, m
.__name
__, 0)
637 self
.namemappers
.append(mapper
)
639 def askdefinitionmodule(self
, type, code
):
640 fss
, ok
= macfs
.PromptGetFile('Where is %s %s declared?'%(type, code
))
642 path
, file = os
.path
.split(fss
.as_pathname())
643 modname
= os
.path
.splitext(file)[0]
644 if not path
in sys
.path
:
645 sys
.path
.insert(0, path
)
646 m
= __import__(modname
)
647 self
.fp
.write("import %s\n"%modname
)
650 def compileclass(self
, cls
):
651 [name
, code
, desc
, properties
, elements
] = cls
652 pname
= identify(name
)
653 if self
.namemappers
[0].hascode('class', code
):
654 # plural forms and such
655 othername
, dummy
, dummy
= self
.namemappers
[0].findcodename('class', code
)
657 self
.fp
.write("\n%s = %s\n"%(pname
, othername
))
660 self
.fp
.write('\nclass %s(aetools.ComponentItem):\n' % pname
)
661 self
.fp
.write('\t"""%s - %s """\n' % (name
, desc
))
662 self
.fp
.write('\twant = %s\n' % `code`
)
663 self
.namemappers
[0].addnamecode('class', pname
, code
)
664 for prop
in properties
:
665 self
.compileproperty(prop
)
666 for elem
in elements
:
667 self
.compileelement(elem
)
669 def compileproperty(self
, prop
):
670 [name
, code
, what
] = prop
672 # Something silly with plurals. Skip it.
674 pname
= identify(name
)
675 if self
.namemappers
[0].hascode('property', code
):
676 # plural forms and such
677 othername
, dummy
, dummy
= self
.namemappers
[0].findcodename('property', code
)
678 if pname
== othername
:
681 self
.fp
.write("\n%s = %s\n"%(pname
, othername
))
684 self
.fp
.write("class %s(aetools.NProperty):\n" % pname
)
685 self
.fp
.write('\t"""%s - %s """\n' % (name
, what
[1]))
686 self
.fp
.write("\twhich = %s\n" % `code`
)
687 self
.fp
.write("\twant = %s\n" % `what
[0]`
)
688 self
.namemappers
[0].addnamecode('property', pname
, code
)
690 def compileelement(self
, elem
):
691 [code
, keyform
] = elem
693 self
.fp
.write("# element %s as %s\n" % (`code`
, keyform
))
695 def fillclasspropsandelems(self
, cls
):
696 [name
, code
, desc
, properties
, elements
] = cls
697 cname
= identify(name
)
698 if self
.namemappers
[0].hascode('class', code
) and \
699 self
.namemappers
[0].findcodename('class', code
)[0] != cname
:
700 # This is an other name (plural or so) for something else. Skip.
704 for prop
in properties
:
705 [pname
, pcode
, what
] = prop
708 pname
= identify(pname
)
710 for elem
in elements
:
711 [ecode
, keyform
] = elem
714 name
, ename
, module
= self
.findcodename('class', ecode
)
717 self
.fp
.write("# XXXX %s element %s not found!!\n"%(cname
, `ecode`
))
719 elist
.append((name
, ename
))
722 self
.fp
.write("%s._propdict = {\n"%cname
)
724 self
.fp
.write("\t'%s' : %s,\n"%(n
, n
))
726 self
.fp
.write("%s._elemdict = {\n"%cname
)
727 for n
, fulln
in elist
:
728 self
.fp
.write("\t'%s' : %s,\n"%(n
, fulln
))
731 def compilecomparison(self
, comp
):
732 [name
, code
, comment
] = comp
733 iname
= identify(name
)
734 self
.namemappers
[0].addnamecode('comparison', iname
, code
)
736 self
.fp
.write("class %s(aetools.NComparison):\n" % iname
)
737 self
.fp
.write('\t"""%s - %s """\n' % (name
, comment
))
739 def compileenumeration(self
, enum
):
741 name
= "_Enum_%s" % identify(code
)
743 self
.fp
.write("%s = {\n" % name
)
745 self
.compileenumerator(item
)
746 self
.fp
.write("}\n\n")
747 self
.namemappers
[0].addnamecode('enum', name
, code
)
750 def compileenumerator(self
, item
):
751 [name
, code
, desc
] = item
752 self
.fp
.write("\t%s : %s,\t# %s\n" % (`
identify(name
)`
, `code`
, desc
))
754 def checkforenum(self
, enum
):
755 """This enum code is used by an event. Make sure it's available"""
756 name
, fullname
, module
= self
.findcodename('enum', enum
)
759 self
.fp
.write("_Enum_%s = None # XXXX enum %s not found!!\n"%(identify(enum
), enum
))
763 self
.fp
.write("from %s import %s\n"%(module
, name
))
768 self
.fp
.write("\n#\n# Indices of types declared in this module\n#\n")
769 self
.fp
.write("_classdeclarations = {\n")
770 for k
, v
in self
.namemappers
[0].getall('class'):
771 self
.fp
.write("\t%s : %s,\n" % (`k`
, v
))
773 self
.fp
.write("\n_propdeclarations = {\n")
774 for k
, v
in self
.namemappers
[0].getall('property'):
775 self
.fp
.write("\t%s : %s,\n" % (`k`
, v
))
777 self
.fp
.write("\n_compdeclarations = {\n")
778 for k
, v
in self
.namemappers
[0].getall('comparison'):
779 self
.fp
.write("\t%s : %s,\n" % (`k`
, v
))
781 self
.fp
.write("\n_enumdeclarations = {\n")
782 for k
, v
in self
.namemappers
[0].getall('enum'):
783 self
.fp
.write("\t%s : %s,\n" % (`k`
, v
))
786 def compiledata(data
):
787 [type, description
, flags
] = data
788 return "%s -- %s %s" % (`
type`
, `description`
, compiledataflags(flags
))
791 return data
[0] == 'null'
793 def is_optional(data
):
794 return (data
[2] & 0x8000)
797 return (data
[2] & 0x2000)
799 def getdatadoc(data
):
800 [type, descr
, flags
] = data
806 return 'an AE object reference'
807 return "undocumented, typecode %s"%`
type`
809 dataflagdict
= {15: "optional", 14: "list", 13: "enum", 12: "mutable"}
810 def compiledataflags(flags
):
814 if i
in dataflagdict
.keys():
815 bits
.append(dataflagdict
[i
])
818 return '[%s]' % string
.join(bits
)
821 """Turn any string into an identifier:
823 - replace other illegal chars by _xx_ (hex code)
824 - prepend _ if the result is a python keyword
827 return "_empty_ae_name"
829 ok
= string
.ascii_letters
+ '_'
830 ok2
= ok
+ string
.digits
837 rv
= rv
+ '_%02.2x_'%ord(c
)
839 if keyword
.iskeyword(rv
):
843 # Call the main program
845 if __name__
== '__main__':
848 print identify('for')