2012-04-30 08:40:55 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Type interface {
|
|
|
|
Initialize(p *Protocol)
|
|
|
|
SrcName() string
|
|
|
|
XmlName() string
|
|
|
|
Size() Size
|
|
|
|
|
|
|
|
Define(c *Context)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Translation is used *only* when transitioning from XML types to
|
|
|
|
// our better representation. They are placeholders for the real types (below)
|
|
|
|
// that will replace them.
|
|
|
|
type Translation struct {
|
|
|
|
xmlName string
|
|
|
|
}
|
|
|
|
|
|
|
|
func newTranslation(name string) *Translation {
|
|
|
|
return &Translation{xmlName: name}
|
|
|
|
}
|
|
|
|
|
|
|
|
// RealType takes 'XmlName' and finds its real concrete type in our Protocol.
|
|
|
|
// It is an error if we can't find such a type.
|
|
|
|
func (t *Translation) RealType(p *Protocol) Type {
|
|
|
|
// Check to see if there is a namespace. If so, strip it and use it to
|
|
|
|
// make sure we only look for a type in that protocol.
|
|
|
|
namespace, typeName := "", t.XmlName()
|
|
|
|
if ni := strings.Index(t.XmlName(), ":"); ni > -1 {
|
|
|
|
namespace, typeName = strings.ToLower(typeName[:ni]), typeName[ni+1:]
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(namespace) == 0 || namespace == strings.ToLower(p.Name) {
|
|
|
|
for _, typ := range p.Types {
|
|
|
|
if typeName == typ.XmlName() {
|
|
|
|
return typ
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, imp := range p.Imports {
|
|
|
|
if len(namespace) == 0 || namespace == strings.ToLower(imp.Name) {
|
|
|
|
for _, typ := range imp.Types {
|
|
|
|
if typeName == typ.XmlName() {
|
|
|
|
return typ
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
panic("Could not find real type for translation type: " + t.XmlName())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *Translation) SrcName() string {
|
|
|
|
panic("it is illegal to call SrcName on a translation type")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *Translation) XmlName() string {
|
|
|
|
return t.xmlName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *Translation) Size() Size {
|
|
|
|
panic("it is illegal to call Size on a translation type")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *Translation) Define(c *Context) {
|
|
|
|
panic("it is illegal to call Define on a translation type")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *Translation) Initialize(p *Protocol) {
|
|
|
|
panic("it is illegal to call Initialize on a translation type")
|
|
|
|
}
|
|
|
|
|
|
|
|
type Base struct {
|
|
|
|
srcName string
|
|
|
|
xmlName string
|
2012-04-30 08:44:31 +02:00
|
|
|
size Size
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Base) SrcName() string {
|
|
|
|
return b.srcName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Base) XmlName() string {
|
|
|
|
return b.xmlName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Base) Size() Size {
|
|
|
|
return b.size
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Base) Initialize(p *Protocol) {
|
|
|
|
b.srcName = TypeSrcName(p, b)
|
|
|
|
}
|
|
|
|
|
|
|
|
type Enum struct {
|
|
|
|
srcName string
|
|
|
|
xmlName string
|
2012-04-30 08:44:31 +02:00
|
|
|
Items []*EnumItem
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type EnumItem struct {
|
|
|
|
srcName string
|
|
|
|
xmlName string
|
2012-04-30 08:44:31 +02:00
|
|
|
Expr Expression
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (enum *Enum) SrcName() string {
|
|
|
|
return enum.srcName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (enum *Enum) XmlName() string {
|
|
|
|
return enum.xmlName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (enum *Enum) Size() Size {
|
|
|
|
panic("Cannot take size of enum")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (enum *Enum) Initialize(p *Protocol) {
|
|
|
|
enum.srcName = TypeSrcName(p, enum)
|
|
|
|
for _, item := range enum.Items {
|
2012-05-06 00:21:48 +02:00
|
|
|
item.srcName = SrcName(p, item.xmlName)
|
2012-04-30 08:40:55 +02:00
|
|
|
if item.Expr != nil {
|
|
|
|
item.Expr.Initialize(p)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type Resource struct {
|
|
|
|
srcName string
|
|
|
|
xmlName string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Resource) SrcName() string {
|
|
|
|
return r.srcName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Resource) XmlName() string {
|
|
|
|
return r.xmlName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Resource) Size() Size {
|
|
|
|
return newFixedSize(BaseTypeSizes["Id"])
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *Resource) Initialize(p *Protocol) {
|
|
|
|
r.srcName = TypeSrcName(p, r)
|
|
|
|
}
|
|
|
|
|
|
|
|
type TypeDef struct {
|
|
|
|
srcName string
|
|
|
|
xmlName string
|
2012-04-30 08:44:31 +02:00
|
|
|
Old Type
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TypeDef) SrcName() string {
|
|
|
|
return t.srcName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TypeDef) XmlName() string {
|
|
|
|
return t.xmlName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TypeDef) Size() Size {
|
|
|
|
return t.Old.Size()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TypeDef) Initialize(p *Protocol) {
|
|
|
|
t.Old = t.Old.(*Translation).RealType(p)
|
|
|
|
t.srcName = TypeSrcName(p, t)
|
|
|
|
}
|
|
|
|
|
|
|
|
type Event struct {
|
2012-04-30 08:44:31 +02:00
|
|
|
srcName string
|
|
|
|
xmlName string
|
|
|
|
Number int
|
2012-04-30 08:40:55 +02:00
|
|
|
NoSequence bool
|
2012-04-30 08:44:31 +02:00
|
|
|
Fields []Field
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Event) SrcName() string {
|
|
|
|
return e.srcName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Event) XmlName() string {
|
|
|
|
return e.xmlName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Event) Size() Size {
|
2012-05-01 07:08:03 +02:00
|
|
|
return newExpressionSize(&Value{v: 32})
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Event) Initialize(p *Protocol) {
|
|
|
|
e.srcName = TypeSrcName(p, e)
|
|
|
|
for _, field := range e.Fields {
|
|
|
|
field.Initialize(p)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Event) EvType() string {
|
|
|
|
return fmt.Sprintf("%sEvent", e.srcName)
|
|
|
|
}
|
|
|
|
|
|
|
|
type EventCopy struct {
|
|
|
|
srcName string
|
|
|
|
xmlName string
|
2012-04-30 08:44:31 +02:00
|
|
|
Old Type
|
|
|
|
Number int
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *EventCopy) SrcName() string {
|
|
|
|
return e.srcName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *EventCopy) XmlName() string {
|
|
|
|
return e.xmlName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *EventCopy) Size() Size {
|
2012-05-02 07:46:30 +02:00
|
|
|
return newExpressionSize(&Value{v: 32})
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *EventCopy) Initialize(p *Protocol) {
|
|
|
|
e.srcName = TypeSrcName(p, e)
|
|
|
|
e.Old = e.Old.(*Translation).RealType(p)
|
|
|
|
if _, ok := e.Old.(*Event); !ok {
|
|
|
|
panic("an EventCopy's old type *must* be *Event")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *EventCopy) EvType() string {
|
|
|
|
return fmt.Sprintf("%sEvent", e.srcName)
|
|
|
|
}
|
|
|
|
|
|
|
|
type Error struct {
|
|
|
|
srcName string
|
|
|
|
xmlName string
|
2012-04-30 08:44:31 +02:00
|
|
|
Number int
|
|
|
|
Fields []Field
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Error) SrcName() string {
|
|
|
|
return e.srcName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Error) XmlName() string {
|
|
|
|
return e.xmlName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Error) Size() Size {
|
2012-05-02 07:46:30 +02:00
|
|
|
return newExpressionSize(&Value{v: 32})
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Error) Initialize(p *Protocol) {
|
|
|
|
e.srcName = TypeSrcName(p, e)
|
2012-05-02 07:46:30 +02:00
|
|
|
for _, field := range e.Fields {
|
|
|
|
field.Initialize(p)
|
|
|
|
}
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Error) ErrConst() string {
|
|
|
|
return fmt.Sprintf("Bad%s", e.srcName)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Error) ErrType() string {
|
|
|
|
return fmt.Sprintf("%sError", e.srcName)
|
|
|
|
}
|
|
|
|
|
|
|
|
type ErrorCopy struct {
|
|
|
|
srcName string
|
|
|
|
xmlName string
|
2012-04-30 08:44:31 +02:00
|
|
|
Old Type
|
|
|
|
Number int
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *ErrorCopy) SrcName() string {
|
|
|
|
return e.srcName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *ErrorCopy) XmlName() string {
|
|
|
|
return e.xmlName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *ErrorCopy) Size() Size {
|
2012-05-02 07:46:30 +02:00
|
|
|
return newExpressionSize(&Value{v: 32})
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *ErrorCopy) Initialize(p *Protocol) {
|
|
|
|
e.srcName = TypeSrcName(p, e)
|
|
|
|
e.Old = e.Old.(*Translation).RealType(p)
|
|
|
|
if _, ok := e.Old.(*Error); !ok {
|
|
|
|
panic("an ErrorCopy's old type *must* be *Event")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *ErrorCopy) ErrConst() string {
|
|
|
|
return fmt.Sprintf("Bad%s", e.srcName)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *ErrorCopy) ErrType() string {
|
|
|
|
return fmt.Sprintf("%sError", e.srcName)
|
|
|
|
}
|
|
|
|
|
|
|
|
type Struct struct {
|
|
|
|
srcName string
|
|
|
|
xmlName string
|
2012-04-30 08:44:31 +02:00
|
|
|
Fields []Field
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Struct) SrcName() string {
|
|
|
|
return s.srcName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Struct) XmlName() string {
|
|
|
|
return s.xmlName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Struct) Size() Size {
|
|
|
|
size := newFixedSize(0)
|
|
|
|
for _, field := range s.Fields {
|
|
|
|
size = size.Add(field.Size())
|
|
|
|
}
|
|
|
|
return size
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Struct) Initialize(p *Protocol) {
|
|
|
|
s.srcName = TypeSrcName(p, s)
|
|
|
|
for _, field := range s.Fields {
|
|
|
|
field.Initialize(p)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-03 07:00:01 +02:00
|
|
|
// HasList returns whether there is a field in this struct that is a list.
|
|
|
|
// When true, a more involved calculation is necessary to compute this struct's
|
|
|
|
// size.
|
|
|
|
func (s *Struct) HasList() bool {
|
|
|
|
for _, field := range s.Fields {
|
|
|
|
if _, ok := field.(*ListField); ok {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2012-04-30 08:40:55 +02:00
|
|
|
type Union struct {
|
|
|
|
srcName string
|
|
|
|
xmlName string
|
2012-04-30 08:44:31 +02:00
|
|
|
Fields []Field
|
2012-04-30 08:40:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (u *Union) SrcName() string {
|
|
|
|
return u.srcName
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *Union) XmlName() string {
|
|
|
|
return u.xmlName
|
|
|
|
}
|
|
|
|
|
|
|
|
// Size for Union is broken. At least, it's broken for XKB.
|
|
|
|
// It *looks* like the protocol inherently relies on some amount of
|
|
|
|
// memory unsafety, since some members of unions in XKB are *variable* in
|
|
|
|
// length! The only thing I can come up with, maybe, is when a union has
|
|
|
|
// variable size, simply return the raw bytes. Then it's up to the user to
|
|
|
|
// pass those raw bytes into the appropriate New* constructor. GROSS!
|
|
|
|
// As of now, just pluck out the first field and return that size. This
|
|
|
|
// should work for union elements in randr.xml and xproto.xml.
|
|
|
|
func (u *Union) Size() Size {
|
|
|
|
return u.Fields[0].Size()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (u *Union) Initialize(p *Protocol) {
|
2012-05-01 07:08:03 +02:00
|
|
|
u.srcName = fmt.Sprintf("%sUnion", TypeSrcName(p, u))
|
2012-04-30 08:40:55 +02:00
|
|
|
for _, field := range u.Fields {
|
|
|
|
field.Initialize(p)
|
|
|
|
}
|
|
|
|
}
|