checkin of Jack's original version

This commit is contained in:
Guido van Rossum 1995-03-02 14:05:29 +00:00
parent df804f8591
commit d211220cd2
27 changed files with 1525 additions and 0 deletions

View File

@ -0,0 +1,46 @@
#
# Example input file for modulator if you don't have tk.
#
# You may also have to strip some imports out of modulator to make
# it work.
#
# Generate code for a simple object with a method called sample
o = genmodule.object()
o.name = 'simple object'
o.abbrev = 'simp'
o.methodlist = ['sample']
o.funclist = ['new']
#
# Generate code for an object that looks numberish
#
o2 = genmodule.object()
o2.name = 'number-like object'
o2.abbrev = 'nl'
o2.typelist = ['tp_as_number']
o2.funclist = ['new', 'tp_repr', 'tp_compare']
#
# Generate code for a method with a full complement of functions,
# some methods, accessible as sequence and allowing structmember.c type
# structure access as well.
#
o3 = genmodule.object()
o3.name = 'over-the-top object'
o3.abbrev = 'ot'
o3.methodlist = ['method1', 'method2']
o3.funclist = ['new', 'tp_dealloc', 'tp_print', 'tp_getattr', 'tp_setattr',
'tp_compare', 'tp_repr', 'tp_hash']
o3.typelist = ['tp_as_sequence', 'structure']
#
# Now generate code for a module that incorporates these object types.
# Also add the boilerplates for functions to create instances of each
# type.
#
m = genmodule.module()
m.name = 'sample'
m.abbrev = 'sample'
m.methodlist = ['newsimple', 'newnumberish', 'newott']
m.objects = [o, o2, o3]

17
Tools/modulator/README Normal file
View File

@ -0,0 +1,17 @@
This is release 1.0 of modulator, a generator of boilerplate code for
modules to be written in C.
Usage when you have tk is *reall* simple: start modulator, fill out
the forms specifying all the objects and methods, tell modulator
whether objects should also be accessible as sequences, etc and press
'generate code'. It will write a complete skeleton module for you.
Usage when you don't have tk is slightly more difficult. Look at
EXAMPLE.py for some details.
Oh yeah: you'll probably want to change Templates/copyright, or all
your code ends up as being copyrighted to CWI:-)
Let me know what you think,
Jack Jansen, jack@cwi.nl

View File

@ -0,0 +1,37 @@
# A ScrolledList widget feels like a list widget but also has a
# vertical scroll bar on its right. (Later, options may be added to
# add a horizontal bar as well, to make the bars disappear
# automatically when not needed, to move them to the other side of the
# window, etc.)
#
# Configuration options are passed to the List widget.
# A Frame widget is inserted between the master and the list, to hold
# the Scrollbar widget.
# Most methods calls are inherited from the List widget; Pack methods
# are redirected to the Frame widget however.
from Tkinter import *
from Tkinter import _cnfmerge
class ScrolledListbox(Listbox):
def __init__(self, master=None, cnf={}):
cnf = _cnfmerge(cnf)
fcnf = {}
vcnf = {'name': 'vbar',
Pack: {'side': 'right', 'fill': 'y'},}
for k in cnf.keys():
if type(k) == ClassType or k == 'name':
fcnf[k] = cnf[k]
del cnf[k]
self.frame = Frame(master, fcnf)
self.vbar = Scrollbar(self.frame, vcnf)
cnf[Pack] = {'side': 'left', 'fill': 'both', 'expand': 'yes'}
cnf['name'] = 'list'
Listbox.__init__(self, self.frame, cnf)
self['yscrollcommand'] = (self.vbar, 'set')
self.vbar['command'] = (self, 'yview')
# Copy Pack methods of self.frame -- hack!
for m in Pack.__dict__.keys():
if m[0] != '_' and m != 'config':
setattr(self, m, getattr(self.frame, m))

View File

@ -0,0 +1,23 @@
/***********************************************************
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
The Netherlands.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
******************************************************************/

View File

@ -0,0 +1,7 @@
#include "allobjects.h"
#include "modsupport.h" /* For getargs() etc. */
static object *ErrorObject;
/* ----------------------------------------------------- */

View File

@ -0,0 +1,12 @@
static object *
$abbrev$_$method$(self, args)
object *self; /* Not used */
object *args;
{
if (!newgetargs(args, ""))
return NULL;
INCREF(None);
return None;
}

