diff options
author | Guido van Rossum <guido@python.org> | 1995-03-02 14:05:29 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1995-03-02 14:05:29 (GMT) |
commit | d211220cd2ea4e51f58cd30fb8fa22a1a62b3b2d (patch) | |
tree | 64cc091fbaf5531ea833bdc2cad32f4731617a7e /Tools/modulator/modulator.py | |
parent | df804f8591bcb38ffd4a915c76bd6277ce766a5e (diff) | |
download | cpython-d211220cd2ea4e51f58cd30fb8fa22a1a62b3b2d.zip cpython-d211220cd2ea4e51f58cd30fb8fa22a1a62b3b2d.tar.gz cpython-d211220cd2ea4e51f58cd30fb8fa22a1a62b3b2d.tar.bz2 |
checkin of Jack's original version
Diffstat (limited to 'Tools/modulator/modulator.py')
-rwxr-xr-x | Tools/modulator/modulator.py | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/Tools/modulator/modulator.py b/Tools/modulator/modulator.py new file mode 100755 index 0000000..b569ac6 --- /dev/null +++ b/Tools/modulator/modulator.py @@ -0,0 +1,379 @@ +#! /usr/local/bin/python +# +# Modulator - Generate skeleton modules. +# +# The user fills out some forms with information about what the module +# should support (methods, objects), names of these things, prefixes to +# use for C code, whether the objects should also support access as numbers, +# etc etc etc. +# When the user presses 'Generate code' we generate a complete skeleton +# module in C. +# +# Alternatively, the selections made can be save to a python sourcefile and +# this sourcefile can be passed on the command line (resulting in the same +# skeleton C code). +# +# Jack Jansen, CWI, October 1994. +# + +import sys, os +sys.path.append(os.path.join(os.environ['HOME'], 'src/python/Demo/modulator')) + +from Tkinter import * +from Tkextra import * +import tkinter +from ScrolledListbox import ScrolledListbox +import sys +import genmodule +import string + +oops = 'oops' + +# Check that string is a legal C identifier +def checkid(str): + if not str: return 0 + if not str[0] in string.letters+'_': + return 0 + for c in str[1:]: + if not c in string.letters+string.digits+'_': + return 0 + return 1 + +def getlistlist(list): + rv = [] + n = list.size() + for i in range(n): + rv.append(list.get(i)) + return rv + +class UI: + def __init__(self): + self.main = Frame() + self.main.pack() + self.main.master.title('Modulator: Module view') + self.cmdframe = Frame(self.main, {'relief':'raised', 'bd':'0.5m', + Pack:{'side':'top', + 'fill':'x'}}) + self.objframe = Frame(self.main, {Pack:{'side':'top', 'fill':'x', + 'expand':1}}) + + + self.check_button = Button(self.cmdframe, + {'text':'Check', 'command':self.cb_check, + Pack:{'side':'left', 'padx':'0.5m'}}) + self.save_button = Button(self.cmdframe, + {'text':'Save...', 'command':self.cb_save, + Pack:{'side':'left', 'padx':'0.5m'}}) + self.code_button = Button(self.cmdframe, + {'text':'Generate code...', + 'command':self.cb_gencode, + Pack:{'side':'left', 'padx':'0.5m'}}) + self.quit_button = Button(self.cmdframe, + {'text':'Quit', + 'command':self.cb_quit, + Pack:{'side':'right', 'padx':'0.5m'}}) + + self.module = UI_module(self) + self.objects = [] + self.modified = 0 + + def run(self): + self.main.mainloop() + + def cb_quit(self, *args): + if self.modified: + if not askyn('You have not saved\nAre you sure you want to quit?'): + return + sys.exit(0) + + def cb_check(self, *args): + try: + self.module.synchronize() + for o in self.objects: + o.synchronize() + except oops: + pass + + def cb_save(self, *args): + try: + pycode = self.module.gencode('m', self.objects) + except oops: + return + + fn = askfile('Python file name: ') + if not fn: + return + + fp = open(fn, 'w') + + fp.write(pycode) + fp.close() + + def cb_gencode(self, *args): + try: + pycode = self.module.gencode('m', self.objects) + except oops: + pass + + fn = askfile('C file name: ') + if not fn: + return + + fp = open(fn, 'w') + + try: + exec pycode + except: + message('An error occurred:-)') + return + genmodule.write(fp, m) + fp.close() + +class UI_module: + def __init__(self, parent): + self.parent = parent + self.frame = Frame(parent.objframe, {'relief':'raised', 'bd':'0.2m', + Pack:{'side':'top', + 'fill':'x'}}) + self.f1 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m', + 'fill':'x'}}) + self.f2 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m', + 'fill':'x'}}) + self.f3 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m', + 'fill':'x'}}) + self.f4 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m', + 'fill':'x'}}) + + self.l1 = Label(self.f1, {'text':'Module:', Pack:{'side':'left', + 'padx':'0.5m'}}) + self.name_entry = Entry(self.f1, {'relief':'sunken', + Pack:{'side':'left', 'padx':'0.5m', 'expand':1}}) + self.l2 = Label(self.f1, {'text':'Abbrev:', Pack:{'side':'left', + 'padx':'0.5m'}}) + self.abbrev_entry = Entry(self.f1, {'relief':'sunken', 'width':5, + Pack:{'side':'left', 'padx':'0.5m'}}) + + self.l3 = Label(self.f2, {'text':'Methods:', Pack:{'side':'left', + 'padx':'0.5m'}}) + self.method_list = ScrolledListbox(self.f2, {'relief':'sunken','bd':2, + Pack:{'side':'left', 'expand':1, + 'padx':'0.5m', 'fill':'both'}}) + + self.l4 = Label(self.f3, {'text':'Add method:', Pack:{'side':'left', + 'padx':'0.5m'}}) + self.method_entry = Entry(self.f3, {'relief':'sunken', + Pack:{'side':'left', 'padx':'0.5m', 'expand':1}}) + self.method_entry.bind('<Return>', self.cb_method) + self.delete_button = Button(self.f3, {'text':'Delete method', + 'command':self.cb_delmethod, + Pack:{'side':'left', + 'padx':'0.5m'}}) + + self.newobj_button = Button(self.f4, {'text':'new object', + 'command':self.cb_newobj, + Pack:{'side':'left', + 'padx':'0.5m'}}) + + def cb_delmethod(self, *args): + list = self.method_list.curselection() + for i in list: + self.method_list.delete(i) + + def cb_newobj(self, *arg): + self.parent.objects.append(UI_object(self.parent)) + + def cb_method(self, *arg): + name = self.method_entry.get() + if not name: + return + self.method_entry.delete('0', 'end') + self.method_list.insert('end', name) + + def synchronize(self): + n = self.name_entry.get() + if not n: + message('Module name not set') + raise oops + if not checkid(n): + message('Module name not an identifier:\n'+n) + raise oops + if not self.abbrev_entry.get(): + self.abbrev_entry.insert('end', n) + m = getlistlist(self.method_list) + for n in m: + if not checkid(n): + message('Method name not an identifier:\n'+n) + raise oops + + def gencode(self, name, objects): + rv = '' + self.synchronize() + for o in objects: + o.synchronize() + onames = [] + for i in range(len(objects)): + oname = 'o'+`i+1` + rv = rv + objects[i].gencode(oname) + onames.append(oname) + rv = rv + (name+' = genmodule.module()\n') + rv = rv + (name+'.name = '+`self.name_entry.get()`+'\n') + rv = rv + (name+'.abbrev = '+`self.abbrev_entry.get()`+'\n') + rv = rv + (name+'.methodlist = '+`getlistlist(self.method_list)`+'\n') + rv = rv + (name+'.objects = ['+string.joinfields(onames, ',')+']\n') + rv = rv + ('\n') + return rv + +object_number = 0 + +class UI_object: + def __init__(self, parent): + global object_number + + object_number = object_number + 1 + self.num = object_number + self.vpref = 'o'+`self.num`+'_' + self.frame = Toplevel(parent.objframe) +# self.frame.pack() + self.frame.title('Modulator: object view') +# self.frame = Frame(parent.objframe, {'relief':'raised', 'bd':'0.2m', +# Pack:{'side':'top', +# 'fill':'x'}}) + self.f1 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m', + 'fill':'x'}}) + self.f2 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m', + 'fill':'x'}}) + self.f3 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m', + 'fill':'x'}}) + self.f4 = Frame(self.frame, {Pack:{'side':'top', 'pady':'0.5m', + 'fill':'x'}}) + + + self.l1 = Label(self.f1, {'text':'Object:', Pack:{'side':'left', + 'padx':'0.5m'}}) + self.name_entry = Entry(self.f1, {'relief':'sunken', + Pack:{'side':'left', 'padx':'0.5m', 'expand':1}}) + self.l2 = Label(self.f1, {'text':'Abbrev:', Pack:{'side':'left', + 'padx':'0.5m'}}) + self.abbrev_entry = Entry(self.f1, {'relief':'sunken', 'width':5, + Pack:{'side':'left', 'padx':'0.5m'}}) + + self.l3 = Label(self.f2, {'text':'Methods:', Pack:{'side':'left', + 'padx':'0.5m'}}) + self.method_list = ScrolledListbox(self.f2, {'relief':'sunken','bd':2, + Pack:{'side':'left', 'expand':1, + 'padx':'0.5m', 'fill':'both'}}) + + self.l4 = Label(self.f3, {'text':'Add method:', Pack:{'side':'left', + 'padx':'0.5m'}}) + self.method_entry = Entry(self.f3, {'relief':'sunken', + Pack:{'side':'left', 'padx':'0.5m', 'expand':1}}) + self.method_entry.bind('<Return>', self.cb_method) + self.delete_button = Button(self.f3, {'text':'Delete method', + 'command':self.cb_delmethod, + Pack:{'side':'left', + 'padx':'0.5m'}}) + + + self.l5 = Label(self.f4, {'text':'functions:', + Pack:{'side':'left', + 'padx':'0.5m'}}) + self.f5 = Frame(self.f4, {Pack:{'side':'left', 'pady':'0.5m', + 'fill':'both'}}) + self.l6 = Label(self.f4, {'text':'Types:', + Pack:{'side':'left', 'padx':'0.5m'}}) + self.f6 = Frame(self.f4, {Pack:{'side':'left', 'pady':'0.5m', + 'fill':'x'}}) + self.funcs = {} + for i in genmodule.FUNCLIST: + vname = self.vpref+i + self.f5.setvar(vname, 0) + b = Checkbutton(self.f5, {'variable':vname, 'text':i, + Pack:{'side':'top', 'pady':'0.5m', + 'anchor':'w','expand':1}}) + self.funcs[i] = b + self.f5.setvar(self.vpref+'new', 1) + + self.types = {} + for i in genmodule.TYPELIST: + vname = self.vpref + i + self.f6.setvar(vname, 0) + b = Checkbutton(self.f6, {'variable':vname, 'text':i, + Pack:{'side':'top', 'pady':'0.5m', + 'anchor':'w'}}) + self.types[i] = b + + def cb_method(self, *arg): + name = self.method_entry.get() + if not name: + return + self.method_entry.delete('0', 'end') + self.method_list.insert('end', name) + + def cb_delmethod(self, *args): + list = self.method_list.curselection() + for i in list: + self.method_list.delete(i) + + def synchronize(self): + n = self.name_entry.get() + if not n: + message('Object name not set') + raise oops + if not self.abbrev_entry.get(): + self.abbrev_entry.insert('end', n) + n = self.abbrev_entry.get() + if not checkid(n): + message('Abbreviation not an identifier:\n'+n) + raise oops + m = getlistlist(self.method_list) + for n in m: + if not checkid(n): + message('Method name not an identifier:\n'+n) + raise oops + if m: + self.f5.setvar(self.vpref+'tp_getattr', 1) + pass + + def gencode(self, name): + rv = '' + rv = rv + (name+' = genmodule.object()\n') + rv = rv + (name+'.name = '+`self.name_entry.get()`+'\n') + rv = rv + (name+'.abbrev = '+`self.abbrev_entry.get()`+'\n') + rv = rv + (name+'.methodlist = '+`getlistlist(self.method_list)`+'\n') + fl = [] + for fn in genmodule.FUNCLIST: + vname = self.vpref + fn + if self.f5.getvar(vname) == '1': + fl.append(fn) + rv = rv + (name+'.funclist = '+`fl`+'\n') + + fl = [] + for fn in genmodule.TYPELIST: + vname = self.vpref + fn + if self.f5.getvar(vname) == '1': + fl.append(fn) + + rv = rv + (name+'.typelist = '+`fl`+'\n') + + rv = rv + ('\n') + return rv + + +def main(): + if len(sys.argv) < 2: + ui = UI() + ui.run() + elif len(sys.argv) == 2: + fp = open(sys.argv[1]) + pycode = fp.read() + try: + exec pycode + except: + sys.stderr.write('An error occurred:-)\n') + sys.exit(1) + genmodule.write(sys.stdout, m) + else: + sys.stderr.write('Usage: modulator [file]\n') + sys.exit(1) + +main() |