commit e8d6e30106ac0a2d97d5cdfe640e19277bb36648
parent ff96728bdd586d89fa19f605446e9b1b56b35f0e
Author: Christoph Lohmann <20h@r-36.net>
Date: Tue, 10 Apr 2012 17:33:19 +0200
Adding seq command.
Diffstat:
M | LICENSE | | | 2 | ++ |
M | Makefile | | | 1 | + |
A | seq.c | | | 167 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 170 insertions(+), 0 deletions(-)
diff --git a/LICENSE b/LICENSE
@@ -8,6 +8,8 @@ MIT/X Consortium License
© 2011 pancake <pancake@youterm.com>
© 2011 Random832 <random832@fastmail.us>
© 2012 William Haddon <william@haddonthethird.net>
+© 2012 Kurt H. Maier <khm@intma.in>
+© 2012 Christoph Lohmann <20h@r-36.net>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
diff --git a/Makefile b/Makefile
@@ -51,6 +51,7 @@ SRC = \
true.c \
tty.c \
uname.c \
+ seq.c \
wc.c
OBJ = $(SRC:.c=.o) $(LIB)
diff --git a/seq.c b/seq.c
@@ -0,0 +1,167 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <libgen.h>
+
+#include "util.h"
+
+char afmt[4096];
+
+char *
+getalignedwidthfmt(char *fmt, char *starts, char *steps, char *ends)
+{
+ char starttmp[4096], steptmp[4096], endtmp[4096];
+ char *startdelim, *stepdelim, *enddelim;
+ int startl, startr, stepr, endl, endr;
+ int maxl, maxr;
+
+ /*
+ * 1.) Get a temp buffer we can work in.
+ * 2.) Calculate the *r(ight) and *l(eft) size.
+ */
+ memmove(starttmp, starts, strlen(starts)+1);
+ startdelim = strchr(starttmp, '.');
+ if (startdelim != NULL) {
+ startdelim[0] = '\0';
+ startr = strlen(startdelim+1);
+ } else {
+ startr = 0;
+ }
+ startl = strlen(starttmp);
+ if (starttmp[0] == '+')
+ startl--;
+
+ memmove(endtmp, ends, strlen(ends)+1);
+ enddelim = strchr(endtmp, '.');
+ if (enddelim != NULL) {
+ enddelim[0] = '\0';
+ endr = strlen(enddelim+1);
+ } else {
+ endr = 0;
+ }
+ endl = strlen(endtmp);
+ if (endtmp[0] == '+')
+ endl--;
+
+ /*
+ * We do not care for the left length of the step, because it
+ * will never be displayed.
+ */
+ memmove(steptmp, steps, strlen(steps)+1);
+ stepdelim = strchr(steptmp, '.');
+ if (stepdelim != NULL) {
+ stepdelim[0] = '\0';
+ stepr = strlen(stepdelim+1);
+ } else {
+ stepr = 0;
+ }
+
+ maxl = (startl > endl)? startl : endl;
+ maxr = (startl > endr)? startr : endr;
+ if (stepr > maxr)
+ maxr = stepr;
+
+ if (maxl <= 1) {
+ snprintf(afmt, sizeof(afmt), "%%.%df", maxr);
+ } else if (maxr == 0) {
+ snprintf(afmt, sizeof(afmt), "%%0%d.f", maxl);
+ } else {
+ snprintf(afmt, sizeof(afmt), "%%0%d.%df", maxl+maxr+1, maxr);
+ }
+
+ return afmt;
+}
+
+int
+main(int argc, char *argv[])
+{
+ char c, *fmt, *sep, *starts, *steps, *ends;
+ bool wflag = false;
+ double start, step, end, out;
+
+ sep = "\n";
+ fmt = "%G";
+
+ starts = "1";
+ steps = "1";
+ ends = "1";
+
+ while((c = getopt(argc, argv, "f:s:w")) != -1) {
+ switch(c) {
+ case 'f':
+ fmt = optarg;
+ break;
+ case 's':
+ sep = optarg;
+ break;
+ case 'w':
+ wflag = true;
+ break;
+ }
+ }
+
+ switch(argc-optind) {
+ case 3:
+ starts = argv[optind++];
+ steps = argv[optind++];
+ ends = argv[optind++];
+ break;
+ case 2:
+ starts = argv[optind++];
+ ends = argv[optind++];
+ break;
+ case 1:
+ ends = argv[optind++];
+ break;
+ default:
+ eprintf("usage: %s [-f fmt] [-s separator] [-w] [start [step]]"
+ " end\n", basename(argv[0]));
+ }
+
+ start = atof(starts);
+ step = atof(steps);
+ end = atof(ends);
+
+ if (step == 0)
+ return EXIT_FAILURE;
+
+ if (start > end) {
+ if (step > 0)
+ return EXIT_FAILURE;
+ } else if (start < end) {
+ if (step < 0)
+ return EXIT_FAILURE;
+ }
+
+ if (wflag)
+ fmt = getalignedwidthfmt(fmt, starts, steps, ends);
+ printf("%s\n", fmt);
+
+ for (out = start;;) {
+ printf(fmt, out);
+
+ out += step;
+ if (start > end) {
+ if (out >= end) {
+ printf("%s", sep);
+ } else {
+ break;
+ }
+ } else if (start < end) {
+ if (out <= end) {
+ printf("%s", sep);
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ printf("\n");
+
+ return EXIT_SUCCESS;
+}
+