aboutsummaryrefslogtreecommitdiff
path: root/seq.c
diff options
context:
space:
mode:
authorCharles Cabergs <me@cacharle.xyz>2020-08-08 16:22:55 +0200
committerCharles Cabergs <me@cacharle.xyz>2020-08-08 16:22:55 +0200
commit284e1b7a5c4b1b0b0f38d16ecb1507ea4ac964f4 (patch)
tree838e1c692f431ed83d615c5c0cfe63d57d757c64 /seq.c
parent40560618aa165add94a80f70d2b187546ed47cfe (diff)
downloadcoreutils-284e1b7a5c4b1b0b0f38d16ecb1507ea4ac964f4.tar.gz
coreutils-284e1b7a5c4b1b0b0f38d16ecb1507ea4ac964f4.tar.bz2
coreutils-284e1b7a5c4b1b0b0f38d16ecb1507ea4ac964f4.zip
Moved everything in root
Diffstat (limited to 'seq.c')
-rw-r--r--seq.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/seq.c b/seq.c
new file mode 100644
index 0000000..8307fc4
--- /dev/null
+++ b/seq.c
@@ -0,0 +1,126 @@
+#define _POSIX_C_SOURCE 2
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+
+typedef struct
+{
+ long double value;
+ int precision;
+ int integer_len;
+} t_num;
+
+char *g_name = "seq";
+
+int parse_num(char *s, t_num *num)
+{
+ char *tmp;
+
+ errno = 0;
+ num->value = strtold(s, &tmp);
+ if (errno != 0 || *tmp != '\0')
+ {
+ fprintf(stderr, "%s: invalid floating point argument: '%s'\n", g_name, s);
+ exit(EXIT_FAILURE);
+ }
+ num->precision = 0;
+ num->integer_len = strlen(s);
+ if ((tmp = strchr(s, '.')) != NULL)
+ {
+ num->precision = strlen(tmp + 1);
+ num->integer_len = tmp - s;
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc == 1)
+ {
+ fprintf(stderr, "%s: missing operand\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ int option;
+ char *separator = "\n";
+ bool padding = false;
+
+ g_name = argv[0];
+
+ while ((option = getopt(argc, argv, "f:s:w0123456789")) != -1)
+ {
+ if (isdigit(option))
+ break;
+ switch (option)
+ {
+ case 'f':
+ exit(EXIT_FAILURE); // TODO
+ break;
+ case 's':
+ separator = optarg;
+ break;
+ case 'w':
+ padding = true;
+ break;
+ }
+ }
+
+ t_num first;
+ t_num increment;
+ t_num last;
+
+ first.value = 1.0;
+ first.precision = 0;
+ increment.value = 1.0;
+ increment.precision = 0;
+
+ switch (argc - optind)
+ {
+ case 1:
+ parse_num(argv[optind], &last);
+ break;
+ case 2:
+ parse_num(argv[optind], &first);
+ parse_num(argv[optind + 1], &last);
+ break;
+ case 3:
+ parse_num(argv[optind], &first);
+ parse_num(argv[optind + 1], &increment);
+ if (increment.value == 0)
+ {
+ fprintf(stderr, "%s: invalid Zero increment value '%s'\n", argv[0], argv[optind + 3]);
+ exit(EXIT_FAILURE);
+ }
+ parse_num(argv[optind + 2], &last);
+ break;
+ default:
+ fprintf(stderr, "%s: extra operand '%s'\n", argv[0], argv[optind + 3]);
+ exit(EXIT_FAILURE);
+ break;
+ }
+
+ while (increment.value > 0 ? (first.value <= last.value) : (first.value >= last.value))
+ {
+ int precision = MAX(first.precision, increment.precision);
+ if (!padding)
+ printf("%.*llf", precision, first.value);
+ else
+ {
+ int width = MAX(last.integer_len, first.integer_len);
+ if (precision != 0)
+ width += precision + 1;
+ printf("%0*.*llf", width, precision, first.value);
+ }
+ first.value += increment.value;
+ if (increment.value > 0 ? (first.value <= last.value) : (first.value >= last.value))
+ fputs(separator, stdout);
+ }
+ putchar('\n');
+ return EXIT_SUCCESS;
+}