summaryrefslogtreecommitdiff
path: root/src/pkg/xgb/go_client.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/xgb/go_client.py')
-rw-r--r--src/pkg/xgb/go_client.py704
1 files changed, 0 insertions, 704 deletions
diff --git a/src/pkg/xgb/go_client.py b/src/pkg/xgb/go_client.py
deleted file mode 100644
index f26548000..000000000
--- a/src/pkg/xgb/go_client.py
+++ /dev/null
@@ -1,704 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2009 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-from xml.etree.cElementTree import *
-from os.path import basename, exists
-import getopt
-import sys
-import re
-import math
-
-_ns = None
-
-outfile = None
-golines = []
-def go(fmt, *args):
- golines.append(fmt % args)
-
-namere = re.compile('([A-Z0-9][a-z]+|[A-Z0-9]+(?![a-z])|[a-z]+)')
-allcaps = re.compile('^[A-Z0-9]+$')
-
-sizeoftab = {
- "byte": 1,
- "int8": 1,
- "uint8": 1,
- "int16": 2,
- "uint16": 2,
- "int32": 4,
- "uint32": 4,
- "float32": 4,
- "float64": 8,
- "Id": 4,
- "Keysym": 4,
- "Timestamp": 4,
-}
-
-def sizeof(t):
- if t in sizeoftab:
- return sizeoftab[t]
- return 4
-
-symbols = []
-
-def readsymbols(filename):
- symbols.append("XXX Dummy XXX")
- if exists(filename):
- for line in open(filename, 'r').readlines():
- symbols.append(line.strip())
-
-#
-# Name munging crap for names, enums and types.
-#
-
-mangletab = {
- "int8_t": "int8",
- "uint8_t": "byte",
- "uint16_t": "uint16",
- "uint32_t": "uint32",
- "int16_t": "int16",
- "int32_t": "int32",
- "float": "float32",
- "double": "float64",
- "char": "byte",
- "void": "byte",
- 'VISUALTYPE': 'VisualInfo',
- 'DEPTH': 'DepthInfo',
- 'SCREEN': 'ScreenInfo',
- 'Setup': 'SetupInfo',
- 'WINDOW': 'Id',
-}
-
-def mangle(str):
- if str in mangletab:
- return mangletab[str]
- return str
-
-def camel(str):
- return str[0].upper() + str[1:]
-def uncamel(str):
- return str[0].lower() + str[1:]
-
-def nitem(str):
- split = namere.finditer(str)
- return ''.join([camel(match.group(0)) for match in split])
-
-def titem(str):
- str = mangle(str)
- if str in sizeoftab:
- return str
- if allcaps.match(str):
- return str.capitalize()
- return nitem(str)
-
-def n(list):
- "Mangle name (JoinedCamelCase) and chop off 'xcb' prefix."
- if len(list) == 1:
- parts = [nitem(list[0])]
- else:
- parts = [nitem(x) for x in list[1:]]
- return ''.join(parts)
-
-def t(list):
- "Mangle name (JoinedCamelCase) and chop off 'xcb' prefix. Preserve primitive type names."
- if len(list) == 1:
- return titem(list[0])
- else:
- parts = [titem(x) for x in list[1:]]
- return ''.join(parts)
-
-#
-# Various helper functions
-#
-
-def go_type_setup(self, name, postfix):
- '''
- Sets up all the Go-related state by adding additional data fields to
- all Field and Type objects. Here is where we figure out most of our
- variable and function names.
-
- Recurses into child fields and list member types.
- '''
- # Do all the various names in advance
- self.c_type = t(name + postfix)
- self.c_request_name = n(name)
- self.c_reply_name = n(name + ('Reply',))
- self.c_reply_type = t(name + ('Reply',))
-
- if not self.is_container:
- return
-
- offset = 0
- for field in self.fields:
- go_type_setup(field.type, field.field_type, ())
- if field.type.is_list:
- go_type_setup(field.type.member, field.field_type, ())
- field.c_field_type = t(field.field_type)
- field.c_field_name = n((field.field_name,))
- field.c_subscript = '[%d]' % field.type.nmemb if (field.type.nmemb > 1) else ''
- field.c_pointer = ' ' if field.type.nmemb == 1 else '[]'
- field.c_offset = offset
- if field.type.fixed_size():
- offset += field.type.size * field.type.nmemb
-
-def go_accessor_length(expr, prefix, iswriting):
- '''
- Figures out what C code is needed to get a length field.
- For fields that follow a variable-length field, use the accessor.
- Otherwise, just reference the structure field directly.
- '''
- prefarrow = '' if prefix == '' else prefix + '.'
- if expr.lenfield_name != None:
- lenstr = prefarrow + n((expr.lenfield_name,))
- if iswriting and lenstr.endswith("Len"):
- # chop off ...Len and refer to len(array) instead
- return "len(" + lenstr[:-3] + ")"
- return "int(" + lenstr + ")"
- else:
- return str(expr.nmemb)
-
-def go_accessor_expr(expr, prefix, iswriting):
- '''
- Figures out what C code is needed to get the length of a list field.
- Recurses for math operations.
- Returns bitcount for value-mask fields.
- Otherwise, uses the value of the length field.
- '''
- lenexp = go_accessor_length(expr, prefix, iswriting)
- if expr.op != None:
- return '(' + go_accessor_expr(expr.lhs, prefix, iswriting) + ' ' + expr.op + ' ' + go_accessor_expr(expr.rhs, prefix, iswriting) + ')'
- elif expr.bitfield:
- return 'popCount(' + lenexp + ')'
- else:
- return lenexp
-
-def go_complex(self, fieldlist=None):
- '''
- Helper function for handling all structure types.
- Called for all structs, requests, replies, events, errors.
- '''
- if self.is_union:
- go('type %s struct /*union */ {', self.c_type)
- else:
- go('type %s struct {', self.c_type)
- if not fieldlist:
- fieldlist = self.fields
- for field in fieldlist:
- if field.type.is_pad:
- continue
- if field.wire and field.type.fixed_size():
- go(' %s %s%s', field.c_field_name, field.c_subscript, field.c_field_type)
- if field.wire and not field.type.fixed_size():
- go(' %s []%s', field.c_field_name, field.c_field_type)
- go('}')
- go('')
-
-def go_get(dst, ofs, typename, typesize):
- dst = "v." + dst
- if typesize == 1:
- if typename == 'byte':
- go('%s = b[%s]', dst, ofs)
- else:
- go('%s = %s(b[%s])', dst, typename, ofs)
- elif typesize == 2:
- if typename == 'uint16':
- go('%s = get16(b[%s:])', dst, ofs)
- else:
- go('%s = %s(get16(b[%s:]))', dst, typename, ofs)
- elif typesize == 4:
- if typename == 'uint32':
- go('%s = get32(b[%s:])', dst, ofs)
- else:
- go('%s = %s(get32(b[%s:]))', dst, typename, ofs)
- else:
- go('get%s(b[%s:], &%s)', typename, ofs, dst)
-
-def go_get_list(dst, ofs, typename, typesize, count):
- if typesize == 1 and typename == 'byte':
- go('copy(v.%s[0:%s], b[%s:])', dst, count, ofs)
- else:
- go('for i := 0; i < %s; i++ {', count)
- go_get(dst + "[i]", ofs + "+i*" + str(typesize), typename, typesize)
- go('}')
-
-
-def go_complex_reader_help(self, fieldlist):
- firstvar = 1
- total = 0
- for field in fieldlist:
- fieldname = field.c_field_name
- fieldtype = field.c_field_type
- if field.wire and field.type.fixed_size():
- total = field.c_offset + field.type.size * field.type.nmemb
- if field.type.is_pad:
- continue
- if field.type.nmemb == 1:
- go_get(fieldname, field.c_offset, fieldtype, field.type.size)
- else:
- go_get_list(fieldname, field.c_offset, fieldtype, field.type.size, field.type.nmemb)
- if field.wire and not field.type.fixed_size():
- lenstr = go_accessor_expr(field.type.expr, 'v', False)
- if firstvar:
- firstvar = 0
- go('offset := %d', field.c_offset)
- else:
- go('offset = pad(offset)')
- go('v.%s = make([]%s, %s)', fieldname, fieldtype, lenstr)
- if fieldtype in sizeoftab:
- go_get_list(fieldname, "offset", fieldtype, sizeoftab[fieldtype], "len(v."+fieldname+")")
- go('offset += len(v.%s) * %d', fieldname, sizeoftab[fieldtype])
- else:
- go('for i := 0; i < %s; i++ {', lenstr)
- go(' offset += get%s(b[offset:], &v.%s[i])', fieldtype, fieldname)
- go('}')
- if not firstvar:
- return 'offset'
- return str(total)
-
-def go_complex_reader(self):
- go('func get%s(b []byte, v *%s) int {', self.c_type, self.c_type)
- go(' return %s', go_complex_reader_help(self, self.fields))
- go('}')
- go('')
-
-def structsize(fieldlist):
- fixedtotal = 0
- for field in fieldlist:
- if field.wire and field.type.fixed_size():
- fixedtotal += field.type.size * field.type.nmemb
- return fixedtotal
-
-def go_put(src, ofs, typename, typesize):
- if typesize == 1:
- if typename == 'byte':
- go('b[%s] = %s', ofs, src)
- else:
- go('b[%s] = byte(%s)', ofs, src)
- elif typesize == 2:
- if typename == 'uint16':
- go('put16(b[%s:], %s)', ofs, src)
- else:
- go('put16(b[%s:], uint16(%s))', ofs, src)
- elif typesize == 4:
- if typename == 'uint32':
- go('put32(b[%s:], %s)', ofs, src)
- else:
- go('put32(b[%s:], uint32(%s))', ofs, src)
- else:
- go('put%s(b[%s:], %s)', typename, ofs, src)
-
-
-def go_complex_writer_help(fieldlist, prefix=''):
- prefarrow = '' if prefix == '' else prefix + '.'
- for field in fieldlist:
- fieldname = prefarrow + field.c_field_name
- fieldtype = field.c_field_type
- if fieldname.endswith("Len"):
- fieldname = "len(%s)" % fieldname[:-3]
- fieldtype = "(exp)"
- if not field.type.fixed_size():
- continue
- if field.type.is_expr:
- expstr = go_accessor_expr(field.type.expr, prefix, True)
- go_put(expstr, field.c_offset, "(exp)", field.type.size)
- elif not field.type.is_pad:
- if field.type.nmemb == 1:
- go_put(fieldname, field.c_offset, fieldtype, field.type.size)
- else:
- go(' copy(b[%d:%d], %s)', field.c_offset, field.c_offset + field.type.nmemb, fieldname)
-
-def go_complex_writer_arguments(param_fields, endstr):
- out = []
- for field in param_fields:
- namestr = field.c_field_name
- typestr = field.c_pointer + t(field.field_type)
- if typestr == '[]byte' and namestr == 'Name':
- typestr = 'string'
- out.append(namestr + ' ' + typestr)
- go(' ' + ', '.join(out) + ')' + endstr)
-
-def go_complex_writer_arguments_names(param_fields):
- out = []
- for field in param_fields:
- out.append(field.c_field_name)
- return ', '.join(out)
-
-def go_complex_writer(self, name, void):
- func_name = self.c_request_name
-
- param_fields = []
- wire_fields = []
- for field in self.fields:
- if field.visible:
- # _len is taken from the list directly
- if not field.field_name.endswith("_len"):
- # The field should appear as a call parameter
- param_fields.append(field)
- if field.wire and not field.auto:
- # We need to set the field up in the structure
- wire_fields.append(field)
-
- if void:
- go('func (c *Conn) %s(', func_name)
- go_complex_writer_arguments(param_fields, "{")
- else:
- go('func (c *Conn) %sRequest(', func_name)
- go_complex_writer_arguments(param_fields, "Cookie {")
-
- fixedlength = math.ceil(float(structsize(self.fields)) / float(4))
- fixedsize = fixedlength * 4
-
- if fixedsize <= 32:
- go(' b := c.scratch[0:%d]', fixedsize)
- else:
- go(' b := make([]byte, %d)', fixedsize)
- firstvar = 0
- for field in wire_fields:
- if not field.type.fixed_size():
- if not firstvar:
- firstvar = 1
- go(' n := %d', fixedsize)
- go(' n += pad(%s * %d)', go_accessor_expr(field.type.expr, '', True), field.type.size)
- if not firstvar:
- go(' put16(b[2:], %d)', fixedlength)
- else:
- go(' put16(b[2:], uint16(n / 4))')
- go(' b[0] = %s', self.opcode)
- go_complex_writer_help(wire_fields)
- if not void:
- if firstvar:
- go(' cookie := c.sendRequest(b)')
- else:
- go(' return c.sendRequest(b)')
- else:
- go(' c.sendRequest(b)')
-
- # send extra data
- for field in param_fields:
- if not field.type.fixed_size():
- if field.type.is_list:
- fieldname = field.c_field_name
- lenstr = go_accessor_expr(field.type.expr, '', True)
- if t(field.field_type) == 'byte':
- if fieldname == 'Name':
- go(' c.sendString(%s)', fieldname)
- else:
- go(' c.sendBytes(%s[0:%s])', fieldname, lenstr)
- elif t(field.field_type) == 'uint32':
- go(' c.sendUInt32List(%s[0:%s])', fieldname, lenstr)
- else:
- go(' c.send%sList(%s, %s)', t(field.field_type), fieldname, lenstr)
-
- if not void and firstvar:
- go(' return cookie')
- go('}')
- go('')
-
- if not void:
- args = go_complex_writer_arguments_names(param_fields)
- go('func (c *Conn) %s(', func_name)
- go_complex_writer_arguments(param_fields, '(*%s, os.Error) {' % self.c_reply_type)
- go(' return c.%sReply(c.%sRequest(%s))', func_name, func_name, args)
- go('}')
- go('')
-
-#
-# Struct definitions, readers and writers
-#
-
-def go_struct(self, name):
- go_type_setup(self, name, ())
- if symbols and t(name) not in symbols:
- go('// excluding struct %s\n', t(name))
- return
-
- if self.c_type == 'SetupRequest': return
- if self.c_type == 'SetupFailed': return
- if self.c_type == 'SetupAuthenticate': return
-
- go_complex(self)
- go_complex_reader(self)
-
- if self.c_type == 'Format': return
- if self.c_type == 'VisualInfo': return
- if self.c_type == 'DepthInfo': return
- if self.c_type == 'SetupInfo': return
- if self.c_type == 'ScreenInfo': return
-
- # omit variable length struct writers, they're never used
- if not self.fixed_size():
- go('// omitting variable length send%s', self.c_type)
- go('')
- return
-
- go('func (c *Conn) send%sList(list []%s, count int) {', self.c_type, self.c_type)
- go(' b0 := make([]byte, %d * count)', structsize(self.fields))
- go(' for k := 0; k < count; k++ {')
- go(' b := b0[k * %d:]', structsize(self.fields))
- go_complex_writer_help(self.fields, 'list[k]')
- go(' }')
- go(' c.sendBytes(b0)')
- go('}')
- go('')
-
-def go_union(self, name):
- pass
-
-#
-# Request writers with reply structs and readers where needed
-#
-
-def replyfields(self):
- l = []
- for field in self.fields:
- if field.type.is_pad or not field.wire: continue
- if field.field_name == 'response_type': continue
- if field.field_name == 'sequence': continue
- if field.field_name == 'length':
- if self.c_reply_name != 'GetImageReply' and self.c_reply_name != 'GetKeyboardMappingReply':
- continue
- l.append(field)
- return l
-
-def go_reply(self, name):
- '''
- Declares the function that returns the reply structure.
- '''
- fields = replyfields(self.reply)
- go_complex(self.reply, fields)
- go('func (c *Conn) %s(cookie Cookie) (*%s, os.Error) {', self.c_reply_name, self.c_reply_type)
- go(' b, error := c.waitForReply(cookie)')
- go(' if error != nil { return nil, error }')
- go(' v := new(%s)', self.c_reply_type)
- go_complex_reader_help(self.reply, fields)
- go(' return v, nil')
- go('}')
- go('')
-
-def go_request(self, name):
- '''
- Exported function that handles request declarations.
- '''
- go_type_setup(self, name, ('Request',))
- if symbols and n(name) not in symbols:
- go('// excluding request %s\n', n(name))
- return
-
- if self.reply:
- go_complex_writer(self, name, False)
- go_type_setup(self.reply, name, ('Reply',))
- go_reply(self, name)
- else:
- go_complex_writer(self, name, True)
-
-#
-# Event structs and readers
-#
-
-def eventfields(self):
- l = []
- for field in self.fields:
- if field.type.is_pad or not field.wire: continue
- if field.field_name == 'response_type': continue
- if field.field_name == 'sequence': continue
- l.append(field)
- return l
-
-eventlist = []
-
-def dumpeventlist():
- go('func parseEvent(buf []byte) (Event, os.Error) {')
- go(' switch buf[0] {')
- for event in eventlist:
- go(' case %s: return get%sEvent(buf), nil', event, event)
- go(' }')
- go(' return nil, os.NewError("unknown event type")')
- go('}')
-
-def go_event(self, name):
- '''
- Exported function that handles event declarations.
- '''
- go_type_setup(self, name, ('Event',))
- if symbols and t(name) not in symbols:
- go('// excluding event %s\n', t(name))
- return
-
- eventlist.append(n(name))
-
- go('const %s = %s', t(name), self.opcodes[name])
- go('')
- fields = eventfields(self)
- if self.name == name:
- # Structure definition
- go_complex(self, fields)
- go('func get%s(b []byte) %s {', self.c_type, self.c_type)
- go(' var v %s', self.c_type)
- go_complex_reader_help(self, fields)
- go(' return v')
- go('}')
- go('')
- else:
- # maybe skip this depending on how it interacts with type switching on interfaces
- go('type %s %s', n(name + ('Event',)), n(self.name + ('Event',)))
- go('')
- go('func get%s(b []byte) %s {', self.c_type, self.c_type)
- go(' return (%s)(get%s(b))', n(name + ('Event',)), n(self.name + ('Event',)))
- go('}')
- go('')
-
-#
-# Map simple types to primitive types
-#
-
-def go_simple(self, name):
- '''
- Exported function that handles cardinal type declarations.
- These are types which are typedef'd to one of the CARDx's, char, float, etc.
- We stick them into the mangletab. Lop off xcb prefix.
- '''
- go_type_setup(self, name, ())
- if self.name != name:
- if _ns.is_ext:
- name = name[2]
- else:
- name = name[1]
- if name == "KEYSYM":
- mangletab[name] = "Keysym"
- elif name == "TIMESTAMP":
- mangletab[name] = "Timestamp"
- elif self.size == 4:
- mangletab[name] = "Id"
- else:
- mangletab[name] = t(self.name)
-
-#
-# Dump enums as consts, calculate implicit values instead
-# of using iota.
-#
-
-def go_enum(self, name):
- if symbols and t(name) not in symbols:
- go('// excluding enum %s\n', t(name))
- return
- go('const (')
- iota = 0
- for (enam, eval) in self.values:
- if str(eval) == '':
- iota = iota + 1
- eval = iota
- else:
- iota = int(eval)
- if name[1] == 'Atom':
- s = name[1] + "".join([x.capitalize() for x in enam.split("_")])
- else:
- s = n(name + (enam,))
- go(' %s = %s', s, eval)
- go(')')
- go('')
-
-errorlist = []
-
-def dumperrorlist():
- go('var errorNames = map[byte]string{')
- for error in errorlist:
- go(' Bad%s: "%s",', error, error)
- go('}')
- go('')
-
-def go_error(self, name):
- '''
- Exported function that handles error declarations.
- '''
- errorlist.append(n(name))
- go('const Bad%s = %s', n(name), self.opcodes[name])
- go('')
-
-#
-# Create the go file
-#
-
-def go_open(self):
- '''
- Exported function that handles module open.
- Opens the files and writes out the auto-generated code.
- '''
- global _ns
- _ns = self.namespace
-
- go('// This file was generated automatically from %s.', _ns.file)
- go('')
- go('package xgb')
- go('')
- go('import "os"')
- go('')
-
- if _ns.is_ext:
- go('const %s_MAJOR_VERSION = %s', _ns.ext_name.upper(), _ns.major_version)
- go('const %s_MINOR_VERSION = %s', _ns.ext_name.upper(), _ns.minor_version)
- go('')
-
-def go_close(self):
- '''
- Exported function that handles module close.
- '''
- global outfile
- if len(eventlist) > 0:
- dumpeventlist()
- if len(errorlist) > 0:
- dumperrorlist()
- if not outfile:
- outfile = '%s.go' % _ns.header
- gofile = open(outfile, 'w')
- for line in golines:
- gofile.write(line)
- gofile.write('\n')
- gofile.close()
-
-# Main routine starts here
-
-# Must create an "output" dictionary before any xcbgen imports.
-output = {'open' : go_open,
- 'close' : go_close,
- 'simple' : go_simple,
- 'enum' : go_enum,
- 'struct' : go_struct,
- 'union' : go_union,
- 'request' : go_request,
- 'event' : go_event,
- 'error' : go_error
- }
-
-# 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:s:o:')
-except getopt.GetoptError, err:
- print str(err)
- print 'Usage: go_client.py [-p path] [-s symbol_list_file] [-o output.go] file.xml'
- sys.exit(1)
-
-for (opt, arg) in opts:
- if opt == '-p':
- sys.path.append(arg)
- if opt == '-s':
- readsymbols(arg)
- if opt == '-o':
- outfile = arg
-
-# Import the module class
-try:
- from xcbgen.state import Module
-except ImportError:
- print 'Failed to load the xcbgen Python package!'
- print 'Make sure that xcb/proto installed it on your Python path,'
- print 'or pass the path with -p.'
- print ''
- raise
-
-module = Module(args[0], output)
-module.register()
-module.resolve()
-module.generate()