mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
Can process hex numbers
This commit is contained in:
parent
f848e334ee
commit
eea2c97cd8
@ -15,6 +15,16 @@ var pathTests = []struct {
|
||||
expectedTokens []interface{}
|
||||
expectedPostFix []interface{}
|
||||
}{
|
||||
{
|
||||
"0x12",
|
||||
append(make([]interface{}, 0), "18 (int64)"),
|
||||
append(make([]interface{}, 0), "18 (int64)"),
|
||||
},
|
||||
{
|
||||
"0X12",
|
||||
append(make([]interface{}, 0), "18 (int64)"),
|
||||
append(make([]interface{}, 0), "18 (int64)"),
|
||||
},
|
||||
{
|
||||
".a\n",
|
||||
append(make([]interface{}, 0), "a"),
|
||||
|
@ -166,6 +166,20 @@ func numberValue() lex.Action {
|
||||
}
|
||||
}
|
||||
|
||||
func hexValue() lex.Action {
|
||||
return func(s *lex.Scanner, m *machines.Match) (interface{}, error) {
|
||||
var originalString = string(m.Bytes)
|
||||
var numberString = originalString[2:]
|
||||
log.Debugf("numberString: %v", numberString)
|
||||
var number, errParsingInt = strconv.ParseInt(numberString, 16, 64) // nolint
|
||||
if errParsingInt != nil {
|
||||
return nil, errParsingInt
|
||||
}
|
||||
|
||||
return &token{TokenType: operationToken, Operation: createValueOperation(number, originalString)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func floatValue() lex.Action {
|
||||
return func(s *lex.Scanner, m *machines.Match) (interface{}, error) {
|
||||
var numberString = string(m.Bytes)
|
||||
@ -328,6 +342,7 @@ func initLexer() (*lex.Lexer, error) {
|
||||
|
||||
lexer.Add([]byte(`\|`), opToken(pipeOpType))
|
||||
|
||||
lexer.Add([]byte(`0[xX][0-9A-Fa-f]+`), hexValue())
|
||||
lexer.Add([]byte(`-?\d+(\.\d+)`), floatValue())
|
||||
lexer.Add([]byte(`-?[1-9](\.\d+)?[Ee][-+]?\d+`), floatValue())
|
||||
lexer.Add([]byte(`-?\d+`), numberValue())
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
"bytes"
|
||||
"container/list"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
logging "gopkg.in/op/go-logging.v1"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
@ -117,6 +119,17 @@ type Operation struct {
|
||||
UpdateAssign bool // used for assign ops, when true it means we evaluate the rhs given the lhs
|
||||
}
|
||||
|
||||
// yaml numbers can be hex encoded...
|
||||
func parseInt(numberString string) (string, int64, error) {
|
||||
if strings.HasPrefix(numberString, "0x") ||
|
||||
strings.HasPrefix(numberString, "0X") {
|
||||
num, err := strconv.ParseInt(numberString[2:], 16, 64) // nolint
|
||||
return "0x%X", num, err
|
||||
}
|
||||
num, err := strconv.ParseInt(numberString, 10, 64) // nolint
|
||||
return "%v", num, err
|
||||
}
|
||||
|
||||
func createScalarNode(value interface{}, stringValue string) *yaml.Node {
|
||||
var node = &yaml.Node{Kind: yaml.ScalarNode}
|
||||
node.Value = stringValue
|
||||
|
@ -76,17 +76,17 @@ func addScalars(target *CandidateNode, lhs *yaml.Node, rhs *yaml.Node) (*Candida
|
||||
target.Node.Tag = "!!str"
|
||||
target.Node.Value = lhs.Value + rhs.Value
|
||||
} else if lhs.Tag == "!!int" && rhs.Tag == "!!int" {
|
||||
lhsNum, err := strconv.Atoi(lhs.Value)
|
||||
format, lhsNum, err := parseInt(lhs.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rhsNum, err := strconv.Atoi(rhs.Value)
|
||||
_, rhsNum, err := parseInt(rhs.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sum := lhsNum + rhsNum
|
||||
target.Node.Tag = "!!int"
|
||||
target.Node.Value = fmt.Sprintf("%v", sum)
|
||||
target.Node.Value = fmt.Sprintf(format, sum)
|
||||
} else if (lhs.Tag == "!!int" || lhs.Tag == "!!float") && (rhs.Tag == "!!int" || rhs.Tag == "!!float") {
|
||||
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
|
||||
if err != nil {
|
||||
|
@ -91,15 +91,15 @@ func multiplyIntegers(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, e
|
||||
target.Node.Style = lhs.Node.Style
|
||||
target.Node.Tag = "!!int"
|
||||
|
||||
lhsNum, err := strconv.Atoi(lhs.Node.Value)
|
||||
format, lhsNum, err := parseInt(lhs.Node.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rhsNum, err := strconv.Atoi(rhs.Node.Value)
|
||||
_, rhsNum, err := parseInt(rhs.Node.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
target.Node.Value = fmt.Sprintf("%v", lhsNum*rhsNum)
|
||||
target.Node.Value = fmt.Sprintf(format, lhsNum*rhsNum)
|
||||
return target, nil
|
||||
}
|
||||
|
||||
|
@ -62,17 +62,17 @@ func subtractScalars(target *CandidateNode, lhs *yaml.Node, rhs *yaml.Node) (*Ca
|
||||
if lhs.Tag == "!!str" {
|
||||
return nil, fmt.Errorf("strings cannot be subtracted")
|
||||
} else if lhs.Tag == "!!int" && rhs.Tag == "!!int" {
|
||||
lhsNum, err := strconv.Atoi(lhs.Value)
|
||||
format, lhsNum, err := parseInt(lhs.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rhsNum, err := strconv.Atoi(rhs.Value)
|
||||
_, rhsNum, err := parseInt(rhs.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := lhsNum - rhsNum
|
||||
target.Node.Tag = "!!int"
|
||||
target.Node.Value = fmt.Sprintf("%v", result)
|
||||
target.Node.Value = fmt.Sprintf(format, result)
|
||||
} else if (lhs.Tag == "!!int" || lhs.Tag == "!!float") && (rhs.Tag == "!!int" || rhs.Tag == "!!float") {
|
||||
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
|
||||
if err != nil {
|
||||
|
@ -12,6 +12,76 @@ var valueOperatorScenarios = []expressionScenario{
|
||||
"D0, P[], (!!int)::1\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: ``,
|
||||
expression: `0x9f`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!int)::0x9f\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: ``,
|
||||
expression: `0x1A`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!int)::0x1A\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: ``,
|
||||
expression: `0x1A + 2`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!int)::0x1C\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: ``,
|
||||
expression: `0x12 * 2`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!int)::0x24\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: ``,
|
||||
expression: `0xF - 1`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!int)::0xE\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: ``,
|
||||
expression: `12`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!int)::12\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: ``,
|
||||
expression: `12 + 2`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!int)::14\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: ``,
|
||||
expression: `12 * 2`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!int)::24\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: ``,
|
||||
expression: `12 - 2`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!int)::10\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: ``,
|
||||
expression: `0X12`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!int)::0X12\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: ``,
|
||||
expression: `-1`,
|
||||
|
Loading…
Reference in New Issue
Block a user