From af1c95270025aa5578fa661a1ce6e64dd217161a Mon Sep 17 00:00:00 2001 From: James Shubin Date: Sat, 25 Nov 2023 20:57:34 -0500 Subject: [PATCH] lang: funcs: funcgen: Allow []string as inputs This allows us to have the strings.Join function generated. --- lang/funcs/funcgen/config.go | 34 +++++++++++++++++++ lang/funcs/funcgen/fixtures/func_base.tpl | 1 + lang/funcs/funcgen/func.go | 11 +++--- lang/funcs/funcgen/pkg.go | 2 +- .../funcgen/templates/generated_funcs.go.tpl | 1 + lang/funcs/funcgen/util/util.go | 33 ++++++++++++++++++ 6 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 lang/funcs/funcgen/util/util.go diff --git a/lang/funcs/funcgen/config.go b/lang/funcs/funcgen/config.go index 484bd9a5..51dea214 100644 --- a/lang/funcs/funcgen/config.go +++ b/lang/funcs/funcgen/config.go @@ -19,6 +19,7 @@ package main import ( "fmt" + "math/bits" "github.com/purpleidea/mgmt/lang/types" ) @@ -63,6 +64,8 @@ func (obj *arg) ToMcl() (string, error) { return fmt.Sprintf("%s%s", prefix, types.TypeInt.String()), nil case "float64": return fmt.Sprintf("%s%s", prefix, types.TypeFloat.String()), nil + case "[]string": + return fmt.Sprintf("%s%s", prefix, types.NewType("[]str").String()), nil default: return "", fmt.Errorf("cannot convert %v to mcl", obj.Type) } @@ -87,6 +90,37 @@ func (obj *arg) OldToGolang() (string, error) { } } +// ToGolang prints the arg signature as expected by golang. +func (obj *arg) ToGolang(val string) (string, error) { + switch obj.Type { + case "bool": + return fmt.Sprintf("%s.Bool()", val), nil + + case "string", "[]byte": + return fmt.Sprintf("%s.Str()", val), nil + + case "int": + // TODO: consider switching types.Value int64 to int everywhere + if bits.UintSize == 32 { // special case for 32 bit golang + return fmt.Sprintf("int(%s.Int())", val), nil + } + fallthrough + case "int64": + return fmt.Sprintf("%s.Int()", val), nil + + case "float64": + return fmt.Sprintf("%s.Float()", val), nil + + case "[]string": + // This function is in the child util package and is imported by + // the template. + return fmt.Sprintf("util.MclListToGolang(%s)", val), nil + + default: + return "", fmt.Errorf("cannot convert %v to golang", obj) + } +} + // ToTestInput prints the arg signature as expected by tests. func (obj *arg) ToTestInput() (string, error) { switch obj.Type { diff --git a/lang/funcs/funcgen/fixtures/func_base.tpl b/lang/funcs/funcgen/fixtures/func_base.tpl index aa6d2b60..cf0a0388 100644 --- a/lang/funcs/funcgen/fixtures/func_base.tpl +++ b/lang/funcs/funcgen/fixtures/func_base.tpl @@ -20,6 +20,7 @@ package core import ( "testpkg" + "github.com/purpleidea/mgmt/lang/funcs/funcgen/util" "github.com/purpleidea/mgmt/lang/funcs/simple" "github.com/purpleidea/mgmt/lang/types" ) diff --git a/lang/funcs/funcgen/func.go b/lang/funcs/funcgen/func.go index b56bcbe5..5ca36f1c 100644 --- a/lang/funcs/funcgen/func.go +++ b/lang/funcs/funcgen/func.go @@ -101,18 +101,19 @@ func generateTemplate(c config, f functions, path, templateFile, finalName strin func (obj *function) MakeGolangArgs() (string, error) { var args []string for i, a := range obj.Args { - gol, err := a.ToGolang() + input := fmt.Sprintf("input[%d]", i) + gol, err := a.ToGolang(input) if err != nil { return "", err } - input := fmt.Sprintf("input[%d].%s()", i, gol) + switch a.Type { case "int": - input = fmt.Sprintf("int(%s)", input) + gol = fmt.Sprintf("int(%s)", gol) case "[]byte": - input = fmt.Sprintf("[]byte(%s)", input) + gol = fmt.Sprintf("[]byte(%s)", gol) } - args = append(args, input) + args = append(args, gol) } for _, a := range obj.ExtraGolangArgs { args = append(args, a.Value) diff --git a/lang/funcs/funcgen/pkg.go b/lang/funcs/funcgen/pkg.go index 92a803b6..56ce3b6a 100644 --- a/lang/funcs/funcgen/pkg.go +++ b/lang/funcs/funcgen/pkg.go @@ -33,7 +33,7 @@ import ( ) var ( - validSignature = regexp.MustCompile(`^func (?P[A-Z][a-zA-Z0-9]+)\((?P([a-zA-Z]+( (bool|string|int|int64|float64|\[\]byte))?(, )?){0,})\) (?P(bool|string|int|int64|float64|\[\]byte|)|\((bool|string|int|int64|float64|\[\]byte), error\))$`) + validSignature = regexp.MustCompile(`^func (?P[A-Z][a-zA-Z0-9]+)\((?P([a-zA-Z]+( (bool|string|int|int64|float64|\[\]byte|\[\]string))?(, )?){0,})\) (?P(bool|string|int|int64|float64|\[\]byte|)|\((bool|string|int|int64|float64|\[\]byte|), error\))$`) errExcluded = errors.New("function is excluded") ) diff --git a/lang/funcs/funcgen/templates/generated_funcs.go.tpl b/lang/funcs/funcgen/templates/generated_funcs.go.tpl index 7823dda2..f2838bab 100644 --- a/lang/funcs/funcgen/templates/generated_funcs.go.tpl +++ b/lang/funcs/funcgen/templates/generated_funcs.go.tpl @@ -20,6 +20,7 @@ package core import ( {{ range $i, $func := .Packages }} {{ if not (eq .Alias "") }}{{.Alias}} {{end}}"{{.Name}}" {{ end }} + "github.com/purpleidea/mgmt/lang/funcs/funcgen/util" "github.com/purpleidea/mgmt/lang/funcs/simple" "github.com/purpleidea/mgmt/lang/types" ) diff --git a/lang/funcs/funcgen/util/util.go b/lang/funcs/funcgen/util/util.go new file mode 100644 index 00000000..a20f612b --- /dev/null +++ b/lang/funcs/funcgen/util/util.go @@ -0,0 +1,33 @@ +// Mgmt +// Copyright (C) 2013-2023+ James Shubin and the project contributors +// Written by James Shubin and the project contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// Package util provides some functions to be imported by the generated file. +package util + +import ( + "github.com/purpleidea/mgmt/lang/types" +) + +// MclListToGolang is a helper function that converts an mcl []str to the golang +// equivalent of []string. This is imported by the generated functions. +func MclListToGolang(val types.Value) []string { + ret := []string{} + for _, x := range val.List() { + ret = append(ret, x.Str()) + } + return ret +}