Fix union data size for types with enums 51/19951/1
authorOndrej Fabry <ofabry@cisco.com>
Tue, 4 Jun 2019 12:47:19 +0000 (14:47 +0200)
committerOndrej Fabry <ofabry@cisco.com>
Tue, 4 Jun 2019 12:47:19 +0000 (14:47 +0200)
- this also fixed proper alphabetical order for struct tags
- env var DEBUG_BINAPI_GENERATOR=y can be used to enable debug mode

Change-Id: I5b08a696ad2ff2a297872f231f9229cd956ee443
Signed-off-by: Ondrej Fabry <ofabry@cisco.com>
adapter/socketclient/socketclient.go
cmd/binapi-generator/generate.go
cmd/binapi-generator/main.go
cmd/binapi-generator/parse_test.go
cmd/binapi-generator/types.go

index c80af36..4a76df2 100644 (file)
@@ -464,7 +464,7 @@ func (c *vppClient) read() ([]byte, error) {
                return nil, nil
        }
        if n != 16 {
-               Log.Debug("invalid header data (%d): % 0X", n, header[:n])
+               Log.Debugf("invalid header data (%d): % 0X", n, header[:n])
                return nil, fmt.Errorf("invalid header (expected 16 bytes, got %d)", n)
        }
        Log.Debugf(" - read header %d bytes: % 0X", n, header)
index 64d1071..4ffe88e 100644 (file)
@@ -20,6 +20,7 @@ import (
        "fmt"
        "io"
        "path/filepath"
+       "sort"
        "strings"
        "unicode"
 )
@@ -41,6 +42,7 @@ type context struct {
 
        includeAPIVersionCrc bool // include constant with API version CRC string
        includeComments      bool // include parts of original source in comments
+       includeBinapiNames   bool // include binary API names as struct tag
 
        moduleName  string // name of the source VPP module
        packageName string // name of the Go package being generated
@@ -606,19 +608,31 @@ func generateField(ctx *context, w io.Writer, fields []Field, i int) {
                }
        }
 
