diff options
| author | Andrew Gallant (Ocelot) <Andrew.Gallant@tufts.edu> | 2012-05-02 01:46:30 -0400 | 
|---|---|---|
| committer | Andrew Gallant (Ocelot) <Andrew.Gallant@tufts.edu> | 2012-05-02 01:46:30 -0400 | 
| commit | 39507f86ab0468292c24081a80f41c1799d6b477 (patch) | |
| tree | 002668a66ec90c71b3bbd05141b378d0b2218d58 /nexgb | |
| parent | f48b6fafc6d96527a554876e13fc5a0b548005af (diff) | |
| download | haven-39507f86ab0468292c24081a80f41c1799d6b477.tar.gz haven-39507f86ab0468292c24081a80f41c1799d6b477.tar.xz haven-39507f86ab0468292c24081a80f41c1799d6b477.zip | |
finally starting on the crescendo: requests and replies.
Diffstat (limited to 'nexgb')
| -rw-r--r-- | nexgb/xgbgen/context.go | 3 | ||||
| -rw-r--r-- | nexgb/xgbgen/field.go | 4 | ||||
| -rw-r--r-- | nexgb/xgbgen/go.go | 9 | ||||
| -rw-r--r-- | nexgb/xgbgen/go_error.go | 65 | ||||
| -rw-r--r-- | nexgb/xgbgen/go_event.go | 21 | ||||
| -rw-r--r-- | nexgb/xgbgen/go_list.go | 4 | ||||
| -rw-r--r-- | nexgb/xgbgen/go_reply.go | 19 | ||||
| -rw-r--r-- | nexgb/xgbgen/representation.go | 53 | ||||
| -rw-r--r-- | nexgb/xgbgen/translation.go | 12 | ||||
| -rw-r--r-- | nexgb/xgbgen/type.go | 9 | ||||
| -rw-r--r-- | nexgb/xgbgen/xml.go | 2 | 
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"`  } | 
