summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Henstridge <james@daa.com.au>2001-07-08 04:11:36 +0000
committerJames Henstridge <jamesh@src.gnome.org>2001-07-08 04:11:36 +0000
commitb7ae5546be6dff9454daaf95a08330b6f359d504 (patch)
tree78b60d6f17275e2757aeebd672df40841dd2511e
parent6d878d7b890cde01d13590e3e6b9f65d261744b5 (diff)
downloadpygtk-b7ae5546be6dff9454daaf95a08330b6f359d504.tar.gz
new program to convert v2 defs to v3 defs. It will probably only work with
2001-07-08 James Henstridge <james@daa.com.au> * 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 <james@daa.com.au> * 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.
-rw-r--r--ChangeLog22
-rw-r--r--codegen/defsconvert.py130
-rwxr-xr-xcodegen/h2def.py140
-rw-r--r--codegen/scmexpr.py4
4 files changed, 233 insertions, 63 deletions
diff --git a/ChangeLog b/ChangeLog
index 91628e29..cb3e045e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2001-07-08 James Henstridge <james@daa.com.au>
+
+ * 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 <james@daa.com.au>
+
+ * 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 <james@daa.com.au>
* 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,)