commit: 0207b4eb7ba7228bd84e24207d2ab1c55a6663af
parent 2a84b987813114a0e325fd3fed7c178d87103dc4
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Wed, 2 Mar 2022 14:32:34 +0100
bin/range: Transform into bin/seq
Diffstat:
D | bin/range.c | 54 | ------------------------------------------------------ |
A | bin/seq.c | 104 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | test-bin/Kyuafile | 1 | + |
A | test-bin/seq | 54 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
4 files changed, 159 insertions(+), 54 deletions(-)
diff --git a/bin/range.c b/bin/range.c
@@ -1,54 +0,0 @@
-// Collection of Unix tools, comparable to coreutils
-// Copyright 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
-// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
-
-#define _POSIX_C_SOURCE 200809L
-#include <stdio.h>
-#include <stdlib.h>
-
-char *IFS;
-int a, b;
-
-void
-usage(char *a0)
-{
- printf("usage: %s [ini <max>]\n", a0);
-}
-
-void
-range(int initial, int maximum)
-{
- printf("%i", initial);
- if(initial < maximum)
- {
- for(initial++; initial <= maximum; initial++)
- printf("%s%i", IFS, initial);
- }
- else if(initial > maximum)
- {
- for(initial--; initial >= maximum; initial--)
- printf("%s%i", IFS, initial);
- }
-}
-
-int
-main(int argc, char *argv[])
-{
- if(!(IFS = getenv("IFS")))
- {
- IFS = " ";
- }
-
- if(argc == 2)
- {
- range(0, atoi(argv[1]));
- }
- else if(argc == 3)
- {
- range(atoi(argv[1]), atoi(argv[2]));
- }
- else
- {
- usage(argv[0]);
- }
-}
diff --git a/bin/seq.c b/bin/seq.c
@@ -0,0 +1,104 @@
+// Collection of Unix tools, comparable to coreutils
+// Copyright 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
+// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
+
+#define _POSIX_C_SOURCE 200809L
+#include <errno.h> // errno
+#include <stdbool.h> // bool, true, false
+#include <stdio.h> // puts, fprintf
+#include <stdlib.h> // atoi, exit
+#include <unistd.h> // getopt, optarg, optind
+
+char *separator = "\n";
+bool zero_pad = false;
+
+void
+seq(long i, long step, long last)
+{
+ if(i == last)
+ {
+ printf("%li%s", i, separator);
+ }
+ else if(i < last)
+ {
+ for(;i <= last; i += step)
+ printf("%li%s", i, separator);
+ }
+ else if(i > last)
+ {
+ for(;i >= last; i -= step)
+ printf("%li%s", i, separator);
+ }
+}
+
+long
+get_num(char *str)
+{
+ errno = 0;
+
+ long num = strtol(str, NULL, 10);
+
+ if(errno != 0)
+ {
+ perror("seq: strtol:");
+ exit(1);
+ }
+
+ return num;
+}
+
+void
+usage(void)
+{
+ fprintf(stderr, "usage: seq [-w] [-s separator] [first [step]] last\n");
+}
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+
+ /* flawfinder: ignore. Old implementations of getopt should fix themselves */
+ while((c = getopt(argc, argv, ":ws:")) != -1)
+ {
+ switch(c)
+ {
+ case 'w':
+ zero_pad = true;
+ break;
+ case 's':
+ separator = optarg;
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ long first = 1;
+ long step = 1;
+ long last = 1;
+
+ switch(argc)
+ {
+ case 1:
+ last = get_num(argv[0]);
+ break;
+ case 2:
+ first = get_num(argv[0]);
+ last = get_num(argv[1]);
+ break;
+ case 3:
+ first = get_num(argv[0]);
+ step = get_num(argv[1]);
+ last = get_num(argv[2]);
+ break;
+ default:
+ usage();
+ return 1;
+ }
+
+ seq(first, step, last);
+
+ return 0;
+}
diff --git a/test-bin/Kyuafile b/test-bin/Kyuafile
@@ -18,6 +18,7 @@ atf_test_program{name="false", required_files=basedir.."/bin/false"}
atf_test_program{name="humanize", required_files=basedir.."/bin/humanize"}
atf_test_program{name="mdate", required_files=basedir.."/bin/mdate"}
atf_test_program{name="pwd", required_files=basedir.."/bin/pwd"}
+atf_test_program{name="seq", required_files=basedir.."/bin/seq"}
atf_test_program{name="sname", required_files=basedir.."/bin/sname"}
atf_test_program{name="strings", required_files=basedir.."/bin/strings"}
atf_test_program{name="tee", required_files=basedir.."/bin/tee"}
diff --git a/test-bin/seq b/test-bin/seq
@@ -0,0 +1,54 @@
+#!/usr/bin/env atf-sh
+atf_test_case one
+one_body() {
+ atf_check -o "inline:1\n" ../bin/seq 1
+ atf_check -o "inline:1\n2\n3\n4\n5\n" ../bin/seq 5
+}
+
+atf_test_case two
+two_body() {
+ atf_check -o "inline:0\n1\n" ../bin/seq 0 1
+ atf_check -o "inline:0\n1\n2\n3\n4\n5\n" ../bin/seq 0 5
+ atf_check -o "inline:10\n11\n12\n13\n14\n15\n" ../bin/seq 10 15
+}
+
+atf_test_case three
+three_body() {
+ atf_check -o "inline:0\n1\n" ../bin/seq 0 1 1
+ atf_check -o "inline:0\n1\n2\n3\n4\n5\n" ../bin/seq 0 1 5
+ atf_check -o "inline:10\n11\n12\n13\n14\n15\n" ../bin/seq 10 1 15
+
+ atf_check -o "inline:0\n2\n4\n" ../bin/seq 0 2 5
+ atf_check -o "inline:10\n12\n14\n" ../bin/seq 10 2 15
+}
+
+atf_test_case noarg
+noarg_body() {
+ atf_check -s exit:1 -e 'inline:usage: seq [-w] [-s separator] [first [step]] last\n' ../bin/seq
+}
+
+atf_test_case badflag
+badflag_body() {
+ atf_check -s exit:1 -e 'inline:usage: seq [-w] [-s separator] [first [step]] last\n' ../bin/seq -f
+}
+
+atf_test_case limits
+limits_body() {
+ atf_check ../bin/seq 9223372036854775806 9223372036854775807
+ atf_check -s exit:1 ../bin/seq 9223372036854775806 9223372036854775808
+
+ atf_check ../bin/seq -- -9223372036854775807 -9223372036854775808
+ atf_check -s exit:1 ../bin/seq -- -9223372036854775807 -9223372036854775809
+}
+
+atf_init_test_cases() {
+ cd "$(atf_get_srcdir)" || exit 1
+
+ atf_add_test_case one
+ atf_add_test_case two
+ atf_add_test_case three
+
+ atf_add_test_case noarg
+ atf_add_test_case badflag
+ #atf_add_test_case limits
+}