+       if ctx.includeBinapiNames {
+               fieldTags["binapi"] = field.Name
+       }
        if field.Meta.Limit > 0 {
-               fieldTags["binapi"] = fmt.Sprintf(",limit=%d", field.Meta.Limit)
+               fieldTags["binapi"] = fmt.Sprintf("%s,limit=%d", fieldTags["binapi"], field.Meta.Limit)
        }
 
        if len(fieldTags) > 0 {
                fmt.Fprintf(w, "\t`")
-               var i int
-               for n, t := range fieldTags {
-                       if i > 0 {
+               var keys []string
+               for k := range fieldTags {
+                       keys = append(keys, k)
+               }
+               sort.Strings(keys)
+               var n int
+               for _, tt := range keys {
+                       t, ok := fieldTags[tt]
+                       if !ok {
+                               continue
+                       }
+                       if n > 0 {
                                fmt.Fprintf(w, " ")
                        }
-                       i++
-                       fmt.Fprintf(w, `%s:"%s"`, n, t)
+                       n++
+                       fmt.Fprintf(w, `%s:"%s"`, tt, t)
                }
                fmt.Fprintf(w, "`")
        }
index b3a131c..faed54f 100644 (file)
@@ -30,15 +30,18 @@ import (
 )
 
 var (
-       inputFile       = flag.String("input-file", "", "Input file with VPP API in JSON format.")
-       inputDir        = flag.String("input-dir", ".", "Input directory with VPP API files in JSON format.")
-       outputDir       = flag.String("output-dir", ".", "Output directory where package folders will be generated.")
-       includeAPIVer   = flag.Bool("include-apiver", false, "Include APIVersion constant for each module.")
-       includeComments = flag.Bool("include-comments", false, "Include JSON API source in comments for each object.")
-       continueOnError = flag.Bool("continue-onerror", false, "Continue with next file on error.")
-       debug           = flag.Bool("debug", false, "Enable debug mode.")
+       inputFile          = flag.String("input-file", "", "Input file with VPP API in JSON format.")
+       inputDir           = flag.String("input-dir", ".", "Input directory with VPP API files in JSON format.")
+       outputDir          = flag.String("output-dir", ".", "Output directory where package folders will be generated.")
+       includeAPIVer      = flag.Bool("include-apiver", false, "Include APIVersion constant for each module.")
+       includeComments    = flag.Bool("include-comments", false, "Include JSON API source in comments for each object.")
+       includeBinapiNames = flag.Bool("include-binapi-names", false, "Include binary API names in struct tag.")
+       continueOnError    = flag.Bool("continue-onerror", false, "Continue with next file on error.")
+       debug              = flag.Bool("debug", debugMode, "Enable debug mode.")
 )
 
+var debugMode = os.Getenv("DEBUG_BINAPI_GENERATOR") != ""
+
 var log = logrus.Logger{
        Level:     logrus.InfoLevel,
        Formatter: &logrus.TextFormatter{},
@@ -107,6 +110,7 @@ func generateFromFile(inputFile, outputDir string) error {
 
        ctx.includeAPIVersionCrc = *includeAPIVer
        ctx.includeComments = *includeComments
+       ctx.includeBinapiNames = *includeBinapiNames
 
        // read input file contents
        ctx.inputData, err = readFile(inputFile)
index ea15ec5..e145979 100644 (file)
@@ -32,34 +32,63 @@ func TestSizeOfType(t *testing.T) {
                input   Type
                expsize int
        }{
-               {name: "basic1",
-                       input: Type{Fields: []Field{
-                               {Type: "u8"},
-                       }},
+               {
+                       name: "basic1",
+                       input: Type{
+                               Fields: []Field{
+                                       {Type: "u8"},
+                               },
+                       },
                        expsize: 1,
                },
-               {name: "basic2",
-                       input: Type{Fields: []Field{
-                               {Type: "u8", Length: 4},
-                       }},
+               {
+                       name: "basic2",
+                       input: Type{
+                               Fields: []Field{
+                                       {Type: "u8", Length: 4},
+                               },
+                       },
                        expsize: 4,
                },
-               {name: "basic3",
-                       input: Type{Fields: []Field{
-                               {Type: "u8", Length: 16},
-                       }},
+               {
+                       name: "basic3",
+                       input: Type{
+                               Fields: []Field{
+                                       {Type: "u8", Length: 16},
+                               },
+                       },
                        expsize: 16,
                },
-               {name: "invalid1",
-                       input: Type{Fields: []Field{
-                               {Type: "x", Length: 16},
-                       }},
+               {
+                       name: "withEnum",
+                       input: Type{
+                               Fields: []Field{
+                                       {Type: "u16"},
+                                       {Type: "vl_api_myenum_t"},
+                               },
+                       },
+                       expsize: 6,
+               },
+               {
+                       name: "invalid1",
+                       input: Type{
+                               Fields: []Field{
+                                       {Type: "x", Length: 16},
+                               },
+                       },
                        expsize: 0,
                },
        }
        for _, test := range tests {
                t.Run(test.name, func(t *testing.T) {
-                       size := getSizeOfType(&test.input)
+                       ctx := &context{
+                               packageData: &Package{
+                                       Enums: []Enum{
+                                               {Name: "myenum", Type: "u32"},
+                                       },
+                               },
+                       }
+                       size := getSizeOfType(ctx, &test.input)
                        if size != test.expsize {
                                t.Errorf("expected %d, got %d", test.expsize, size)
                        }
index 3aa9819..d056251 100644 (file)
@@ -69,8 +69,13 @@ func convertToGoType(ctx *context, binapiType string) (typ string) {
        return typ
 }
 
-func getSizeOfType(typ *Type) (size int) {
+func getSizeOfType(ctx *context, typ *Type) (size int) {
        for _, field := range typ.Fields {
+               enum := getEnumByRef(ctx, field.Type)
+               if enum != nil {
+                       size += getSizeOfBinapiTypeLength(enum.Type, field.Length)
+                       continue
+               }
                size += getSizeOfBinapiTypeLength(field.Type, field.Length)
        }
        return size
@@ -84,9 +89,19 @@ func getSizeOfBinapiTypeLength(typ string, length int) (size int) {
                        return n
                }
        }
+
        return
 }
 
+func getEnumByRef(ctx *context, ref string) *Enum {
+       for _, typ := range ctx.packageData.Enums {
+               if ref == toApiType(typ.Name) {
+                       return &typ
+               }
+       }
+       return nil
+}
+
 func getTypeByRef(ctx *context, ref string) *Type {
        for _, typ := range ctx.packageData.Types {
                if ref == toApiType(typ.Name) {
@@ -109,7 +124,7 @@ func getUnionSize(ctx *context, union *Union) (maxSize int) {
        for _, field := range union.Fields {
                typ := getTypeByRef(ctx, field.Type)
                if typ != nil {
-                       if size := getSizeOfType(typ); size > maxSize {
+                       if size := getSizeOfType(ctx, typ); size > maxSize {
                                maxSize = size
                        }
                        continue
@@ -125,5 +140,6 @@ func getUnionSize(ctx *context, union *Union) (maxSize int) {
                        continue
                }
        }
+       logf("getUnionSize: %s %+v max=%v", union.Name, union.Fields, maxSize)
        return
 }