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{}
|
expectedTokens []interface{}
|
||||||
expectedPostFix []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",
|
".a\n",
|
||||||
append(make([]interface{}, 0), "a"),
|
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 {
|
func floatValue() lex.Action {
|
||||||
return func(s *lex.Scanner, m *machines.Match) (interface{}, error) {
|
return func(s *lex.Scanner, m *machines.Match) (interface{}, error) {
|
||||||
var numberString = string(m.Bytes)
|
var numberString = string(m.Bytes)
|
||||||
@ -328,6 +342,7 @@ func initLexer() (*lex.Lexer, error) {
|
|||||||
|
|
||||||
lexer.Add([]byte(`\|`), opToken(pipeOpType))
|
lexer.Add([]byte(`\|`), opToken(pipeOpType))
|
||||||
|
|
||||||
|
lexer.Add([]byte(`0[xX][0-9A-Fa-f]+`), hexValue())
|
||||||
lexer.Add([]byte(`-?\d+(\.\d+)`), floatValue())
|
lexer.Add([]byte(`-?\d+(\.\d+)`), floatValue())
|
||||||
lexer.Add([]byte(`-?[1-9](\.\d+)?[Ee][-+]?\d+`), floatValue())
|
lexer.Add([]byte(`-?[1-9](\.\d+)?[Ee][-+]?\d+`), floatValue())
|
||||||
lexer.Add([]byte(`-?\d+`), numberValue())
|
lexer.Add([]byte(`-?\d+`), numberValue())
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"container/list"
|
"container/list"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
logging "gopkg.in/op/go-logging.v1"
|
logging "gopkg.in/op/go-logging.v1"
|
||||||
yaml "gopkg.in/yaml.v3"
|
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
|
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 {
|
func createScalarNode(value interface{}, stringValue string) *yaml.Node {
|
||||||
var node = &yaml.Node{Kind: yaml.ScalarNode}
|
var node = &yaml.Node{Kind: yaml.ScalarNode}
|
||||||
node.Value = stringValue
|
node.Value = stringValue
|
||||||
|
@ -76,17 +76,17 @@ func addScalars(target *CandidateNode, lhs *yaml.Node, rhs *yaml.Node) (*Candida
|
|||||||
target.Node.Tag = "!!str"
|
target.Node.Tag = "!!str"
|
||||||
target.Node.Value = lhs.Value + rhs.Value
|
target.Node.Value = lhs.Value + rhs.Value
|
||||||
} else if lhs.Tag == "!!int" && rhs.Tag == "!!int" {
|
} else if lhs.Tag == "!!int" && rhs.Tag == "!!int" {
|
||||||
lhsNum, err := strconv.Atoi(lhs.Value)
|
format, lhsNum, err := parseInt(lhs.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rhsNum, err := strconv.Atoi(rhs.Value)
|
_, rhsNum, err := parseInt(rhs.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sum := lhsNum + rhsNum
|
sum := lhsNum + rhsNum
|
||||||
target.Node.Tag = "!!int"
|
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") {
|
} else if (lhs.Tag == "!!int" || lhs.Tag == "!!float") && (rhs.Tag == "!!int" || rhs.Tag == "!!float") {
|
||||||
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
|
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -91,15 +91,15 @@ func multiplyIntegers(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, e
|
|||||||
target.Node.Style = lhs.Node.Style
|
target.Node.Style = lhs.Node.Style
|
||||||
target.Node.Tag = "!!int"
|
target.Node.Tag = "!!int"
|
||||||
|
|
||||||
lhsNum, err := strconv.Atoi(lhs.Node.Value)
|
format, lhsNum, err := parseInt(lhs.Node.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rhsNum, err := strconv.Atoi(rhs.Node.Value)
|
_, rhsNum, err := parseInt(rhs.Node.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
target.Node.Value = fmt.Sprintf("%v", lhsNum*rhsNum)
|
target.Node.Value = fmt.Sprintf(format, lhsNum*rhsNum)
|
||||||
return target, nil
|
return target, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,17 +62,17 @@ func subtractScalars(target *CandidateNode, lhs *yaml.Node, rhs *yaml.Node) (*Ca
|
|||||||
if lhs.Tag == "!!str" {
|
if lhs.Tag == "!!str" {
|
||||||
return nil, fmt.Errorf("strings cannot be subtracted")
|
return nil, fmt.Errorf("strings cannot be subtracted")
|
||||||
} else if lhs.Tag == "!!int" && rhs.Tag == "!!int" {
|
} else if lhs.Tag == "!!int" && rhs.Tag == "!!int" {
|
||||||
lhsNum, err := strconv.Atoi(lhs.Value)
|
format, lhsNum, err := parseInt(lhs.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rhsNum, err := strconv.Atoi(rhs.Value)
|
_, rhsNum, err := parseInt(rhs.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := lhsNum - rhsNum
|
result := lhsNum - rhsNum
|
||||||
target.Node.Tag = "!!int"
|
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") {
|
} else if (lhs.Tag == "!!int" || lhs.Tag == "!!float") && (rhs.Tag == "!!int" || rhs.Tag == "!!float") {
|
||||||
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
|
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -12,6 +12,76 @@ var valueOperatorScenarios = []expressionScenario{
|
|||||||
"D0, P[], (!!int)::1\n",
|
"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: ``,
|
document: ``,
|
||||||
expression: `-1`,
|
expression: `-1`,
|
||||||
|
Loading…
Reference in New Issue
Block a user