reading lines into a buffe - ploot - simple plotting tools
(HTM) git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ploot
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
(DIR) LICENSE
---
(DIR) commit b22b1b174646f828a28144c010961a9c57f54dbd
(DIR) parent 522bbe841ea86e232baf35ba638fe490cc763325
(HTM) Author: Josuah Demangeon <mail@josuah.net>
Date: Wed, 2 May 2018 01:12:56 +0200
reading lines into a buffe
Diffstat:
A config.h | 8 ++++++++
M ffplot.c | 2 +-
M main.c | 132 ++++++++++++++++++++++++++++---
M ploot.h | 11 ++++++++++-
A util.c | 21 +++++++++++++++++++++
5 files changed, 162 insertions(+), 12 deletions(-)
---
(DIR) diff --git a/config.h b/config.h
@@ -0,0 +1,8 @@
+ColorList colorlist[] = {
+ { "red", { 0xffff, 0x4444, 0x4444, 0xffff } },
+ { "orange", { 0xffff, 0x9999, 0x4444, 0xffff } },
+ { "yellow", { 0xffff, 0xffff, 0x4444, 0xffff } },
+ { "green", { 0x1111, 0xffff, 0x5555, 0xffff } },
+ { "cyan", { 0x0000, 0xffff, 0xdddd, 0xffff } },
+ { NULL, { 0, 0, 0, 0 } }
+};
(DIR) diff --git a/ffplot.c b/ffplot.c
@@ -193,7 +193,7 @@ legend(Canvas *can, Color *label_fg, Vlist *v, int n)
ffdraw_str_left(can, &v->col, "\1", font, x, y);
y += FONT_W * 2;
- ffdraw_str_left(can, label_fg, v->name, font, x, y);
+ ffdraw_str_left(can, label_fg, v->label, font, x, y);
}
}
(DIR) diff --git a/main.c b/main.c
@@ -2,9 +2,13 @@
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
+#include <limits.h>
+#include <string.h>
+#include <ctype.h>
#include "arg.h"
#include "ploot.h"
+#include "config.h" /* after ploot.h for type definitions */
#define LEN(x) (sizeof(x) / sizeof(*x))
@@ -12,25 +16,132 @@ char *argv0;
char *tflag = "";
char *uflag = "";
+static int
+color(Color *col, char *name)
+{
+ ColorList *c;
+
+ for (c = colorlist; c->name != NULL; c++) {
+ if (strcmp(name, c->name) == 0) {
+ memcpy(col, &c->col, sizeof(*col));
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+void
+estriplf(char *line)
+{
+ char *lf;
+
+ if ((lf = strchr(line, '\n')) == NULL || lf[1] != '\0')
+ fputs("invalid input\n", stderr), exit(1);
+ *lf = '\0';
+}
+
static void
-usage(void)
+read_labels(Vlist *v, char **argv, char *buf)
{
- fprintf(stderr, "usage: %s [-t title] [-u unit] label:color...\n", argv0);
- exit(1);
+ if (fgets(buf, LINE_MAX, stdin) == NULL) {
+ if (ferror(stdin))
+ perror("fread from stdin");
+ else
+ fputs("missing label line\n", stderr);
+ exit(1);
+ }
+ estriplf(buf);
+
+ if (strcmp(strsep(&buf, ","), "epoch") != 0)
+ fputs("first label must be \"epoch\"\n", stderr), exit(1);
+
+ for (; *argv != NULL; v++, argv++)
+ if ((v->label = strsep(&buf, ",")) == NULL)
+ fputs("more arguments than columns\n", stderr), exit(1);
+ else if (color(&v->col, *argv) == -1)
+ fprintf(stderr, "unknown color: %s\n", *argv), exit(1);
+
+ if (strsep(&buf, ",") != NULL)
+ fputs("more columns than arguments\n", stderr), exit(1);
+}
+
+long
+eatol(char *str)
+{
+ char *s;
+
+ for (s = str; *s != '\0'; s++)
+ if (!isdigit(*s))
+ fputs("invalid number format", stderr), exit(0);
+ return atol(str);
}
void
-read_labels(Vlist *v, int n)
+add_value(double **v, int *bufsiz, int nval, char *field)
{
- (void)v;
- (void)n;
+ if (nval >= *bufsiz) {
+ *bufsiz *= 2;
+ if ((*v = realloc(*v, *bufsiz)) == NULL)
+ perror("reallocating values buffer"), exit(1);
+ }
+ (*v)[nval] = eatol(field);
+}
+
+/*
+ * Add to each column the value on the current row.
+ */
+void
+add_each_value(Vlist *v, int *bufsiz, int ncol, int nval, char *line)
+{
+ time_t epoch;
+ int n;
+ char *field;
+
+ if ((field = strsep(&line, ",")) == NULL)
+ fprintf(stderr, "%d: missing epoch\n", nval), exit(0);
+
+ epoch = eatol(field);
+
+ for (n = 0; (field = strsep(&line, ",")) != NULL; n++, v++) {
+ if (n > ncol)
+ fprintf(stderr, "%d: too many fields\n", nval), exit(0);
+ add_value(&v->v, bufsiz, nval, field);
+ }
+ if (n < ncol)
+ fprintf(stderr, "%d: too few fields\n", nval), exit(0);
}
+/*
+ * < ncol >
+ * epoch,a1,b1,c1 ^
+ * epoch,a2,b2,c2 nval
+ * epoch,a3,b3,c3 v
+ */
void
-read_values(Vlist *v, int n)
+read_values(Vlist *v, int ncol)
{
- (void)v;
- (void)n;
+ int n, nval, bufsiz;
+ char line[LINE_MAX];
+
+ for (nval = 0; fgets(line, sizeof(line), stdin); nval++) {
+ estriplf(line);
+ add_each_value(v, &bufsiz, ncol, nval, line);
+ }
+ for (n = 0; n < ncol; n++, v++)
+ v->n = nval;
+}
+
+static void
+usage(void)
+{
+ ColorList *c;
+
+ fprintf(stderr, "usage: %s [-t title] [-u unit] color...\n"
+ "available colors as defined by \"config.h\":\n", argv0);
+ for (c = colorlist; c->name != NULL; c++)
+ fprintf(stderr, "- %s\n", c->name);
+ exit(1);
}
int
@@ -39,6 +150,7 @@ main(int argc, char **argv)
Vlist *v;
double vmin, vmax, vstep;
time_t tmin, tmax, tstep;
+ char labels[LINE_MAX];
ARGBEGIN {
case 't':
@@ -55,7 +167,7 @@ main(int argc, char **argv)
vmin = -30; vmax = 700; vstep = 120;
tmin = 0; tmax = 2000; tstep = 300;
- read_labels(v, argc);
+ read_labels(v, argv, labels);
read_values(v, argc);
ffdraw(tflag, uflag, v, argc,
(DIR) diff --git a/ploot.h b/ploot.h
@@ -25,9 +25,14 @@ typedef struct {
time_t *t; /* array of timestamps */
double *v; /* array of values */
int n; /* number of values */
- char *name; /* for the legend */
+ char *label; /* for the legend */
} Vlist;
+typedef struct {
+ char *name;
+ Color col;
+} ColorList;
+
/* ffdraw.c */
void ffdraw_pixel (Canvas *, Color *, int, int);
void ffdraw_rectangle(Canvas *, Color *, int, int, int, int);
@@ -42,3 +47,7 @@ void ffdraw_print (Canvas *);
/* ffplot.c */
void ffdraw (char *, char *, Vlist *, int, double, double,
double, time_t, time_t, time_t);
+
+/* util.c */
+char *strsep (char **, const char *);
+
(DIR) diff --git a/util.c b/util.c
@@ -0,0 +1,21 @@
+#include <string.h>
+
+#include "ploot.h"
+
+char *
+strsep(char **strp, const char *sep)
+{
+ char *s, *prev;
+
+ if (*strp == NULL)
+ return NULL;
+ for (s = prev = *strp; strchr(sep, *s) == NULL; s++);
+ if (*s == '\0') {
+ *strp = NULL;
+ return prev;
+ }
+ *s = '\0';
+ *strp = s + 1;
+
+ return prev;
+}