Introduction
Introduction Statistics Contact Development Disclaimer Help
ploot-feed.c - ploot - simple plotting tools
git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65…
Log
Files
Refs
Tags
README
LICENSE
---
ploot-feed.c (4792B)
---
1 #include <ctype.h>
2 #include <errno.h>
3 #include <fcntl.h>
4 #include <limits.h>
5 #include <stdint.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <time.h>
10 #include <unistd.h>
11 #include "util.h"
12
13 #ifndef __OpenBSD__
14 #define pledge(...) 0
15 #endif
16
17 #define WIDTH_MAX 1024
18 #define BRAILLE_START 10240
19
20 static int wflag = 80;
21 static int width = 0;
22
23 /*
24 * Turn the bit at position (row, col) on in the .
25 */
26 static void
27 plot_dot(long *out, int row, int col)
28 {
29 long flags[4][2] = {
30 { 0x01, 0x08 },
31 { 0x02, 0x10 },
32 { 0x04, 0x20 },
33 { 0x40, 0x80 },
34 };
35
36 *out |= flags[row][col];;
37 }
38
39 static void
40 plot_val(long *out, double val, double max, int row)
41 {
42 int col, c;
43
44 val = MIN(max, val);
45 col = (int)(val * (double)(width - 1) / max * 2);
46 for (c = 0; c < col; c++)
47 plot_dot(out + c / 2, row, c % 2);
48 }
49
50 /*
51 * Change the braille characters on a whole row, this for all the
52 * values line.
53 */
54 static time_t
55 plot_row(long *out, char *line, double *max, int nrow, int ncol)
56 {
57 time_t epoch;
58 double val;
59 int n;
60 char *tok;
61
62 tok = strsep(&line, "\t");
63 if (!tok)
64 err(100, "*** missing epoch value");
65 epoch = strtol(tok, NULL, 10);
66 if (errno)
67 warn("*** parsing epoch '%s'", tok);
68
69 for (n = 0; (tok = strsep(&line, "\t")) != NULL; n++) {
70 if (n >= ncol)
71 err(100, "too many values");
72 val = atof(tok);
73 plot_val(out + n * width, val, max[n], nrow);
74 }
75 if (n < ncol)
76 err(100, "not enough values");
77
78 return epoch;
79 }
80
81 /*
82 * Read enough input in order to print one line and plot it into 'out'.
83 */
84 static time_t
85 plot_line(long *out, double *max, int ncol)
86 {
87 time_t epoch;
88 int n, nrow;
89 long *o, rune;
90 char *line;
91 size_t sz;
92
93 for (rune = BRAILLE_START, o = out, n = ncol * width; n > 0; o++…
94 memcpy(o, &rune, sizeof(rune));
95 *o = '\0';
96 for (rune = 0x2502, o = out, n = 0; n < ncol; o += width, n++)
97 memcpy(o, &rune, sizeof(rune));
98 out++;
99
100 line = NULL, sz = 0;
101 for (nrow = 0; nrow < 4; nrow++) {
102 if (getline(&line, &sz, stdin) == -1) {
103 if (ferror(stdin))
104 err(111, "reading row from stdin");
105 exit(0);
106 }
107 epoch = plot_row(out, line, max, nrow, ncol);
108 }
109
110 free(line);
111 return epoch;
112 }
113
114 static void
115 put_time(time_t epoch, time_t last, int nline)
116 {
117 char *out, buf[sizeof("XXxXXxXX ")];
118
119 switch (nline % 3) {
120 case 0:
121 strftime(buf, sizeof(buf), "%H:%M:%S _", localtime(&epoc…
122 out = buf;
123 break;
124 case 1:
125 strftime(buf, sizeof(buf), "%y/%m/%d ", localtime(&last…
126 out = buf;
127 break;
128 case 2:
129 out = " ";
130 break;
131 }
132
133 fputs(out, stdout);
134 }
135
136 static void
137 put_line(long *out)
138 {
139 for (; *out != '\0'; out++)
140 put3utf(*out);
141 puts("│");
142 }
143
144 static void
145 plot(char labels[4069], double *max, int ncol)
146 {
147 time_t epoch, last_epoch;
148 long out[WIDTH_MAX + 1];
149 int n;
150
151 last_epoch = epoch = 0;
152
153 for (n = 0;; n = (n == 25 ? 0 : n + 1)) {
154 if (n == 0) {
155 put_time(0, 0, 2);
156 fputs(labels, stdout);
157 puts("│");
158 }
159
160 epoch = plot_line(out, max, ncol);
161 put_time(epoch, last_epoch, n);
162 last_epoch = epoch;
163 put_line(out);
164
165 fflush(stdout);
166 }
167 }
168
169 /*
170 * Label must be able to store all pointers to token buf has to
171 * offer: sizeof(*buf / 2).
172 */
173 static int
174 read_labels(char **labv)
175 {
176 int ncol;
177 char *cp, *line, *tok;
178 size_t sz;
179
180 line = NULL, sz = 0;
181 if (getline(&line, &sz, stdin) == -1) {
182 if (ferror(stdin))
183 err(111, "reading labels from stdin");
184 err(100, "missing label line", stderr);
185 }
186 strchomp(line);
187 cp = line;
188
189 if (strcmp(strsep(&cp, "\t"), "epoch") != 0)
190 err(100, "first label must be 'epoch'");
191
192 for (ncol = 0; (tok = strsep(&cp, "\t")) != NULL; ncol++, labv++)
193 *labv = tok;
194 *labv = NULL;
195
196 if (ncol < 1)
197 err(100, "no label found");
198 return ncol;
199 }
200
201 static void
202 fmt_labels(char out[4069], int ncol, char *labels[4069 / 2])
203 {
204 int i, n;
205
206 for (i = 0; i < ncol; labels++, i++) {
207 n = 4069 - (width + sizeof("│")) * i;
208 out += snprintf(out, n, "│%-*s", width - 1, *labels);
209 }
210 }
211
212 static void
213 usage(void)
214 {
215 fprintf(stderr, "usage: %s [-w width] maxval... <tsv\n", arg0);
216 exit(1);
217 }
218
219 int
220 main(int argc, char **argv)
221 {
222 double max[4069 / 2], *m;
223 int ncol, nmax;
224 char *labv[4069 / 2], labels[4069];
225 int c;
226
227 if (pledge("stdio", "") < 0)
228 err(1, "pledge: %s", strerror(errno));
229
230 arg0 = *argv;
231 while ((c = getopt(argc, argv, "w:")) > -1) {
232 switch (c) {
233 case 'w':
234 wflag = atoi(optarg);
235 break;
236 default:
237 usage();
238 }
239 }
240 argc -= optind;
241 argv += optind;
242
243 if (argc == 0)
244 usage();
245
246 nmax = argc;
247 for (m = max; argc > 0; argc--, argv++, m++) {
248 *m = strtod(*argv, NULL);
249 if (errno)
250 warn("*** parsing float '%s'", *argv);
251 }
252
253 ncol = read_labels(labv);
254 width = (wflag - sizeof("XXxXXxXX _")) / ncol - sizeof("|");
255 fmt_labels(labels, ncol, labv);
256 if (ncol != nmax)
257 err(100, "not as many labels and arguments");
258 plot(labels, max, ncol);
259
260 return 0;
261 }
You are viewing proxied material from bitreich.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.