sonar

Scan files at memory bandwidth speed.
Log | Files | Refs

commit 03b698ff54d3b59dad8785d9d6076337f35a81c8
parent 05918e2de6bea36e9679c983aa138feb6bf1e831
Author: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Date:   Sun, 20 Sep 2026 07:44:43 -0300

main: refuse an option it does not understand

`--walk-workers=N` was accepted but never listed, and everything else a dash
could start fell through to the target, so `--lives` was scanned for as a volume
and reported as a missing one. A value that did not parse was dropped in silence,
which is worse in a tool whose flags exist to be swept: a mistyped width reads as
a result for the default.

Both now stop the run and say which argument was wrong.

Diffstat:
Mmain.odin | 40+++++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 13 deletions(-)

diff --git a/main.odin b/main.odin @@ -53,7 +53,9 @@ run :: proc() -> int { for arg in os.args[1:] { switch arg { case "-h", "--help", "/?": - fmt.println("usage: sonar [drive] [--live] [--buffered] [--no-skip] [--min-skip=N] [--workers=N] [--chunk=N]") + fmt.println( + "usage: sonar [drive] [--live] [--buffered] [--no-skip] [--min-skip=N] [--workers=N] [--walk-workers=N] [--chunk=N]", + ) return 0 case "--live": live = true @@ -64,26 +66,28 @@ run :: proc() -> int { case: // --min-skip=<bytes> tunes how long a run of dead records must be before // breaking the sequential read to jump over it pays for itself. + ok := true switch { case strings.has_prefix(arg, "--min-skip="): - if n, parsed := strconv.parse_int(arg[len("--min-skip="):]); parsed { - opts.min_skip = n - } + opts.min_skip, ok = number(arg) case strings.has_prefix(arg, "--workers="): - if n, parsed := strconv.parse_int(arg[len("--workers="):]); parsed { - opts.workers = n - } + opts.workers, ok = number(arg) case strings.has_prefix(arg, "--walk-workers="): - if n, parsed := strconv.parse_int(arg[len("--walk-workers="):]); parsed { - wcfg.workers = n - } + wcfg.workers, ok = number(arg) case strings.has_prefix(arg, "--chunk="): - if n, parsed := strconv.parse_int(arg[len("--chunk="):]); parsed { - opts.chunk_size = n - } + opts.chunk_size, ok = number(arg) + case strings.has_prefix(arg, "-"): + // Anything else starting with a dash is a mistyped option. Taking it + // for the target would report that the volume cannot be found. + fmt.eprintfln("error: unknown option %s", arg) + return 1 case: target = arg } + if !ok { + fmt.eprintfln("error: %s needs a number", arg) + return 1 + } } } @@ -189,6 +193,16 @@ run :: proc() -> int { return 0 } +// The value of a `--name=value` option. +@(private = "file") +number :: proc(arg: string) -> (int, bool) { + i := strings.index_byte(arg, '=') + if i < 0 { + return 0, false + } + return strconv.parse_int(arg[i + 1:]) +} + /* Credit every node's bytes to each of its ancestors.