aboutsummaryrefslogtreecommitdiff
path: root/nexgb/xgbgen/xml_fields.go
diff options
context:
space:
mode:
Diffstat (limited to 'nexgb/xgbgen/xml_fields.go')
-rw-r--r--nexgb/xgbgen/xml_fields.go86
1 files changed, 86 insertions, 0 deletions
diff --git a/nexgb/xgbgen/xml_fields.go b/nexgb/xgbgen/xml_fields.go
new file mode 100644
index 0000000..8b7b5c7
--- /dev/null
+++ b/nexgb/xgbgen/xml_fields.go
@@ -0,0 +1,86 @@
+package main
+
+import (
+ "encoding/xml"
+ "log"
+)
+
+type XMLField struct {
+ XMLName xml.Name
+
+ // For 'pad' element
+ Bytes uint `xml:"bytes,attr"`
+ Align uint16 `xml:"align,attr"`
+
+ // For 'field', 'list', 'localfield', 'exprfield' and 'switch' elements.
+ Name string `xml:"name,attr"`
+
+ // For 'field', 'list', 'localfield', and 'exprfield' elements.
+ Type string `xml:"type,attr"`
+
+ // For 'list', 'exprfield' and 'switch' elements.
+ Expr *XMLExpression `xml:",any"`
+
+ // For 'valueparm' element.
+ ValueMaskType string `xml:"value-mask-type,attr"`
+ ValueMaskName string `xml:"value-mask-name,attr"`
+ ValueListName string `xml:"value-list-name,attr"`
+
+ // For 'switch' element.
+ Bitcases []*XMLBitcase `xml:"bitcase"`
+
+ // I don't know which elements these are for. The documentation is vague.
+ // They also seem to be completely optional.
+ OptEnum string `xml:"enum,attr"`
+ OptMask string `xml:"mask,attr"`
+ OptAltEnum string `xml:"altenum,attr"`
+}
+
+// Bitcase represents a single expression followed by any number of fields.
+// Namely, if the switch's expression (all bitcases are inside a switch),
+// and'd with the bitcase's expression is equal to the bitcase expression,
+// then the fields should be included in its parent structure.
+// Note that since a bitcase is unique in that expressions and fields are
+// siblings, we must exhaustively search for one of them. Essentially,
+// it's the closest thing to a Union I can get to in Go without interfaces.
+// Would an '<expression>' tag have been too much to ask? :-(
+type XMLBitcase struct {
+ Fields []*XMLField `xml:",any"`
+
+ // All the different expressions.
+ // When it comes time to choose one, use the 'Expr' method.
+ ExprOp *XMLExpression `xml:"op"`
+ ExprUnOp *XMLExpression `xml:"unop"`
+ ExprField *XMLExpression `xml:"fieldref"`
+ ExprValue *XMLExpression `xml:"value"`
+ ExprBit *XMLExpression `xml:"bit"`
+ ExprEnum *XMLExpression `xml:"enumref"`
+ ExprSum *XMLExpression `xml:"sumof"`
+ ExprPop *XMLExpression `xml:"popcount"`
+}
+
+// Expr chooses the only non-nil Expr* field from Bitcase.
+// Panic if there is more than one non-nil expression.
+func (b *XMLBitcase) Expr() *XMLExpression {
+ choices := []*XMLExpression{
+ b.ExprOp, b.ExprUnOp, b.ExprField, b.ExprValue,
+ b.ExprBit, b.ExprEnum, b.ExprSum, b.ExprPop,
+ }
+
+ var choice *XMLExpression = nil
+ numNonNil := 0
+ for _, c := range choices {
+ if c != nil {
+ numNonNil++
+ choice = c
+ }
+ }
+
+ if choice == nil {
+ log.Panicf("No top level expression found in a bitcase.")
+ }
+ if numNonNil > 1 {
+ log.Panicf("More than one top-level expression was found in a bitcase.")
+ }
+ return choice
+}