View File

@ -0,0 +1,30 @@
/* List of methods defined in the module */
static struct methodlist $abbrev$_methods[] = {
$methodlist$
{NULL, NULL} /* sentinel */
};
/* Initialization function for the module (*must* be called init$name$) */
void
init$name$()
{
object *m, *d;
/* Create the module and add the functions */
m = initmodule("$name$", $abbrev$_methods);
/* Add some symbolic constants to the module */
d = getmoduledict(m);
ErrorObject = newstringobject("$name$.error");
dictinsert(d, "error", ErrorObject);
/* XXXX Add constants here */
/* Check for errors */
if (err_occurred())
fatal("can't initialize module $name$");
}

View File

@ -0,0 +1,12 @@
/* Declarations for objects of type $name$ */
typedef struct {
OB_HEAD
/* XXXX Add your own stuff here */
} $abbrev$object;
staticforward typeobject $Abbrev$type;
#define is_$abbrev$object(v) ((v)->ob_type == &$Abbrev$type)
/* ---------------------------------------------------------------- */

View File

@ -0,0 +1,11 @@
static object *
$abbrev$_$method$(self, args)
$abbrev$object *self;
object *args;
{
if (!newgetargs(args, ""))
return NULL;
INCREF(None);
return None;
}

View File

@ -0,0 +1,7 @@
static struct methodlist $abbrev$_methods[] = {
$methodlist$
{NULL, NULL} /* sentinel */
};
/* ---------- */

View File

@ -0,0 +1,12 @@
static $abbrev$object *
new$abbrev$object()
{
$abbrev$object *self;
self = NEWOBJ($abbrev$object, &$Abbrev$type);
if (self == NULL)
return NULL;
/* XXXX Add your own initializers here */
return self;
}

View File

@ -0,0 +1,41 @@
/* Code to access structure members by accessing attributes */
#include "structmember.h"
#define OFF(x) offsetof(XXXXobject, x)
static struct memberlist $abbrev$_memberlist[] = {
/* XXXX Add lines like { "foo", T_INT, OFF(foo), RO } */
{NULL} /* Sentinel */
};
static object *
$abbrev$_getattr(self, name)
$abbrev$object *self;
char *name;
{
object *rv;
/* XXXX Add your own getattr code here */
rv = getmember((char *)/*XXXX*/0, $abbrev$_memberlist, name);
if (rv)
return rv;
err_clear();
return findmethod($abbrev$_methods, (object *)self, name);
}
static int
$abbrev$_setattr(self, name, v)
$abbrev$object *self;
char *name;
object *v;
{
/* XXXX Add your own setattr code here */
if ( v == NULL ) {
err_setstr(AttributeError, "Cannot delete attribute");
return -1;
}
return setmember((char *)/*XXXX*/0, $abbrev$_memberlist, name, v);
}

View File

@ -0,0 +1,22 @@
static typeobject $Abbrev$type = {
OB_HEAD_INIT(&Typetype)
0, /*ob_size*/
"$name$", /*tp_name*/
sizeof($abbrev$object), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor)$tp_dealloc$, /*tp_dealloc*/
(printfunc)$tp_print$, /*tp_print*/
(getattrfunc)$tp_getattr$, /*tp_getattr*/
(setattrfunc)$tp_setattr$, /*tp_setattr*/
(cmpfunc)$tp_compare$, /*tp_compare*/
(reprfunc)$tp_repr$, /*tp_repr*/
$tp_as_number$, /*tp_as_number*/
$tp_as_sequence$, /*tp_as_sequence*/
$tp_as_mapping$, /*tp_as_mapping*/
(hashfunc)$tp_hash$, /*tp_hash*/
};
/* End of code for $name$ objects */
/* -------------------------------------------------------- */

View File

@ -0,0 +1,33 @@
/* Code to access $name$ objects as mappings */
static int
$abbrev$_length(self)
$abbrev$object *self;
{
/* XXXX Return the size of the mapping */
}
static object *
$abbrev$_subscript(self, key)
$abbrev$object *self;
object *key;
{
/* XXXX Return the item of self indexed by key */
}
static int
$abbrev$_ass_sub(self, v, w)
$abbrev$object *self;
object *v, *w;
{
/* XXXX Put w in self under key v */
return 0;
}
static mapping_methods $abbrev$_as_mapping = {
(inquiry)$abbrev$_length, /*mp_length*/
(binaryfunc)$abbrev$_subscript, /*mp_subscript*/
(objobjargproc)$abbrev$_ass_sub, /*mp_ass_subscript*/
};
/* -------------------------------------------------------- */

