From b7ae5546be6dff9454daaf95a08330b6f359d504 Mon Sep 17 00:00:00 2001 From: James Henstridge Date: Sun, 8 Jul 2001 04:11:36 +0000 Subject: new program to convert v2 defs to v3 defs. It will probably only work with 2001-07-08 James Henstridge * codegen/defsconvert.py (convert): new program to convert v2 defs to v3 defs. It will probably only work with files in the style created by the h2def.py program. 2001-07-07 James Henstridge * codegen/h2def.py (to_upper_str): add function to convert a type name to upper case with underscores using the same algorithm as gtk+ (with an extra rule to catch cases like GObject. (typecode): function to create a typecode like GTK_TYPE_WIDGET from the type name. (write_obj_defs): output v3 defs. (write_enum_defs): output v3 defs. (define_func): replace 'G_CONST_RETURN ' to 'const-' for return value. (write_func): output v3 defs. * codegen/scmexpr.py (parse): make the parser ignore single quotes, which are used in the new defs format. --- ChangeLog | 22 ++++++++ codegen/defsconvert.py | 130 +++++++++++++++++++++++++++++++++++++++++++++ codegen/h2def.py | 140 +++++++++++++++++++++++++++---------------------- codegen/scmexpr.py | 4 +- 4 files changed, 233 insertions(+), 63 deletions(-) create mode 100644 codegen/defsconvert.py diff --git a/ChangeLog b/ChangeLog index 91628e29..cb3e045e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2001-07-08 James Henstridge + + * codegen/defsconvert.py (convert): new program to convert v2 defs + to v3 defs. It will probably only work with files in the style + created by the h2def.py program. + +2001-07-07 James Henstridge + + * codegen/h2def.py (to_upper_str): add function to convert a type + name to upper case with underscores using the same algorithm as + gtk+ (with an extra rule to catch cases like GObject. + (typecode): function to create a typecode like GTK_TYPE_WIDGET + from the type name. + (write_obj_defs): output v3 defs. + (write_enum_defs): output v3 defs. + (define_func): replace 'G_CONST_RETURN ' to 'const-' for return + value. + (write_func): output v3 defs. + + * codegen/scmexpr.py (parse): make the parser ignore single + quotes, which are used in the new defs format. + 2001-07-03 James Henstridge * gtk/gtk.override (_wrap_gtk_list_store_new): fix up function diff --git a/codegen/defsconvert.py b/codegen/defsconvert.py new file mode 100644 index 00000000..365a507f --- /dev/null +++ b/codegen/defsconvert.py @@ -0,0 +1,130 @@ +import sys +import string, re + +# ------------------ Create typecodes from typenames --------- + +_upperstr_pat1 = re.compile(r'([^A-Z])([A-Z])') +_upperstr_pat2 = re.compile(r'([A-Z][A-Z])([A-Z][0-9a-z])') +_upperstr_pat3 = re.compile(r'^([A-Z])([A-Z])') + +def to_upper_str(name): + """Converts a typename to the equivalent upercase and underscores + name. This is used to form the type conversion macros and enum/flag + name variables""" + name = _upperstr_pat1.sub(r'\1_\2', name) + name = _upperstr_pat2.sub(r'\1_\2', name) + name = _upperstr_pat3.sub(r'\1_\2', name, count=1) + return string.upper(name) + +def typecode(typename): + """create a typecode (eg. GTK_TYPE_WIDGET) from a typename""" + return string.replace(to_upper_str(typename), '_', '_TYPE_', 1) + + +STATE_START = 0 +STATE_OBJECT = 1 +STATE_INTERFACE = 2 +STATE_BOXED = 3 +STATE_ENUM = 4 +STATE_FLAGS = 5 +STATE_METHOD = 6 +STATE_FUNCTION = 7 + +def convert(infp=sys.stdin, outfp=sys.stdout): + state = STATE_START + seen_params = 0 + + line = infp.readline() + while line: + if line[:8] == '(object ': + state = STATE_OBJECT + seen_params = 0 + outfp.write('(define-object ' + line[8:]) + elif line[:11] == '(interface ': + state = STATE_INTERFACE + seen_params = 0 + outfp.write('(define-interface ' + line[11:]) + elif line[:7] == '(boxed ': + state = STATE_BOXED + seen_params = 0 + outfp.write('(define-boxed ' + line[7:]) + elif line[:6] == '(enum ': + state = STATE_ENUM + seen_params = 0 + outfp.write('(define-enum ' + line[6:]) + elif line[:7] == '(flags ': + state = STATE_FLAGS + seen_params = 0 + outfp.write('(define-flags ' + line[7:]) + elif line[:8] == '(method ': + state = STATE_METHOD + seen_params = 0 + outfp.write('(define-method ' + line[8:]) + elif line[:10] == '(function ': + state = STATE_FUNCTION + seen_params = 0 + outfp.write('(define-function ' + line[10:]) + elif line[:13] == ' (in-module ': + outfp.write(re.sub(r'^(\s+\(in-module\s+)(\w+)(.*)$', + r'\1"\2"\3', line)) + elif line[:10] == ' (parent ': + outfp.write(re.sub(r'^(\s+\(parent\s+)(\w+)(\s+\((\w+)\))?(.*)$', + r'\1"\4\2"\5', line)) + elif line[:14] == ' (implements ': + outfp.write(re.sub(r'^(\s+\(implements\s+)([^\s]+)(\s*\))$', + r'\1"\2"\3', line)) + elif line[:13] == ' (of-object ': + outfp.write(re.sub(r'^(\s+\(of-object\s+)(\w+)(\s+\((\w+)\))?(.*)$', + r'\1"\4\2"\5', line)) + elif line[:10] == ' (c-name ': + outfp.write(re.sub(r'^(\s+\(c-name\s+)([^\s]+)(\s*\))$', + r'\1"\2"\3', line)) + if state in (STATE_OBJECT, STATE_INTERFACE, STATE_BOXED, + STATE_ENUM, STATE_FLAGS): + c_name = re.match(r'^\s+\(c-name\s+([^\s]+)\s*\)$', + line).group(1) + outfp.write(' (gtype-id "%s")\n' % typecode(c_name)) + elif line[:15] == ' (return-type ': + outfp.write(re.sub(r'^(\s+\(return-type\s+)([^\s]+)(\s*\))$', + r'\1"\2"\3', line)) + elif line[:13] == ' (copy-func ': + outfp.write(re.sub(r'^(\s+\(copy-func\s+)(\w+)(.*)$', + r'\1"\2"\3', line)) + elif line[:16] == ' (release-func ': + outfp.write(re.sub(r'^(\s+\(release-func\s+)(\w+)(.*)$', + r'\1"\2"\3', line)) + elif line[:9] == ' (field ': + if not seen_params: + outfp.write(' (fields\n') + seen_params = 1 + outfp.write(re.sub(r'^\s+\(field\s+\(type-and-name\s+([^\s]+)\s+([^\s]+)\s*\)\s*\)$', + ' \'("\\1" "\\2")', line)) + elif line[:9] == ' (value ': + if not seen_params: + outfp.write(' (values\n') + seen_params = 1 + outfp.write(re.sub(r'^\s+\(value\s+\(name\s+([^\s]+)\)\s+\(c-name\s+([^\s]+)\s*\)\s*\)$', + ' \'("\\1" "\\2")', line)) + elif line[:13] == ' (parameter ': + if not seen_params: + outfp.write(' (parameters\n') + seen_params = 1 + outfp.write(re.sub(r'^\s+\(parameter\s+\(type-and-name\s+([^\s]+)\s+([^\s]+)\s*\)(\s*.*)\)$', + ' \'("\\1" "\\2"\\3)', line)) + elif line[:11] == ' (varargs ': + if seen_params: + outfp.write(' )\n') + seen_params = 0 + outfp.write(' (varargs #t)\n') + elif line[0] == ')': + if seen_params: + outfp.write(' )\n') + seen_params = 0 + state = STATE_START + outfp.write(line) + else: + outfp.write(line) + line = infp.readline() + +if __name__ == '__main__': + convert() diff --git a/codegen/h2def.py b/codegen/h2def.py index 851d9c33..95974faf 100755 --- a/codegen/h2def.py +++ b/codegen/h2def.py @@ -12,10 +12,32 @@ import string, sys, re, types +# ------------------ Create typecodes from typenames --------- + +_upperstr_pat1 = re.compile(r'([^A-Z])([A-Z])') +_upperstr_pat2 = re.compile(r'([A-Z][A-Z])([A-Z][0-9a-z])') +_upperstr_pat3 = re.compile(r'^([A-Z])([A-Z])') + +def to_upper_str(name): + """Converts a typename to the equivalent upercase and underscores + name. This is used to form the type conversion macros and enum/flag + name variables""" + name = _upperstr_pat1.sub(r'\1_\2', name) + name = _upperstr_pat2.sub(r'\1_\2', name) + name = _upperstr_pat3.sub(r'\1_\2', name, count=1) + return string.upper(name) + +def typecode(typename): + """create a typecode (eg. GTK_TYPE_WIDGET) from a typename""" + return string.replace(to_upper_str(typename), '_', '_TYPE_', 1) + + # ------------------ Find object definitions ----------------- obj_name_pat = "[A-Z][a-z]*[A-Z][A-Za-z0-9]*" +split_prefix_pat = re.compile('([A-Z][a-z]*)([A-Za-z0-9]+)') + def find_obj_defs(buf, objdefs=[]): """ Try to find object definitions in header files. @@ -76,30 +98,21 @@ def write_obj_defs(objdefs, output): fp.write(';; -*- scheme -*-\n') fp.write('; object definitions ...\n') - pat = re.compile('([A-Z][a-z]+)([A-Za-z0-9]+)') for klass, parent in objdefs: - m = pat.match(klass) + m = split_prefix_pat.match(klass) cmodule = None cname = klass if m: cmodule = m.group(1) cname = m.group(2) - if parent: - m = pat.match(parent) - pmodule = None - pname = parent - if m: - pmodule = m.group(1) - pname = m.group(2) - - fp.write('(object ' + cname + '\n') + + fp.write('(define-object ' + cname + '\n') if cmodule: - fp.write(' (in-module ' + cmodule + ')\n') + fp.write(' (in-module "' + cmodule + '")\n') if parent: - fp.write(' (parent ' + pname) - if pmodule: fp.write(' (' + pmodule + ')') - fp.write(')\n') - fp.write(' (c-name ' + klass + ')\n') + fp.write(' (parent "' + parent + '")\n') + fp.write(' (c-name "' + klass + '")\n') + fp.write(' (gtype-id "' + typecode(klass) + '")\n') # should do something about accessible fields fp.write(')\n\n') @@ -141,32 +154,34 @@ def write_enum_defs(enums, output=None): fp=sys.stdout fp.write(';; Enumerations and flags ...\n\n') - pat = re.compile('([A-Z][a-z]+)([A-Za-z0-9]+)') trans = string.maketrans(string.uppercase + '_', string.lowercase + '-') for cname, isflags, entries in enums: name = cname module = None - m = pat.match(cname) + m = split_prefix_pat.match(cname) if m: module = m.group(1) name = m.group(2) if isflags: - fp.write('(flags ' + name + '\n') + fp.write('(define-flags ' + name + '\n') else: - fp.write('(enum ' + name + '\n') + fp.write('(define-enum ' + name + '\n') if module: - fp.write(' (in-module ' + module + ')\n') - fp.write(' (c-name ' + cname + ')\n') + fp.write(' (in-module "' + module + '")\n') + fp.write(' (c-name "' + cname + '")\n') + fp.write(' (gtype-id "' + typecode(cname) + '")\n') prefix = entries[0] for ent in entries: # shorten prefix til we get a match ... - # and handle GDK_FONT_FoNT, GDK_FONT_FONTSET case + # and handle GDK_FONT_FONT, GDK_FONT_FONTSET case while ent[:len(prefix)] != prefix or len(prefix) >= len(ent): prefix = prefix[:-1] + prefix_len = len(prefix) + fp.write(' (values\n') for ent in entries: - fp.write(' (value (name ' + - string.translate(ent[len(prefix):], trans) + - ') (c-name ' + ent + '))\n') + fp.write(' \'("%s" "%s")\n' % + (string.translate(ent[prefix_len:], trans), ent)) + fp.write(' )\n') fp.write(')\n\n') # ------------------ Find function definitions ----------------- @@ -229,6 +244,7 @@ def define_func(buf,fp): continue func = m.group('func') ret = m.group('ret') + ret = string.replace(ret, 'G_CONST_RETURN ', 'const-') ret = string.replace(ret, 'const ', 'const-') args=m.group('args') args=arg_split_pat.split(args,', ') @@ -239,7 +255,6 @@ def define_func(buf,fp): write_func(fp, func, ret, args) get_type_pat = re.compile(r'(const-)?([A-Za-z0-9]+)\*?\s+') -get_mod_pat = re.compile('([A-Z][a-z]+)([A-Za-z0-9]+)') def write_func(fp, name, ret, args): if len(args) >= 1: @@ -251,41 +266,55 @@ def write_func(fp, name, ret, args): if munged_name[:len(obj)] == string.lower(obj): regex = string.join(map(lambda x: x+'_?',string.lower(obj)),'') mname = re.sub(regex, '', name) - fp.write('(method ' + mname + '\n') - m = get_mod_pat.match(obj) - if m: - fp.write(' (of-object ' + m.group(2) + - ' (' + m.group(1) + '))\n') - fp.write(' (c-name ' + name + ')\n') + fp.write('(define-method ' + mname + '\n') + fp.write(' (of-object "' + obj + '")\n') + fp.write(' (c-name "' + name + '")\n') if ret != 'void': - fp.write(' (return-type ' + ret + ')\n') + fp.write(' (return-type "' + ret + '")\n') else: - fp.write(' (return-type none)\n') + fp.write(' (return-type "none")\n') + is_varargs = 0 + has_args = len(args) > 1 for arg in args[1:]: if arg == '...': - fp.write(' (varargs t)\n') + is_varargs = 1 elif arg in ('void', 'void '): - pass - else: - fp.write(' (parameter (type-and-name ' + arg + '))\n') + has_args = 0 + if has_args: + fp.write(' (parameters\n') + for arg in args[1:]: + if arg != '...': + fp.write(' \'("%s" "%s")\n' % + tuple(string.split(arg))) + fp.write(' )\n') + if is_varargs: + fp.write(' (varargs #t)\n') fp.write(')\n\n') return # it is either a constructor or normal function # FIXME: put in constructor check - fp.write('(function ' + name + '\n') + fp.write('(define-function ' + name + '\n') # do in-module thingee - fp.write(' (c-name ' + name + ')\n') + fp.write(' (c-name "' + name + '")\n') if ret != 'void': - fp.write(' (return-type ' + ret + ')\n') + fp.write(' (return-type "' + ret + '")\n') else: - fp.write(' (return-type none)\n') + fp.write(' (return-type "none")\n') + is_varargs = 0 + has_args = len(args) > 0 for arg in args: if arg == '...': - fp.write(' (varargs t)\n') - elif arg == 'void': - pass - else: - fp.write(' (parameter (type-and-name ' + arg + '))\n') + is_varargs = 1 + elif arg in ('void', 'void '): + has_args = 0 + if has_args: + fp.write(' (parameters\n') + for arg in args: + if arg != '...': + fp.write(' \'("%s" "%s")\n' % tuple(string.split(arg))) + fp.write(' )\n') + if is_varargs: + fp.write(' (varargs #t)\n') fp.write(')\n\n') def write_def(input,output=None): @@ -304,20 +333,7 @@ def write_def(input,output=None): buf = define_func(buf, fp) fp.write('\n') -# ------------------ Glue code ----------------- - -def make_gdk_defs(): - """ This is intended to be run only by the package maintainer!!! """ - p='/usr/local/src/gtk+-1.2.6/gdk/' - gdk= [ - 'gdk.h', - 'gdkrgb.h', - #'gdktypes.h' - ] - fp=open('_gdk_func.defs','w') - for h in gdk: - write_def(p+h,fp) - fp.close() +# ------------------ Main function ----------------- verbose=0 if __name__ == '__main__': diff --git a/codegen/scmexpr.py b/codegen/scmexpr.py index 362b6231..83f33aa5 100644 --- a/codegen/scmexpr.py +++ b/codegen/scmexpr.py @@ -44,9 +44,11 @@ def parse(fp): stack[-1] = stack[-1] + (string.atof(str),) elif line[0] == ';': break + elif line[0] == "'": + line = line[1:] # consume single quote else: str = "" - while line and line[0] not in " \t();\n": + while line and line[0] not in "(); '\t\r\n": str = str + line[0] line = line[1:] stack[-1] = stack[-1] + (str,) -- cgit v1.2.1