Compare commits
No commits in common. "ca0376a181ef9e0616baef2f232253098c15df26" and "683d71ff8b79d3821002df9850ab40cb5ca686f7" have entirely different histories.
ca0376a181
...
683d71ff8b
5 changed files with 36 additions and 142 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,4 +5,3 @@ deps.zig
|
||||||
/test.in
|
/test.in
|
||||||
/test.out
|
/test.out
|
||||||
/test.expect
|
/test.expect
|
||||||
/dist
|
|
||||||
|
|
15
Makefile
15
Makefile
|
@ -1,15 +0,0 @@
|
||||||
dist: inttest
|
|
||||||
mkdir dist
|
|
||||||
cp zig-out/bin/skip dist/
|
|
||||||
|
|
||||||
inttest: zig-out/bin/skip
|
|
||||||
./test.sh
|
|
||||||
|
|
||||||
zig-out/bin/skip: unittest
|
|
||||||
zig build
|
|
||||||
|
|
||||||
unittest: zigmod src/main.zig
|
|
||||||
zig build test
|
|
||||||
|
|
||||||
zigmod: zig.mod
|
|
||||||
zigmod ci
|
|
47
README.md
47
README.md
|
@ -42,8 +42,6 @@ line 4
|
||||||
|
|
||||||
### Skip until a number of matching lines
|
### Skip until a number of matching lines
|
||||||
|
|
||||||
The whole line must match.
|
|
||||||
|
|
||||||
This example reads the named file.
|
This example reads the named file.
|
||||||
|
|
||||||
File: `input.txt`
|
File: `input.txt`
|
||||||
|
@ -69,9 +67,7 @@ gamma
|
||||||
alpha
|
alpha
|
||||||
```
|
```
|
||||||
|
|
||||||
### Skip lines until a number of tokens are seen
|
### Skip lines until a number of tokens as seen
|
||||||
|
|
||||||
Looks for a string within a line, counting each occurance.
|
|
||||||
|
|
||||||
This example reads the file from stdin.
|
This example reads the file from stdin.
|
||||||
|
|
||||||
|
@ -103,44 +99,3 @@ commodo consequat.
|
||||||
|
|
||||||
It matches the first `dolor` on line 1,
|
It matches the first `dolor` on line 1,
|
||||||
and the second on line 4 as part of the word `dolore`.
|
and the second on line 4 as part of the word `dolore`.
|
||||||
|
|
||||||
### Skip lines until a lines with tokens are seen
|
|
||||||
|
|
||||||
Looks for a string within a line, only counting each matching line once.
|
|
||||||
|
|
||||||
This example reads the file from stdin.
|
|
||||||
|
|
||||||
File: `input.txt`
|
|
||||||
|
|
||||||
```text
|
|
||||||
Lorem ipsum dolor sit amet,
|
|
||||||
consectetur adipiscing elit,
|
|
||||||
sed do eiusmod tempor incididunt
|
|
||||||
ut labore et dolore magna aliqua.
|
|
||||||
Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco
|
|
||||||
laboris nisi ut aliquip ex ea
|
|
||||||
commodo consequat.
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cat input.txt | skip 4 --token m --ignore-extras
|
|
||||||
```
|
|
||||||
|
|
||||||
Will output:
|
|
||||||
|
|
||||||
```text
|
|
||||||
quis nostrud exercitation ullamco
|
|
||||||
laboris nisi ut aliquip ex ea
|
|
||||||
commodo consequat.
|
|
||||||
```
|
|
||||||
|
|
||||||
Without `--ignore-extras`, it would have found the fourth `m` on line 3, and displayed:
|
|
||||||
|
|
||||||
```text
|
|
||||||
ut labore et dolore magna aliqua.
|
|
||||||
Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco
|
|
||||||
laboris nisi ut aliquip ex ea
|
|
||||||
commodo consequat.
|
|
||||||
```
|
|
||||||
|
|
27
src/main.zig
27
src/main.zig
|
@ -46,7 +46,6 @@ const Config = struct {
|
||||||
file: ?fs.File,
|
file: ?fs.File,
|
||||||
line: ?[]const u8 = null,
|
line: ?[]const u8 = null,
|
||||||
token: ?[]const u8 = null,
|
token: ?[]const u8 = null,
|
||||||
ignoreExtras: bool,
|
|
||||||
|
|
||||||
pub fn deinit(self: @This()) void {
|
pub fn deinit(self: @This()) void {
|
||||||
if (self.file) |f| {
|
if (self.file) |f| {
|
||||||
|
@ -61,14 +60,13 @@ fn parseArgs(allocator: mem.Allocator) !Config {
|
||||||
clap.parseParam("[<FILE>] The file to read or stdin if not given") catch unreachable,
|
clap.parseParam("[<FILE>] The file to read or stdin if not given") catch unreachable,
|
||||||
clap.parseParam("-l, --line <STR> Skip until N lines matching this") catch unreachable,
|
clap.parseParam("-l, --line <STR> Skip until N lines matching this") catch unreachable,
|
||||||
clap.parseParam("-t, --token <STR> Skip lines until N tokens found") catch unreachable,
|
clap.parseParam("-t, --token <STR> Skip lines until N tokens found") catch unreachable,
|
||||||
clap.parseParam("-i, --ignore-extras Only count the first token on each line") catch unreachable,
|
|
||||||
clap.parseParam("-h, --help Display this help and exit") catch unreachable,
|
clap.parseParam("-h, --help Display this help and exit") catch unreachable,
|
||||||
clap.parseParam("-v, --version Display the version") catch unreachable,
|
clap.parseParam("-v, --version Display the version") catch unreachable,
|
||||||
};
|
};
|
||||||
var diag = clap.Diagnostic{};
|
var diag = clap.Diagnostic{};
|
||||||
var args = clap.parse(clap.Help, ¶ms, .{ .diagnostic = &diag }) catch |err| {
|
var args = clap.parse(clap.Help, ¶ms, .{ .diagnostic = &diag }) catch |err| {
|
||||||
diag.report(io.getStdErr().writer(), err) catch {};
|
diag.report(io.getStdErr().writer(), err) catch {};
|
||||||
return error.BadArgs;
|
return error.EarlyExit;
|
||||||
};
|
};
|
||||||
defer args.deinit();
|
defer args.deinit();
|
||||||
|
|
||||||
|
@ -99,15 +97,6 @@ fn parseArgs(allocator: mem.Allocator) !Config {
|
||||||
if (args.option("--token")) |match| {
|
if (args.option("--token")) |match| {
|
||||||
token = try allocator.dupe(u8, match);
|
token = try allocator.dupe(u8, match);
|
||||||
}
|
}
|
||||||
var ignoreExtras: bool = false;
|
|
||||||
if (args.flag("--ignore-extras")) {
|
|
||||||
if (token) |_| {
|
|
||||||
ignoreExtras = true;
|
|
||||||
} else {
|
|
||||||
try io.getStdErr().writer().print("Error: --ignore-extras requires --token\n", .{});
|
|
||||||
return error.BadArgs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var n: u32 = 0;
|
var n: u32 = 0;
|
||||||
var file: ?fs.File = null;
|
var file: ?fs.File = null;
|
||||||
|
@ -133,7 +122,6 @@ fn parseArgs(allocator: mem.Allocator) !Config {
|
||||||
.file = file,
|
.file = file,
|
||||||
.line = line,
|
.line = line,
|
||||||
.token = token,
|
.token = token,
|
||||||
.ignoreExtras = ignoreExtras,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,23 +132,22 @@ fn dumpInput(config: Config, in: fs.File, out: fs.File, allocator: mem.Allocator
|
||||||
var c: usize = 0;
|
var c: usize = 0;
|
||||||
while (c < config.lines) {
|
while (c < config.lines) {
|
||||||
const line = it.next();
|
const line = it.next();
|
||||||
if (line) |memory| {
|
|
||||||
if (config.line) |match| {
|
if (config.line) |match| {
|
||||||
|
if (line) |memory| {
|
||||||
if (mem.eql(u8, match, memory)) {
|
if (mem.eql(u8, match, memory)) {
|
||||||
c += 1;
|
c += 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (config.token) |token| {
|
if (config.token) |token| {
|
||||||
const occurances = mem.count(u8, memory, token);
|
if (line) |memory| {
|
||||||
if (config.ignoreExtras and occurances > 0) {
|
c += mem.count(u8, memory, token);
|
||||||
c += 1;
|
|
||||||
} else {
|
|
||||||
c += occurances;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c += 1;
|
c += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (line) |memory| {
|
||||||
allocator.free(memory);
|
allocator.free(memory);
|
||||||
} else return;
|
} else return;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +166,6 @@ test "dumpInput skip 1 line" {
|
||||||
const config = Config{
|
const config = Config{
|
||||||
.lines = 1,
|
.lines = 1,
|
||||||
.file = file,
|
.file = file,
|
||||||
.ignoreExtras = false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
try dumpInput(config, file, output, testing.allocator);
|
try dumpInput(config, file, output, testing.allocator);
|
||||||
|
@ -210,7 +196,6 @@ test "dumpInput skip 2 line 'alpha'" {
|
||||||
.lines = 2,
|
.lines = 2,
|
||||||
.file = file,
|
.file = file,
|
||||||
.line = "alpha",
|
.line = "alpha",
|
||||||
.ignoreExtras = false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
try dumpInput(config, file, output, testing.allocator);
|
try dumpInput(config, file, output, testing.allocator);
|
||||||
|
|
62
test.sh
62
test.sh
|
@ -2,14 +2,6 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
SKIP="./zig-out/bin/skip"
|
|
||||||
DIFF="diff -u --color"
|
|
||||||
|
|
||||||
if test ! -x $SKIP ; then
|
|
||||||
echo "File missing: $SKIP - try 'zig build'"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "> skip a line when reading from stdin"
|
echo "> skip a line when reading from stdin"
|
||||||
INPUT=$(cat<<EOF
|
INPUT=$(cat<<EOF
|
||||||
line 1
|
line 1
|
||||||
|
@ -17,9 +9,8 @@ line 2
|
||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
echo "line 2" > test.expect
|
echo "line 2" > test.expect
|
||||||
echo "$INPUT" | $SKIP 1 > test.out
|
echo "$INPUT" | ./skip 1 > test.out
|
||||||
$DIFF test.expect test.out
|
diff --brief test.expect test.out
|
||||||
rm test.expect test.out
|
|
||||||
|
|
||||||
echo "> skip a line when reading from a file"
|
echo "> skip a line when reading from a file"
|
||||||
cat<<EOF > test.in
|
cat<<EOF > test.in
|
||||||
|
@ -27,9 +18,8 @@ line 1
|
||||||
line 2
|
line 2
|
||||||
EOF
|
EOF
|
||||||
echo "line 2" > test.expect
|
echo "line 2" > test.expect
|
||||||
$SKIP 1 test.in > test.out
|
./skip 1 test.in > test.out
|
||||||
$DIFF test.expect test.out
|
diff --brief test.expect test.out
|
||||||
rm test.expect test.out
|
|
||||||
|
|
||||||
echo "> skip until 2 matching lines seen"
|
echo "> skip until 2 matching lines seen"
|
||||||
cat<<EOF > test.in
|
cat<<EOF > test.in
|
||||||
|
@ -45,9 +35,8 @@ alpha
|
||||||
gamma
|
gamma
|
||||||
alpha
|
alpha
|
||||||
EOF
|
EOF
|
||||||
$SKIP 2 test.in --line alpha > test.out
|
./skip 2 test.in --line alpha > test.out
|
||||||
$DIFF test.expect test.out
|
diff --brief test.expect test.out
|
||||||
rm test.in test.expect test.out
|
|
||||||
|
|
||||||
echo "> skip lines until 2 tokens seen"
|
echo "> skip lines until 2 tokens seen"
|
||||||
cat<<EOF > test.in
|
cat<<EOF > test.in
|
||||||
|
@ -66,37 +55,17 @@ quis nostrud exercitation ullamco
|
||||||
laboris nisi ut aliquip ex ea
|
laboris nisi ut aliquip ex ea
|
||||||
commodo consequat.
|
commodo consequat.
|
||||||
EOF
|
EOF
|
||||||
$SKIP 2 test.in --token dolor > test.out 2
|
./skip 2 test.in --token dolor > test.out
|
||||||
$DIFF test.expect test.out
|
diff --brief test.expect test.out
|
||||||
rm test.in test.expect test.out
|
|
||||||
|
|
||||||
echo "> handle unknown parameter with simple error message"
|
echo "> handle unknown parameter with simple error message"
|
||||||
cat<<EOF > test.expect.err
|
cat<<EOF > test.expect
|
||||||
Invalid argument '--foo'
|
Invalid argument '--foo'
|
||||||
EOF
|
EOF
|
||||||
cat<<EOF > test.expect
|
./skip --foo > test.out 2>&1 || ## error is expected
|
||||||
EOF
|
diff --brief test.expect test.out
|
||||||
touch test.out test.err
|
|
||||||
$SKIP --foo > test.out 2> test.err
|
|
||||||
$DIFF test.expect test.out
|
|
||||||
$DIFF test.expect.err test.err
|
|
||||||
rm test.expect test.out
|
|
||||||
rm test.expect.err test.err
|
|
||||||
|
|
||||||
echo "> handle ignore-extra when token is missing"
|
echo "> skip lines until 3 tokens seen - ignored extra tokens on same line"
|
||||||
cat<<EOF > test.expect.err
|
|
||||||
Error: --ignore-extras requires --token
|
|
||||||
EOF
|
|
||||||
cat<<EOF > test.expect
|
|
||||||
EOF
|
|
||||||
touch test.out test.err
|
|
||||||
$SKIP --ignore-extras > test.out 2> test.err
|
|
||||||
$DIFF test.expect test.out
|
|
||||||
$DIFF test.expect.err test.err
|
|
||||||
rm test.expect test.out
|
|
||||||
rm test.expect.err test.err
|
|
||||||
|
|
||||||
echo "> skip lines until 4 tokens seen - ignored extra tokens on same line"
|
|
||||||
cat<<EOF > test.in
|
cat<<EOF > test.in
|
||||||
Lorem ipsum dolor sit amet,
|
Lorem ipsum dolor sit amet,
|
||||||
consectetur adipiscing elit,
|
consectetur adipiscing elit,
|
||||||
|
@ -112,8 +81,9 @@ quis nostrud exercitation ullamco
|
||||||
laboris nisi ut aliquip ex ea
|
laboris nisi ut aliquip ex ea
|
||||||
commodo consequat.
|
commodo consequat.
|
||||||
EOF
|
EOF
|
||||||
$SKIP 4 test.in --token m --ignore-extras > test.out
|
./skip 3 test.in --token m --ignore-extras > test.out
|
||||||
$DIFF test.expect test.out
|
diff --brief test.expect test.out
|
||||||
rm test.in test.expect test.out
|
|
||||||
|
rm test.in test.out test.expect
|
||||||
|
|
||||||
echo done
|
echo done
|
||||||
|
|
Loading…
Reference in a new issue