Introduction
Introduction Statistics Contact Development Disclaimer Help
seq.c - sbase - suckless unix tools
git clone git://git.suckless.org/sbase
Log
Files
Refs
README
LICENSE
---
seq.c (2581B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include "util.h"
7
8 static int
9 digitsleft(const char *d)
10 {
11 int shift;
12 char *exp;
13
14 if (*d == '+')
15 d++;
16 exp = strpbrk(d, "eE");
17 shift = exp ? estrtonum(exp + 1, INT_MIN, INT_MAX) : 0;
18
19 return MAX(0, strspn(d, "-0123456789") + shift);
20 }
21
22 static int
23 digitsright(const char *d)
24 {
25 int shift, after;
26 char *exp;
27
28 exp = strpbrk(d, "eE");
29 shift = exp ? estrtonum(&exp[1], INT_MIN, INT_MAX) : 0;
30 after = (d = strchr(d, '.')) ? strspn(&d[1], "0123456789") : 0;
31
32 return MAX(0, after - shift);
33 }
34
35 static int
36 validfmt(const char *fmt)
37 {
38 int occur = 0;
39
40 literal:
41 while (*fmt)
42 if (*fmt++ == '%')
43 goto format;
44 return occur == 1;
45
46 format:
47 if (*fmt == '%') {
48 fmt++;
49 goto literal;
50 }
51 fmt += strspn(fmt, "-+#0 '");
52 fmt += strspn(fmt, "0123456789");
53 if (*fmt == '.') {
54 fmt++;
55 fmt += strspn(fmt, "0123456789");
56 }
57 if (*fmt == 'L')
58 fmt++;
59
60 switch (*fmt) {
61 case 'f': case 'F':
62 case 'g': case 'G':
63 case 'e': case 'E':
64 case 'a': case 'A':
65 occur++;
66 goto literal;
67 default:
68 return 0;
69 }
70 }
71
72 static void
73 usage(void)
74 {
75 eprintf("usage: %s [-f fmt] [-s sep] [-w] "
76 "[startnum [step]] endnum\n", argv0);
77 }
78
79 int
80 main(int argc, char *argv[])
81 {
82 double start, step, end, out, dir;
83 int wflag = 0, left, right;
84 char *tmp, ftmp[BUFSIZ], *fmt = ftmp;
85 const char *starts = "1", *steps = "1", *ends = "1", *sep = "\n";
86
87 ARGBEGIN {
88 case 'f':
89 if (!validfmt(tmp=EARGF(usage())))
90 eprintf("%s: invalid format\n", tmp);
91 fmt = tmp;
92 break;
93 case 's':
94 sep = EARGF(usage());
95 break;
96 case 'w':
97 wflag = 1;
98 break;
99 default:
100 usage();
101 } ARGEND
102
103 switch (argc) {
104 case 3:
105 steps = argv[1];
106 argv[1] = argv[2];
107 /* fallthrough */
108 case 2:
109 starts = argv[0];
110 argv++;
111 /* fallthrough */
112 case 1:
113 ends = argv[0];
114 break;
115 default:
116 usage();
117 }
118 start = estrtod(starts);
119 step = estrtod(steps);
120 end = estrtod(ends);
121
122 dir = (step > 0) ? 1.0 : -1.0;
123 if (step == 0 || start * dir > end * dir)
124 return 1;
125
126 if (fmt == ftmp) {
127 right = MAX(digitsright(starts),
128 MAX(digitsright(ends),
129 digitsright(steps)));
130
131 if (wflag) {
132 left = MAX(digitsleft(starts), digitsleft(ends));
133
134 snprintf(ftmp, sizeof ftmp, "%%0%d.%df",
135 right + left + (right != 0), rig…
136 } else
137 snprintf(ftmp, sizeof ftmp, "%%.%df", right);
138 }
139 for (out = start; out * dir <= end * dir; out += step) {
140 if (out != start)
141 fputs(sep, stdout);
142 printf(fmt, out);
143 }
144 putchar('\n');
145
146 return fshut(stdout, "<stdout>");
147 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.