View File

@ -0,0 +1,249 @@
/* Code to access $name$ objects as numbers */
static object *
$abbrev$_add(v, w)
$abbrev$object *v;
$abbrev$object *w;
{
/* XXXX Add them */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_sub(v, w)
$abbrev$object *v;
$abbrev$object *w;
{
/* XXXX Subtract them */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_mul(v, w)
$abbrev$object *v;
$abbrev$object *w;
{
/* XXXX Multiply them */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_div(x, y)
$abbrev$object *x;
$abbrev$object *y;
{
/* XXXX Divide them */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_mod(x, y)
$abbrev$object *x;
$abbrev$object *y;
{
/* XXXX Modulo them */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_divmod(x, y)
$abbrev$object *x;
$abbrev$object *y;
{
/* XXXX Return 2-tuple with div and mod */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_pow(v, w, z)
$abbrev$object *v;
$abbrev$object *w;
$abbrev$object *z;
{
/* XXXX */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_neg(v)
$abbrev$object *v;
{
/* XXXX */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_pos(v)
$abbrev$object *v;
{
/* XXXX */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_abs(v)
$abbrev$object *v;
{
/* XXXX */
err_setstr(SystemError, "not implemented");
return NULL;
}
static int
$abbrev$_nonzero(v)
$abbrev$object *v;
{
/* XXXX Return 1 if non-zero */
err_setstr(SystemError, "not implemented");
return -1;
}
static object *
$abbrev$_invert(v)
$abbrev$object *v;
{
/* XXXX */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_lshift(v, w)
$abbrev$object *v;
$abbrev$object *w;
{
/* XXXX */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_rshift(v, w)
$abbrev$object *v;
$abbrev$object *w;
{
/* XXXX */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_and(v, w)
$abbrev$object *v;
$abbrev$object *w;
{
/* XXXX */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_xor(v, w)
$abbrev$object *v;
$abbrev$object *w;
{
/* XXXX */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_or(v, w)
$abbrev$object *v;
$abbrev$object *w;
{
/* XXXX */
err_setstr(SystemError, "not implemented");
return NULL;
}
static int
$abbrev$_coerce(pv, pw)
object **pv;
object **pw;
{
/* XXXX I haven't a clue... */
return 1;
}
static object *
$abbrev$_int(v)
$abbrev$object *v;
{
/* XXXX */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_long(v)
$abbrev$object *v;
{
/* XXXX */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_float(v)
$abbrev$object *v;
{
/* XXXX */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_oct(v)
$abbrev$object *v;
{
/* XXXX Return object as octal stringobject */
err_setstr(SystemError, "not implemented");
return NULL;
}
static object *
$abbrev$_hex(v)
$abbrev$object *v;
{
/* XXXX Return object as hex stringobject */
err_setstr(SystemError, "not implemented");
return NULL;
}
static number_methods $abbrev$_as_number = {
(binaryfunc)$abbrev$_add, /*nb_add*/
(binaryfunc)$abbrev$_sub, /*nb_subtract*/
(binaryfunc)$abbrev$_mul, /*nb_multiply*/
(binaryfunc)$abbrev$_div, /*nb_divide*/
(binaryfunc)$abbrev$_mod, /*nb_remainder*/
(binaryfunc)$abbrev$_divmod, /*nb_divmod*/
(ternaryfunc)$abbrev$_pow, /*nb_power*/
(unaryfunc)$abbrev$_neg, /*nb_negative*/
(unaryfunc)$abbrev$_pos, /*nb_positive*/
(unaryfunc)$abbrev$_abs, /*nb_absolute*/
(inquiry)$abbrev$_nonzero, /*nb_nonzero*/
(unaryfunc)$abbrev$_invert, /*nb_invert*/
(binaryfunc)$abbrev$_lshift, /*nb_lshift*/
(binaryfunc)$abbrev$_rshift, /*nb_rshift*/
(binaryfunc)$abbrev$_and, /*nb_and*/
(binaryfunc)$abbrev$_xor, /*nb_xor*/
(binaryfunc)$abbrev$_or, /*nb_or*/
(coercion)$abbrev$_coerce, /*nb_coerce*/
(unaryfunc)$abbrev$_int, /*nb_int*/
(unaryfunc)$abbrev$_long, /*nb_long*/
(unaryfunc)$abbrev$_float, /*nb_float*/
(unaryfunc)$abbrev$_oct, /*nb_oct*/
(unaryfunc)$abbrev$_hex, /*nb_hex*/
};
/* ------------------------------------------------------- */

View File

@ -0,0 +1,73 @@
/* Code to handle accessing $name$ objects as sequence objects */
static int
$abbrev$_length(self)
$abbrev$object *self;
{
/* XXXX Return the size of the object */
}
static object *
$abbrev$_concat(self, bb)
$abbrev$object *self;
object *bb;
{
/* XXXX Return the concatenation of self and bb */
}
static object *
$abbrev$_repeat(self, n)
$abbrev$object *self;
int n;
{
/* XXXX Return a new object that is n times self */
}
static object *
$abbrev$_item(self, i)
$abbrev$object *self;
int i;
{
/* XXXX Return the i-th object of self */
}
static object *
$abbrev$_slice(self, ilow, ihigh)
$abbrev$object *self;
int ilow, ihigh;
{
/* XXXX Return the ilow..ihigh slice of self in a new object */
}
static int
$abbrev$_ass_item(self, i, v)
$abbrev$object *self;
int i;
object *v;
{
/* XXXX Assign to the i-th element of self */
return 0;
}
static int
$abbrev$_ass_slice(self, ilow, ihigh, v)
listobject *self;
int ilow, ihigh;
object *v;
{
/* XXXX Replace ilow..ihigh slice of self with v */
return 0;
}
static sequence_methods $abbrev$_as_sequence = {
(inquiry)$abbrev$_length, /*sq_length*/
(binaryfunc)$abbrev$_concat, /*sq_concat*/
(intargfunc)$abbrev$_repeat, /*sq_repeat*/
(intargfunc)$abbrev$_item, /*sq_item*/
(intintargfunc)$abbrev$_slice, /*sq_slice*/
(intobjargproc)$abbrev$_ass_item, /*sq_ass_item*/
(intintobjargproc)$abbrev$_ass_slice, /*sq_ass_slice*/
};
/* -------------------------------------------------------------- */

View File

@ -0,0 +1,7 @@
static int
$abbrev$_compare(v, w)
$abbrev$object *v, *w;
{
/* XXXX Compare objects and return -1, 0 or 1 */
}

View File

@ -0,0 +1,8 @@
static void
$abbrev$_dealloc(self)
$abbrev$object *self;
{
/* XXXX Add your own cleanup code here */
DEL(self);
}

View File

@ -0,0 +1,9 @@
static object *
$abbrev$_getattr(self, name)
$abbrev$object *self;
char *name;
{
/* XXXX Add your own getattr code here */
return findmethod($abbrev$_methods, (object *)self, name);
}

View File

@ -0,0 +1,7 @@
static long
$abbrev$_hash(self)
$abbrev$object *self;
{
/* XXXX Return a hash of self (or -1) */
}

View File

@ -0,0 +1,10 @@
static int
$abbrev$_print(self, fp, flags)
$abbrev$object *self;
FILE *fp;
int flags;
{
/* XXXX Add code here to print self to fp */
return 0;
}

View File

@ -0,0 +1,10 @@
static object *
$abbrev$_repr(self)
$abbrev$object *self;
{
object *s;
/* XXXX Add code here to put self into s */
return s;
}

View File

@ -0,0 +1,10 @@
static int
$abbrev$_setattr(self, name, v)
$abbrev$object *self;
char *name;
object *v;
{
/* XXXX Add your own setattr code here */
return -1;
}

235
Tools/modulator/Tkextra.py Executable file
View File

@ -0,0 +1,235 @@
#! /usr/local/bin/python
# A Python function that generates dialog boxes with a text message,
# optional bitmap, and any number of buttons.
# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270.
from Tkinter import *
mainWidget = None
def dialog(master, title, text, bitmap, default, *args):
# 1. Create the top-level window and divide it into top
# and bottom parts.
w = Toplevel(master, {'class': 'Dialog'})
w.title(title)
w.iconname('Dialog')
top = Frame(w, {'relief': 'raised', 'bd': 1,
Pack: {'side': 'top', 'fill': 'both'}})
bot = Frame(w, {'relief': 'raised', 'bd': 1,
Pack: {'side': 'bottom', 'fill': 'both'}})
# 2. Fill the top part with the bitmap and message.
msg = Message(top,
{'width': '3i',
'text': text,
'font': '-Adobe-Times-Medium-R-Normal-*-180-*',
Pack: {'side': 'right', 'expand': 1,
'fill': 'both',
'padx': '3m', 'pady': '3m'}})
if bitmap:
bm = Label(top, {'bitmap': bitmap,
Pack: {'side': 'left',
'padx': '3m', 'pady': '3m'}})
# 3. Create a row of buttons at the bottom of the dialog.
buttons = []
i = 0
for but in args:
b = Button(bot, {'text': but,
'command': ('set', 'button', i)})
buttons.append(b)
if i == default:
bd = Frame(bot, {'relief': 'sunken', 'bd': 1,
Pack: {'side': 'left', 'expand': 1,
'padx': '3m', 'pady': '2m'}})
b.lift()
b.pack ({'in': bd, 'side': 'left',
'padx': '2m', 'pady': '2m',
'ipadx': '2m', 'ipady': '1m'})
else:
b.pack ({'side': 'left', 'expand': 1,
'padx': '3m', 'pady': '3m',
'ipady': '2m', 'ipady': '1m'})
i = i+1
# 4. Set up a binding for <Return>, if there's a default,
# set a grab, and claim the focus too.
if default >= 0:
w.bind('<Return>',
lambda e, b=buttons[default], i=default:
(b.flash(),
b.setvar('button', i)))
oldFocus = w.tk.call('focus') # XXX
w.grab_set()
w.focus()
# 5. Wait for the user to respond, then restore the focus
# and return the index of the selected button.
w.waitvar('button')
w.destroy()
w.tk.call('focus', oldFocus) # XXX
return w.getint(w.getvar('button'))
def strdialog(master, title, text, bitmap, default, *args):
# 1. Create the top-level window and divide it into top
# and bottom parts.
w = Toplevel(master, {'class': 'Dialog'})
w.title(title)
w.iconname('Dialog')
top = Frame(w, {'relief': 'raised', 'bd': 1,
Pack: {'side': 'top', 'fill': 'both'}})
if args:
bot = Frame(w, {'relief': 'raised', 'bd': 1,
Pack: {'side': 'bottom', 'fill': 'both'}})
# 2. Fill the top part with the bitmap, message and input field.
if bitmap:
bm = Label(top, {'bitmap': bitmap,
Pack: {'side': 'left',
'padx': '3m', 'pady': '3m'}})
msg = Message(top,
{'width': '3i',
'text': text,
'font': '-Adobe-Times-Medium-R-Normal-*-180-*',
Pack: {'side': 'left',
'fill': 'both',
'padx': '3m', 'pady': '3m'}})
field = Entry(top,
{'relief':'sunken',
Pack:{'side':'left',
'fill':'x',
'expand':1,
'padx':'3m', 'pady':'3m'}})
# 3. Create a row of buttons at the bottom of the dialog.
buttons = []
i = 0
for but in args:
b = Button(bot, {'text': but,
'command': ('set', 'button', i)})
buttons.append(b)
if i == default:
bd = Frame(bot, {'relief': 'sunken', 'bd': 1,
Pack: {'side': 'left', 'expand': 1,
'padx': '3m', 'pady': '2m'}})
b.lift()
b.pack ({'in': bd, 'side': 'left',
'padx': '2m', 'pady': '2m',
'ipadx': '2m', 'ipady': '1m'})
else:
b.pack ({'side': 'left', 'expand': 1,
'padx': '3m', 'pady': '3m',
'ipady': '2m', 'ipady': '1m'})
i = i+1
# 4. Set up a binding for <Return>, if there's a default,
# set a grab, and claim the focus too.
if not args:
w.bind('<Return>', lambda arg, top=top: top.setvar('button', 0))
field.bind('<Return>', lambda arg, top=top: top.setvar('button', 0))
elif default >= 0:
w.bind('<Return>',
lambda e, b=buttons[default], i=default:
(b.flash(),
b.setvar('button', i)))
field.bind('<Return>',
lambda e, b=buttons[default], i=default:
(b.flash(),
b.setvar('button', i)))
oldFocus = w.tk.call('focus') # XXX
w.grab_set()
field.focus()
# 5. Wait for the user to respond, then restore the focus
# and return the index of the selected button.
w.waitvar('button')
v = field.get()
w.destroy()
w.tk.call('focus', oldFocus) # XXX
if args:
return v, w.getint(w.getvar('button'))
else:
return v
def message(str):
i = dialog(mainWidget, 'Message', str, '', 0, 'OK')
def askyn(str):
i = dialog(mainWidget, 'Question', str, '', 0, 'No', 'Yes')
return i
def askync(str):
i = dialog(mainWidget, 'Question', str, '', 0, 'Cancel', 'No', 'Yes')
return i-1
def askstr(str):
i = strdialog(mainWidget, 'Question', str, '', 0)
return i
def askfile(str): # XXXX For now...
i = strdialog(mainWidget, 'Question', str, '', 0)
return i
# The rest is the test program.
def _go():
i = dialog(mainWidget,
'Not Responding',
"The file server isn't responding right now; "
"I'll keep trying.",
'',
-1,
'OK')
print 'pressed button', i
i = dialog(mainWidget,
'File Modified',
'File "tcl.h" has been modified since '
'the last time it was saved. '
'Do you want to save it before exiting the application?',
'warning',
0,
'Save File',
'Discard Changes',
'Return To Editor')
print 'pressed button', i
print message('Test of message')
print askyn('Test of yes/no')
print askync('Test of yes/no/cancel')
print askstr('Type a string:')
print strdialog(mainWidget, 'Question', 'Another string:', '',
0, 'Save', 'Save as text')
def _test():
import sys
global mainWidget
mainWidget = Frame()
Pack.config(mainWidget)
start = Button(mainWidget,
{'text': 'Press Here To Start', 'command': _go})
start.pack()
endit = Button(mainWidget,
{'text': 'Exit',
'command': 'exit',
Pack: {'fill' : 'both'}})
mainWidget.mainloop()
if __name__ == '__main__':
_test()

157
Tools/modulator/genmodule.py Executable file
View File

@ -0,0 +1,157 @@
#
# Genmodule - A python program to help you build (template) modules.
#
# Usage:
#
# o = genmodule.object()
# o.name = 'dwarve object'
# o.abbrev = 'dw'
# o.funclist = ['new', 'dealloc', 'getattr', 'setattr']
# o.methodlist = ['dig']
#
# m = genmodule.module()
# m.name = 'beings'
# m.abbrev = 'be'
# m.methodlist = ['newdwarve']
# m.objects = [o]
#
# genmodule.write(sys.stdout, m)
#
import sys
import os
import varsubst
import string
error = 'genmodule.error'
#
# Names of functions in the object-description struct.
#
FUNCLIST = ['new', 'tp_dealloc', 'tp_print', 'tp_getattr', 'tp_setattr',
'tp_compare', 'tp_repr', 'tp_hash']
TYPELIST = ['tp_as_number', 'tp_as_sequence', 'tp_as_mapping', 'structure']
#
# writer is a base class for the object and module classes
# it contains code common to both.
#
class writer:
def __init__(self):
self._subst = None
def makesubst(self):
if not self._subst:
if not self.__dict__.has_key('abbrev'):
self.abbrev = self.name
self.Abbrev = string.upper(self.abbrev[0])+self.abbrev[1:]
subst = varsubst.Varsubst(self.__dict__)
subst.useindent(1)
self._subst = subst.subst
def addcode(self, name, fp):
ifp = self.opentemplate(name)
self.makesubst()
d = ifp.read()
d = self._subst(d)
fp.write(d)
def opentemplate(self, name):
for p in sys.path:
fn = os.path.join(p, name)
if os.path.exists(fn):
return open(fn, 'r')
fn = os.path.join(p, 'Templates')
fn = os.path.join(fn, name)
if os.path.exists(fn):
return open(fn, 'r')
raise error, 'Template '+name+' not found for '+self._type+' '+ \
self.name
class module(writer):
_type = 'module'
def writecode(self, fp):
self.addcode('copyright', fp)
self.addcode('module_head', fp)
for o in self.objects:
o.writehead(fp)
for o in self.objects:
o.writebody(fp)
new_ml = ''
for fn in self.methodlist:
self.method = fn
self.addcode('module_method', fp)
new_ml = new_ml + ('{"%s",\t%s_%s,\t1},\n'%(fn, self.abbrev, fn))
self.methodlist = new_ml
self.addcode('module_tail', fp)
class object(writer):
_type = 'object'
def __init__(self):
self.typelist = []
self.methodlist = []
self.funclist = ['new']
writer.__init__(self)
def writecode(self, fp):
self.addcode('copyright', fp)
self.writehead(fp)
self.writebody(fp)
def writehead(self, fp):
self.addcode('object_head', fp)
def writebody(self, fp):
new_ml = ''
for fn in self.methodlist:
self.method = fn
self.addcode('object_method', fp)
new_ml = new_ml + ('{"%s",\t%s_%s,\t1},\n'%(fn, self.abbrev, fn))
self.methodlist = new_ml
self.addcode('object_mlist', fp)
# Add getattr if we have methods
if self.methodlist and not 'tp_getattr' in self.funclist:
self.funclist.insert(0, 'tp_getattr')
for fn in FUNCLIST:
setattr(self, fn, '0')
#
# Special case for structure-access objects: put getattr in the
# list of functions but don't generate code for it directly,
# the code is obtained from the object_structure template.
# The same goes for setattr.
#
if 'structure' in self.typelist:
if 'tp_getattr' in self.funclist:
self.funclist.remove('tp_getattr')
if 'tp_setattr' in self.funclist:
self.funclist.remove('tp_setattr')
self.tp_getattr = self.abbrev + '_getattr'
self.tp_setattr = self.abbrev + '_setattr'
for fn in self.funclist:
self.addcode('object_'+fn, fp)
setattr(self, fn, '%s_%s'%(self.abbrev, fn[3:]))
for tn in TYPELIST:
setattr(self, tn, '0')
for tn in self.typelist:
self.addcode('object_'+tn, fp)
setattr(self, tn, '&%s_%s'%(self.abbrev, tn[3:]))
self.addcode('object_tail', fp)
def write(fp, obj):
obj.writecode(fp)
if __name__ == '__main__':
o = object()
o.name = 'dwarve object'
o.abbrev = 'dw'
o.funclist = ['new', 'tp_dealloc']
o.methodlist = ['dig']
m = module()
m.name = 'beings'
m.abbrev = 'be'
m.methodlist = ['newdwarve']
m.objects = [o]
write(sys.stdout, m)

379
Tools/modulator/modulator.py Executable file
View File

@ -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()

View File

@ -0,0 +1,61 @@
#
# Variable substitution. Variables are $delimited$
#
import string
import regex
import regsub
error = 'varsubst.error'
class Varsubst:
def __init__(self, dict):
self.dict = dict
self.prog = regex.compile('\$[a-zA-Z0-9_]*\$')
self.do_useindent = 0
def useindent(self, onoff):
self.do_useindent = onoff
def subst(self, str):
rv = ''
while 1:
pos = self.prog.search(str)
if pos < 0:
return rv + str
if pos:
rv = rv + str[:pos]
str = str[pos:]
len = self.prog.match(str)
if len == 2:
# Escaped dollar
rv = rv + '$'
str = str[2:]
continue
name = str[1:len-1]
str = str[len:]
if not self.dict.has_key(name):
raise error, 'No such variable: '+name
value = self.dict[name]
if self.do_useindent and '\n' in value:
value = self._modindent(value, rv)
rv = rv + value
def _modindent(self, value, old):
lastnl = string.rfind(old, '\n', 0) + 1
lastnl = len(old) - lastnl
sub = '\n' + (' '*lastnl)
return regsub.gsub('\n', sub, value)
def _test():
import sys
import os
sys.stderr.write('-- Copying stdin to stdout with environment map --\n')
c = Varsubst(os.environ)
c.useindent(1)
d = sys.stdin.read()
sys.stdout.write(c.subst(d))
sys.exit(1)
if __name__ == '__main__':
_test()