aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Gallant (Ocelot) <Andrew.Gallant@tufts.edu>2012-05-02 01:46:30 -0400
committerAndrew Gallant (Ocelot) <Andrew.Gallant@tufts.edu>2012-05-02 01:46:30 -0400
commit39507f86ab0468292c24081a80f41c1799d6b477 (patch)
tree002668a66ec90c71b3bbd05141b378d0b2218d58
parentf48b6fafc6d96527a554876e13fc5a0b548005af (diff)
downloadhaven-39507f86ab0468292c24081a80f41c1799d6b477.tar.gz
haven-39507f86ab0468292c24081a80f41c1799d6b477.tar.xz
haven-39507f86ab0468292c24081a80f41c1799d6b477.zip
finally starting on the crescendo: requests and replies.
-rw-r--r--nexgb/xgbgen/context.go3
-rw-r--r--nexgb/xgbgen/field.go4
-rw-r--r--nexgb/xgbgen/go.go9
-rw-r--r--nexgb/xgbgen/go_error.go65
-rw-r--r--nexgb/xgbgen/go_event.go21
-rw-r--r--nexgb/xgbgen/go_list.go4
-rw-r--r--nexgb/xgbgen/go_reply.go19
-rw-r--r--nexgb/xgbgen/representation.go53
-rw-r--r--nexgb/xgbgen/translation.go12
-rw-r--r--nexgb/xgbgen/type.go9
-rw-r--r--nexgb/xgbgen/xml.go2
11 files changed, 153 insertions, 48 deletions
diff --git a/nexgb/xgbgen/context.go b/nexgb/xgbgen/context.go
index 67801c7..33641b3 100644
--- a/nexgb/xgbgen/context.go
+++ b/nexgb/xgbgen/context.go
@@ -51,4 +51,7 @@ func (c *Context) Morph(xmlBytes []byte) {
for _, typ := range c.protocol.Types {
typ.Define(c)
}
+ for _, req := range c.protocol.Requests {
+ req.Define(c)
+ }
}
diff --git a/nexgb/xgbgen/field.go b/nexgb/xgbgen/field.go
index 6d39af2..8d8412c 100644
--- a/nexgb/xgbgen/field.go
+++ b/nexgb/xgbgen/field.go
@@ -102,8 +102,10 @@ func (f *ListField) Size() Size {
return newExpressionSize(simpleLen)
case *Resource:
return newExpressionSize(simpleLen)
+ case *TypeDef:
+ return newExpressionSize(simpleLen)
default:
- log.Fatalf("Cannot compute list size with type '%T'.", f.Type)
+ log.Panicf("Cannot compute list size with type '%T'.", f.Type)
}
panic("unreachable")
}
diff --git a/nexgb/xgbgen/go.go b/nexgb/xgbgen/go.go
index 11e413b..b7b153e 100644
--- a/nexgb/xgbgen/go.go
+++ b/nexgb/xgbgen/go.go
@@ -105,57 +105,48 @@ func (f *PadField) Write(c *Context) {
// Local fields
func (f *LocalField) Define(c *Context) {
c.Putln("// local field: %s %s", f.SrcName(), f.Type.SrcName())
- panic("todo")
}
func (f *LocalField) Read(c *Context) {
c.Putln("// reading local field: %s (%s) :: %s",
f.SrcName(), f.Size(), f.Type.SrcName())
- panic("todo")
}
func (f *LocalField) Write(c *Context) {
c.Putln("// writing local field: %s (%s) :: %s",
f.SrcName(), f.Size(), f.Type.SrcName())
- panic("todo")
}
// Expr fields
func (f *ExprField) Define(c *Context) {
c.Putln("// expression field: %s %s (%s)",
f.SrcName(), f.Type.SrcName(), f.Expr)
- panic("todo")
}
func (f *ExprField) Read(c *Context) {
c.Putln("// reading expression field: %s (%s) (%s) :: %s",
f.SrcName(), f.Size(), f.Expr, f.Type.SrcName())
- panic("todo")
}
func (f *ExprField) Write(c *Context) {
c.Putln("// writing expression field: %s (%s) (%s) :: %s",
f.SrcName(), f.Size(), f.Expr, f.Type.SrcName())
- panic("todo")
}
// Value field
func (f *ValueField) Define(c *Context) {
c.Putln("// valueparam field: type: %s, mask name: %s, list name: %s",
f.MaskType.SrcName(), f.MaskName, f.ListName)
- panic("todo")
}
func (f *ValueField) Read(c *Context) {
c.Putln("// reading valueparam: type: %s, mask name: %s, list name: %s",
f.MaskType.SrcName(), f.MaskName, f.ListName)
- panic("todo")
}
func (f *ValueField) Write(c *Context) {
c.Putln("// writing valueparam: type: %s, mask name: %s, list name: %s",
f.MaskType.SrcName(), f.MaskName, f.ListName)
- panic("todo")
}
// Switch field
diff --git a/nexgb/xgbgen/go_error.go b/nexgb/xgbgen/go_error.go
index 493a8b9..17c0db5 100644
--- a/nexgb/xgbgen/go_error.go
+++ b/nexgb/xgbgen/go_error.go
@@ -3,15 +3,53 @@ package main
// Error types
func (e *Error) Define(c *Context) {
c.Putln("// Error definition %s (%d)", e.SrcName(), e.Number)
+ c.Putln("// Size: %s", e.Size())
+ c.Putln("")
+ c.Putln("const %s = %d", e.ErrConst(), e.Number)
+ c.Putln("")
+ c.Putln("type %s struct {", e.ErrType())
+ c.Putln("Sequence uint16")
+ c.Putln("NiceName string")
+ for _, field := range e.Fields {
+ field.Define(c)
+ }
+ c.Putln("}")
c.Putln("")
-}
-func (e *Error) Read(c *Context, prefix string) {
- c.Putln("// Error read %s", e.SrcName())
+ // Read defines a function that transforms a byte slice into this
+ // error struct.
+ e.Read(c)
+
+ // Makes sure that this error type is an Error interface.
+ c.Putln("func (v %s) ImplementsError() { }", e.ErrType())
+ c.Putln("")
+
+ // Let's the XGB event loop read this error.
+ c.Putln("func init() {")
+ c.Putln("newErrorFuncs[%d] = New%s", e.Number, e.ErrType())
+ c.Putln("}")
+ c.Putln("")
}
-func (e *Error) Write(c *Context, prefix string) {
- c.Putln("// Error write %s", e.SrcName())
+func (e *Error) Read(c *Context) {
+ c.Putln("// Error read %s", e.SrcName())
+ c.Putln("func New%s(buf []byte) %s {", e.ErrType(), e.ErrType())
+ c.Putln("v := %s{}", e.ErrType())
+ c.Putln("v.NiceName = \"%s\"", e.SrcName())
+ c.Putln("")
+ c.Putln("b := 1 // skip error determinant")
+ c.Putln("b += 1 // don't read error number")
+ c.Putln("")
+ c.Putln("v.Sequence = get16(buf[b:])")
+ c.Putln("b += 2")
+ c.Putln("")
+ for _, field := range e.Fields {
+ field.Read(c)
+ c.Putln("")
+ }
+ c.Putln("return v")
+ c.Putln("}")
+ c.Putln("")
}
// ErrorCopy types
@@ -27,31 +65,20 @@ func (e *ErrorCopy) Define(c *Context) {
// error struct.
e.Read(c)
- // Write defines a function that transoforms this error struct into
- // a byte slice.
- e.Write(c)
-
// Makes sure that this error type is an Error interface.
c.Putln("func (err %s) ImplementsError() { }", e.ErrType())
c.Putln("")
// Let's the XGB know how to read this error.
c.Putln("func init() {")
- c.Putln("newErrorFuncs[%d] = New%s", e.Number, e.SrcName())
+ c.Putln("newErrorFuncs[%d] = New%s", e.Number, e.ErrType())
c.Putln("}")
c.Putln("")
}
func (e *ErrorCopy) Read(c *Context) {
- c.Putln("func New%s(buf []byte) %s {", e.SrcName(), e.ErrType())
- c.Putln("return (%s)(New%s(buf))", e.ErrType(), e.Old.SrcName())
- c.Putln("}")
- c.Putln("")
-}
-
-func (e *ErrorCopy) Write(c *Context) {
- c.Putln("func (err %s) Bytes() []byte {", e.ErrType())
- c.Putln("return (%s)(err).Bytes()", e.Old.(*Error).ErrType())
+ c.Putln("func New%s(buf []byte) %s {", e.ErrType(), e.ErrType())
+ c.Putln("return %s(New%s(buf))", e.ErrType(), e.Old.(*Error).ErrType())
c.Putln("}")
c.Putln("")
}
diff --git a/nexgb/xgbgen/go_event.go b/nexgb/xgbgen/go_event.go
index e6d40b0..fe2a77e 100644
--- a/nexgb/xgbgen/go_event.go
+++ b/nexgb/xgbgen/go_event.go
@@ -4,8 +4,13 @@ package main
func (e *Event) Define(c *Context) {
c.Putln("// Event definition %s (%d)", e.SrcName(), e.Number)
c.Putln("// Size: %s", e.Size())
+ c.Putln("")
+ c.Putln("const %s = %d", e.SrcName(), e.Number)
+ c.Putln("")
c.Putln("type %s struct {", e.EvType())
- c.Putln("Sequence uint16")
+ if !e.NoSequence {
+ c.Putln("Sequence uint16")
+ }
for _, field := range e.Fields {
field.Define(c)
}
@@ -16,7 +21,7 @@ func (e *Event) Define(c *Context) {
// event struct.
e.Read(c)
- // Write defines a function that transoforms this event struct into
+ // Write defines a function that transforms this event struct into
// a byte slice.
e.Write(c)
@@ -26,14 +31,14 @@ func (e *Event) Define(c *Context) {
// Let's the XGB event loop read this event.
c.Putln("func init() {")
- c.Putln("newEventFuncs[%d] = New%s", e.Number, e.SrcName())
+ c.Putln("newEventFuncs[%d] = New%s", e.Number, e.EvType())
c.Putln("}")
c.Putln("")
}
func (e *Event) Read(c *Context) {
c.Putln("// Event read %s", e.SrcName())
- c.Putln("func New%s(buf []byte) %s {", e.SrcName(), e.EvType())
+ c.Putln("func New%s(buf []byte) %s {", e.EvType(), e.EvType())
c.Putln("v := %s{}", e.EvType())
c.Putln("b := 1 // don't read event number")
c.Putln("")
@@ -97,21 +102,21 @@ func (e *EventCopy) Define(c *Context) {
// Let's the XGB event loop read this event.
c.Putln("func init() {")
- c.Putln("newEventFuncs[%d] = New%s", e.Number, e.SrcName())
+ c.Putln("newEventFuncs[%d] = New%s", e.Number, e.EvType())
c.Putln("}")
c.Putln("")
}
func (e *EventCopy) Read(c *Context) {
- c.Putln("func New%s(buf []byte) %s {", e.SrcName(), e.EvType())
- c.Putln("return (%s)(New%s(buf))", e.EvType(), e.Old.SrcName())
+ c.Putln("func New%s(buf []byte) %s {", e.EvType(), e.EvType())
+ c.Putln("return %s(New%s(buf))", e.EvType(), e.Old.(*Event).EvType())
c.Putln("}")
c.Putln("")
}
func (e *EventCopy) Write(c *Context) {
c.Putln("func (v %s) Bytes() []byte {", e.EvType())
- c.Putln("return (%s)(ev).Bytes()", e.Old.(*Event).EvType())
+ c.Putln("return %s(ev).Bytes()", e.Old.(*Event).EvType())
c.Putln("}")
c.Putln("")
}
diff --git a/nexgb/xgbgen/go_list.go b/nexgb/xgbgen/go_list.go
index a95ba71..67ecd34 100644
--- a/nexgb/xgbgen/go_list.go
+++ b/nexgb/xgbgen/go_list.go
@@ -41,7 +41,7 @@ func (f *ListField) Read(c *Context) {
f.SrcName(), t.SrcName(), f.LengthExpr.Reduce("v.", ""))
c.Putln("b += Read%sList(buf[b:], v.%s)", t.SrcName(), f.SrcName())
default:
- log.Fatalf("Cannot read list field '%s' with %T type.",
+ log.Panicf("Cannot read list field '%s' with %T type.",
f.XmlName(), f.Type)
}
}
@@ -70,7 +70,7 @@ func (f *ListField) Write(c *Context) {
case *Struct:
c.Putln("b += %sListBytes(buf[b:], v.%s)", t.SrcName(), f.SrcName())
default:
- log.Fatalf("Cannot read list field '%s' with %T type.",
+ log.Panicf("Cannot read list field '%s' with %T type.",
f.XmlName(), f.Type)
}
}
diff --git a/nexgb/xgbgen/go_reply.go b/nexgb/xgbgen/go_reply.go
new file mode 100644
index 0000000..e561d9c
--- /dev/null
+++ b/nexgb/xgbgen/go_reply.go
@@ -0,0 +1,19 @@
+package main
+
+func (r *Request) Define(c *Context) {
+ c.Putln("// Request %s", r.SrcName())
+ c.Putln("// size: %s", r.Size(c))
+ c.Putln("")
+ if r.Reply != nil {
+ c.Putln("// Request reply for %s", r.SrcName())
+ c.Putln("// size: %s", r.Reply.Size())
+ c.Putln("type %s struct {", r.ReplyName())
+ c.Putln("Sequence uint16")
+ for _, field := range r.Reply.Fields {
+ field.Define(c)
+ }
+ c.Putln("}")
+ c.Putln("")
+ }
+}
+
diff --git a/nexgb/xgbgen/representation.go b/nexgb/xgbgen/representation.go
index 2d33a45..e5d2202 100644
--- a/nexgb/xgbgen/representation.go
+++ b/nexgb/xgbgen/representation.go
@@ -1,5 +1,10 @@
package main
+import (
+ "fmt"
+ "log"
+)
+
type Protocol struct {
Name string
ExtXName string
@@ -44,10 +49,58 @@ func (r *Request) Initialize(p *Protocol) {
}
}
+func (r *Request) SrcName() string {
+ return r.srcName
+}
+
+func (r *Request) XmlName() string {
+ return r.xmlName
+}
+
+func (r *Request) ReplyName() string {
+ if r.Reply == nil {
+ log.Panicf("Cannot call 'ReplyName' on request %s, which has no reply.",
+ r.SrcName())
+ }
+ return fmt.Sprintf("%sReply", r.SrcName())
+}
+
+// Size for Request needs a context.
+// Namely, if this is an extension, we need to account for *four* bytes
+// of a header (extension opcode, request opcode, and the sequence number).
+// If it's a core protocol request, then we only account for *three*
+// bytes of the header (remove the extension opcode).
+func (r *Request) Size(c *Context) Size {
+ size := newFixedSize(0)
+
+ if c.protocol.Name == "xproto" {
+ size = size.Add(newFixedSize(3))
+ } else {
+ size = size.Add(newFixedSize(4))
+ }
+
+ for _, field := range r.Fields {
+ size = size.Add(field.Size())
+ }
+ return size
+}
+
type Reply struct {
Fields []Field
}
+func (r *Reply) Size() Size {
+ size := newFixedSize(0)
+
+ // Account for reply discriminant, sequence number and reply length
+ size = size.Add(newFixedSize(7))
+
+ for _, field := range r.Fields {
+ size = size.Add(field.Size())
+ }
+ return size
+}
+
func (r *Reply) Initialize(p *Protocol) {
for _, field := range r.Fields {
field.Initialize(p)
diff --git a/nexgb/xgbgen/translation.go b/nexgb/xgbgen/translation.go
index 36daa8b..9c7603b 100644
--- a/nexgb/xgbgen/translation.go
+++ b/nexgb/xgbgen/translation.go
@@ -210,11 +210,13 @@ func (x *XMLRequest) Translate() *Request {
// computation of the 'odd_length' field. However, 'string_len' is not
// defined. Therefore, let's forcefully add it as a 'local field'.
// (i.e., a parameter in the caller but does not get send over the wire.)
- stringLenLocal := &LocalField{&SingleField{
- xmlName: "string_len",
- Type: newTranslation("CARD16"),
- }}
- r.Fields = append(r.Fields, stringLenLocal)
+ if x.Name == "QueryTextExtents" {
+ stringLenLocal := &LocalField{&SingleField{
+ xmlName: "string_len",
+ Type: newTranslation("CARD16"),
+ }}
+ r.Fields = append(r.Fields, stringLenLocal)
+ }
return r
}
diff --git a/nexgb/xgbgen/type.go b/nexgb/xgbgen/type.go
index 1e06bda..d8e76a2 100644
--- a/nexgb/xgbgen/type.go
+++ b/nexgb/xgbgen/type.go
@@ -221,7 +221,7 @@ func (e *EventCopy) XmlName() string {
}
func (e *EventCopy) Size() Size {
- panic("Cannot take size of EventCopy type.")
+ return newExpressionSize(&Value{v: 32})
}
func (e *EventCopy) Initialize(p *Protocol) {
@@ -252,11 +252,14 @@ func (e *Error) XmlName() string {
}
func (e *Error) Size() Size {
- panic("Cannot take size of Error type.")
+ return newExpressionSize(&Value{v: 32})
}
func (e *Error) Initialize(p *Protocol) {
e.srcName = TypeSrcName(p, e)
+ for _, field := range e.Fields {
+ field.Initialize(p)
+ }
}
func (e *Error) ErrConst() string {
@@ -283,7 +286,7 @@ func (e *ErrorCopy) XmlName() string {
}
func (e *ErrorCopy) Size() Size {
- panic("Cannot take size of ErrorCopy type.")
+ return newExpressionSize(&Value{v: 32})
}
func (e *ErrorCopy) Initialize(p *Protocol) {
diff --git a/nexgb/xgbgen/xml.go b/nexgb/xgbgen/xml.go
index f219c2d..1b2f89a 100644
--- a/nexgb/xgbgen/xml.go
+++ b/nexgb/xgbgen/xml.go
@@ -135,7 +135,7 @@ type XMLEvents []*XMLEvent
type XMLEvent struct {
Name string `xml:"name,attr"`
Number int `xml:"number,attr"`
- NoSequence bool `xml:"no-sequence-number,true"`
+ NoSequence bool `xml:"no-sequence-number,attr"`
Fields XMLFields `xml:",any"`
}