github.com/BurntSushi/xgb@v0.0.0-20210121224620-deaf085860bc/xgbgen/type.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  )
     7  
     8  type Type interface {
     9  	Initialize(p *Protocol)
    10  	SrcName() string
    11  	XmlName() string
    12  	Size() Size
    13  
    14  	Define(c *Context)
    15  }
    16  
    17  type Types []Type
    18  
    19  func (ts Types) Len() int      { return len(ts) }
    20  func (ts Types) Swap(i, j int) { ts[i], ts[j] = ts[j], ts[i] }
    21  func (ts Types) Less(i, j int) bool {
    22  	x1, x2 := ts[i].XmlName(), ts[j].XmlName()
    23  	s1, s2 := ts[i].SrcName(), ts[j].SrcName()
    24  	return (s1 == s2 && x1 < x2) || s1 < s2
    25  }
    26  
    27  // Translation is used *only* when transitioning from XML types to
    28  // our better representation. They are placeholders for the real types (below)
    29  // that will replace them.
    30  type Translation struct {
    31  	xmlName string
    32  }
    33  
    34  func newTranslation(name string) *Translation {
    35  	return &Translation{xmlName: name}
    36  }
    37  
    38  // RealType takes 'XmlName' and finds its real concrete type in our Protocol.
    39  // It is an error if we can't find such a type.
    40  func (t *Translation) RealType(p *Protocol) Type {
    41  	// Check to see if there is a namespace. If so, strip it and use it to
    42  	// make sure we only look for a type in that protocol.
    43  	namespace, typeName := "", t.XmlName()
    44  	if ni := strings.Index(t.XmlName(), ":"); ni > -1 {
    45  		namespace, typeName = strings.ToLower(typeName[:ni]), typeName[ni+1:]
    46  	}
    47  
    48  	if len(namespace) == 0 || namespace == strings.ToLower(p.Name) {
    49  		for _, typ := range p.Types {
    50  			if typeName == typ.XmlName() {
    51  				return typ
    52  			}
    53  		}
    54  	}
    55  	for _, imp := range p.Imports {
    56  		if len(namespace) == 0 || namespace == strings.ToLower(imp.Name) {
    57  			for _, typ := range imp.Types {
    58  				if typeName == typ.XmlName() {
    59  					return typ
    60  				}
    61  			}
    62  		}
    63  	}
    64  	panic("Could not find real type for translation type: " + t.XmlName())
    65  }
    66  
    67  func (t *Translation) SrcName() string {
    68  	panic("it is illegal to call SrcName on a translation type")
    69  }
    70  
    71  func (t *Translation) XmlName() string {
    72  	return t.xmlName
    73  }
    74  
    75  func (t *Translation) Size() Size {
    76  	panic("it is illegal to call Size on a translation type")
    77  }
    78  
    79  func (t *Translation) Define(c *Context) {
    80  	panic("it is illegal to call Define on a translation type")
    81  }
    82  
    83  func (t *Translation) Initialize(p *Protocol) {
    84  	panic("it is illegal to call Initialize on a translation type")
    85  }
    86  
    87  type Base struct {
    88  	srcName string
    89  	xmlName string
    90  	size    Size
    91  }
    92  
    93  func (b *Base) SrcName() string {
    94  	return b.srcName
    95  }
    96  
    97  func (b *Base) XmlName() string {
    98  	return b.xmlName
    99  }
   100  
   101  func (b *Base) Size() Size {
   102  	return b.size
   103  }
   104  
   105  func (b *Base) Initialize(p *Protocol) {
   106  	b.srcName = TypeSrcName(p, b)
   107  }
   108  
   109  type Enum struct {
   110  	srcName string
   111  	xmlName string
   112  	Items   []*EnumItem
   113  }
   114  
   115  type EnumItem struct {
   116  	srcName string
   117  	xmlName string
   118  	Expr    Expression
   119  }
   120  
   121  func (enum *Enum) SrcName() string {
   122  	return enum.srcName
   123  }
   124  
   125  func (enum *Enum) XmlName() string {
   126  	return enum.xmlName
   127  }
   128  
   129  func (enum *Enum) Size() Size {
   130  	panic("Cannot take size of enum")
   131  }
   132  
   133  func (enum *Enum) Initialize(p *Protocol) {
   134  	enum.srcName = TypeSrcName(p, enum)
   135  	for _, item := range enum.Items {
   136  		item.srcName = SrcName(p, item.xmlName)
   137  		if item.Expr != nil {
   138  			item.Expr.Initialize(p)
   139  		}
   140  	}
   141  }
   142  
   143  type Resource struct {
   144  	srcName string
   145  	xmlName string
   146  }
   147  
   148  func (r *Resource) SrcName() string {
   149  	return r.srcName
   150  }
   151  
   152  func (r *Resource) XmlName() string {
   153  	return r.xmlName
   154  }
   155  
   156  func (r *Resource) Size() Size {
   157  	return newFixedSize(BaseTypeSizes["Id"], true)
   158  }
   159  
   160  func (r *Resource) Initialize(p *Protocol) {
   161  	r.srcName = TypeSrcName(p, r)
   162  }
   163  
   164  type TypeDef struct {
   165  	srcName string
   166  	xmlName string
   167  	Old     Type
   168  }
   169  
   170  func (t *TypeDef) SrcName() string {
   171  	return t.srcName
   172  }
   173  
   174  func (t *TypeDef) XmlName() string {
   175  	return t.xmlName
   176  }
   177  
   178  func (t *TypeDef) Size() Size {
   179  	return t.Old.Size()
   180  }
   181  
   182  func (t *TypeDef) Initialize(p *Protocol) {
   183  	t.Old = t.Old.(*Translation).RealType(p)
   184  	t.srcName = TypeSrcName(p, t)
   185  }
   186  
   187  type Event struct {
   188  	srcName    string
   189  	xmlName    string
   190  	Number     int
   191  	NoSequence bool
   192  	Fields     []Field
   193  }
   194  
   195  func (e *Event) SrcName() string {
   196  	return e.srcName
   197  }
   198  
   199  func (e *Event) XmlName() string {
   200  	return e.xmlName
   201  }
   202  
   203  func (e *Event) Size() Size {
   204  	return newExpressionSize(&Value{v: 32}, true)
   205  }
   206  
   207  func (e *Event) Initialize(p *Protocol) {
   208  	e.srcName = TypeSrcName(p, e)
   209  	for _, field := range e.Fields {
   210  		field.Initialize(p)
   211  	}
   212  }
   213  
   214  func (e *Event) EvType() string {
   215  	return fmt.Sprintf("%sEvent", e.srcName)
   216  }
   217  
   218  type EventCopy struct {
   219  	srcName string
   220  	xmlName string
   221  	Old     Type
   222  	Number  int
   223  }
   224  
   225  func (e *EventCopy) SrcName() string {
   226  	return e.srcName
   227  }
   228  
   229  func (e *EventCopy) XmlName() string {
   230  	return e.xmlName
   231  }
   232  
   233  func (e *EventCopy) Size() Size {
   234  	return newExpressionSize(&Value{v: 32}, true)
   235  }
   236  
   237  func (e *EventCopy) Initialize(p *Protocol) {
   238  	e.srcName = TypeSrcName(p, e)
   239  	e.Old = e.Old.(*Translation).RealType(p)
   240  	if _, ok := e.Old.(*Event); !ok {
   241  		panic("an EventCopy's old type *must* be *Event")
   242  	}
   243  }
   244  
   245  func (e *EventCopy) EvType() string {
   246  	return fmt.Sprintf("%sEvent", e.srcName)
   247  }
   248  
   249  type Error struct {
   250  	srcName string
   251  	xmlName string
   252  	Number  int
   253  	Fields  []Field
   254  }
   255  
   256  func (e *Error) SrcName() string {
   257  	return e.srcName
   258  }
   259  
   260  func (e *Error) XmlName() string {
   261  	return e.xmlName
   262  }
   263  
   264  func (e *Error) Size() Size {
   265  	return newExpressionSize(&Value{v: 32}, true)
   266  }
   267  
   268  func (e *Error) Initialize(p *Protocol) {
   269  	e.srcName = TypeSrcName(p, e)
   270  	for _, field := range e.Fields {
   271  		field.Initialize(p)
   272  	}
   273  }
   274  
   275  func (e *Error) ErrConst() string {
   276  	return fmt.Sprintf("Bad%s", e.srcName)
   277  }
   278  
   279  func (e *Error) ErrType() string {
   280  	return fmt.Sprintf("%sError", e.srcName)
   281  }
   282  
   283  type ErrorCopy struct {
   284  	srcName string
   285  	xmlName string
   286  	Old     Type
   287  	Number  int
   288  }
   289  
   290  func (e *ErrorCopy) SrcName() string {
   291  	return e.srcName
   292  }
   293  
   294  func (e *ErrorCopy) XmlName() string {
   295  	return e.xmlName
   296  }
   297  
   298  func (e *ErrorCopy) Size() Size {
   299  	return newExpressionSize(&Value{v: 32}, true)
   300  }
   301  
   302  func (e *ErrorCopy) Initialize(p *Protocol) {
   303  	e.srcName = TypeSrcName(p, e)
   304  	e.Old = e.Old.(*Translation).RealType(p)
   305  	if _, ok := e.Old.(*Error); !ok {
   306  		panic("an ErrorCopy's old type *must* be *Event")
   307  	}
   308  }
   309  
   310  func (e *ErrorCopy) ErrConst() string {
   311  	return fmt.Sprintf("Bad%s", e.srcName)
   312  }
   313  
   314  func (e *ErrorCopy) ErrType() string {
   315  	return fmt.Sprintf("%sError", e.srcName)
   316  }
   317  
   318  type Struct struct {
   319  	srcName string
   320  	xmlName string
   321  	Fields  []Field
   322  }
   323  
   324  func (s *Struct) SrcName() string {
   325  	return s.srcName
   326  }
   327  
   328  func (s *Struct) XmlName() string {
   329  	return s.xmlName
   330  }
   331  
   332  func (s *Struct) Size() Size {
   333  	size := newFixedSize(0, true)
   334  	for _, field := range s.Fields {
   335  		size = size.Add(field.Size())
   336  	}
   337  	return size
   338  }
   339  
   340  func (s *Struct) Initialize(p *Protocol) {
   341  	s.srcName = TypeSrcName(p, s)
   342  	for _, field := range s.Fields {
   343  		field.Initialize(p)
   344  	}
   345  }
   346  
   347  // HasList returns whether there is a field in this struct that is a list.
   348  // When true, a more involved calculation is necessary to compute this struct's
   349  // size.
   350  func (s *Struct) HasList() bool {
   351  	for _, field := range s.Fields {
   352  		if _, ok := field.(*ListField); ok {
   353  			return true
   354  		}
   355  	}
   356  	return false
   357  }
   358  
   359  type Union struct {
   360  	srcName string
   361  	xmlName string
   362  	Fields  []Field
   363  }
   364  
   365  func (u *Union) SrcName() string {
   366  	return u.srcName
   367  }
   368  
   369  func (u *Union) XmlName() string {
   370  	return u.xmlName
   371  }
   372  
   373  // Size for Union is broken. At least, it's broken for XKB.
   374  // It *looks* like the protocol inherently relies on some amount of
   375  // memory unsafety, since some members of unions in XKB are *variable* in
   376  // length! The only thing I can come up with, maybe, is when a union has
   377  // variable size, simply return the raw bytes. Then it's up to the user to
   378  // pass those raw bytes into the appropriate New* constructor. GROSS!
   379  // As of now, just pluck out the first field and return that size. This
   380  // should work for union elements in randr.xml and xproto.xml.
   381  func (u *Union) Size() Size {
   382  	return u.Fields[0].Size()
   383  }
   384  
   385  func (u *Union) Initialize(p *Protocol) {
   386  	u.srcName = fmt.Sprintf("%sUnion", TypeSrcName(p, u))
   387  	for _, field := range u.Fields {
   388  		field.Initialize(p)
   389  	}
   390  }