Changed xgbgen to support xcb-proto 1.12
* Added minimal support for switch fields. * Changed the way Size is calculated to accomodate for lists inside structs (added to randr) * Removed heuristic to place alignment gaps, they are now explicitly described in xml
This commit is contained in:
parent
a102c4056f
commit
1c01d79ba1
|
@ -1,120 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *Protocol) AddAlignGaps() {
|
|
||||||
for i := range p.Imports {
|
|
||||||
p.Imports[i].AddAlignGaps()
|
|
||||||
}
|
|
||||||
for i := range p.Types {
|
|
||||||
switch t := p.Types[i].(type) {
|
|
||||||
case *Struct:
|
|
||||||
t.Fields = addAlignGapsToFields(t.xmlName, t.Fields)
|
|
||||||
case *Event:
|
|
||||||
t.Fields = addAlignGapsToFields(t.xmlName, t.Fields)
|
|
||||||
case *Error:
|
|
||||||
t.Fields = addAlignGapsToFields(t.xmlName, t.Fields)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i := range p.Requests {
|
|
||||||
p.Requests[i].Fields = addAlignGapsToFields(
|
|
||||||
p.Requests[i].xmlName, p.Requests[i].Fields)
|
|
||||||
if p.Requests[i].Reply != nil {
|
|
||||||
p.Requests[i].Reply.Fields = addAlignGapsToFields(
|
|
||||||
p.Requests[i].xmlName, p.Requests[i].Reply.Fields)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func addAlignGapsToFields(name string, fields []Field) []Field {
|
|
||||||
var i int
|
|
||||||
for i = 0; i < len(fields); i++ {
|
|
||||||
if _, ok := fields[i].(*ListField); ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if i >= len(fields) {
|
|
||||||
return fields
|
|
||||||
}
|
|
||||||
|
|
||||||
r := make([]Field, 0, len(fields)+2)
|
|
||||||
r = append(r, fields[:i]...)
|
|
||||||
|
|
||||||
r = append(r, fields[i])
|
|
||||||
for i = i + 1; i < len(fields); i++ {
|
|
||||||
switch f := fields[i].(type) {
|
|
||||||
case *ListField:
|
|
||||||
// ok, add padding
|
|
||||||
sz := xcbSizeOfType(f.Type)
|
|
||||||
switch {
|
|
||||||
case sz == 1:
|
|
||||||
// nothing
|
|
||||||
case sz == 2:
|
|
||||||
r = append(r, &PadField{0, 2})
|
|
||||||
case sz == 3:
|
|
||||||
panic(fmt.Errorf("Alignment is not a power of 2"))
|
|
||||||
case sz >= 4:
|
|
||||||
r = append(r, &PadField{0, 4})
|
|
||||||
}
|
|
||||||
case *LocalField:
|
|
||||||
// nothing
|
|
||||||
default:
|
|
||||||
fmt.Fprintf(os.Stderr,
|
|
||||||
"Can't add alignment gaps, mix of list and non-list "+
|
|
||||||
"fields: %s\n", name)
|
|
||||||
return fields
|
|
||||||
}
|
|
||||||
r = append(r, fields[i])
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func xcbSizeOfField(fld Field) int {
|
|
||||||
switch f := fld.(type) {
|
|
||||||
case *PadField:
|
|
||||||
return int(f.Bytes)
|
|
||||||
case *SingleField:
|
|
||||||
return xcbSizeOfType(f.Type)
|
|
||||||
case *ListField:
|
|
||||||
return 0
|
|
||||||
case *ExprField:
|
|
||||||
return xcbSizeOfType(f.Type)
|
|
||||||
case *ValueField:
|
|
||||||
return xcbSizeOfType(f.MaskType)
|
|
||||||
case *SwitchField:
|
|
||||||
return 0
|
|
||||||
default:
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func xcbSizeOfType(typ Type) int {
|
|
||||||
switch t := typ.(type) {
|
|
||||||
case *Resource:
|
|
||||||
return 4
|
|
||||||
case *TypeDef:
|
|
||||||
return t.Size().Eval()
|
|
||||||
case *Base:
|
|
||||||
return t.Size().Eval()
|
|
||||||
case *Struct:
|
|
||||||
sz := 0
|
|
||||||
for i := range t.Fields {
|
|
||||||
sz += xcbSizeOfField(t.Fields[i])
|
|
||||||
}
|
|
||||||
return sz
|
|
||||||
case *Union:
|
|
||||||
sz := 0
|
|
||||||
for i := range t.Fields {
|
|
||||||
csz := xcbSizeOfField(t.Fields[i])
|
|
||||||
if csz > sz {
|
|
||||||
sz = csz
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sz
|
|
||||||
default:
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -50,7 +50,22 @@ func (c *Context) Morph(xmlBytes []byte) {
|
||||||
// Translate XML types to nice types
|
// Translate XML types to nice types
|
||||||
c.protocol = parsedXml.Translate(nil)
|
c.protocol = parsedXml.Translate(nil)
|
||||||
|
|
||||||
c.protocol.AddAlignGaps()
|
// For backwards compatibility we patch the type of the send_event field of
|
||||||
|
// PutImage to be byte
|
||||||
|
if c.protocol.Name == "shm" {
|
||||||
|
for _, req := range c.protocol.Requests {
|
||||||
|
if req.xmlName != "PutImage" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, ifield := range req.Fields {
|
||||||
|
field, ok := ifield.(*SingleField)
|
||||||
|
if !ok || field.xmlName != "send_event" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
field.Type = &Base{ srcName: "byte", xmlName: "CARD8", size: newFixedSize(1, true) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Start with Go header.
|
// Start with Go header.
|
||||||
c.Putln("// Package %s is the X client API for the %s extension.",
|
c.Putln("// Package %s is the X client API for the %s extension.",
|
||||||
|
|
|
@ -32,6 +32,9 @@ type Expression interface {
|
||||||
// Initialize makes sure all names in this expression and any subexpressions
|
// Initialize makes sure all names in this expression and any subexpressions
|
||||||
// have been translated to Go source names.
|
// have been translated to Go source names.
|
||||||
Initialize(p *Protocol)
|
Initialize(p *Protocol)
|
||||||
|
|
||||||
|
// Makes all field references relative to path
|
||||||
|
Specialize(path string) Expression
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function is a custom expression not found in the XML. It's simply used
|
// Function is a custom expression not found in the XML. It's simply used
|
||||||
|
@ -62,6 +65,12 @@ func (e *Function) Initialize(p *Protocol) {
|
||||||
e.Expr.Initialize(p)
|
e.Expr.Initialize(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Function) Specialize(path string) Expression {
|
||||||
|
r := *e
|
||||||
|
r.Expr = r.Expr.Specialize(path)
|
||||||
|
return &r
|
||||||
|
}
|
||||||
|
|
||||||
// BinaryOp is an expression that performs some operation (defined in the XML
|
// BinaryOp is an expression that performs some operation (defined in the XML
|
||||||
// file) with Expr1 and Expr2 as operands.
|
// file) with Expr1 and Expr2 as operands.
|
||||||
type BinaryOp struct {
|
type BinaryOp struct {
|
||||||
|
@ -150,6 +159,13 @@ func (e *BinaryOp) Initialize(p *Protocol) {
|
||||||
e.Expr2.Initialize(p)
|
e.Expr2.Initialize(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *BinaryOp) Specialize(path string) Expression {
|
||||||
|
r := *e
|
||||||
|
r.Expr1 = r.Expr1.Specialize(path)
|
||||||
|
r.Expr2 = r.Expr2.Specialize(path)
|
||||||
|
return &r
|
||||||
|
}
|
||||||
|
|
||||||
// UnaryOp is the same as BinaryOp, except it's a unary operator with only
|
// UnaryOp is the same as BinaryOp, except it's a unary operator with only
|
||||||
// one sub-expression.
|
// one sub-expression.
|
||||||
type UnaryOp struct {
|
type UnaryOp struct {
|
||||||
|
@ -186,6 +202,12 @@ func (e *UnaryOp) Initialize(p *Protocol) {
|
||||||
e.Expr.Initialize(p)
|
e.Expr.Initialize(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *UnaryOp) Specialize(path string) Expression {
|
||||||
|
r := *e
|
||||||
|
r.Expr = r.Expr.Specialize(path)
|
||||||
|
return &r
|
||||||
|
}
|
||||||
|
|
||||||
// Padding represents the application of the 'pad' function to some
|
// Padding represents the application of the 'pad' function to some
|
||||||
// sub-expression.
|
// sub-expression.
|
||||||
type Padding struct {
|
type Padding struct {
|
||||||
|
@ -215,6 +237,12 @@ func (e *Padding) Initialize(p *Protocol) {
|
||||||
e.Expr.Initialize(p)
|
e.Expr.Initialize(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Padding) Specialize(path string) Expression {
|
||||||
|
r := *e
|
||||||
|
r.Expr = r.Expr.Specialize(path)
|
||||||
|
return &r
|
||||||
|
}
|
||||||
|
|
||||||
// PopCount represents the application of the 'PopCount' function to
|
// PopCount represents the application of the 'PopCount' function to
|
||||||
// some sub-expression.
|
// some sub-expression.
|
||||||
type PopCount struct {
|
type PopCount struct {
|
||||||
|
@ -244,6 +272,12 @@ func (e *PopCount) Initialize(p *Protocol) {
|
||||||
e.Expr.Initialize(p)
|
e.Expr.Initialize(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *PopCount) Specialize(path string) Expression {
|
||||||
|
r := *e
|
||||||
|
r.Expr = r.Expr.Specialize(path)
|
||||||
|
return &r
|
||||||
|
}
|
||||||
|
|
||||||
// Value represents some constant integer.
|
// Value represents some constant integer.
|
||||||
type Value struct {
|
type Value struct {
|
||||||
v int
|
v int
|
||||||
|
@ -267,6 +301,10 @@ func (e *Value) String() string {
|
||||||
|
|
||||||
func (e *Value) Initialize(p *Protocol) {}
|
func (e *Value) Initialize(p *Protocol) {}
|
||||||
|
|
||||||
|
func (e *Value) Specialize(path string) Expression {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
// Bit represents some bit whose value is computed by '1 << bit'.
|
// Bit represents some bit whose value is computed by '1 << bit'.
|
||||||
type Bit struct {
|
type Bit struct {
|
||||||
b int
|
b int
|
||||||
|
@ -290,6 +328,10 @@ func (e *Bit) String() string {
|
||||||
|
|
||||||
func (e *Bit) Initialize(p *Protocol) {}
|
func (e *Bit) Initialize(p *Protocol) {}
|
||||||
|
|
||||||
|
func (e *Bit) Specialize(path string) Expression {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
// FieldRef represents a reference to some variable in the generated code
|
// FieldRef represents a reference to some variable in the generated code
|
||||||
// with name Name.
|
// with name Name.
|
||||||
type FieldRef struct {
|
type FieldRef struct {
|
||||||
|
@ -321,6 +363,10 @@ func (e *FieldRef) Initialize(p *Protocol) {
|
||||||
e.Name = SrcName(p, e.Name)
|
e.Name = SrcName(p, e.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *FieldRef) Specialize(path string) Expression {
|
||||||
|
return &FieldRef{Name: path + "." + e.Name}
|
||||||
|
}
|
||||||
|
|
||||||
// EnumRef represents a reference to some enumeration field.
|
// EnumRef represents a reference to some enumeration field.
|
||||||
// EnumKind is the "group" an EnumItem is the name of the specific enumeration
|
// EnumKind is the "group" an EnumItem is the name of the specific enumeration
|
||||||
// value inside that group.
|
// value inside that group.
|
||||||
|
@ -351,6 +397,10 @@ func (e *EnumRef) Initialize(p *Protocol) {
|
||||||
e.EnumItem = SrcName(p, e.EnumItem)
|
e.EnumItem = SrcName(p, e.EnumItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *EnumRef) Specialize(path string) Expression {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
// SumOf represents a summation of the variable in the generated code named by
|
// SumOf represents a summation of the variable in the generated code named by
|
||||||
// Name. It is not currently used. (It's XKB voodoo.)
|
// Name. It is not currently used. (It's XKB voodoo.)
|
||||||
type SumOf struct {
|
type SumOf struct {
|
||||||
|
@ -380,3 +430,7 @@ func (e *SumOf) String() string {
|
||||||
func (e *SumOf) Initialize(p *Protocol) {
|
func (e *SumOf) Initialize(p *Protocol) {
|
||||||
e.Name = SrcName(p, e.Name)
|
e.Name = SrcName(p, e.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *SumOf) Specialize(path string) Expression {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
|
@ -73,6 +73,32 @@ func (p *PadField) Size() Size {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RequiredStartAlign struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RequiredStartAlign) Initialize(p *Protocol) { }
|
||||||
|
|
||||||
|
func (f *RequiredStartAlign) SrcName() string {
|
||||||
|
panic("illegal to take source name of a required_start_align field")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RequiredStartAlign) XmlName() string {
|
||||||
|
panic("illegal to take XML name of a required_start_align field")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RequiredStartAlign) SrcType() string {
|
||||||
|
panic("it is illegal to call SrcType on a required_start_align field")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RequiredStartAlign) Size() Size {
|
||||||
|
return newFixedSize(0, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RequiredStartAlign) Define(c *Context) { }
|
||||||
|
|
||||||
|
func (f *RequiredStartAlign) Read(c *Context, prefix string) { }
|
||||||
|
func (f *RequiredStartAlign) Write(c *Context, prefix string) { }
|
||||||
|
|
||||||
// SingleField represents most of the fields in an XML protocol description.
|
// SingleField represents most of the fields in an XML protocol description.
|
||||||
// It corresponds to any single value.
|
// It corresponds to any single value.
|
||||||
type SingleField struct {
|
type SingleField struct {
|
||||||
|
@ -289,35 +315,72 @@ func (f *ValueField) Initialize(p *Protocol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SwitchField represents a 'switch' element in the XML protocol description
|
// SwitchField represents a 'switch' element in the XML protocol description
|
||||||
// file. It is not currently used. (i.e., it is XKB voodoo.)
|
// file.
|
||||||
|
// Currently we translate this to a slice of uint32 and let the user sort
|
||||||
|
// through it.
|
||||||
type SwitchField struct {
|
type SwitchField struct {
|
||||||
|
xmlName string
|
||||||
Name string
|
Name string
|
||||||
|
MaskName string
|
||||||
Expr Expression
|
Expr Expression
|
||||||
Bitcases []*Bitcase
|
Bitcases []*Bitcase
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *SwitchField) SrcName() string {
|
func (f *SwitchField) SrcName() string {
|
||||||
panic("it is illegal to call SrcName on a SwitchField field")
|
return f.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *SwitchField) XmlName() string {
|
func (f *SwitchField) XmlName() string {
|
||||||
panic("it is illegal to call XmlName on a SwitchField field")
|
return f.xmlName
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *SwitchField) SrcType() string {
|
func (f *SwitchField) SrcType() string {
|
||||||
panic("it is illegal to call SrcType on a SwitchField field")
|
return "[]uint32"
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: This is a bit tricky. The size has to be represented as a non-concrete
|
|
||||||
// expression that finds *which* bitcase fields are included, and sums the
|
|
||||||
// sizes of those fields.
|
|
||||||
func (f *SwitchField) Size() Size {
|
func (f *SwitchField) Size() Size {
|
||||||
return newFixedSize(0, true)
|
// TODO: size expression used here is not correct unless every element of
|
||||||
|
// the switch is 32 bit long. This assumption holds for xproto but may not
|
||||||
|
// hold for other protocols (xkb?)
|
||||||
|
listSize := newExpressionSize(&Function{
|
||||||
|
Name: "xgb.Pad",
|
||||||
|
Expr: &BinaryOp{
|
||||||
|
Op: "*",
|
||||||
|
Expr1: &Value{v: 4},
|
||||||
|
Expr2: &PopCount{
|
||||||
|
Expr: &Function{
|
||||||
|
Name: "int",
|
||||||
|
Expr: &FieldRef{
|
||||||
|
Name: f.MaskName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, true)
|
||||||
|
|
||||||
|
return listSize
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *SwitchField) ListLength() Size {
|
||||||
|
return newExpressionSize(&PopCount{
|
||||||
|
Expr: &Function{
|
||||||
|
Name: "int",
|
||||||
|
Expr: &FieldRef{
|
||||||
|
Name: f.MaskName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *SwitchField) Initialize(p *Protocol) {
|
func (f *SwitchField) Initialize(p *Protocol) {
|
||||||
|
f.xmlName = f.Name
|
||||||
f.Name = SrcName(p, f.Name)
|
f.Name = SrcName(p, f.Name)
|
||||||
f.Expr.Initialize(p)
|
f.Expr.Initialize(p)
|
||||||
|
fieldref, ok := f.Expr.(*FieldRef)
|
||||||
|
if !ok {
|
||||||
|
panic("switch field's expression not a fieldref")
|
||||||
|
}
|
||||||
|
f.MaskName = SrcName(p, fieldref.Name)
|
||||||
for _, bitcase := range f.Bitcases {
|
for _, bitcase := range f.Bitcases {
|
||||||
bitcase.Expr.Initialize(p)
|
bitcase.Expr.Initialize(p)
|
||||||
for _, field := range bitcase.Fields {
|
for _, field := range bitcase.Fields {
|
||||||
|
|
|
@ -186,11 +186,8 @@ func (f *ValueField) Read(c *Context, prefix string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *ValueField) Write(c *Context, prefix string) {
|
func (f *ValueField) Write(c *Context, prefix string) {
|
||||||
// big time mofos
|
|
||||||
if rq, ok := f.Parent.(*Request); !ok || rq.SrcName() != "ConfigureWindow" {
|
|
||||||
WriteSimpleSingleField(c,
|
WriteSimpleSingleField(c,
|
||||||
fmt.Sprintf("%s%s", prefix, f.MaskName), f.MaskType)
|
fmt.Sprintf("%s%s", prefix, f.MaskName), f.MaskType)
|
||||||
}
|
|
||||||
c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix))
|
c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix))
|
||||||
c.Putln("xgb.Put32(buf[b:], %s%s[i])", prefix, f.ListName)
|
c.Putln("xgb.Put32(buf[b:], %s%s[i])", prefix, f.ListName)
|
||||||
c.Putln("b += 4")
|
c.Putln("b += 4")
|
||||||
|
@ -200,16 +197,24 @@ func (f *ValueField) Write(c *Context, prefix string) {
|
||||||
|
|
||||||
// Switch field
|
// Switch field
|
||||||
func (f *SwitchField) Define(c *Context) {
|
func (f *SwitchField) Define(c *Context) {
|
||||||
c.Putln("// switch field: %s (%s)", f.Name, f.Expr)
|
c.Putln("%s []uint32", f.Name)
|
||||||
panic("todo")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *SwitchField) Read(c *Context, prefix string) {
|
func (f *SwitchField) Read(c *Context, prefix string) {
|
||||||
c.Putln("// reading switch field: %s (%s)", f.Name, f.Expr)
|
c.Putln("")
|
||||||
panic("todo")
|
c.Putln("%s%s = make([]uint32, %s)",
|
||||||
|
prefix, f.Name, f.ListLength().Reduce(prefix))
|
||||||
|
c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix))
|
||||||
|
c.Putln("%s%s[i] = xgb.Get32(buf[b:])", prefix, f.Name)
|
||||||
|
c.Putln("b += 4")
|
||||||
|
c.Putln("}")
|
||||||
|
c.Putln("b = xgb.Pad(b)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *SwitchField) Write(c *Context, prefix string) {
|
func (f *SwitchField) Write(c *Context, prefix string) {
|
||||||
c.Putln("// writing switch field: %s (%s)", f.Name, f.Expr)
|
c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix))
|
||||||
panic("todo")
|
c.Putln("xgb.Put32(buf[b:], %s%s[i])", prefix, f.Name)
|
||||||
|
c.Putln("b += 4")
|
||||||
|
c.Putln("}")
|
||||||
|
c.Putln("b = xgb.Pad(b)")
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,10 +205,7 @@ func (r *Request) ParamNames() string {
|
||||||
for _, field := range r.Fields {
|
for _, field := range r.Fields {
|
||||||
switch f := field.(type) {
|
switch f := field.(type) {
|
||||||
case *ValueField:
|
case *ValueField:
|
||||||
// mofos...
|
|
||||||
if r.SrcName() != "ConfigureWindow" {
|
|
||||||
names = append(names, f.MaskName)
|
names = append(names, f.MaskName)
|
||||||
}
|
|
||||||
names = append(names, f.ListName)
|
names = append(names, f.ListName)
|
||||||
case *PadField:
|
case *PadField:
|
||||||
continue
|
continue
|
||||||
|
@ -226,17 +223,16 @@ func (r *Request) ParamNameTypes() string {
|
||||||
for _, field := range r.Fields {
|
for _, field := range r.Fields {
|
||||||
switch f := field.(type) {
|
switch f := field.(type) {
|
||||||
case *ValueField:
|
case *ValueField:
|
||||||
// mofos...
|
|
||||||
if r.SrcName() != "ConfigureWindow" {
|
|
||||||
nameTypes = append(nameTypes,
|
nameTypes = append(nameTypes,
|
||||||
fmt.Sprintf("%s %s", f.MaskName, f.MaskType.SrcName()))
|
fmt.Sprintf("%s %s", f.MaskName, f.MaskType.SrcName()))
|
||||||
}
|
|
||||||
nameTypes = append(nameTypes,
|
nameTypes = append(nameTypes,
|
||||||
fmt.Sprintf("%s []uint32", f.ListName))
|
fmt.Sprintf("%s []uint32", f.ListName))
|
||||||
case *PadField:
|
case *PadField:
|
||||||
continue
|
continue
|
||||||
case *ExprField:
|
case *ExprField:
|
||||||
continue
|
continue
|
||||||
|
case *RequiredStartAlign:
|
||||||
|
continue
|
||||||
default:
|
default:
|
||||||
nameTypes = append(nameTypes,
|
nameTypes = append(nameTypes,
|
||||||
fmt.Sprintf("%s %s", field.SrcName(), field.SrcType()))
|
fmt.Sprintf("%s %s", field.SrcName(), field.SrcType()))
|
||||||
|
|
|
@ -105,17 +105,15 @@ func (r *Request) Size(c *Context) Size {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, field := range r.Fields {
|
for _, field := range r.Fields {
|
||||||
switch field.(type) {
|
switch field := field.(type) {
|
||||||
case *LocalField: // local fields don't go over the wire
|
case *LocalField: // local fields don't go over the wire
|
||||||
continue
|
continue
|
||||||
case *SingleField:
|
case *SingleField:
|
||||||
// mofos!!!
|
fsz := field.Size()
|
||||||
if r.SrcName() == "ConfigureWindow" &&
|
if _, isstruct := field.Type.(*Struct); isstruct {
|
||||||
field.SrcName() == "ValueMask" {
|
fsz.Expression = fsz.Expression.Specialize(field.SrcName())
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
size = size.Add(field.Size())
|
size = size.Add(fsz)
|
||||||
default:
|
default:
|
||||||
size = size.Add(field.Size())
|
size = size.Add(field.Size())
|
||||||
}
|
}
|
||||||
|
|
|
@ -325,12 +325,14 @@ func (x *XMLField) Translate(parent interface{}) Field {
|
||||||
case "pad":
|
case "pad":
|
||||||
return &PadField{
|
return &PadField{
|
||||||
Bytes: x.Bytes,
|
Bytes: x.Bytes,
|
||||||
|
Align: x.Align,
|
||||||
}
|
}
|
||||||
case "field":
|
case "field":
|
||||||
return &SingleField{
|
s := &SingleField{
|
||||||
xmlName: x.Name,
|
xmlName: x.Name,
|
||||||
Type: newTranslation(x.Type),
|
Type: newTranslation(x.Type),
|
||||||
}
|
}
|
||||||
|
return s
|
||||||
case "list":
|
case "list":
|
||||||
return &ListField{
|
return &ListField{
|
||||||
xmlName: x.Name,
|
xmlName: x.Name,
|
||||||
|
@ -365,6 +367,8 @@ func (x *XMLField) Translate(parent interface{}) Field {
|
||||||
swtch.Bitcases[i] = bitcase.Translate()
|
swtch.Bitcases[i] = bitcase.Translate()
|
||||||
}
|
}
|
||||||
return swtch
|
return swtch
|
||||||
|
case "required_start_align":
|
||||||
|
return &RequiredStartAlign{}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Panicf("Unrecognized field element: %s", x.XMLName.Local)
|
log.Panicf("Unrecognized field element: %s", x.XMLName.Local)
|
||||||
|
|
|
@ -10,6 +10,7 @@ type XMLField struct {
|
||||||
|
|
||||||
// For 'pad' element
|
// For 'pad' element
|
||||||
Bytes uint `xml:"bytes,attr"`
|
Bytes uint `xml:"bytes,attr"`
|
||||||
|
Align uint16 `xml:"align,attr"`
|
||||||
|
|
||||||
// For 'field', 'list', 'localfield', 'exprfield' and 'switch' elements.
|
// For 'field', 'list', 'localfield', 'exprfield' and 'switch' elements.
|
||||||
Name string `xml:"name,attr"`
|
Name string `xml:"name,attr"`
|
||||||
|
|
Loading…
Reference in New Issue