github.com/GuanceCloud/cliutils@v1.1.21/pipeline/ptinput/funcs/fn_cover.go (about)

     1  // Unless explicitly stated otherwise all files in this repository are licensed
     2  // under the MIT License.
     3  // This product includes software developed at Guance Cloud (https://www.guance.com/).
     4  // Copyright 2021-present Guance, Inc.
     5  
     6  package funcs
     7  
     8  import (
     9  	"fmt"
    10  	"unicode"
    11  	"unicode/utf8"
    12  
    13  	"github.com/GuanceCloud/cliutils/pipeline/ptinput"
    14  	"github.com/GuanceCloud/platypus/pkg/ast"
    15  	"github.com/GuanceCloud/platypus/pkg/engine/runtime"
    16  	"github.com/GuanceCloud/platypus/pkg/errchain"
    17  )
    18  
    19  func CoverChecking(ctx *runtime.Task, funcExpr *ast.CallExpr) *errchain.PlError {
    20  	if len(funcExpr.Param) != 2 {
    21  		return runtime.NewRunError(ctx, fmt.Sprintf(
    22  			"func %s expects 2 args", funcExpr.Name), funcExpr.NamePos)
    23  	}
    24  
    25  	if _, err := getKeyName(funcExpr.Param[0]); err != nil {
    26  		return runtime.NewRunError(ctx, err.Error(), funcExpr.Param[0].StartPos())
    27  	}
    28  
    29  	if funcExpr.Param[1].NodeType != ast.TypeListLiteral {
    30  		return runtime.NewRunError(ctx, fmt.Sprintf(
    31  			"param range expects ListInitExpr, got %s", funcExpr.Param[1].NodeType),
    32  			funcExpr.Param[1].StartPos())
    33  	}
    34  
    35  	set := funcExpr.Param[1].ListLiteral()
    36  
    37  	if len(set.List) != 2 {
    38  		return runtime.NewRunError(ctx, fmt.Sprintf(
    39  			"param between range value `%v' is not expected", funcExpr.Param[1]),
    40  			funcExpr.Param[1].StartPos())
    41  	}
    42  
    43  	if (set.List[0].NodeType != ast.TypeFloatLiteral && set.List[0].NodeType != ast.TypeIntegerLiteral) ||
    44  		(set.List[1].NodeType != ast.TypeFloatLiteral && set.List[1].NodeType != ast.TypeIntegerLiteral) {
    45  		return runtime.NewRunError(ctx, fmt.Sprintf(
    46  			"range value `%v' is not expected", set), funcExpr.Param[1].StartPos())
    47  	}
    48  
    49  	return nil
    50  }
    51  
    52  func Cover(ctx *runtime.Task, funcExpr *ast.CallExpr) *errchain.PlError {
    53  	if len(funcExpr.Param) != 2 {
    54  		return runtime.NewRunError(ctx, fmt.Sprintf(
    55  			"func %s expects 2 args", funcExpr.Name), funcExpr.NamePos)
    56  	}
    57  
    58  	key, err := getKeyName(funcExpr.Param[0])
    59  	if err != nil {
    60  		return runtime.NewRunError(ctx, err.Error(), funcExpr.Param[0].StartPos())
    61  	}
    62  
    63  	if funcExpr.Param[1].NodeType != ast.TypeListLiteral {
    64  		return nil
    65  	}
    66  
    67  	set := funcExpr.Param[1].ListLiteral()
    68  
    69  	var start, end int
    70  
    71  	if len(set.List) != 2 {
    72  		return runtime.NewRunError(ctx, fmt.Sprintf(
    73  			"param between range value `%v' is not expected", set),
    74  			funcExpr.Param[1].StartPos())
    75  	}
    76  
    77  	switch set.List[0].NodeType { //nolint:exhaustive
    78  	case ast.TypeIntegerLiteral:
    79  		start = int(set.List[0].IntegerLiteral().Val)
    80  	case ast.TypeFloatLiteral:
    81  		start = int(set.List[0].FloatLiteral().Val)
    82  	default:
    83  		return runtime.NewRunError(ctx, fmt.Sprintf(
    84  			"range value `%v' is not expected", set),
    85  			funcExpr.Param[1].StartPos())
    86  	}
    87  
    88  	switch set.List[1].NodeType { //nolint:exhaustive
    89  	case ast.TypeIntegerLiteral:
    90  		end = int(set.List[1].IntegerLiteral().Val)
    91  	case ast.TypeFloatLiteral:
    92  		end = int(set.List[1].FloatLiteral().Val)
    93  	default:
    94  		return runtime.NewRunError(ctx, fmt.Sprintf(
    95  			"range value `%v' is not expected", set),
    96  			funcExpr.Param[1].StartPos())
    97  	}
    98  
    99  	cont1, err := ctx.GetKey(key)
   100  	if err != nil {
   101  		l.Debugf("key `%v' not exist, ignored", key)
   102  		return nil //nolint:nilerr
   103  	}
   104  
   105  	var cont string
   106  
   107  	switch v := cont1.Value.(type) {
   108  	case string:
   109  		cont = v
   110  	default:
   111  		return nil
   112  	}
   113  
   114  	if end > utf8.RuneCountInString(cont) {
   115  		end = utf8.RuneCountInString(cont)
   116  	}
   117  
   118  	// end less than 0  become greater than 0
   119  	if end < 0 {
   120  		end += utf8.RuneCountInString(cont) + 1
   121  	}
   122  	// start less than 0  become greater than 0
   123  	if start <= 0 {
   124  		start += utf8.RuneCountInString(cont) + 1
   125  	}
   126  
   127  	// unreasonable subscript
   128  	if start > end {
   129  		l.Debug("invalid cover range")
   130  		return nil
   131  		// return runtime.NewRunError(ctx, "invalid cover range", funcExpr.Param[1].StartPos())
   132  	}
   133  
   134  	arrCont := []rune(cont)
   135  
   136  	for i := 0; i < len(arrCont); i++ {
   137  		if i+1 >= start && i < end {
   138  			if unicode.Is(unicode.Han, arrCont[i]) {
   139  				arrCont[i] = rune('*')
   140  			} else {
   141  				arrCont[i] = rune('*')
   142  			}
   143  		}
   144  	}
   145  
   146  	_ = addKey2PtWithVal(ctx.InData(), key, string(arrCont),
   147  		ast.String, ptinput.KindPtDefault)
   148  
   149  	return nil
   150  }