mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-28 18:21:52 +00:00
split out substr0 and substr1, and make substr==substr0 the default for backward compatibility with Miller <= 5
This commit is contained in:
parent
638f526eff
commit
59fa1f482f
5 changed files with 82 additions and 23 deletions
|
|
@ -62,9 +62,9 @@ mlr -n --ojson put
|
|||
"s93": ""
|
||||
}
|
||||
{
|
||||
"u35": "cde",
|
||||
"u37": "cdefg",
|
||||
"u17": "abcdefg",
|
||||
"u35": "def",
|
||||
"u37": "",
|
||||
"u17": "",
|
||||
"u07": "",
|
||||
"u39": "",
|
||||
"u53": (error),
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
|
||||
mlr put $y = substr($x, 0, 0)
|
||||
x=abcdefg,y=
|
||||
x=abcdefg,y=a
|
||||
|
||||
mlr put $y = substr($x, 0, 7)
|
||||
x=abcdefg,y=
|
||||
|
||||
mlr put $y = substr($x, 1, 7)
|
||||
x=abcdefg,y=abcdefg
|
||||
x=abcdefg,y=
|
||||
|
||||
mlr put $y = substr($x, 1, 6)
|
||||
x=abcdefg,y=abcdef
|
||||
x=abcdefg,y=bcdefg
|
||||
|
||||
mlr put $y = substr($x, 2, 5)
|
||||
x=abcdefg,y=bcde
|
||||
x=abcdefg,y=cdef
|
||||
|
||||
mlr put $y = substr($x, 2, 3)
|
||||
x=abcdefg,y=bc
|
||||
x=abcdefg,y=cd
|
||||
|
||||
mlr put $y = substr($x, 3, 3)
|
||||
x=abcdefg,y=c
|
||||
x=abcdefg,y=d
|
||||
|
||||
mlr put $y = substr($x, 4, 3)
|
||||
x=abcdefg,y=(error)
|
||||
|
||||
mlr put $y = substr($x, 2, 5)
|
||||
x=1234567,y=2345
|
||||
x=1234567,y=3456
|
||||
|
||||
|
|
|
|||
|
|
@ -428,27 +428,28 @@ regex-match operator: try '$y = ~$x'.`,
|
|||
ternaryFunc: types.MlrvalSub,
|
||||
},
|
||||
|
||||
{
|
||||
name: "substr",
|
||||
class: FUNC_CLASS_STRING,
|
||||
help: `substr(s,m,n) gives substring of s from 1-up position m to n xxxxxx fix me
|
||||
inclusive. Negative indices -len .. -1 alias to 1 .. len.`,
|
||||
ternaryFunc: types.MlrvalSubstr0Up,
|
||||
},
|
||||
{
|
||||
name: "substr0",
|
||||
class: FUNC_CLASS_STRING,
|
||||
help: `substr(s,m,n) gives substring of s from 1-up position m to n xxxxxx fix me
|
||||
inclusive. Negative indices -len .. -1 alias to 1 .. len.`,
|
||||
help: `substr0(s,m,n) gives substring of s from 0-up position m to n
|
||||
inclusive. Negative indices -len .. -1 alias to 0 .. len-1.`,
|
||||
ternaryFunc: types.MlrvalSubstr0Up,
|
||||
},
|
||||
{
|
||||
name: "substr1",
|
||||
class: FUNC_CLASS_STRING,
|
||||
help: `substr(s,m,n) gives substring of s from 1-up position m to n xxxxxx fix me
|
||||
help: `substr1(s,m,n) gives substring of s from 1-up position m to n
|
||||
inclusive. Negative indices -len .. -1 alias to 1 .. len.`,
|
||||
ternaryFunc: types.MlrvalSubstr1Up,
|
||||
},
|
||||
{
|
||||
name: "substr",
|
||||
class: FUNC_CLASS_STRING,
|
||||
help: `substr is an alias for substr0. See also substr1. Miller is generally 1-up
|
||||
with all array indices, but, this is a backward-compatibility issue with Miller 5 and below.
|
||||
Arrays are new in Miller 6; the substr function is older.`,
|
||||
ternaryFunc: types.MlrvalSubstr0Up,
|
||||
},
|
||||
|
||||
{
|
||||
name: "tolower",
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ func (this *ArraySliceAccessNode) Evaluate(
|
|||
return types.MLRVAL_ABSENT
|
||||
}
|
||||
if baseMlrval.IsString() {
|
||||
return types.MlrvalSubstr(baseMlrval, lowerIndexMlrval, upperIndexMlrval)
|
||||
return types.MlrvalSubstr1Up(baseMlrval, lowerIndexMlrval, upperIndexMlrval)
|
||||
}
|
||||
array := baseMlrval.GetArray()
|
||||
if array == nil {
|
||||
|
|
|
|||
|
|
@ -60,10 +60,10 @@ func MlrvalDot(input1, input2 *Mlrval) *Mlrval {
|
|||
}
|
||||
|
||||
// ================================================================
|
||||
// substr(s,m,n) gives substring of s from 1-up position m to n inclusive.
|
||||
// substr1(s,m,n) gives substring of s from 1-up position m to n inclusive.
|
||||
// Negative indices -len .. -1 alias to 0 .. len-1.
|
||||
|
||||
func MlrvalSubstr(input1, input2, input3 *Mlrval) *Mlrval {
|
||||
func MlrvalSubstr1Up(input1, input2, input3 *Mlrval) *Mlrval {
|
||||
if !input1.IsStringOrVoid() {
|
||||
if input1.IsNumeric() {
|
||||
// JIT-stringify, if not already (e.g. intval scanned from string
|
||||
|
|
@ -109,6 +109,64 @@ func MlrvalSubstr(input1, input2, input3 *Mlrval) *Mlrval {
|
|||
}
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// substr0(s,m,n) gives substring of s from 0-up position m to n inclusive.
|
||||
// Negative indices -len .. -1 alias to 0 .. len-1.
|
||||
|
||||
func MlrvalSubstr0Up(input1, input2, input3 *Mlrval) *Mlrval {
|
||||
if !input1.IsStringOrVoid() {
|
||||
if input1.IsNumeric() {
|
||||
// JIT-stringify, if not already (e.g. intval scanned from string
|
||||
// in input-file data)
|
||||
input1.setPrintRep()
|
||||
} else {
|
||||
return MLRVAL_ERROR
|
||||
}
|
||||
}
|
||||
// TODO: fix this with regard to UTF-8 and runes.
|
||||
strlen := int(len(input1.printrep))
|
||||
|
||||
// For array slices like s[1:2], s[:2], s[1:], when the lower index is
|
||||
// empty in the DSL expression it comes in here as a 1. But when the upper
|
||||
// index is empty in the DSL expression it comes in here as "".
|
||||
if !input2.IsInt() {
|
||||
return MLRVAL_ERROR
|
||||
}
|
||||
lowerMindex := input2.intval
|
||||
if lowerMindex >= 0 {
|
||||
// Make 1-up
|
||||
lowerMindex += 1
|
||||
}
|
||||
|
||||
upperMindex := strlen
|
||||
if input3.IsEmpty() {
|
||||
// Keep strlen
|
||||
} else if !input3.IsInt() {
|
||||
return MLRVAL_ERROR
|
||||
} else {
|
||||
upperMindex = input3.intval
|
||||
if upperMindex >= 0 {
|
||||
// Make 1-up
|
||||
upperMindex += 1
|
||||
}
|
||||
}
|
||||
|
||||
// Convert from negative-aliased 1-up to positive-only 0-up
|
||||
m, mok := UnaliasArrayLengthIndex(strlen, lowerMindex)
|
||||
n, nok := UnaliasArrayLengthIndex(strlen, upperMindex)
|
||||
|
||||
if !mok || !nok {
|
||||
return MlrvalPointerFromString("")
|
||||
} else if m > n {
|
||||
return MLRVAL_ERROR
|
||||
} else {
|
||||
// Note Golang slice indices are 0-up, and the 1st index is inclusive
|
||||
// while the 2nd is exclusive. For Miller, indices are 1-up and both
|
||||
// are inclusive.
|
||||
return MlrvalPointerFromString(input1.printrep[m : n+1])
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
func MlrvalTruncate(input1, input2 *Mlrval) *Mlrval {
|
||||
if input1.IsErrorOrAbsent() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue