1515package tagexpr
1616
1717import (
18+ "context"
1819 "fmt"
1920 "reflect"
2021 "regexp"
@@ -44,44 +45,54 @@ func RegFunc(funcName string, fn func(...interface{}) interface{}, force ...bool
4445 return nil
4546}
4647
47- func newFunc ( funcName string , fn func ( ... interface {}) interface {}) func ( * Expr , * string ) ExprNode {
48+ func ( p * Expr ) parseFuncSign ( funcName string , expr * string ) ( boolOpposite * bool , signOpposite * bool , args [] ExprNode , found bool ) {
4849 prefix := funcName + "("
4950 length := len (funcName )
50- return func (p * Expr , expr * string ) ExprNode {
51- last , boolOpposite := getBoolOpposite (expr )
52- if ! strings .HasPrefix (last , prefix ) {
53- return nil
51+ last , boolOpposite , signOpposite := getBoolAndSignOpposite (expr )
52+ if ! strings .HasPrefix (last , prefix ) {
53+ return
54+ }
55+ * expr = last [length :]
56+ lastStr := * expr
57+ subExprNode := readPairedSymbol (expr , '(' , ')' )
58+ if subExprNode == nil {
59+ return
60+ }
61+ * subExprNode = "," + * subExprNode
62+ for {
63+ if strings .HasPrefix (* subExprNode , "," ) {
64+ * subExprNode = (* subExprNode )[1 :]
65+ operand := newGroupExprNode ()
66+ _ , err := p .parseExprNode (trimLeftSpace (subExprNode ), operand )
67+ if err != nil {
68+ * expr = lastStr
69+ return
70+ }
71+ sortPriority (operand .RightOperand ())
72+ args = append (args , operand )
73+ } else {
74+ * expr = lastStr
75+ return
76+ }
77+ trimLeftSpace (subExprNode )
78+ if len (* subExprNode ) == 0 {
79+ found = true
80+ return
5481 }
55- * expr = last [length :]
56- lastStr := * expr
57- subExprNode := readPairedSymbol (expr , '(' , ')' )
58- if subExprNode == nil {
82+ }
83+ }
84+
85+ func newFunc (funcName string , fn func (... interface {}) interface {}) func (* Expr , * string ) ExprNode {
86+ return func (p * Expr , expr * string ) ExprNode {
87+ boolOpposite , signOpposite , args , found := p .parseFuncSign (funcName , expr )
88+ if ! found {
5989 return nil
6090 }
61- f := & funcExprNode {
91+ return & funcExprNode {
6292 fn : fn ,
6393 boolOpposite : boolOpposite ,
64- }
65- * subExprNode = "," + * subExprNode
66- for {
67- if strings .HasPrefix (* subExprNode , "," ) {
68- * subExprNode = (* subExprNode )[1 :]
69- operand := newGroupExprNode ()
70- _ , err := p .parseExprNode (trimLeftSpace (subExprNode ), operand )
71- if err != nil {
72- * expr = lastStr
73- return nil
74- }
75- sortPriority (operand .RightOperand ())
76- f .args = append (f .args , operand )
77- } else {
78- * expr = lastStr
79- return nil
80- }
81- trimLeftSpace (subExprNode )
82- if len (* subExprNode ) == 0 {
83- return f
84- }
94+ signOpposite : signOpposite ,
95+ args : args ,
8596 }
8697 }
8798}
@@ -91,23 +102,25 @@ type funcExprNode struct {
91102 args []ExprNode
92103 fn func (... interface {}) interface {}
93104 boolOpposite * bool
105+ signOpposite * bool
94106}
95107
96- func (f * funcExprNode ) Run (currField string , tagExpr * TagExpr ) interface {} {
108+ func (f * funcExprNode ) Run (ctx context. Context , currField string , tagExpr * TagExpr ) interface {} {
97109 var args []interface {}
98110 if n := len (f .args ); n > 0 {
99111 args = make ([]interface {}, n )
100112 for k , v := range f .args {
101- args [k ] = v .Run (currField , tagExpr )
113+ args [k ] = v .Run (ctx , currField , tagExpr )
102114 }
103115 }
104- return realValue (f .fn (args ... ), f .boolOpposite )
116+ return realValue (f .fn (args ... ), f .boolOpposite , f . signOpposite )
105117}
106118
107119// --------------------------- Built-in function ---------------------------
108120func init () {
109121 funcList ["regexp" ] = readRegexpFuncExprNode
110122 funcList ["sprintf" ] = readSprintfFuncExprNode
123+ funcList ["range" ] = readRangeFuncExprNode
111124 err := RegFunc ("len" , func (args ... interface {}) (n interface {}) {
112125 if len (args ) != 1 {
113126 return 0
@@ -159,7 +172,7 @@ type regexpFuncExprNode struct {
159172}
160173
161174func readRegexpFuncExprNode (p * Expr , expr * string ) ExprNode {
162- last , boolOpposite := getBoolOpposite (expr )
175+ last , boolOpposite , _ := getBoolAndSignOpposite (expr )
163176 if ! strings .HasPrefix (last , "regexp(" ) {
164177 return nil
165178 }
@@ -207,8 +220,8 @@ func readRegexpFuncExprNode(p *Expr, expr *string) ExprNode {
207220 return e
208221}
209222
210- func (re * regexpFuncExprNode ) Run (currField string , tagExpr * TagExpr ) interface {} {
211- param := re .rightOperand .Run (currField , tagExpr )
223+ func (re * regexpFuncExprNode ) Run (ctx context. Context , currField string , tagExpr * TagExpr ) interface {} {
224+ param := re .rightOperand .Run (ctx , currField , tagExpr )
212225 switch v := param .(type ) {
213226 case string :
214227 bol := re .re .MatchString (v )
@@ -276,12 +289,12 @@ func readSprintfFuncExprNode(p *Expr, expr *string) ExprNode {
276289 }
277290}
278291
279- func (se * sprintfFuncExprNode ) Run (currField string , tagExpr * TagExpr ) interface {} {
292+ func (se * sprintfFuncExprNode ) Run (ctx context. Context , currField string , tagExpr * TagExpr ) interface {} {
280293 var args []interface {}
281294 if n := len (se .args ); n > 0 {
282295 args = make ([]interface {}, n )
283296 for i , e := range se .args {
284- args [i ] = e .Run (currField , tagExpr )
297+ args [i ] = e .Run (ctx , currField , tagExpr )
285298 }
286299 }
287300 return fmt .Sprintf (se .format , args ... )
0 commit comments