diff --git a/nexgb/xgbgen/context.go b/nexgb/xgbgen/context.go index c40313f..697413e 100644 --- a/nexgb/xgbgen/context.go +++ b/nexgb/xgbgen/context.go @@ -5,6 +5,7 @@ import ( "encoding/xml" "fmt" "log" + "sort" "time" ) @@ -70,6 +71,8 @@ func (c *Context) Morph(xmlBytes []byte) { if c.protocol.isExt() { c.Putln("\"github.com/BurntSushi/xgb/xproto\"") } + + sort.Sort(Protocols(c.protocol.Imports)) for _, imp := range c.protocol.Imports { // We always import xproto, so skip it if it's explicitly imported if imp.Name == "xproto" { @@ -142,6 +145,8 @@ func (c *Context) Morph(xmlBytes []byte) { } // Now write Go source code + sort.Sort(Types(c.protocol.Types)) + sort.Sort(Requests(c.protocol.Requests)) for _, typ := range c.protocol.Types { typ.Define(c) } diff --git a/nexgb/xgbgen/protocol.go b/nexgb/xgbgen/protocol.go index d56663d..433f4e2 100644 --- a/nexgb/xgbgen/protocol.go +++ b/nexgb/xgbgen/protocol.go @@ -22,6 +22,12 @@ type Protocol struct { Requests []*Request } +type Protocols []*Protocol + +func (ps Protocols) Len() int { return len(ps) } +func (ps Protocols) Swap(i, j int) { ps[i], ps[j] = ps[j], ps[i] } +func (ps Protocols) Less(i, j int) bool { return ps[i].ExtName < ps[j].ExtName } + // Initialize traverses all structures, looks for 'Translation' type, // and looks up the real type in the namespace. It also sets the source // name for all relevant fields/structures. diff --git a/nexgb/xgbgen/request_reply.go b/nexgb/xgbgen/request_reply.go index b8afe48..11a4e44 100644 --- a/nexgb/xgbgen/request_reply.go +++ b/nexgb/xgbgen/request_reply.go @@ -17,6 +17,12 @@ type Request struct { Reply *Reply // A reply, if one exists for this request. } +type Requests []*Request + +func (rs Requests) Len() int { return len(rs) } +func (rs Requests) Swap(i, j int) { rs[i], rs[j] = rs[j], rs[i] } +func (rs Requests) Less(i, j int) bool { return rs[i].xmlName < rs[j].xmlName } + // Initialize creates the proper Go source name for this request. // It also initializes the reply if one exists, and all fields in this request. func (r *Request) Initialize(p *Protocol) { diff --git a/nexgb/xgbgen/translation.go b/nexgb/xgbgen/translation.go index 0123669..778304f 100644 --- a/nexgb/xgbgen/translation.go +++ b/nexgb/xgbgen/translation.go @@ -137,10 +137,13 @@ func (x *XMLEvent) Translate() *Event { xmlName: x.Name, Number: x.Number, NoSequence: x.NoSequence, - Fields: make([]Field, len(x.Fields)), + Fields: make([]Field, 0, len(x.Fields)), } - for i, field := range x.Fields { - ev.Fields[i] = field.Translate(ev) + for _, field := range x.Fields { + if field.XMLName.Local == "doc" { + continue + } + ev.Fields = append(ev.Fields, field.Translate(ev)) } return ev } @@ -200,11 +203,14 @@ func (x *XMLRequest) Translate() *Request { xmlName: x.Name, Opcode: x.Opcode, Combine: x.Combine, - Fields: make([]Field, len(x.Fields)), + Fields: make([]Field, 0, len(x.Fields)), Reply: x.Reply.Translate(), } - for i, field := range x.Fields { - r.Fields[i] = field.Translate(r) + for _, field := range x.Fields { + if field.XMLName.Local == "doc" { + continue + } + r.Fields = append(r.Fields, field.Translate(r)) } // Address bug (or legacy code) in QueryTextExtents. @@ -229,10 +235,13 @@ func (x *XMLReply) Translate() *Reply { } r := &Reply{ - Fields: make([]Field, len(x.Fields)), + Fields: make([]Field, 0, len(x.Fields)), } - for i, field := range x.Fields { - r.Fields[i] = field.Translate(r) + for _, field := range x.Fields { + if field.XMLName.Local == "doc" { + continue + } + r.Fields = append(r.Fields, field.Translate(r)) } return r } @@ -380,7 +389,6 @@ func SrcName(p *Protocol, name string) string { if newn, ok := NameMap[name]; ok { return newn } - return splitAndTitle(name) } diff --git a/nexgb/xgbgen/type.go b/nexgb/xgbgen/type.go index 521f67e..ded5be2 100644 --- a/nexgb/xgbgen/type.go +++ b/nexgb/xgbgen/type.go @@ -14,6 +14,16 @@ type Type interface { Define(c *Context) } +type Types []Type + +func (ts Types) Len() int { return len(ts) } +func (ts Types) Swap(i, j int) { ts[i], ts[j] = ts[j], ts[i] } +func (ts Types) Less(i, j int) bool { + x1, x2 := ts[i].XmlName(), ts[j].XmlName() + s1, s2 := ts[i].SrcName(), ts[j].SrcName() + return (s1 == s2 && x1 < x2) || s1 < s2 +} + // 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.