1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#define FOR_seq
26#include "toys.h"
27
28GLOBALS(
29 char *s, *f;
30
31 int precision, buflen;
32)
33
34
35static void insanitize(char *f)
36{
37 char *s = next_printf(f, 0);
38
39 if (!s) error_exit("bad -f no %%f");
40 if (-1 == stridx("aAeEfFgG", *s) || (s = next_printf(s, 0)))
41 error_exit("bad -f '%s'@%d", f, (int)(s-f+1));
42}
43
44
45
46static double parsef(char *s)
47{
48 char *dp = strchr(s, '.');
49
50 if (dp++) TT.precision = maxof(TT.precision, strcspn(dp, "eE"));
51
52 return xstrtod(s);
53}
54
55
56
57static char *itoa(char *s, int i)
58{
59 char buf[16], *ff = buf;
60 unsigned n = i;
61
62 if (i<0) {
63 *s++ = '-';
64 n = -i;
65 }
66 do *ff++ = '0'+n%10; while ((n /= 10));
67 do *s++ = *--ff; while (ff>buf);
68 *s++ = '\n';
69
70 return s;
71}
72
73static char *flush_toybuf(char *ss)
74{
75 if (ss-toybuf<TT.buflen) return ss;
76 xwrite(1, toybuf, ss-toybuf);
77
78 return toybuf;
79}
80
81void seq_main(void)
82{
83 char fbuf[32], *ss;
84 double first = 1, increment = 1, last, dd;
85 int ii, inc = 1, len, slen;
86
87
88 if (!TT.s) TT.s = "\n";
89 switch (toys.optc) {
90 case 3: increment = parsef(toys.optargs[1]);
91 case 2: first = parsef(*toys.optargs);
92 default: last = parsef(toys.optargs[toys.optc-1]);
93 }
94
95
96 if (FLAG(f)) insanitize(TT.f);
97 for (ii = len = 0; ii<3; ii++) {
98 dd = (double []){first, increment, last}[ii];
99 len = maxof(len, snprintf(0, 0, "%.*f", TT.precision, fabs(dd)));
100 if (ii == 2) dd += increment;
101 slen = dd;
102 if (dd != slen) inc = 0;
103 }
104 if (!FLAG(f)) sprintf(TT.f = fbuf, "%%0%d.%df", len, TT.precision);
105 TT.buflen = sizeof(toybuf) - 32 - len - TT.precision - strlen(TT.s);
106 if (TT.buflen<0) error_exit("bad -s");
107
108
109 if (!toys.optflags && inc) {
110 ii = first;
111 len = last;
112 inc = increment;
113 ss = toybuf;
114 if (inc>0) for (; ii<=len; ii += inc)
115 ss = flush_toybuf(itoa(ss, ii));
116 else if (inc<0) for (; ii>=len; ii += inc)
117 ss = flush_toybuf(itoa(ss, ii));
118 if (ss != toybuf) xwrite(1, toybuf, ss-toybuf);
119
120 return;
121 }
122
123
124
125
126 if (!increment) return;
127
128
129 for (ii = 0, ss = toybuf;; ii++) {
130
131 dd = first+ii*increment;
132 if ((increment<0 && dd<last) || (increment>0 && dd>last)) break;
133 if (ii) ss = flush_toybuf(stpcpy(ss, TT.s));
134 ss += sprintf(ss, TT.f, dd);
135 }
136 *ss++ = '\n';
137 xwrite(1, toybuf, ss-toybuf);
138}
139