mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-17 16:38:54 +00:00
Strip dead code from pkg/ (#2121)
Found with golang.org/x/tools/cmd/deadcode (rooted at cmd/mlr + tests) and staticcheck U1000; each finding verified by hand before deletion. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
6d7c3000aa
commit
b817040747
15 changed files with 32 additions and 346 deletions
|
|
@ -545,70 +545,6 @@ func BIF_dot_divide(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
|
|||
return dotdivide_dispositions[input1.Type()][input2.Type()](input1, input2)
|
||||
}
|
||||
|
||||
// 64-bit integer division: DSL operator './/'. See also
|
||||
// https://miller.readthedocs.io/en/latest/reference-main-arithmetic
|
||||
|
||||
func dotidivide_i_ii(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
|
||||
a := input1.AcquireIntValue()
|
||||
b := input2.AcquireIntValue()
|
||||
|
||||
if b == 0 {
|
||||
// Compute inf/nan as with floats rather than fatal runtime FPE on integer divide by zero
|
||||
return mlrval.FromFloat(float64(a) / float64(b))
|
||||
}
|
||||
|
||||
// Pythonic division, not C division.
|
||||
q := a / b
|
||||
r := a % b
|
||||
if a < 0 {
|
||||
if b > 0 {
|
||||
if r != 0 {
|
||||
q--
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if b < 0 {
|
||||
if r != 0 {
|
||||
q--
|
||||
}
|
||||
}
|
||||
}
|
||||
return mlrval.FromInt(q)
|
||||
}
|
||||
|
||||
func dotidivide_f_if(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
|
||||
return mlrval.FromFloat(math.Floor(float64(input1.AcquireIntValue()) / input2.AcquireFloatValue()))
|
||||
}
|
||||
func dotidivide_f_fi(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
|
||||
return mlrval.FromFloat(math.Floor(input1.AcquireFloatValue() / float64(input2.AcquireIntValue())))
|
||||
}
|
||||
func dotidivide_f_ff(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
|
||||
return mlrval.FromFloat(math.Floor(input1.AcquireFloatValue() / input2.AcquireFloatValue()))
|
||||
}
|
||||
|
||||
func didte(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
|
||||
return mlrval.FromTypeErrorBinary(".//", input1, input2)
|
||||
}
|
||||
|
||||
var dotidivide_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
|
||||
// . INT FLOAT BOOL VOID STRING ARRAY MAP FUNC ERROR NULL ABSENT
|
||||
/*INT */ {dotidivide_i_ii, dotidivide_f_if, didte, _void, didte, _absn, _absn, didte, didte, didte, _1___},
|
||||
/*FLOAT */ {dotidivide_f_fi, dotidivide_f_ff, didte, _void, didte, _absn, _absn, didte, didte, didte, _1___},
|
||||
/*BOOL */ {didte, didte, didte, didte, didte, _absn, _absn, didte, didte, didte, didte},
|
||||
/*VOID */ {_void, _void, didte, _void, didte, _absn, _absn, didte, didte, didte, _absn},
|
||||
/*STRING */ {didte, didte, didte, didte, didte, _absn, _absn, didte, didte, didte, didte},
|
||||
/*ARRAY */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, didte, _absn, _absn, _absn},
|
||||
/*MAP */ {_absn, _absn, _absn, _absn, _absn, _absn, _absn, didte, _absn, _absn, _absn},
|
||||
/*FUNC */ {didte, didte, didte, didte, didte, didte, didte, didte, didte, didte, didte},
|
||||
/*ERROR */ {didte, didte, didte, didte, didte, _absn, _absn, didte, didte, didte, didte},
|
||||
/*NULL */ {didte, didte, didte, didte, didte, _absn, _absn, didte, didte, didte, _absn},
|
||||
/*ABSENT */ {_2___, _2___, didte, _absn, didte, _absn, _absn, didte, didte, didte, _absn},
|
||||
}
|
||||
|
||||
func BIF_dot_int_divide(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
|
||||
return dotidivide_dispositions[input1.Type()][input2.Type()](input1, input2)
|
||||
}
|
||||
|
||||
// Modulus
|
||||
|
||||
func modulus_i_ii(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ func TestBIF_plus_binary_overflow(t *testing.T) {
|
|||
//func BIF_dot_minus(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval
|
||||
//func BIF_dot_times(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval
|
||||
//func BIF_dot_divide(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval
|
||||
//func BIF_dot_int_divide(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval
|
||||
//func BIF_modulus(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval
|
||||
//func BIF_mod_add(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval
|
||||
//func BIF_mod_sub(input1, input2, input3 *mlrval.Mlrval) *mlrval.Mlrval
|
||||
|
|
|
|||
|
|
@ -99,13 +99,6 @@ func _zero1(input1 *mlrval.Mlrval) *mlrval.Mlrval {
|
|||
return mlrval.FromInt(0)
|
||||
}
|
||||
|
||||
// Return one (unary)
|
||||
//
|
||||
//lint:ignore U1000 util function might be used later
|
||||
func __one1(input1 *mlrval.Mlrval) *mlrval.Mlrval {
|
||||
return mlrval.FromInt(1)
|
||||
}
|
||||
|
||||
// Return null (unary)
|
||||
func _null1(input1 *mlrval.Mlrval) *mlrval.Mlrval {
|
||||
return mlrval.NULL
|
||||
|
|
|
|||
|
|
@ -58,20 +58,6 @@ func SetFailColor(name string) bool {
|
|||
}
|
||||
return ok
|
||||
}
|
||||
func SetREPLPS1Color(name string) bool {
|
||||
escape, ok := lumin.MakeANSIEscapesFromName(name)
|
||||
if ok {
|
||||
replPS1ColorString = escape
|
||||
}
|
||||
return ok
|
||||
}
|
||||
func SetREPLPS2Color(name string) bool {
|
||||
escape, ok := lumin.MakeANSIEscapesFromName(name)
|
||||
if ok {
|
||||
replPS2ColorString = escape
|
||||
}
|
||||
return ok
|
||||
}
|
||||
func SetHelpColor(name string) bool {
|
||||
escape, ok := lumin.MakeANSIEscapesFromName(name)
|
||||
if ok {
|
||||
|
|
|
|||
|
|
@ -1,99 +1,12 @@
|
|||
// Package dkvpx (see also dkvpx_reader.go) writes DKVPX records: comma-delimited
|
||||
// Package dkvpx (see also dkvpx_reader.go) handles DKVPX records: comma-delimited
|
||||
// key=value pairs with selective quoting. Keys and values are double-quoted only
|
||||
// when they contain comma, equals, newline, or double-quote.
|
||||
package dkvpx
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/johnkerl/miller/v6/pkg/lib"
|
||||
)
|
||||
|
||||
// A Writer writes DKVPX records. It mirrors the structure of csv.Writer.
|
||||
type Writer struct {
|
||||
Comma rune // Pair delimiter (set to ',' by NewWriter)
|
||||
UseCRLF bool // True to use \r\n as the line terminator
|
||||
w *bufio.Writer
|
||||
}
|
||||
|
||||
// NewWriter returns a new Writer that writes to w.
|
||||
func NewWriter(w io.Writer) *Writer {
|
||||
return &Writer{
|
||||
Comma: ',',
|
||||
w: bufio.NewWriter(w),
|
||||
}
|
||||
}
|
||||
|
||||
// Write writes a single DKVPX record. Keys and values are quoted only when
|
||||
// they contain comma, equals, newline, or double-quote.
|
||||
func (w *Writer) Write(record *lib.OrderedMap[string]) error {
|
||||
if record == nil || record.IsEmpty() {
|
||||
return w.writeLineEnd()
|
||||
}
|
||||
|
||||
first := true
|
||||
for pe := record.Head; pe != nil; pe = pe.Next {
|
||||
if !first {
|
||||
if _, err := w.w.WriteRune(w.Comma); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
first = false
|
||||
|
||||
if err := w.writeQuotedIfNeeded(pe.Key); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.w.WriteByte('='); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.writeQuotedIfNeeded(pe.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return w.writeLineEnd()
|
||||
}
|
||||
|
||||
// writeQuotedIfNeeded writes the string, adding surrounding quotes and escaping
|
||||
// internal quotes only when the string contains comma, equals, newline, or quote.
|
||||
func (w *Writer) writeQuotedIfNeeded(s string) error {
|
||||
if !needsQuoting(s) {
|
||||
_, err := w.w.WriteString(s)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := w.w.WriteByte('"'); err != nil {
|
||||
return err
|
||||
}
|
||||
// Escape " as ""
|
||||
for len(s) > 0 {
|
||||
i := strings.IndexAny(s, "\"\r\n")
|
||||
if i < 0 {
|
||||
i = len(s)
|
||||
}
|
||||
if _, err := w.w.WriteString(s[:i]); err != nil {
|
||||
return err
|
||||
}
|
||||
s = s[i:]
|
||||
if len(s) > 0 {
|
||||
switch s[0] {
|
||||
case '"':
|
||||
if _, err := w.w.WriteString(`""`); err != nil {
|
||||
return err
|
||||
}
|
||||
case '\r', '\n':
|
||||
if err := w.w.WriteByte(s[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
s = s[1:]
|
||||
}
|
||||
}
|
||||
return w.w.WriteByte('"')
|
||||
}
|
||||
|
||||
// needsQuoting reports whether the string must be quoted (contains comma,
|
||||
// equals, newline, or double-quote).
|
||||
func needsQuoting(s string) bool {
|
||||
|
|
@ -120,32 +33,3 @@ func FormatField(s string) string {
|
|||
b.WriteByte('"')
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func (w *Writer) writeLineEnd() error {
|
||||
if w.UseCRLF {
|
||||
_, err := w.w.WriteString("\r\n")
|
||||
return err
|
||||
}
|
||||
return w.w.WriteByte('\n')
|
||||
}
|
||||
|
||||
// Flush writes any buffered data to the underlying io.Writer.
|
||||
func (w *Writer) Flush() {
|
||||
w.w.Flush()
|
||||
}
|
||||
|
||||
// Error reports any error that has occurred during a previous Write or Flush.
|
||||
func (w *Writer) Error() error {
|
||||
_, err := w.w.Write(nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// WriteAll writes multiple DKVPX records and then calls Flush.
|
||||
func (w *Writer) WriteAll(records []*lib.OrderedMap[string]) error {
|
||||
for _, record := range records {
|
||||
if err := w.Write(record); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return w.w.Flush()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,68 +4,45 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/johnkerl/miller/v6/pkg/lib"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestWrite_Basic(t *testing.T) {
|
||||
var buf strings.Builder
|
||||
wr := NewWriter(&buf)
|
||||
rec := lib.NewOrderedMap[string]()
|
||||
rec.Put("x", "1")
|
||||
rec.Put("y", "2")
|
||||
rec.Put("z", "3")
|
||||
err := wr.Write(rec)
|
||||
assert.NoError(t, err)
|
||||
wr.Flush()
|
||||
assert.NoError(t, wr.Error())
|
||||
assert.Equal(t, "x=1,y=2,z=3\n", buf.String())
|
||||
func TestFormatField_Basic(t *testing.T) {
|
||||
assert.Equal(t, "x", FormatField("x"))
|
||||
assert.Equal(t, "1", FormatField("1"))
|
||||
assert.Equal(t, "abc def", FormatField("abc def"))
|
||||
}
|
||||
|
||||
func TestWrite_QuotesWhenNeeded(t *testing.T) {
|
||||
var buf strings.Builder
|
||||
wr := NewWriter(&buf)
|
||||
rec := lib.NewOrderedMap[string]()
|
||||
rec.Put("x,y", "a,b,c")
|
||||
rec.Put("z", "3")
|
||||
err := wr.Write(rec)
|
||||
assert.NoError(t, err)
|
||||
wr.Flush()
|
||||
assert.Equal(t, `"x,y"="a,b,c",z=3`+"\n", buf.String())
|
||||
func TestFormatField_QuotesWhenNeeded(t *testing.T) {
|
||||
assert.Equal(t, `"x,y"`, FormatField("x,y"))
|
||||
assert.Equal(t, `"a,b,c"`, FormatField("a,b,c"))
|
||||
}
|
||||
|
||||
func TestWrite_ValueWithEquals(t *testing.T) {
|
||||
var buf strings.Builder
|
||||
wr := NewWriter(&buf)
|
||||
rec := lib.NewOrderedMap[string]()
|
||||
rec.Put("a", "b=c")
|
||||
err := wr.Write(rec)
|
||||
assert.NoError(t, err)
|
||||
wr.Flush()
|
||||
assert.Equal(t, `a="b=c"`+"\n", buf.String())
|
||||
func TestFormatField_ValueWithEquals(t *testing.T) {
|
||||
assert.Equal(t, `"b=c"`, FormatField("b=c"))
|
||||
}
|
||||
|
||||
func TestWrite_EscapedQuotes(t *testing.T) {
|
||||
var buf strings.Builder
|
||||
wr := NewWriter(&buf)
|
||||
rec := lib.NewOrderedMap[string]()
|
||||
rec.Put("x", `the "word"`)
|
||||
err := wr.Write(rec)
|
||||
assert.NoError(t, err)
|
||||
wr.Flush()
|
||||
assert.Equal(t, `x="the ""word"""`+"\n", buf.String())
|
||||
func TestFormatField_EscapedQuotes(t *testing.T) {
|
||||
assert.Equal(t, `"the ""word"""`, FormatField(`the "word"`))
|
||||
}
|
||||
|
||||
func TestWrite_RoundTrip(t *testing.T) {
|
||||
func TestFormatField_RoundTrip(t *testing.T) {
|
||||
input := `"x,y"="a,b,c",z=3` + "\n"
|
||||
rdr := NewReader(strings.NewReader(input))
|
||||
rec, err := rdr.Read()
|
||||
assert.NoError(t, err)
|
||||
|
||||
var buf strings.Builder
|
||||
wr := NewWriter(&buf)
|
||||
err = wr.Write(rec)
|
||||
assert.NoError(t, err)
|
||||
wr.Flush()
|
||||
assert.Equal(t, input, buf.String())
|
||||
var sb strings.Builder
|
||||
first := true
|
||||
for pe := rec.Head; pe != nil; pe = pe.Next {
|
||||
if !first {
|
||||
sb.WriteByte(',')
|
||||
}
|
||||
first = false
|
||||
sb.WriteString(FormatField(pe.Key))
|
||||
sb.WriteByte('=')
|
||||
sb.WriteString(FormatField(pe.Value))
|
||||
}
|
||||
sb.WriteByte('\n')
|
||||
assert.Equal(t, input, sb.String())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,15 +98,3 @@ func InternalCodingErrorPanic(message string) {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
// WhereAreWe shows a stack trace from the current callsite.
|
||||
func WhereAreWe() {
|
||||
// Start at 1, not 0, since this function itself is not of interest.
|
||||
for i := 1; i < 20; i++ {
|
||||
_, fileName, fileLine, ok := runtime.Caller(i)
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
fmt.Printf(" %s %d\n", fileName, fileLine)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,15 +52,6 @@ func StringListToSet(stringList []string) map[string]bool {
|
|||
return stringSet
|
||||
}
|
||||
|
||||
// ReverseStringList reverses strs in place.
|
||||
//
|
||||
// Deprecated: use slices.Reverse instead.
|
||||
//
|
||||
//go:fix inline
|
||||
func ReverseStringList(strs []string) {
|
||||
slices.Reverse(strs)
|
||||
}
|
||||
|
||||
// SortedStrings returns a new slice containing the strings in strs in ascending order.
|
||||
func SortedStrings(strs []string) []string {
|
||||
result := make([]string, len(strs))
|
||||
|
|
@ -190,15 +181,6 @@ func WriteTempFileOrDie(contents string) string {
|
|||
return handle.Name()
|
||||
}
|
||||
|
||||
// CopyStringArray returns a copy of input.
|
||||
//
|
||||
// Deprecated: use slices.Clone instead.
|
||||
//
|
||||
//go:fix inline
|
||||
func CopyStringArray(input []string) []string {
|
||||
return slices.Clone(input)
|
||||
}
|
||||
|
||||
func StripEmpties(input []string) []string {
|
||||
output := make([]string, 0, len(input))
|
||||
for _, e := range input {
|
||||
|
|
|
|||
|
|
@ -27,9 +27,6 @@ type CmpFuncInt func(input1, input2 *Mlrval) int // -1, 0, 1 for <=>
|
|||
func Equals(input1, input2 *Mlrval) bool {
|
||||
return cmp_dispositions[input1.Type()][input2.Type()](input1, input2) == 0
|
||||
}
|
||||
func NotEquals(input1, input2 *Mlrval) bool {
|
||||
return cmp_dispositions[input1.Type()][input2.Type()](input1, input2) != 0
|
||||
}
|
||||
func GreaterThan(input1, input2 *Mlrval) bool {
|
||||
return cmp_dispositions[input1.Type()][input2.Type()](input1, input2) > 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,20 +51,6 @@ func TestEqual(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNotEquals(t *testing.T) {
|
||||
for i := range orderedMlrvals {
|
||||
mvi := orderedMlrvals[i]
|
||||
for j := range orderedMlrvals {
|
||||
mvj := orderedMlrvals[j]
|
||||
assert.Equal(t, i != j, NotEquals(mvi, mvj), fmt.Sprintf(
|
||||
"slots i=%d type=%s value=%s, j=%d type=%s value=%s",
|
||||
i, mvi.GetTypeName(), mvi.String(),
|
||||
j, mvj.GetTypeName(), mvj.String(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLessThan(t *testing.T) {
|
||||
for i := range orderedMlrvals {
|
||||
mvi := orderedMlrvals[i]
|
||||
|
|
|
|||
|
|
@ -24,11 +24,6 @@ type tInferrer func(mv *Mlrval) *Mlrval
|
|||
|
||||
var packageLevelInferrer tInferrer = inferNormally
|
||||
|
||||
// SetInferNormally is the default behavior.
|
||||
func SetInferNormally() {
|
||||
packageLevelInferrer = inferNormally
|
||||
}
|
||||
|
||||
// SetInferrerOctalAsInt is for mlr -O.
|
||||
func SetInferrerOctalAsInt() {
|
||||
packageLevelInferrer = inferWithOctalAsInt
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package scan
|
||||
|
||||
import ()
|
||||
|
||||
// TODO: comment re context
|
||||
|
||||
// o grammar for numbers & case-through
|
||||
|
|
@ -53,11 +51,6 @@ func FindScanType(sinput string) ScanType {
|
|||
return scanTypeString
|
||||
}
|
||||
|
||||
// Convenience function for unit test
|
||||
func findScanTypeName(sinput string) string {
|
||||
return TypeNames[FindScanType(sinput)]
|
||||
}
|
||||
|
||||
func findScanTypePositiveNumberOrString(input []byte) ScanType {
|
||||
if len(input) == 0 {
|
||||
return scanTypeString
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// Convenience function for unit test
|
||||
func findScanTypeName(sinput string) string {
|
||||
return TypeNames[FindScanType(sinput)]
|
||||
}
|
||||
|
||||
func TestFindScanTypeNameStrings(t *testing.T) {
|
||||
assert.Equal(t, typeNameString, findScanTypeName(""))
|
||||
assert.Equal(t, typeNameString, findScanTypeName("-"))
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@ import (
|
|||
)
|
||||
|
||||
type Script struct {
|
||||
exeName string
|
||||
name string
|
||||
name string
|
||||
|
||||
doWarnings bool
|
||||
cstRootNode *cst.RootNode
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
package types
|
||||
|
||||
// List is a thin wrapper around a slice which functions as a list/queue. The Items attribute is
|
||||
// exposed as public since I want iteration (at many, many callsites) to be easy.
|
||||
type List[T any] struct {
|
||||
Items []T
|
||||
}
|
||||
|
||||
func NewList[T any](capacity int) *List[T] {
|
||||
return &List[T]{
|
||||
make([]T, 0, capacity),
|
||||
}
|
||||
}
|
||||
|
||||
// Front will panic if the list is empty
|
||||
func (ell *List[T]) Front() T {
|
||||
return ell.Items[0]
|
||||
}
|
||||
|
||||
func (ell *List[T]) Len() int {
|
||||
return len(ell.Items)
|
||||
}
|
||||
|
||||
func (ell *List[T]) PushBack(e T) {
|
||||
ell.Items = append(ell.Items, e)
|
||||
}
|
||||
|
||||
func (ell *List[T]) PushBackMultiple(mell []T) {
|
||||
ell.Items = append(ell.Items, mell...)
|
||||
}
|
||||
|
||||
func (ell *List[T]) Clear() {
|
||||
ell.Items = ell.Items[0:0:cap(ell.Items)]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue