diff options
Diffstat (limited to 'nexgb/xgbgen')
-rw-r--r-- | nexgb/xgbgen/context.go | 76 | ||||
-rw-r--r-- | nexgb/xgbgen/expression.go | 4 | ||||
-rw-r--r-- | nexgb/xgbgen/field.go | 2 | ||||
-rw-r--r-- | nexgb/xgbgen/go.go | 10 | ||||
-rw-r--r-- | nexgb/xgbgen/go_error.go | 23 | ||||
-rw-r--r-- | nexgb/xgbgen/go_event.go | 27 | ||||
-rw-r--r-- | nexgb/xgbgen/go_list.go | 22 | ||||
-rw-r--r-- | nexgb/xgbgen/go_request_reply.go | 53 | ||||
-rw-r--r-- | nexgb/xgbgen/go_single_field.go | 42 | ||||
-rw-r--r-- | nexgb/xgbgen/go_struct.go | 10 | ||||
-rw-r--r-- | nexgb/xgbgen/go_union.go | 14 | ||||
-rw-r--r-- | nexgb/xgbgen/protocol.go | 24 | ||||
-rw-r--r-- | nexgb/xgbgen/request_reply.go | 3 | ||||
-rw-r--r-- | nexgb/xgbgen/translation.go | 36 |
14 files changed, 194 insertions, 152 deletions
diff --git a/nexgb/xgbgen/context.go b/nexgb/xgbgen/context.go index a7a1d1d..67699cf 100644 --- a/nexgb/xgbgen/context.go +++ b/nexgb/xgbgen/context.go @@ -5,7 +5,6 @@ import ( "encoding/xml" "fmt" "log" - "strings" "time" ) @@ -49,10 +48,10 @@ func (c *Context) Morph(xmlBytes []byte) { parsedXml.Imports.Eval() // Translate XML types to nice types - c.protocol = parsedXml.Translate() + c.protocol = parsedXml.Translate(nil) // Start with Go header. - c.Putln("package xgb") + c.Putln("package %s", c.protocol.PkgName()) c.Putln("") c.Putln("/*") c.Putln("\tThis file was generated by %s.xml on %s.", @@ -61,44 +60,53 @@ func (c *Context) Morph(xmlBytes []byte) { c.Putln("*/") c.Putln("") - // Write imports in comments - if len(c.protocol.Imports) > 0 { - c.Putln("// Imports are not necessary for XGB because everything is ") - c.Putln("// in one package. They are still listed here for reference.") - for _, imp := range c.protocol.Imports { - c.Putln("// import \"%s\"", imp.Name) + // Write imports. We always need to import at least xgb. + // We also need to import xproto if it's an extension. + c.Putln("import (") + c.Putln("\"github.com/BurntSushi/xgb\"") + c.Putln("") + if c.protocol.isExt() { + c.Putln("\"github.com/BurntSushi/xgb/xproto\"") + } + for _, imp := range c.protocol.Imports { + // We always import xproto, so skip it if it's explicitly imported + if imp.Name == "xproto" { + continue } - c.Putln("") + c.Putln("\"github.com/BurntSushi/xgb/%s\"", imp.Name) } + c.Putln(")") + c.Putln("") // If this is an extension, create a function to initialize the extension // before it can be used. if c.protocol.isExt() { - name := strings.Title(c.protocol.Name) + "Init" xname := c.protocol.ExtXName - c.Putln("// %s must be called before using the %s extension.", - name, xname) - c.Putln("func (c *Conn) %s() error {", name) - c.Putln("reply, err := c.QueryExtension(%d, \"%s\").Reply()", + c.Putln("// Init must be called before using the %s extension.", + xname) + c.Putln("func Init(c *xgb.Conn) error {") + c.Putln("reply, err := xproto.QueryExtension(c, %d, \"%s\").Reply()", len(xname), xname) c.Putln("switch {") c.Putln("case err != nil:") c.Putln("return err") c.Putln("case !reply.Present:") - c.Putln("return errorf(\"No extension named %s could be found on "+ + c.Putln("return xgb.Errorf(\"No extension named %s could be found on "+ "on the server.\")", xname) c.Putln("}") c.Putln("") - c.Putln("c.extLock.Lock()") - c.Putln("c.extensions[\"%s\"] = reply.MajorOpcode", xname) - c.Putln("for evNum, fun := range newExtEventFuncs[\"%s\"] {", xname) - c.Putln("newEventFuncs[int(reply.FirstEvent) + evNum] = fun") + c.Putln("xgb.ExtLock.Lock()") + c.Putln("c.Extensions[\"%s\"] = reply.MajorOpcode", xname) + c.Putln("for evNum, fun := range xgb.NewExtEventFuncs[\"%s\"] {", + xname) + c.Putln("xgb.NewEventFuncs[int(reply.FirstEvent) + evNum] = fun") c.Putln("}") - c.Putln("for errNum, fun := range newExtErrorFuncs[\"%s\"] {", xname) - c.Putln("newErrorFuncs[int(reply.FirstError) + errNum] = fun") + c.Putln("for errNum, fun := range xgb.NewExtErrorFuncs[\"%s\"] {", + xname) + c.Putln("xgb.NewErrorFuncs[int(reply.FirstError) + errNum] = fun") c.Putln("}") - c.Putln("c.extLock.Unlock()") + c.Putln("xgb.ExtLock.Unlock()") c.Putln("") c.Putln("return nil") c.Putln("}") @@ -107,8 +115,26 @@ func (c *Context) Morph(xmlBytes []byte) { // Make sure newExtEventFuncs["EXT_NAME"] map is initialized. // Same deal for newExtErrorFuncs["EXT_NAME"] c.Putln("func init() {") - c.Putln("newExtEventFuncs[\"%s\"] = make(map[int]newEventFun)", xname) - c.Putln("newExtErrorFuncs[\"%s\"] = make(map[int]newErrorFun)", xname) + c.Putln("xgb.NewExtEventFuncs[\"%s\"] = make(map[int]xgb.NewEventFun)", + xname) + c.Putln("xgb.NewExtErrorFuncs[\"%s\"] = make(map[int]xgb.NewErrorFun)", + xname) + c.Putln("}") + c.Putln("") + } else { + // In the xproto package, we must provide a Setup function that uses + // SetupBytes in xgb.Conn to return a SetupInfo structure. + c.Putln("// Setup parses the setup bytes retrieved when") + c.Putln("// connecting into a SetupInfo struct.") + c.Putln("func Setup(c *xgb.Conn) *SetupInfo {") + c.Putln("setup := new(SetupInfo)") + c.Putln("SetupInfoRead(c.SetupBytes, setup)") + c.Putln("return setup") + c.Putln("}") + c.Putln("") + c.Putln("// DefaultScreen gets the default screen info from SetupInfo.") + c.Putln("func (s *SetupInfo) DefaultScreen(c *xgb.Conn) *ScreenInfo {") + c.Putln("return &s.Roots[c.DefaultScreen]") c.Putln("}") c.Putln("") } diff --git a/nexgb/xgbgen/expression.go b/nexgb/xgbgen/expression.go index 0966b58..2047b5f 100644 --- a/nexgb/xgbgen/expression.go +++ b/nexgb/xgbgen/expression.go @@ -204,7 +204,7 @@ func (e *Padding) Reduce(prefix string) string { if e.Concrete() { return fmt.Sprintf("%d", e.Eval()) } - return fmt.Sprintf("pad(%s)", e.Expr.Reduce(prefix)) + return fmt.Sprintf("xgb.Pad(%s)", e.Expr.Reduce(prefix)) } func (e *Padding) String() string { @@ -233,7 +233,7 @@ func (e *PopCount) Reduce(prefix string) string { if e.Concrete() { return fmt.Sprintf("%d", e.Eval()) } - return fmt.Sprintf("popCount(%s)", e.Expr.Reduce(prefix)) + return fmt.Sprintf("xgb.PopCount(%s)", e.Expr.Reduce(prefix)) } func (e *PopCount) String() string { diff --git a/nexgb/xgbgen/field.go b/nexgb/xgbgen/field.go index 7c83f1a..78475f8 100644 --- a/nexgb/xgbgen/field.go +++ b/nexgb/xgbgen/field.go @@ -245,7 +245,7 @@ func (f *ValueField) SrcType() string { func (f *ValueField) Size() Size { maskSize := f.MaskType.Size() listSize := newExpressionSize(&Function{ - Name: "pad", + Name: "xgb.Pad", Expr: &BinaryOp{ Op: "*", Expr1: &Value{v: 4}, diff --git a/nexgb/xgbgen/go.go b/nexgb/xgbgen/go.go index 2b2c191..6c680e8 100644 --- a/nexgb/xgbgen/go.go +++ b/nexgb/xgbgen/go.go @@ -82,7 +82,7 @@ func (enum *Enum) Define(c *Context) { func (res *Resource) Define(c *Context) { c.Putln("type %s uint32", res.SrcName()) c.Putln("") - c.Putln("func (c *Conn) New%sId() (%s, error) {", + c.Putln("func New%sId(c *xgb.Conn) (%s, error) {", res.SrcName(), res.SrcName()) c.Putln("id, err := c.NewId()") c.Putln("if err != nil {") @@ -167,10 +167,10 @@ func (f *ValueField) Read(c *Context, prefix string) { c.Putln("%s%s = make([]uint32, %s)", prefix, f.ListName, f.ListLength().Reduce(prefix)) c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix)) - c.Putln("%s%s[i] = Get32(buf[b:])", prefix, f.ListName) + c.Putln("%s%s[i] = xgb.Get32(buf[b:])", prefix, f.ListName) c.Putln("b += 4") c.Putln("}") - c.Putln("b = pad(b)") + c.Putln("b = xgb.Pad(b)") } func (f *ValueField) Write(c *Context, prefix string) { @@ -180,10 +180,10 @@ func (f *ValueField) Write(c *Context, prefix string) { fmt.Sprintf("%s%s", prefix, f.MaskName), f.MaskType) } c.Putln("for i := 0; i < %s; i++ {", f.ListLength().Reduce(prefix)) - c.Putln("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("}") - c.Putln("b = pad(b)") + c.Putln("b = xgb.Pad(b)") } // Switch field diff --git a/nexgb/xgbgen/go_error.go b/nexgb/xgbgen/go_error.go index f4577ef..b7721be 100644 --- a/nexgb/xgbgen/go_error.go +++ b/nexgb/xgbgen/go_error.go @@ -30,10 +30,10 @@ func (e *Error) Define(c *Context) { // Let's the XGB event loop read this error. c.Putln("func init() {") if c.protocol.isExt() { - c.Putln("newExtErrorFuncs[\"%s\"][%d] = New%s", + c.Putln("xgb.NewExtErrorFuncs[\"%s\"][%d] = %sNew", c.protocol.ExtXName, e.Number, e.ErrType()) } else { - c.Putln("newErrorFuncs[%d] = New%s", e.Number, e.ErrType()) + c.Putln("xgb.NewErrorFuncs[%d] = %sNew", e.Number, e.ErrType()) } c.Putln("}") c.Putln("") @@ -41,14 +41,14 @@ func (e *Error) Define(c *Context) { func (e *Error) Read(c *Context) { c.Putln("// Error read %s", e.SrcName()) - c.Putln("func New%s(buf []byte) Error {", e.ErrType()) + c.Putln("func %sNew(buf []byte) xgb.Error {", 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("v.Sequence = xgb.Get16(buf[b:])") c.Putln("b += 2") c.Putln("") for _, field := range e.Fields { @@ -101,18 +101,18 @@ func (e *ErrorCopy) Define(c *Context) { // Let's the XGB know how to read this error. c.Putln("func init() {") if c.protocol.isExt() { - c.Putln("newExtErrorFuncs[\"%s\"][%d] = New%s", + c.Putln("xgb.NewExtErrorFuncs[\"%s\"][%d] = %sNew", c.protocol.ExtXName, e.Number, e.ErrType()) } else { - c.Putln("newErrorFuncs[%d] = New%s", e.Number, e.ErrType()) + c.Putln("xgb.NewErrorFuncs[%d] = %sNew", e.Number, e.ErrType()) } c.Putln("}") c.Putln("") } func (e *ErrorCopy) Read(c *Context) { - c.Putln("func New%s(buf []byte) Error {", e.ErrType()) - c.Putln("v := %s(New%s(buf).(%s))", + c.Putln("func %sNew(buf []byte) xgb.Error {", e.ErrType()) + c.Putln("v := %s(%sNew(buf).(%s))", e.ErrType(), e.Old.(*Error).ErrType(), e.Old.(*Error).ErrType()) c.Putln("v.NiceName = \"%s\"", e.SrcName()) c.Putln("return v") @@ -148,7 +148,7 @@ func ErrorFieldString(c *Context, fields []Field, errName string) { c.Putln("fieldVals := make([]string, 0, %d)", len(fields)) c.Putln("fieldVals = append(fieldVals, \"NiceName: \" + err.NiceName)") c.Putln("fieldVals = append(fieldVals, "+ - "sprintf(\"Sequence: %s\", err.Sequence))", "%d") + "xgb.Sprintf(\"Sequence: %s\", err.Sequence))", "%d") for _, field := range fields { switch field.(type) { case *PadField: @@ -158,11 +158,12 @@ func ErrorFieldString(c *Context, fields []Field, errName string) { c.Putln("fieldVals = append(fieldVals, \"%s: \" + err.%s)", field.SrcName(), field.SrcName()) } else { - format := fmt.Sprintf("sprintf(\"%s: %s\", err.%s)", + format := fmt.Sprintf("xgb.Sprintf(\"%s: %s\", err.%s)", field.SrcName(), "%d", field.SrcName()) c.Putln("fieldVals = append(fieldVals, %s)", format) } } } - c.Putln("return \"%s {\" + stringsJoin(fieldVals, \", \") + \"}\"", errName) + c.Putln("return \"%s {\" + xgb.StringsJoin(fieldVals, \", \") + \"}\"", + errName) } diff --git a/nexgb/xgbgen/go_event.go b/nexgb/xgbgen/go_event.go index f55e26f..d7ef109 100644 --- a/nexgb/xgbgen/go_event.go +++ b/nexgb/xgbgen/go_event.go @@ -48,10 +48,10 @@ func (e *Event) Define(c *Context) { // Let's the XGB event loop read this event. c.Putln("func init() {") if c.protocol.isExt() { - c.Putln("newExtEventFuncs[\"%s\"][%d] = New%s", + c.Putln("xgb.NewExtEventFuncs[\"%s\"][%d] = %sNew", c.protocol.ExtXName, e.Number, e.EvType()) } else { - c.Putln("newEventFuncs[%d] = New%s", e.Number, e.EvType()) + c.Putln("xgb.NewEventFuncs[%d] = %sNew", e.Number, e.EvType()) } c.Putln("}") c.Putln("") @@ -59,13 +59,13 @@ func (e *Event) Define(c *Context) { func (e *Event) Read(c *Context) { c.Putln("// Event read %s", e.SrcName()) - c.Putln("func New%s(buf []byte) Event {", e.EvType()) + c.Putln("func %sNew(buf []byte) xgb.Event {", e.EvType()) c.Putln("v := %s{}", e.EvType()) c.Putln("b := 1 // don't read event number") c.Putln("") for i, field := range e.Fields { if i == 1 && !e.NoSequence { - c.Putln("v.Sequence = Get16(buf[b:])") + c.Putln("v.Sequence = xgb.Get16(buf[b:])") c.Putln("b += 2") c.Putln("") } @@ -136,18 +136,18 @@ func (e *EventCopy) Define(c *Context) { // Let's the XGB event loop read this event. c.Putln("func init() {") if c.protocol.isExt() { - c.Putln("newExtEventFuncs[\"%s\"][%d] = New%s", + c.Putln("xgb.NewExtEventFuncs[\"%s\"][%d] = %sNew", c.protocol.ExtXName, e.Number, e.EvType()) } else { - c.Putln("newEventFuncs[%d] = New%s", e.Number, e.EvType()) + c.Putln("xgb.NewEventFuncs[%d] = %sNew", e.Number, e.EvType()) } c.Putln("}") c.Putln("") } func (e *EventCopy) Read(c *Context) { - c.Putln("func New%s(buf []byte) Event {", e.EvType()) - c.Putln("return %s(New%s(buf).(%s))", + c.Putln("func %sNew(buf []byte) xgb.Event {", e.EvType()) + c.Putln("return %s(%sNew(buf).(%s))", e.EvType(), e.Old.(*Event).EvType(), e.Old.(*Event).EvType()) c.Putln("}") c.Putln("") @@ -166,7 +166,7 @@ func EventFieldString(c *Context, fields []Field, evName string) { c.Putln("fieldVals := make([]string, 0, %d)", len(fields)) if evName != "KeymapNotify" { c.Putln("fieldVals = append(fieldVals, "+ - "sprintf(\"Sequence: %s\", v.Sequence))", "%d") + "xgb.Sprintf(\"Sequence: %s\", v.Sequence))", "%d") } for _, field := range fields { switch f := field.(type) { @@ -183,19 +183,20 @@ func EventFieldString(c *Context, fields []Field, evName string) { switch field.SrcType() { case "string": - format := fmt.Sprintf("sprintf(\"%s: %s\", v.%s)", + format := fmt.Sprintf("xgb.Sprintf(\"%s: %s\", v.%s)", field.SrcName(), "%s", field.SrcName()) c.Putln("fieldVals = append(fieldVals, %s)", format) case "bool": - format := fmt.Sprintf("sprintf(\"%s: %s\", v.%s)", + format := fmt.Sprintf("xgb.Sprintf(\"%s: %s\", v.%s)", field.SrcName(), "%t", field.SrcName()) c.Putln("fieldVals = append(fieldVals, %s)", format) default: - format := fmt.Sprintf("sprintf(\"%s: %s\", v.%s)", + format := fmt.Sprintf("xgb.Sprintf(\"%s: %s\", v.%s)", field.SrcName(), "%d", field.SrcName()) c.Putln("fieldVals = append(fieldVals, %s)", format) } } } - c.Putln("return \"%s {\" + stringsJoin(fieldVals, \", \") + \"}\"", evName) + c.Putln("return \"%s {\" + xgb.StringsJoin(fieldVals, \", \") + \"}\"", + evName) } diff --git a/nexgb/xgbgen/go_list.go b/nexgb/xgbgen/go_list.go index b01519b..4cf962a 100644 --- a/nexgb/xgbgen/go_list.go +++ b/nexgb/xgbgen/go_list.go @@ -21,7 +21,7 @@ func (f *ListField) Read(c *Context, prefix string) { c.Putln("for i := 0; i < int(%s); i++ {", length) ReadSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) c.Putln("}") - c.Putln("b = pad(b)") + c.Putln("b = xgb.Pad(b)") case *Base: length := f.LengthExpr.Reduce(prefix) if strings.ToLower(t.XmlName()) == "char" { @@ -29,13 +29,13 @@ func (f *ListField) Read(c *Context, prefix string) { c.Putln("byteString := make([]%s, %s)", t.SrcName(), length) c.Putln("copy(byteString[:%s], buf[b:])", length) c.Putln("%s%s = string(byteString)", prefix, f.SrcName()) - c.Putln("b += pad(int(%s))", length) + c.Putln("b += xgb.Pad(int(%s))", length) c.Putln("}") } else if t.SrcName() == "byte" { c.Putln("%s%s = make([]%s, %s)", prefix, f.SrcName(), t.SrcName(), length) c.Putln("copy(%s%s[:%s], buf[b:])", prefix, f.SrcName(), length) - c.Putln("b += pad(int(%s))", length) + c.Putln("b += xgb.Pad(int(%s))", length) } else { c.Putln("%s%s = make([]%s, %s)", prefix, f.SrcName(), t.SrcName(), length) @@ -43,7 +43,7 @@ func (f *ListField) Read(c *Context, prefix string) { ReadSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) c.Putln("}") - c.Putln("b = pad(b)") + c.Putln("b = xgb.Pad(b)") } case *TypeDef: length := f.LengthExpr.Reduce(prefix) @@ -52,16 +52,16 @@ func (f *ListField) Read(c *Context, prefix string) { c.Putln("for i := 0; i < int(%s); i++ {", length) ReadSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) c.Putln("}") - c.Putln("b = pad(b)") + c.Putln("b = xgb.Pad(b)") case *Union: c.Putln("%s%s = make([]%s, %s)", prefix, f.SrcName(), t.SrcName(), f.LengthExpr.Reduce(prefix)) - c.Putln("b += Read%sList(buf[b:], %s%s)", + c.Putln("b += %sReadList(buf[b:], %s%s)", t.SrcName(), prefix, f.SrcName()) case *Struct: c.Putln("%s%s = make([]%s, %s)", prefix, f.SrcName(), t.SrcName(), f.LengthExpr.Reduce(prefix)) - c.Putln("b += Read%sList(buf[b:], %s%s)", + c.Putln("b += %sReadList(buf[b:], %s%s)", t.SrcName(), prefix, f.SrcName()) default: log.Panicf("Cannot read list field '%s' with %T type.", @@ -77,18 +77,18 @@ func (f *ListField) Write(c *Context, prefix string) { WriteSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) c.Putln("}") - c.Putln("b = pad(b)") + c.Putln("b = xgb.Pad(b)") case *Base: length := f.Length().Reduce(prefix) if t.SrcName() == "byte" { c.Putln("copy(buf[b:], %s%s[:%s])", prefix, f.SrcName(), length) - c.Putln("b += pad(int(%s))", length) + c.Putln("b += xgb.Pad(int(%s))", length) } else { c.Putln("for i := 0; i < int(%s); i++ {", length) WriteSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) c.Putln("}") - c.Putln("b = pad(b)") + c.Putln("b = xgb.Pad(b)") } case *TypeDef: length := f.Length().Reduce(prefix) @@ -96,7 +96,7 @@ func (f *ListField) Write(c *Context, prefix string) { WriteSimpleSingleField(c, fmt.Sprintf("%s%s[i]", prefix, f.SrcName()), t) c.Putln("}") - c.Putln("b = pad(b)") + c.Putln("b = xgb.Pad(b)") case *Union: c.Putln("b += %sListBytes(buf[b:], %s%s)", t.SrcName(), prefix, f.SrcName()) diff --git a/nexgb/xgbgen/go_request_reply.go b/nexgb/xgbgen/go_request_reply.go index a9e624d..200260c 100644 --- a/nexgb/xgbgen/go_request_reply.go +++ b/nexgb/xgbgen/go_request_reply.go @@ -9,22 +9,22 @@ func (r *Request) Define(c *Context) { c.Putln("// Request %s", r.SrcName()) c.Putln("// size: %s", r.Size(c)) c.Putln("type %s struct {", r.CookieName()) - c.Putln("*cookie") + c.Putln("*xgb.Cookie") c.Putln("}") c.Putln("") if r.Reply != nil { - c.Putln("func (c *Conn) %s(%s) %s {", + c.Putln("func %s(c *xgb.Conn, %s) %s {", r.SrcName(), r.ParamNameTypes(), r.CookieName()) - c.Putln("cookie := c.newCookie(true, true)") - c.Putln("c.newRequest(c.%s(%s), cookie)", r.ReqName(), r.ParamNames()) + c.Putln("cookie := c.NewCookie(true, true)") + c.Putln("c.NewRequest(%s(c, %s), cookie)", r.ReqName(), r.ParamNames()) c.Putln("return %s{cookie}", r.CookieName()) c.Putln("}") c.Putln("") - c.Putln("func (c *Conn) %sUnchecked(%s) %s {", + c.Putln("func %sUnchecked(c *xgb.Conn, %s) %s {", r.SrcName(), r.ParamNameTypes(), r.CookieName()) - c.Putln("cookie := c.newCookie(false, true)") - c.Putln("c.newRequest(c.%s(%s), cookie)", r.ReqName(), r.ParamNames()) + c.Putln("cookie := c.NewCookie(false, true)") + c.Putln("c.NewRequest(%s(c, %s), cookie)", r.ReqName(), r.ParamNames()) c.Putln("return %s{cookie}", r.CookieName()) c.Putln("}") c.Putln("") @@ -32,27 +32,27 @@ func (r *Request) Define(c *Context) { r.ReadReply(c) } else { c.Putln("// Write request to wire for %s", r.SrcName()) - c.Putln("func (c *Conn) %s(%s) %s {", + c.Putln("func %s(c *xgb.Conn, %s) %s {", r.SrcName(), r.ParamNameTypes(), r.CookieName()) - c.Putln("cookie := c.newCookie(false, false)") - c.Putln("c.newRequest(c.%s(%s), cookie)", r.ReqName(), r.ParamNames()) + c.Putln("cookie := c.NewCookie(false, false)") + c.Putln("c.NewRequest(%s(c, %s), cookie)", r.ReqName(), r.ParamNames()) c.Putln("return %s{cookie}", r.CookieName()) c.Putln("}") c.Putln("") - c.Putln("func (c *Conn) %sChecked(%s) %s {", + c.Putln("func %sChecked(c *xgb.Conn, %s) %s {", r.SrcName(), r.ParamNameTypes(), r.CookieName()) - c.Putln("cookie := c.newCookie(true, false)") - c.Putln("c.newRequest(c.%s(%s), cookie)", r.ReqName(), r.ParamNames()) + c.Putln("cookie := c.NewCookie(true, false)") + c.Putln("c.NewRequest(%s(c, %s), cookie)", r.ReqName(), r.ParamNames()) c.Putln("return %s{cookie}", r.CookieName()) c.Putln("}") c.Putln("") - } - c.Putln("func (cook %s) Check() error {", r.CookieName()) - c.Putln("return cook.check()") - c.Putln("}") - c.Putln("") + c.Putln("func (cook %s) Check() error {", r.CookieName()) + c.Putln("return cook.Cookie.Check()") + c.Putln("}") + c.Putln("") + } r.WriteRequest(c) } @@ -71,7 +71,7 @@ func (r *Request) ReadReply(c *Context) { c.Putln("// Waits and reads reply data from request %s", r.SrcName()) c.Putln("func (cook %s) Reply() (*%s, error) {", r.CookieName(), r.ReplyTypeName()) - c.Putln("buf, err := cook.reply()") + c.Putln("buf, err := cook.Cookie.Reply()") c.Putln("if err != nil {") c.Putln("return nil, err") c.Putln("}") @@ -92,10 +92,10 @@ func (r *Request) ReadReply(c *Context) { field.Read(c, "v.") c.Putln("") if i == 0 { - c.Putln("v.Sequence = Get16(buf[b:])") + c.Putln("v.Sequence = xgb.Get16(buf[b:])") c.Putln("b += 2") c.Putln("") - c.Putln("v.Length = Get32(buf[b:]) // 4-byte units") + c.Putln("v.Length = xgb.Get32(buf[b:]) // 4-byte units") c.Putln("b += 4") c.Putln("") } @@ -107,19 +107,20 @@ func (r *Request) ReadReply(c *Context) { func (r *Request) WriteRequest(c *Context) { writeSize := func() { - c.Putln("Put16(buf[b:], uint16(size / 4)) " + + c.Putln("xgb.Put16(buf[b:], uint16(size / 4)) " + "// write request size in 4-byte units") c.Putln("b += 2") c.Putln("") } c.Putln("// Write request to wire for %s", r.SrcName()) - c.Putln("func (c *Conn) %s(%s) []byte {", r.ReqName(), r.ParamNameTypes()) + c.Putln("func %s(c *xgb.Conn, %s) []byte {", + r.ReqName(), r.ParamNameTypes()) c.Putln("size := %s", r.Size(c)) c.Putln("b := 0") c.Putln("buf := make([]byte, size)") c.Putln("") if c.protocol.isExt() { - c.Putln("buf[b] = c.extensions[\"%s\"]", + c.Putln("buf[b] = c.Extensions[\"%s\"]", strings.ToUpper(c.protocol.ExtXName)) c.Putln("b += 1") c.Putln("") @@ -165,7 +166,7 @@ func (r *Request) ParamNames() string { names = append(names, fmt.Sprintf("%s", field.SrcName())) } } - return strings.Join(names, ",") + return strings.Join(names, ", ") } func (r *Request) ParamNameTypes() string { @@ -189,5 +190,5 @@ func (r *Request) ParamNameTypes() string { fmt.Sprintf("%s %s", field.SrcName(), field.SrcType())) } } - return strings.Join(nameTypes, ",") + return strings.Join(nameTypes, ", ") } diff --git a/nexgb/xgbgen/go_single_field.go b/nexgb/xgbgen/go_single_field.go index 433ebe3..3e3fa53 100644 --- a/nexgb/xgbgen/go_single_field.go +++ b/nexgb/xgbgen/go_single_field.go @@ -12,17 +12,17 @@ func (f *SingleField) Define(c *Context) { func ReadSimpleSingleField(c *Context, name string, typ Type) { switch t := typ.(type) { case *Resource: - c.Putln("%s = %s(Get32(buf[b:]))", name, t.SrcName()) + c.Putln("%s = %s(xgb.Get32(buf[b:]))", name, t.SrcName()) case *TypeDef: switch t.Size().Eval() { case 1: c.Putln("%s = %s(buf[b])", name, t.SrcName()) case 2: - c.Putln("%s = %s(Get16(buf[b:]))", name, t.SrcName()) + c.Putln("%s = %s(xgb.Get16(buf[b:]))", name, t.SrcName()) case 4: - c.Putln("%s = %s(Get32(buf[b:]))", name, t.SrcName()) + c.Putln("%s = %s(xgb.Get32(buf[b:]))", name, t.SrcName()) case 8: - c.Putln("%s = %s(Get64(buf[b:]))", name, t.SrcName()) + c.Putln("%s = %s(xgb.Get64(buf[b:]))", name, t.SrcName()) } case *Base: // If this is a bool, stop short and do something special. @@ -40,11 +40,11 @@ func ReadSimpleSingleField(c *Context, name string, typ Type) { case 1: val = fmt.Sprintf("buf[b]") case 2: - val = fmt.Sprintf("Get16(buf[b:])") + val = fmt.Sprintf("xgb.Get16(buf[b:])") case 4: - val = fmt.Sprintf("Get32(buf[b:])") + val = fmt.Sprintf("xgb.Get32(buf[b:])") case 8: - val = fmt.Sprintf("Get64(buf[b:])") + val = fmt.Sprintf("xgb.Get64(buf[b:])") } // We need to convert base types if they aren't uintXX or byte @@ -71,10 +71,10 @@ func (f *SingleField) Read(c *Context, prefix string) { ReadSimpleSingleField(c, fmt.Sprintf("%s%s", prefix, f.SrcName()), t) case *Struct: c.Putln("%s%s = %s{}", prefix, f.SrcName(), t.SrcName()) - c.Putln("b += Read%s(buf[b:], &%s%s)", t.SrcName(), prefix, f.SrcName()) + c.Putln("b += %sRead(buf[b:], &%s%s)", t.SrcName(), prefix, f.SrcName()) case *Union: c.Putln("%s%s = %s{}", prefix, f.SrcName(), t.SrcName()) - c.Putln("b += Read%s(buf[b:], &%s%s)", t.SrcName(), prefix, f.SrcName()) + c.Putln("b += %sRead(buf[b:], &%s%s)", t.SrcName(), prefix, f.SrcName()) default: log.Panicf("Cannot read field '%s' with %T type.", f.XmlName(), f.Type) } @@ -83,17 +83,17 @@ func (f *SingleField) Read(c *Context, prefix string) { func WriteSimpleSingleField(c *Context, name string, typ Type) { switch t := typ.(type) { case *Resource: - c.Putln("Put32(buf[b:], uint32(%s))", name) + c.Putln("xgb.Put32(buf[b:], uint32(%s))", name) case *TypeDef: switch t.Size().Eval() { case 1: c.Putln("buf[b] = byte(%s)", name) case 2: - c.Putln("Put16(buf[b:], uint16(%s))", name) + c.Putln("xgb.Put16(buf[b:], uint16(%s))", name) case 4: - c.Putln("Put32(buf[b:], uint32(%s))", name) + c.Putln("xgb.Put32(buf[b:], uint32(%s))", name) case 8: - c.Putln("Put64(buf[b:], uint64(%s))", name) + c.Putln("xgb.Put64(buf[b:], uint64(%s))", name) } case *Base: // If this is a bool, stop short and do something special. @@ -115,21 +115,21 @@ func WriteSimpleSingleField(c *Context, name string, typ Type) { } case 2: if t.SrcName() != "uint16" { - c.Putln("Put16(buf[b:], uint16(%s))", name) + c.Putln("xgb.Put16(buf[b:], uint16(%s))", name) } else { - c.Putln("Put16(buf[b:], %s)", name) + c.Putln("xgb.Put16(buf[b:], %s)", name) } case 4: if t.SrcName() != "uint32" { - c.Putln("Put32(buf[b:], uint32(%s))", name) + c.Putln("xgb.Put32(buf[b:], uint32(%s))", name) } else { - c.Putln("Put32(buf[b:], %s)", name) + c.Putln("xgb.Put32(buf[b:], %s)", name) } case 8: if t.SrcName() != "uint64" { - c.Putln("Put64(buf[b:], uint64(%s))", name) + c.Putln("xgb.Put64(buf[b:], uint64(%s))", name) } else { - c.Putln("Put64(buf[b:], %s)", name) + c.Putln("xgb.Put64(buf[b:], %s)", name) } } default: @@ -152,13 +152,13 @@ func (f *SingleField) Write(c *Context, prefix string) { c.Putln("{") c.Putln("unionBytes := %s%s.Bytes()", prefix, f.SrcName()) c.Putln("copy(buf[b:], unionBytes)") - c.Putln("b += pad(len(unionBytes))") + c.Putln("b += xgb.Pad(len(unionBytes))") c.Putln("}") case *Struct: c.Putln("{") c.Putln("structBytes := %s%s.Bytes()", prefix, f.SrcName()) c.Putln("copy(buf[b:], structBytes)") - c.Putln("b += pad(len(structBytes))") + c.Putln("b += xgb.Pad(len(structBytes))") c.Putln("}") default: log.Fatalf("Cannot read field '%s' with %T type.", f.XmlName(), f.Type) diff --git a/nexgb/xgbgen/go_struct.go b/nexgb/xgbgen/go_struct.go index 9884194..7f33b21 100644 --- a/nexgb/xgbgen/go_struct.go +++ b/nexgb/xgbgen/go_struct.go @@ -35,7 +35,7 @@ func (s *Struct) Define(c *Context) { // 'ReadStructName' should only be used to read raw reply data from the wire. func (s *Struct) Read(c *Context) { c.Putln("// Struct read %s", s.SrcName()) - c.Putln("func Read%s(buf []byte, v *%s) int {", s.SrcName(), s.SrcName()) + c.Putln("func %sRead(buf []byte, v *%s) int {", s.SrcName(), s.SrcName()) c.Putln("b := 0") c.Putln("") @@ -54,16 +54,16 @@ func (s *Struct) Read(c *Context) { // the number of bytes read from the byte slice. func (s *Struct) ReadList(c *Context) { c.Putln("// Struct list read %s", s.SrcName()) - c.Putln("func Read%sList(buf []byte, dest []%s) int {", + c.Putln("func %sReadList(buf []byte, dest []%s) int {", s.SrcName(), s.SrcName()) c.Putln("b := 0") c.Putln("for i := 0; i < len(dest); i++ {") c.Putln("dest[i] = %s{}", s.SrcName()) - c.Putln("b += Read%s(buf[b:], &dest[i])", s.SrcName()) + c.Putln("b += %sRead(buf[b:], &dest[i])", s.SrcName()) c.Putln("}") - c.Putln("return pad(b)") + c.Putln("return xgb.Pad(b)") c.Putln("}") c.Putln("") @@ -93,7 +93,7 @@ func (s *Struct) WriteList(c *Context) { c.Putln("for _, item := range list {") c.Putln("structBytes = item.Bytes()") c.Putln("copy(buf[b:], structBytes)") - c.Putln("b += pad(len(structBytes))") + c.Putln("b += xgb.Pad(len(structBytes))") c.Putln("}") c.Putln("return b") c.Putln("}") diff --git a/nexgb/xgbgen/go_union.go b/nexgb/xgbgen/go_union.go index 73e85f7..91300a2 100644 --- a/nexgb/xgbgen/go_union.go +++ b/nexgb/xgbgen/go_union.go @@ -8,7 +8,7 @@ func (u *Union) Define(c *Context) { c.Putln("// Instead use one of the following constructors for '%s':", u.SrcName()) for _, field := range u.Fields { - c.Putln("// New%s%s(%s %s) %s", u.SrcName(), field.SrcName(), + c.Putln("// %s%sNew(%s %s) %s", u.SrcName(), field.SrcName(), field.SrcName(), field.SrcType(), u.SrcName()) } @@ -40,7 +40,7 @@ func (u *Union) New(c *Context) { for _, field := range u.Fields { c.Putln("// Union constructor for %s for field %s.", u.SrcName(), field.SrcName()) - c.Putln("func New%s%s(%s %s) %s {", + c.Putln("func %s%sNew(%s %s) %s {", u.SrcName(), field.SrcName(), field.SrcName(), field.SrcType(), u.SrcName()) c.Putln("var b int") @@ -66,7 +66,7 @@ func (u *Union) New(c *Context) { func (u *Union) Read(c *Context) { c.Putln("// Union read %s", u.SrcName()) - c.Putln("func Read%s(buf []byte, v *%s) int {", u.SrcName(), u.SrcName()) + c.Putln("func %sRead(buf []byte, v *%s) int {", u.SrcName(), u.SrcName()) c.Putln("var b int") c.Putln("") for _, field := range u.Fields { @@ -81,14 +81,14 @@ func (u *Union) Read(c *Context) { func (u *Union) ReadList(c *Context) { c.Putln("// Union list read %s", u.SrcName()) - c.Putln("func Read%sList(buf []byte, dest []%s) int {", + c.Putln("func %sReadList(buf []byte, dest []%s) int {", u.SrcName(), u.SrcName()) c.Putln("b := 0") c.Putln("for i := 0; i < len(dest); i++ {") c.Putln("dest[i] = %s{}", u.SrcName()) - c.Putln("b += Read%s(buf[b:], &dest[i])", u.SrcName()) + c.Putln("b += %sRead(buf[b:], &dest[i])", u.SrcName()) c.Putln("}") - c.Putln("return pad(b)") + c.Putln("return xgb.Pad(b)") c.Putln("}") c.Putln("") } @@ -121,7 +121,7 @@ func (u *Union) WriteList(c *Context) { c.Putln("for _, item := range list {") c.Putln("unionBytes = item.Bytes()") c.Putln("copy(buf[b:], unionBytes)") - c.Putln("b += pad(len(unionBytes))") + c.Putln("b += xgb.Pad(len(unionBytes))") c.Putln("}") c.Putln("return b") c.Putln("}") diff --git a/nexgb/xgbgen/protocol.go b/nexgb/xgbgen/protocol.go index 83dde14..d56663d 100644 --- a/nexgb/xgbgen/protocol.go +++ b/nexgb/xgbgen/protocol.go @@ -1,6 +1,7 @@ package main import ( + "log" "strings" ) @@ -9,6 +10,7 @@ import ( // if this protocol imports other other extensions. The import relationship // is recursive. type Protocol struct { + Parent *Protocol Name string ExtXName string ExtName string @@ -33,6 +35,28 @@ func (p *Protocol) Initialize() { } } +// PkgName returns the name of this package. +// i.e., 'xproto' for the core X protocol, 'randr' for the RandR extension, etc. +func (p *Protocol) PkgName() string { + return strings.Replace(p.Name, "_", "", -1) +} + +// ProtocolGet searches the current context for the protocol with the given +// name. (i.e., the current protocol and its imports.) +// It is an error if one is not found. +func (p *Protocol) ProtocolFind(name string) *Protocol { + if p.Name == name { + return p // that was easy + } + for _, imp := range p.Imports { + if imp.Name == name { + return imp + } + } + log.Panicf("Could not find protocol with name '%s'.", name) + panic("unreachable") +} + // isExt returns true if this protocol is an extension. // i.e., it's name isn't "xproto". func (p *Protocol) isExt() bool { diff --git a/nexgb/xgbgen/request_reply.go b/nexgb/xgbgen/request_reply.go index 4daa4ac..637266b 100644 --- a/nexgb/xgbgen/request_reply.go +++ b/nexgb/xgbgen/request_reply.go @@ -3,7 +3,6 @@ package main import ( "fmt" "log" - "strings" "unicode" ) @@ -23,7 +22,7 @@ type Request struct { func (r *Request) Initialize(p *Protocol) { r.srcName = SrcName(p, r.xmlName) if p.isExt() { - r.srcName = strings.Title(strings.ToLower(p.Name)) + r.srcName + r.srcName = r.srcName } if r.Reply != nil { diff --git a/nexgb/xgbgen/translation.go b/nexgb/xgbgen/translation.go index 44d615d..0123669 100644 --- a/nexgb/xgbgen/translation.go +++ b/nexgb/xgbgen/translation.go @@ -18,8 +18,9 @@ import ( "strings" ) -func (xml *XML) Translate() *Protocol { +func (xml *XML) Translate(parent *Protocol) *Protocol { protocol := &Protocol{ + Parent: parent, Name: xml.Header, ExtXName: xml.ExtensionXName, ExtName: xml.ExtensionName, @@ -33,7 +34,8 @@ func (xml *XML) Translate() *Protocol { for _, imp := range xml.Imports { if imp.xml != nil { - protocol.Imports = append(protocol.Imports, imp.xml.Translate()) + protocol.Imports = append(protocol.Imports, + imp.xml.Translate(protocol)) } } @@ -209,7 +211,7 @@ func (x *XMLRequest) Translate() *Request { // The XML protocol description references 'string_len' in the // 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.) + // (i.e., a parameter in the caller but does not get sent over the wire.) if x.Name == "QueryTextExtents" { stringLenLocal := &LocalField{&SingleField{ xmlName: "string_len", @@ -399,27 +401,15 @@ func TypeSrcName(p *Protocol, typ Type) string { if colon := strings.Index(t, ":"); colon > -1 { namespace := t[:colon] rest := t[colon+1:] - return splitAndTitle(namespace) + splitAndTitle(rest) + return p.ProtocolFind(namespace).PkgName() + "." + splitAndTitle(rest) } - // Since there is no namespace, we need to look for a namespace - // in the current context. - niceType := splitAndTitle(t) - if p.isExt() { - for _, typ2 := range p.Types { - if t == typ2.XmlName() { - return strings.Title(p.Name) + niceType - } - } - for _, imp := range p.Imports { - for _, typ2 := range imp.Types { - if t == typ2.XmlName() { - return strings.Title(imp.Name) + niceType - } - } - } + // Since there's no namespace, we're left with the raw type name. + // If the type is part of the source we're generating (i.e., there is + // no parent protocol), then just return that type name. + // Otherwise, we must qualify it with a package name. + if p.Parent == nil { + return splitAndTitle(t) } - - // We couldn't find one, so return it without a prefix. - return niceType + return p.PkgName() + "." + splitAndTitle(t) } |