github.com/robotn/xgb@v0.0.0-20190912153532-2cb92d044934/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 }