X-Git-Url: http://git.demorecorder.com/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fc_client.py;h=d86d05e2421910122ec40e65f9e0fc6d53aa8ae4;hb=e82c34c2f7ac3fbb23ab14cbee8df2dd9178f5a4;hp=835ae5c929fafa1aea8567fb23a89724574f264e;hpb=b3832bcc46d85110fdb2b553df6249a831cfe0fa;p=free-sw%2Fxcb%2Flibxcb diff --git a/src/c_client.py b/src/c_client.py index 835ae5c..d86d05e 100755 --- a/src/c_client.py +++ b/src/c_client.py @@ -1,7 +1,8 @@ #!/usr/bin/env python from xml.etree.cElementTree import * -from sys import argv from os.path import basename +import getopt +import sys import re # Jump to the bottom of this file for the main routine @@ -16,18 +17,6 @@ _cplusplus_annoyances = {'class' : '_class', 'new' : '_new', 'delete': '_delete'} -_cardinal_types = ['CARD8', 'uint8_t', - 'CARD16','uint16_t', - 'CARD32','uint32_t', - 'INT8', 'int8_t', - 'INT16', 'int16_t', - 'INT32', 'int32_t', - 'BYTE', - 'BOOL', - 'char', - 'void', - 'float', - 'double'] _hlines = [] _hlevel = 0 _clines = [] @@ -146,6 +135,9 @@ def c_open(self): _ns = self.namespace _ns.c_ext_global_name = _n(_ns.prefix + ('id',)) + # Build the type-name collision avoidance table used by c_enum + build_collision_table() + _h_setlevel(0) _c_setlevel(0) @@ -175,6 +167,12 @@ def c_open(self): for (n, h) in self.imports: _hc('#include "%s.h"', h) + _h('') + _h('#ifdef __cplusplus') + _h('extern "C" {') + _h('#endif') + + if _ns.is_ext: _h('') _h('#define XCB_%s_MAJOR_VERSION %s', _ns.ext_name.upper(), _ns.major_version) _h('#define XCB_%s_MINOR_VERSION %s', _ns.ext_name.upper(), _ns.minor_version) @@ -182,7 +180,7 @@ def c_open(self): _h('extern xcb_extension_t %s;', _ns.c_ext_global_name) _c('') - _c('xcb_extension_t %s = { "%s" };', _ns.c_ext_global_name, _ns.ext_xname) + _c('xcb_extension_t %s = { "%s", 0 };', _ns.c_ext_global_name, _ns.ext_xname) def c_close(self): ''' @@ -192,6 +190,12 @@ def c_close(self): _h_setlevel(2) _c_setlevel(2) _hc('') + + _h('') + _h('#ifdef __cplusplus') + _h('}') + _h('#endif') + _h('') _h('#endif') _h('') @@ -215,13 +219,26 @@ def c_close(self): cfile.write('\n') cfile.close() +def build_collision_table(): + global namecount + namecount = {} + + for v in module.types.values(): + name = _t(v[0]) + namecount[name] = (namecount.get(name) or 0) + 1 + def c_enum(self, name): ''' Exported function that handles enum declarations. ''' + + tname = _t(name) + if namecount[tname] > 1: + tname = _t(name + ('enum',)) + _h_setlevel(0) _h('') - _h('typedef enum %s {', _t(name)) + _h('typedef enum %s {', tname) count = len(self.values) @@ -231,7 +248,7 @@ def c_enum(self, name): comma = ',' if count > 0 else '' _h(' %s%s%s%s', _n(name + (enam,)).upper(), equals, eval, comma) - _h('} %s;', _t(name)) + _h('} %s;', tname) def _c_type_setup(self, name, postfix): ''' @@ -306,7 +323,7 @@ def _c_iterator_get_end(field, accum): return _c_iterator_get_end(field.type.last_varsized_field, accum) if field.type.is_list: # XXX we can always use the first way - if field.type.c_type in _cardinal_types: + if field.type.member.is_simple: return field.c_end_name + '(' + accum + ')' else: return field.type.member.c_end_name + '(' + field.c_iterator_name + '(' + accum + '))' @@ -442,7 +459,7 @@ def _c_accessors_field(self, field): ''' Declares the accessor functions for a non-list field that follows a variable-length field. ''' - if field.field_type[0] in _cardinal_types: + if field.type.is_simple: _hc('') _hc('') _hc('/*****************************************************************************') @@ -534,7 +551,7 @@ def _c_accessors_list(self, field): _c(' return %s;', _c_accessor_get_expr(field.type.expr, 'R')) _c('}') - if field.field_type[0] in _cardinal_types: + if field.type.member.is_simple: _hc('') _hc('') _hc('/*****************************************************************************') @@ -634,9 +651,15 @@ def _c_complex(self): struct_fields = [] maxtypelen = 0 + varfield = None for field in self.fields: if not field.type.fixed_size(): - break + varfield = field.c_field_name + continue + if varfield != None and not field.type.is_pad and field.wire: + errmsg = '%s: warning: variable field %s followed by fixed field %s\n' % (self.c_type, varfield, field.c_field_name) + sys.stderr.write(errmsg) + # sys.exit(1) if field.wire: struct_fields.append(field) @@ -982,6 +1005,18 @@ output = {'open' : c_open, # Boilerplate below this point +# Check for the argument that specifies path to the xcbgen python package. +try: + opts, args = getopt.getopt(sys.argv[1:], 'p:') +except getopt.GetoptError, err: + print str(err) + print 'Usage: c_client.py [-p path] file.xml' + sys.exit(1) + +for (opt, arg) in opts: + if opt == '-p': + sys.path.append(arg) + # Import the module class try: from xcbgen.state import Module @@ -996,7 +1031,7 @@ except ImportError: raise # Parse the xml header -module = Module(argv[1], output) +module = Module(args[0], output) # Build type-registry and resolve type dependencies module.register()