move from CSV to TSV - ploot - simple plotting tools | |
git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65… | |
Log | |
Files | |
Refs | |
Tags | |
README | |
LICENSE | |
--- | |
commit 98d0cb5aa9d2adb27b2a992e90debce8b3843c5b | |
parent 8836c19534760f2ce037c39bde9dc5591011ed07 | |
Author: Josuah Demangeon <[email protected]> | |
Date: Sun, 27 Jun 2021 04:57:00 +0200 | |
move from CSV to TSV | |
Diffstat: | |
M Makefile | 6 +++--- | |
M README.md | 6 +++--- | |
D csv.c | 154 -----------------------------… | |
D csv.h | 22 ---------------------- | |
D example.csv | 114 -----------------------------… | |
M example.png | 0 | |
A example.tsv | 114 +++++++++++++++++++++++++++++… | |
M ploot-braille.c | 14 +++++++------- | |
D ploot-csv.5 | 77 -----------------------------… | |
M ploot-farbfeld.1 | 10 +++++----- | |
M ploot-farbfeld.c | 18 +++++++++--------- | |
M ploot-feed.1 | 6 +++--- | |
M ploot-feed.c | 10 +++++----- | |
A ploot-tsv.5 | 77 +++++++++++++++++++++++++++++… | |
A tsv.c | 154 +++++++++++++++++++++++++++++… | |
A tsv.h | 22 ++++++++++++++++++++++ | |
16 files changed, 402 insertions(+), 402 deletions(-) | |
--- | |
diff --git a/Makefile b/Makefile | |
@@ -7,9 +7,9 @@ LFLAGS = -static -lm | |
PREFIX = /usr/local | |
MANOREFIX = $(PREFIX)/share/man | |
-SRC = csv.c drawille.c font.c font13.c font8.c util.c | |
-INC = csv.h drawille.h font.h util.h | |
-BIN = ploot-feed ploot-braille ploot-text ploot-farbfeld | |
+SRC = tsv.c drawille.c font.c font13.c font8.c util.c | |
+INC = tsv.h drawille.h font.h util.h | |
+BIN = ploot-farbfeld ploot-feed ploot-braille ploot-text | |
OBJ = ${SRC:.c=.o} | |
all: ${BIN} | |
diff --git a/README.md b/README.md | |
@@ -3,7 +3,7 @@ ploot | |
ploot-ffplot | |
-------------- | |
-*ploot-ffplot* reads collectd-style comma separated values (CSV) and produces … | |
+*ploot-ffplot* reads collectd-style comma separated values (TSV) and produces … | |
in the ffplot [1] image format (pipe it to ff2png). It is an alternative to | |
RRDtool [2]. | |
@@ -16,12 +16,12 @@ name of the curves. | |
ploot-feed | |
---------- | |
-*ploot-feed* also reads collectd-style comma separated values (CSV) but produc… | |
+*ploot-feed* also reads collectd-style comma separated values (TSV) but produc… | |
a plain text continuous waterfall chart for live monitoring in the terminal. it | |
is an alternative to grafana [1]. | |
``` | |
-% plootxt 1 1 1 <load-average.csv | |
+% plootxt 1 1 1 <load-average.tsv | |
│shortterm │midterm │longterm … | |
17:34:00 _│⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│�… | |
18/05/01 │⣟⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│�… | |
diff --git a/csv.c b/csv.c | |
@@ -1,154 +0,0 @@ | |
-#include "csv.h" | |
-#include <errno.h> | |
-#include <assert.h> | |
-#include <string.h> | |
-#include <time.h> | |
-#include <stdlib.h> | |
-#include <limits.h> | |
-#include <time.h> | |
-#include "util.h" | |
- | |
-/* | |
- * Read CSV data onto a set of (struct csv) and some utilities to work on thes… | |
- */ | |
- | |
-int | |
-csv_min_max(struct csv *vl, int ncol, | |
- time_t *tmin, time_t *tmax, | |
- double *vmin, double *vmax) | |
-{ | |
- double *v; | |
- time_t *t; | |
- size_t n; | |
- | |
- *vmin = *vmax = 0; /* always show 0 on the scale */ | |
- *tmin = *tmax = *vl->t; | |
- | |
- for (; ncol > 0; ncol--, vl++) { | |
- for (t = vl->t, v = vl->v, n = vl->n; n > 0; t++, v++, n--) { | |
- if (*v < *vmin) *vmin = *v; | |
- if (*v > *vmax) *vmax = *v; | |
- if (*t < *tmin) *tmin = *t; | |
- if (*t > *tmax) *tmax = *t; | |
- } | |
- } | |
- if (*tmin == *tmax) | |
- return -1; | |
- return 0; | |
-} | |
- | |
-static void | |
-csv_add_time(struct csv *vl, time_t epoch) | |
-{ | |
- void *mem; | |
- | |
- if ((mem = realloc(vl->t, (vl->n + 1) * sizeof *vl->t)) == NULL) | |
- err(1, "realloc: %s", strerror(errno)); | |
- vl->t = mem; | |
- vl->t[vl->n] = epoch; | |
-} | |
- | |
-static void | |
-csv_add_val(struct csv *vl, double field) | |
-{ | |
- void *mem; | |
- | |
- if ((mem = realloc(vl->v, (vl->n + 1) * sizeof *vl->v)) == NULL) | |
- err(1, "", strerror(errno)); | |
- vl->v = mem; | |
- vl->v[vl->n] = field; | |
-} | |
- | |
-/* | |
- * Add to each column the value on the current row. The time_t | |
- * buffer is shared among all fields. | |
- */ | |
-static void | |
-csv_add_row(struct csv *vl, size_t ncol, char *line) | |
-{ | |
- char *field; | |
- time_t *tbuf; | |
- long l; | |
- double d; | |
- | |
- if ((field = strsep(&line, ",")) == NULL) | |
- err(1, "missing epoch at row %zu", vl->n); | |
- | |
- l = strtol(field, NULL, 10); | |
- if (errno) | |
- err(100, "parsing number '%s'", field); | |
- | |
- csv_add_time(vl, l); | |
- tbuf = vl[0].t; | |
- for (; (field = strsep(&line, ",")); ncol--, vl->n++, vl++) { | |
- if (ncol == 0) | |
- err(1, "too many fields at line %zu", vl->n); | |
- d = strtod(field, NULL); | |
- if (errno) | |
- err(100, "parsing double '%s'", field); | |
- csv_add_val(vl, d); | |
- vl->t = tbuf; | |
- } | |
- if (ncol > 0) | |
- err(1, "too few fields at line %zu", vl->n); | |
-} | |
- | |
-/* | |
- * < (ncol) > | |
- * label1,label2,label3 | |
- */ | |
-void | |
-csv_labels(FILE *fp, struct csv **vlp, size_t *ncol) | |
-{ | |
- char *field, *line, *cp; | |
- struct csv *vl, *col; | |
- size_t sz; | |
- ssize_t r; | |
- | |
- sz = 0, line = NULL; | |
- r = getline(&line, &sz, fp); | |
- if (ferror(fp)) | |
- err(111, "error while reading from file"); | |
- if (feof(fp)) | |
- err(100, "missing label line"); | |
- strchomp(line); | |
- | |
- cp = line; | |
- if (strcmp(strsep(&cp, ","), "epoch") != 0) | |
- err(1, "first label must be 'epoch'"); | |
- | |
- sz = 0, vl = NULL, *ncol = 0; | |
- while ((field = strsep(&cp, ","))) { | |
- if ((vl = realloc(vl, sz += sizeof *vl)) == NULL) | |
- err(1, "realloc: %s", strerror(errno)); | |
- col = vl + (*ncol)++; | |
- memset(col, 0, sizeof *vl); | |
- strlcpy(col->label, field, sizeof col->label); | |
- } | |
- free(line); | |
- *vlp = vl; | |
-} | |
- | |
-/* | |
- * < (ncol) > | |
- * val1a,val1b,val1c ^ | |
- * val2a,val2b,val2c | | |
- * val3a,val3b,val3c (vl->n) | |
- * val4a,val4b,val4c | | |
- * val5a,val5b,val5c v | |
- */ | |
-void | |
-csv_values(FILE *fp, struct csv *vl, size_t ncol) | |
-{ | |
- char *line; | |
- size_t sz; | |
- | |
- sz = 0, line = NULL; | |
- while (getline(&line, &sz, fp) > -1) | |
- csv_add_row(vl, ncol, line); | |
- if (vl->n == 0) | |
- err(1, "no value could be read"); | |
- if (vl->n == 1) | |
- err(1, "only one value could be read"); | |
- free(line); | |
-} | |
diff --git a/csv.h b/csv.h | |
@@ -1,22 +0,0 @@ | |
-#ifndef CSV_H | |
-#define CSV_H | |
- | |
-#include <stdio.h> | |
-#include <time.h> | |
- | |
-/* | |
- * List of values and timestamps. Both have their dedicated buffer | |
- * so that the timestamp buffer can be shared across csv objects. | |
- */ | |
-struct csv { | |
- time_t *t; /* array of timestamps */ | |
- double *v; /* array of values */ | |
- size_t n; /* number of values */ | |
- char label[64]; /* for the legend */ | |
-}; | |
- | |
-void csv_labels(FILE *, struct csv **, size_t *); | |
-void csv_values(FILE *, struct csv *, size_t); | |
-int csv_min_max(struct csv *, int, time_t *, time_t *, double *, double… | |
- | |
-#endif | |
diff --git a/example.csv b/example.csv | |
@@ -1,114 +0,0 @@ | |
-epoch,shortterm,midterm,longterm | |
-1525186140,0.023804,0.056885,0.049561 | |
-1525187040,0.035767,0.047485,0.043701 | |
-1525187940,0.057861,0.050293,0.042480 | |
-1525188840,0.098267,0.099609,0.072266 | |
-1525189740,0.083618,0.091187,0.079468 | |
-1525190640,0.055298,0.063843,0.063354 | |
-1525191540,0.046875,0.056152,0.058960 | |
-1525192440,0.091187,0.062622,0.058716 | |
-1525193340,0.067871,0.060303,0.059937 | |
-1525194240,0.085571,0.056763,0.052612 | |
-1525195140,0.020874,0.054810,0.055176 | |
-1525196040,0.125122,0.062500,0.048096 | |
-1525196940,0.040649,0.041870,0.040649 | |
-1525197840,0.032471,0.049194,0.042114 | |
-1525198740,0.073853,0.088501,0.071045 | |
-1525199640,0.119995,0.072998,0.064697 | |
-1525200540,0.030518,0.043335,0.046265 | |
-1525201440,0.037842,0.042969,0.040894 | |
-1525202340,0.054810,0.049927,0.042358 | |
-1525203240,0.120728,0.077271,0.053589 | |
-1525204140,0.068970,0.086670,0.074585 | |
-1525205040,0.071289,0.083496,0.079834 | |
-1525205940,0.046265,0.059326,0.068848 | |
-1525206840,0.064209,0.083374,0.069214 | |
-1525207740,0.055054,0.046753,0.051758 | |
-1525208640,0.170410,0.088867,0.064575 | |
-1525209540,0.067627,0.092407,0.092163 | |
-1525210440,0.078003,0.087646,0.083130 | |
-1525211340,0.032959,0.043457,0.059204 | |
-1525212240,0.036377,0.054810,0.057861 | |
-1525213140,0.054565,0.078369,0.071655 | |
-1525214040,0.026611,0.041138,0.051514 | |
-1525214940,0.065186,0.067505,0.061768 | |
-1525215840,0.071411,0.055298,0.055176 | |
-1525229081,0.041260,0.045044,0.045654 | |
-1525229081,0.041260,0.045044,0.045654 | |
-1525229981,0.059692,0.102051,0.105835 | |
-1525230881,0.077148,0.067017,0.073730 | |
-1525231781,0.080200,0.074341,0.064575 | |
-1525232681,0.122437,0.099487,0.075806 | |
-1525233581,0.085815,0.076050,0.073486 | |
-1525234481,0.074585,0.064087,0.062012 | |
-1525235381,0.024902,0.047241,0.053345 | |
-1525236281,0.107910,0.081543,0.065918 | |
-1525237181,0.038696,0.075684,0.080688 | |
-1525238081,0.204834,0.181152,0.130737 | |
-1525238981,0.231445,0.158325,0.137695 | |
-1525239881,0.067505,0.089355,0.109497 | |
-1525240781,0.047852,0.088745,0.107910 | |
-1525241681,0.094360,0.085693,0.083618 | |
-1525242581,0.047363,0.043335,0.052856 | |
-1525243481,0.047363,0.031982,0.036621 | |
-1525244381,0.055054,0.042236,0.040039 | |
-1525245281,0.034668,0.041626,0.040039 | |
-1525246181,0.088867,0.065918,0.048706 | |
-1525247081,0.049072,0.051880,0.042236 | |
-1525247981,0.045166,0.048828,0.041382 | |
-1525248881,0.067261,0.061768,0.047852 | |
-1525249781,0.039917,0.056519,0.045654 | |
-1525250681,0.017822,0.030273,0.033081 | |
-1525251581,0.034668,0.033691,0.034546 | |
-1525252481,0.053223,0.051880,0.045166 | |
-1525253381,0.028687,0.050049,0.050659 | |
-1525254281,0.021118,0.042358,0.040649 | |
-1525255181,0.059204,0.047974,0.041870 | |
-1525256081,0.206421,0.141968,0.086670 | |
-1525256981,0.105713,0.087158,0.073486 | |
-1525257881,0.048950,0.060913,0.068359 | |
-1525258781,0.024414,0.036621,0.046753 | |
-1525259681,0.245239,0.109619,0.071045 | |
-1525260581,0.042236,0.063965,0.069092 | |
-1525261481,0.016724,0.054077,0.059692 | |
-1525262381,0.018433,0.078003,0.076660 | |
-1525263281,0.042480,0.057617,0.061890 | |
-1525264181,0.040161,0.041138,0.044189 | |
-1525265081,0.059082,0.090698,0.064575 | |
-1525265981,0.129272,0.080811,0.073486 | |
-1525266881,0.228516,0.164551,0.112915 | |
-1525267781,0.083130,0.058594,0.067627 | |
-1525268681,0.062378,0.063965,0.061523 | |
-1525269581,0.066895,0.069702,0.062500 | |
-1525270481,0.061768,0.080322,0.065674 | |
-1525271381,0.123657,0.089478,0.072021 | |
-1525272281,0.056885,0.045532,0.051514 | |
-1525273181,0.108887,0.056519,0.046387 | |
-1525274081,0.072266,0.119629,0.080078 | |
-1525274981,0.033447,0.058350,0.070190 | |
-1525275881,0.028198,0.050781,0.058105 | |
-1525276781,0.067261,0.059937,0.057495 | |
-1525277681,0.024780,0.028809,0.038452 | |
-1525278581,0.053955,0.049561,0.041748 | |
-1525279481,0.086304,0.065308,0.048096 | |
-1525281698,0.019165,0.047485,0.041870 | |
-1525281698,0.019165,0.047485,0.041870 | |
-1525282598,0.039551,0.034302,0.038086 | |
-1525283498,0.017700,0.022827,0.026367 | |
-1525284398,0.023560,0.034790,0.024292 | |
-1525285298,0.093506,0.078857,0.053101 | |
-1525286198,0.051025,0.066162,0.069458 | |
-1525287098,0.054077,0.057861,0.059082 | |
-1525287998,0.080200,0.071655,0.062744 | |
-1525288898,0.478638,0.375122,0.247192 | |
-1525289798,0.393066,0.390991,0.347046 | |
-1525290698,0.368164,0.383545,0.365723 | |
-1525291598,0.459229,0.463867,0.432129 | |
-1525292498,0.286865,0.354980,0.381958 | |
-1525293398,0.180786,0.178833,0.232910 | |
-1525294298,0.278198,0.260864,0.242920 | |
-1525295198,0.192505,0.183716,0.200806 | |
-1525296098,0.109375,0.185669,0.207153 | |
-1525296098,0.109375,0.185669,0.207153 | |
-1525296998,0.137085,0.126221,0.138184 | |
-1525297898,0.077881,0.092529,0.109619 | |
diff --git a/example.png b/example.png | |
Binary files differ. | |
diff --git a/example.tsv b/example.tsv | |
@@ -0,0 +1,114 @@ | |
+epoch shortterm midterm longterm | |
+1525186140 0.023804 0.056885 0.049561 | |
+1525187040 0.035767 0.047485 0.043701 | |
+1525187940 0.057861 0.050293 0.042480 | |
+1525188840 0.098267 0.099609 0.072266 | |
+1525189740 0.083618 0.091187 0.079468 | |
+1525190640 0.055298 0.063843 0.063354 | |
+1525191540 0.046875 0.056152 0.058960 | |
+1525192440 0.091187 0.062622 0.058716 | |
+1525193340 0.067871 0.060303 0.059937 | |
+1525194240 0.085571 0.056763 0.052612 | |
+1525195140 0.020874 0.054810 0.055176 | |
+1525196040 0.125122 0.062500 0.048096 | |
+1525196940 0.040649 0.041870 0.040649 | |
+1525197840 0.032471 0.049194 0.042114 | |
+1525198740 0.073853 0.088501 0.071045 | |
+1525199640 0.119995 0.072998 0.064697 | |
+1525200540 0.030518 0.043335 0.046265 | |
+1525201440 0.037842 0.042969 0.040894 | |
+1525202340 0.054810 0.049927 0.042358 | |
+1525203240 0.120728 0.077271 0.053589 | |
+1525204140 0.068970 0.086670 0.074585 | |
+1525205040 0.071289 0.083496 0.079834 | |
+1525205940 0.046265 0.059326 0.068848 | |
+1525206840 0.064209 0.083374 0.069214 | |
+1525207740 0.055054 0.046753 0.051758 | |
+1525208640 0.170410 0.088867 0.064575 | |
+1525209540 0.067627 0.092407 0.092163 | |
+1525210440 0.078003 0.087646 0.083130 | |
+1525211340 0.032959 0.043457 0.059204 | |
+1525212240 0.036377 0.054810 0.057861 | |
+1525213140 0.054565 0.078369 0.071655 | |
+1525214040 0.026611 0.041138 0.051514 | |
+1525214940 0.065186 0.067505 0.061768 | |
+1525215840 0.071411 0.055298 0.055176 | |
+1525229081 0.041260 0.045044 0.045654 | |
+1525229081 0.041260 0.045044 0.045654 | |
+1525229981 0.059692 0.102051 0.105835 | |
+1525230881 0.077148 0.067017 0.073730 | |
+1525231781 0.080200 0.074341 0.064575 | |
+1525232681 0.122437 0.099487 0.075806 | |
+1525233581 0.085815 0.076050 0.073486 | |
+1525234481 0.074585 0.064087 0.062012 | |
+1525235381 0.024902 0.047241 0.053345 | |
+1525236281 0.107910 0.081543 0.065918 | |
+1525237181 0.038696 0.075684 0.080688 | |
+1525238081 0.204834 0.181152 0.130737 | |
+1525238981 0.231445 0.158325 0.137695 | |
+1525239881 0.067505 0.089355 0.109497 | |
+1525240781 0.047852 0.088745 0.107910 | |
+1525241681 0.094360 0.085693 0.083618 | |
+1525242581 0.047363 0.043335 0.052856 | |
+1525243481 0.047363 0.031982 0.036621 | |
+1525244381 0.055054 0.042236 0.040039 | |
+1525245281 0.034668 0.041626 0.040039 | |
+1525246181 0.088867 0.065918 0.048706 | |
+1525247081 0.049072 0.051880 0.042236 | |
+1525247981 0.045166 0.048828 0.041382 | |
+1525248881 0.067261 0.061768 0.047852 | |
+1525249781 0.039917 0.056519 0.045654 | |
+1525250681 0.017822 0.030273 0.033081 | |
+1525251581 0.034668 0.033691 0.034546 | |
+1525252481 0.053223 0.051880 0.045166 | |
+1525253381 0.028687 0.050049 0.050659 | |
+1525254281 0.021118 0.042358 0.040649 | |
+1525255181 0.059204 0.047974 0.041870 | |
+1525256081 0.206421 0.141968 0.086670 | |
+1525256981 0.105713 0.087158 0.073486 | |
+1525257881 0.048950 0.060913 0.068359 | |
+1525258781 0.024414 0.036621 0.046753 | |
+1525259681 0.245239 0.109619 0.071045 | |
+1525260581 0.042236 0.063965 0.069092 | |
+1525261481 0.016724 0.054077 0.059692 | |
+1525262381 0.018433 0.078003 0.076660 | |
+1525263281 0.042480 0.057617 0.061890 | |
+1525264181 0.040161 0.041138 0.044189 | |
+1525265081 0.059082 0.090698 0.064575 | |
+1525265981 0.129272 0.080811 0.073486 | |
+1525266881 0.228516 0.164551 0.112915 | |
+1525267781 0.083130 0.058594 0.067627 | |
+1525268681 0.062378 0.063965 0.061523 | |
+1525269581 0.066895 0.069702 0.062500 | |
+1525270481 0.061768 0.080322 0.065674 | |
+1525271381 0.123657 0.089478 0.072021 | |
+1525272281 0.056885 0.045532 0.051514 | |
+1525273181 0.108887 0.056519 0.046387 | |
+1525274081 0.072266 0.119629 0.080078 | |
+1525274981 0.033447 0.058350 0.070190 | |
+1525275881 0.028198 0.050781 0.058105 | |
+1525276781 0.067261 0.059937 0.057495 | |
+1525277681 0.024780 0.028809 0.038452 | |
+1525278581 0.053955 0.049561 0.041748 | |
+1525279481 0.086304 0.065308 0.048096 | |
+1525281698 0.019165 0.047485 0.041870 | |
+1525281698 0.019165 0.047485 0.041870 | |
+1525282598 0.039551 0.034302 0.038086 | |
+1525283498 0.017700 0.022827 0.026367 | |
+1525284398 0.023560 0.034790 0.024292 | |
+1525285298 0.093506 0.078857 0.053101 | |
+1525286198 0.051025 0.066162 0.069458 | |
+1525287098 0.054077 0.057861 0.059082 | |
+1525287998 0.080200 0.071655 0.062744 | |
+1525288898 0.478638 0.375122 0.247192 | |
+1525289798 0.393066 0.390991 0.347046 | |
+1525290698 0.368164 0.383545 0.365723 | |
+1525291598 0.459229 0.463867 0.432129 | |
+1525292498 0.286865 0.354980 0.381958 | |
+1525293398 0.180786 0.178833 0.232910 | |
+1525294298 0.278198 0.260864 0.242920 | |
+1525295198 0.192505 0.183716 0.200806 | |
+1525296098 0.109375 0.185669 0.207153 | |
+1525296098 0.109375 0.185669 0.207153 | |
+1525296998 0.137085 0.126221 0.138184 | |
+1525297898 0.077881 0.092529 0.109619 | |
diff --git a/ploot-braille.c b/ploot-braille.c | |
@@ -9,7 +9,7 @@ | |
#include <unistd.h> | |
#include "drawille.h" | |
#include "util.h" | |
-#include "csv.h" | |
+#include "tsv.h" | |
#ifndef __OpenBSD__ | |
#define pledge(...) 0 | |
@@ -20,7 +20,7 @@ | |
* a vertical and horizontal axis. | |
*/ | |
static int | |
-braille_histogram(struct csv *vl, struct drawille *drw, | |
+braille_histogram(struct tsv *vl, struct drawille *drw, | |
time_t tmin, time_t tmax, double vmin, double vmax) | |
{ | |
int x, xprev, y, yprev, zero; | |
@@ -104,7 +104,7 @@ braille_render(struct drawille *drw, FILE *fp, double min, … | |
} | |
static void | |
-plot(struct csv *vl, size_t ncol, int rows, int cols, FILE *fp) | |
+plot(struct tsv *vl, size_t ncol, int rows, int cols, FILE *fp) | |
{ | |
double vmin, vmax, vstep; | |
time_t tmin, tmax, tstep; | |
@@ -112,7 +112,7 @@ plot(struct csv *vl, size_t ncol, int rows, int cols, FILE … | |
rows = MAX(rows, 2); /* readable */ | |
- if (csv_min_max(vl, ncol, &tmin, &tmax, &vmin, &vmax) < 0) | |
+ if (tsv_min_max(vl, ncol, &tmin, &tmax, &vmin, &vmax) < 0) | |
err(1, "invalid scale: tmin=%lld tmax=%lld vmin=%fd vmax=%fd", | |
(long long)tmin, (long long)tmax, vmin, vmax); | |
@@ -145,7 +145,7 @@ usage(void) | |
int | |
main(int argc, char **argv) | |
{ | |
- struct csv *vl; | |
+ struct tsv *vl; | |
size_t ncol; | |
int c, rows, cols; | |
@@ -181,8 +181,8 @@ main(int argc, char **argv) | |
if (argc > 0) | |
usage(); | |
- csv_labels(stdin, &vl, &ncol); | |
- csv_values(stdin, vl, ncol); | |
+ tsv_labels(stdin, &vl, &ncol); | |
+ tsv_values(stdin, vl, ncol); | |
plot(vl, ncol, rows, cols, stdout); | |
diff --git a/ploot-csv.5 b/ploot-csv.5 | |
@@ -1,77 +0,0 @@ | |
-.Dd $Mdocdate: February 01 2020$ | |
-.Dt PLOOT-CSV 5 | |
-.Os | |
-. | |
-. | |
-.Sh NAME | |
-. | |
-.Nm ploot-csv | |
-.Nd input format used by the ploot set of programs | |
-. | |
-. | |
-.Sh SYNOPSIS | |
-. | |
-.Bd -literal | |
-epoch,column-name-1,column-name-2 | |
-timestamp,value1,value2 | |
-timestamp,value1,value2 | |
-\&... | |
-.Ed | |
-. | |
-. | |
-.Sh DESCRIPTION | |
-. | |
-This is the simple coma-separated format used by the ploot-* programs. | |
-. | |
-. | |
-.Sh INPUT FORMAT | |
-. | |
-.Nm | |
-has a first header line, then zero or more data lines, both | |
-coma-separated list of values. | |
-. | |
-. | |
-.Ss Header line | |
-. | |
-The input must contain a first header line with the label of each column in or… | |
-The first column is always | |
-.Dq epoch . | |
-Then there are the actual column names. | |
-. | |
-.Bd -literal -offset indent | |
-epoch,free_memory,process_count | |
-.Ed | |
-. | |
-. | |
-.Ss Data lines | |
-. | |
-The following lines are the data. | |
-The first column is always an unix timestamp as in | |
-.Vt time_t . | |
-The remaining columns are values parsed as floating point numbers by | |
-.Xr strtod 3 : | |
-. | |
-.Bd -literal -offset indent | |
-1533752053,16.3,45 | |
-1533752054,18.7,42 | |
-1533752055,40.1,39 | |
-1533752056,40.1,39 | |
-.Ed | |
-. | |
-. | |
-.Sh SEE ALSO | |
-. | |
-.Xr ploot-feed 1 , | |
-.Xr ploot-farbfeld 1 | |
-. | |
-.Sh HISTORY | |
-. | |
-.Nm | |
-was defined at | |
-.Lk gopher://bitreich.org/1/scm/ploot/ "Bitreich" | |
-. | |
-. | |
-.Sh AUTHORS | |
-. | |
-.An Josuah Demangeon | |
-.Aq Mt [email protected] | |
diff --git a/ploot-farbfeld.1 b/ploot-farbfeld.1 | |
@@ -6,7 +6,7 @@ | |
.Sh NAME | |
. | |
.Nm ploot-ffplot | |
-.Nd produce a ffplot image of csv input | |
+.Nd produce a ffplot image of tsv input | |
. | |
. | |
.Sh SYNOPSIS | |
@@ -20,7 +20,7 @@ | |
. | |
The | |
.Nm | |
-utility plots an image in the ffplot format out of csv values coming from stdi… | |
+utility plots an image in the ffplot format out of tsv values coming from stdi… | |
. | |
.Bl -tag -width 6n | |
. | |
@@ -29,7 +29,7 @@ Set the title of the plot printed at the top left corner. | |
. | |
.It Ar colors | |
List of argument that specify the color for each column. | |
-If the input csv have 5 columns in addition of the timestamp, there must | |
+If the input tsv have 5 columns in addition of the timestamp, there must | |
be 5 maxval arguments. | |
color_ts available are red, orange, yellow, green, cyan and blue. | |
. | |
@@ -37,7 +37,7 @@ color_ts available are red, orange, yellow, green, cyan and b… | |
. | |
.Pp | |
The input format is documented in the | |
-.Xr ploot-csv 7 | |
+.Xr ploot-tsv 7 | |
manual page. | |
. | |
. | |
@@ -62,7 +62,7 @@ $ ploot-ffplot -t demo -u MB red yellow <sample.txt | |
.Sh SEE ALSO | |
. | |
.Xr ploot-ffplot 1 , | |
-.Xr ploot-csv 7 | |
+.Xr ploot-tsv 7 | |
. | |
.Pp | |
The | |
diff --git a/ploot-farbfeld.c b/ploot-farbfeld.c | |
@@ -11,7 +11,7 @@ | |
#include <string.h> | |
#include <time.h> | |
#include <unistd.h> | |
-#include "csv.h" | |
+#include "tsv.h" | |
#include "font.h" | |
#include "util.h" | |
@@ -287,7 +287,7 @@ ffplot_title(struct ffplot *plot, struct ffcolor *ct, char … | |
} | |
static void | |
-ffplot_plot(struct ffplot *plot, struct csv *vl, struct ffcolor *color, | |
+ffplot_plot(struct ffplot *plot, struct tsv *vl, struct ffcolor *color, | |
double vmin, double vmax, | |
time_t tmin, time_t tmax) | |
{ | |
@@ -310,7 +310,7 @@ ffplot_plot(struct ffplot *plot, struct csv *vl, struct ffc… | |
} | |
static void | |
-ffplot_values(struct ffplot *plot, struct csv *vl, struct ffcolor **cl, size_t… | |
+ffplot_values(struct ffplot *plot, struct tsv *vl, struct ffcolor **cl, size_t… | |
time_t tmin, time_t tmax, | |
double vmin, double vmax) | |
{ | |
@@ -319,7 +319,7 @@ ffplot_values(struct ffplot *plot, struct csv *vl, struct f… | |
} | |
static void | |
-ffplot_legend(struct ffplot *plot, struct ffcolor *fg, struct csv *vl, struct … | |
+ffplot_legend(struct ffplot *plot, struct ffcolor *fg, struct tsv *vl, struct … | |
{ | |
size_t x, y; | |
@@ -342,7 +342,7 @@ ffplot_legend(struct ffplot *plot, struct ffcolor *fg, stru… | |
* x label here | |
*/ | |
static void | |
-plot(struct csv *vl, struct ffcolor **cl, size_t ncol, char *name) | |
+plot(struct tsv *vl, struct ffcolor **cl, size_t ncol, char *name) | |
{ | |
struct ffplot plot = { IMAGE_W, IMAGE_H, 0, 0, NULL }; | |
struct ffcolor plot_bg = { 0x2222, 0x2222, 0x2222, 0xffff }; | |
@@ -353,7 +353,7 @@ plot(struct csv *vl, struct ffcolor **cl, size_t ncol, char… | |
double vmin, vmax, vstep; | |
time_t tmin, tmax, tstep; | |
- csv_min_max(vl, ncol, &tmin, &tmax, &vmin, &vmax); | |
+ tsv_min_max(vl, ncol, &tmin, &tmax, &vmin, &vmax); | |
tstep = scale_time_t(tmin, tmax, 7); | |
vstep = scale_double(vmin, vmax, 7); | |
@@ -424,7 +424,7 @@ usage(void) | |
int | |
main(int argc, char **argv) | |
{ | |
- struct csv *vl; | |
+ struct tsv *vl; | |
struct ffcolor **cl; | |
size_t ncol; | |
int c; | |
@@ -451,12 +451,12 @@ main(int argc, char **argv) | |
if ((cl = calloc(argc, sizeof *cl)) == NULL) | |
err(1, "calloc: %s", strerror(errno)); | |
- csv_labels(stdin, &vl, &ncol); | |
+ tsv_labels(stdin, &vl, &ncol); | |
if (ncol > (size_t)argc) | |
err(1, "too many columns or not enough arguments"); | |
else if (ncol < (size_t)argc) | |
err(1, "too many arguments or not enough columns"); | |
- csv_values(stdin, vl, ncol); | |
+ tsv_values(stdin, vl, ncol); | |
argv_to_color(cl, argv); | |
plot(vl, cl, argc, flag_title); | |
diff --git a/ploot-feed.1 b/ploot-feed.1 | |
@@ -20,7 +20,7 @@ | |
. | |
The | |
.Nm | |
-utility plots a text chart of csv values coming from stdin in real time. | |
+utility plots a text chart of tsv values coming from stdin in real time. | |
. | |
.Bl -tag -width 6n | |
. | |
@@ -29,14 +29,14 @@ is the width of the plot in characters. | |
. | |
.It Ar maxval | |
is a list of argument that specify the maximum value for each column. | |
-If the input csv have 5 columns in addition of the timestamp, there must | |
+If the input tsv have 5 columns in addition of the timestamp, there must | |
be 5 maxval arguments. | |
. | |
.El | |
. | |
.Pp | |
The input format is documented in the | |
-.Xr ploot-csv 7 | |
+.Xr ploot-tsv 7 | |
manual page. | |
. | |
. | |
diff --git a/ploot-feed.c b/ploot-feed.c | |
@@ -59,14 +59,14 @@ plot_row(long *out, char *line, double *max, int nrow, int … | |
int n; | |
char *tok; | |
- tok = strsep(&line, ","); | |
+ tok = strsep(&line, "\t"); | |
if (!tok) | |
err(100, "*** missing epoch value"); | |
epoch = strtol(tok, NULL, 10); | |
if (errno) | |
warn("*** parsing epoch '%s'", tok); | |
- for (n = 0; (tok = strsep(&line, ",")) != NULL; n++) { | |
+ for (n = 0; (tok = strsep(&line, "\t")) != NULL; n++) { | |
if (n >= ncol) | |
err(100, "too many values"); | |
val = atof(tok); | |
@@ -186,10 +186,10 @@ read_labels(char **labv) | |
strchomp(line); | |
cp = line; | |
- if (strcmp(strsep(&cp, ","), "epoch") != 0) | |
+ if (strcmp(strsep(&cp, "\t"), "epoch") != 0) | |
err(100, "first label must be 'epoch'"); | |
- for (ncol = 0; (tok = strsep(&cp, ",")) != NULL; ncol++, labv++) | |
+ for (ncol = 0; (tok = strsep(&cp, "\t")) != NULL; ncol++, labv++) | |
*labv = tok; | |
*labv = NULL; | |
@@ -212,7 +212,7 @@ fmt_labels(char out[4069], int ncol, char *labels[4069 / 2]) | |
static void | |
usage(void) | |
{ | |
- fprintf(stderr, "usage: %s [-w width] maxval... <csv\n", arg0); | |
+ fprintf(stderr, "usage: %s [-w width] maxval... <tsv\n", arg0); | |
exit(1); | |
} | |
diff --git a/ploot-tsv.5 b/ploot-tsv.5 | |
@@ -0,0 +1,77 @@ | |
+.Dd $Mdocdate: February 01 2020$ | |
+.Dt PLOOT-TSV 5 | |
+.Os | |
+. | |
+. | |
+.Sh NAME | |
+. | |
+.Nm ploot-tsv | |
+.Nd input format used by the ploot set of programs | |
+. | |
+. | |
+.Sh SYNOPSIS | |
+. | |
+.Bd -literal | |
+epoch,column-name-1,column-name-2 | |
+timestamp,value1,value2 | |
+timestamp,value1,value2 | |
+\&... | |
+.Ed | |
+. | |
+. | |
+.Sh DESCRIPTION | |
+. | |
+This is the simple coma-separated format used by the ploot-* programs. | |
+. | |
+. | |
+.Sh INPUT FORMAT | |
+. | |
+.Nm | |
+has a first header line, then zero or more data lines, both | |
+coma-separated list of values. | |
+. | |
+. | |
+.Ss Header line | |
+. | |
+The input must contain a first header line with the label of each column in or… | |
+The first column is always | |
+.Dq epoch . | |
+Then there are the actual column names. | |
+. | |
+.Bd -literal -offset indent | |
+epoch,free_memory,process_count | |
+.Ed | |
+. | |
+. | |
+.Ss Data lines | |
+. | |
+The following lines are the data. | |
+The first column is always an unix timestamp as in | |
+.Vt time_t . | |
+The remaining columns are values parsed as floating point numbers by | |
+.Xr strtod 3 : | |
+. | |
+.Bd -literal -offset indent | |
+1533752053,16.3,45 | |
+1533752054,18.7,42 | |
+1533752055,40.1,39 | |
+1533752056,40.1,39 | |
+.Ed | |
+. | |
+. | |
+.Sh SEE ALSO | |
+. | |
+.Xr ploot-feed 1 , | |
+.Xr ploot-farbfeld 1 | |
+. | |
+.Sh HISTORY | |
+. | |
+.Nm | |
+was defined at | |
+.Lk gopher://bitreich.org/1/scm/ploot/ "Bitreich" | |
+. | |
+. | |
+.Sh AUTHORS | |
+. | |
+.An Josuah Demangeon | |
+.Aq Mt [email protected] | |
diff --git a/tsv.c b/tsv.c | |
@@ -0,0 +1,154 @@ | |
+#include "tsv.h" | |
+#include <errno.h> | |
+#include <assert.h> | |
+#include <string.h> | |
+#include <time.h> | |
+#include <stdlib.h> | |
+#include <limits.h> | |
+#include <time.h> | |
+#include "util.h" | |
+ | |
+/* | |
+ * Read TSV data onto a set of (struct tsv) and some utilities to work on thes… | |
+ */ | |
+ | |
+int | |
+tsv_min_max(struct tsv *vl, int ncol, | |
+ time_t *tmin, time_t *tmax, | |
+ double *vmin, double *vmax) | |
+{ | |
+ double *v; | |
+ time_t *t; | |
+ size_t n; | |
+ | |
+ *vmin = *vmax = 0; /* always show 0 on the scale */ | |
+ *tmin = *tmax = *vl->t; | |
+ | |
+ for (; ncol > 0; ncol--, vl++) { | |
+ for (t = vl->t, v = vl->v, n = vl->n; n > 0; t++, v++, n--) { | |
+ if (*v < *vmin) *vmin = *v; | |
+ if (*v > *vmax) *vmax = *v; | |
+ if (*t < *tmin) *tmin = *t; | |
+ if (*t > *tmax) *tmax = *t; | |
+ } | |
+ } | |
+ if (*tmin == *tmax) | |
+ return -1; | |
+ return 0; | |
+} | |
+ | |
+static void | |
+tsv_add_time(struct tsv *vl, time_t epoch) | |
+{ | |
+ void *mem; | |
+ | |
+ if ((mem = realloc(vl->t, (vl->n + 1) * sizeof *vl->t)) == NULL) | |
+ err(1, "realloc: %s", strerror(errno)); | |
+ vl->t = mem; | |
+ vl->t[vl->n] = epoch; | |
+} | |
+ | |
+static void | |
+tsv_add_val(struct tsv *vl, double field) | |
+{ | |
+ void *mem; | |
+ | |
+ if ((mem = realloc(vl->v, (vl->n + 1) * sizeof *vl->v)) == NULL) | |
+ err(1, "", strerror(errno)); | |
+ vl->v = mem; | |
+ vl->v[vl->n] = field; | |
+} | |
+ | |
+/* | |
+ * Add to each column the value on the current row. The time_t | |
+ * buffer is shared among all fields. | |
+ */ | |
+static void | |
+tsv_add_row(struct tsv *vl, size_t ncol, char *line) | |
+{ | |
+ char *field; | |
+ time_t *tbuf; | |
+ long l; | |
+ double d; | |
+ | |
+ if ((field = strsep(&line, "\t")) == NULL) | |
+ err(1, "missing epoch at row %zu", vl->n); | |
+ | |
+ l = strtol(field, NULL, 10); | |
+ if (errno) | |
+ err(100, "parsing number '%s'", field); | |
+ | |
+ tsv_add_time(vl, l); | |
+ tbuf = vl[0].t; | |
+ for (; (field = strsep(&line, "\t")); ncol--, vl->n++, vl++) { | |
+ if (ncol == 0) | |
+ err(1, "too many fields at line %zu", vl->n); | |
+ d = strtod(field, NULL); | |
+ if (errno) | |
+ err(100, "parsing double '%s'", field); | |
+ tsv_add_val(vl, d); | |
+ vl->t = tbuf; | |
+ } | |
+ if (ncol > 0) | |
+ err(1, "too few fields at line %zu", vl->n); | |
+} | |
+ | |
+/* | |
+ * < (ncol) > | |
+ * label1,label2,label3 | |
+ */ | |
+void | |
+tsv_labels(FILE *fp, struct tsv **vlp, size_t *ncol) | |
+{ | |
+ char *field, *line, *cp; | |
+ struct tsv *vl, *col; | |
+ size_t sz; | |
+ ssize_t r; | |
+ | |
+ sz = 0, line = NULL; | |
+ r = getline(&line, &sz, fp); | |
+ if (ferror(fp)) | |
+ err(111, "error while reading from file"); | |
+ if (feof(fp)) | |
+ err(100, "missing label line"); | |
+ strchomp(line); | |
+ | |
+ cp = line; | |
+ if (strcmp(strsep(&cp, "\t"), "epoch") != 0) | |
+ err(1, "first label must be 'epoch'"); | |
+ | |
+ sz = 0, vl = NULL, *ncol = 0; | |
+ while ((field = strsep(&cp, "\t"))) { | |
+ if ((vl = realloc(vl, sz += sizeof *vl)) == NULL) | |
+ err(1, "realloc: %s", strerror(errno)); | |
+ col = vl + (*ncol)++; | |
+ memset(col, 0, sizeof *vl); | |
+ strlcpy(col->label, field, sizeof col->label); | |
+ } | |
+ free(line); | |
+ *vlp = vl; | |
+} | |
+ | |
+/* | |
+ * < (ncol) > | |
+ * val1a,val1b,val1c ^ | |
+ * val2a,val2b,val2c | | |
+ * val3a,val3b,val3c (vl->n) | |
+ * val4a,val4b,val4c | | |
+ * val5a,val5b,val5c v | |
+ */ | |
+void | |
+tsv_values(FILE *fp, struct tsv *vl, size_t ncol) | |
+{ | |
+ char *line; | |
+ size_t sz; | |
+ | |
+ sz = 0, line = NULL; | |
+ while (getline(&line, &sz, fp) > -1) | |
+ tsv_add_row(vl, ncol, line); | |
+ if (vl->n == 0) | |
+ err(1, "no value could be read"); | |
+ if (vl->n == 1) | |
+ err(1, "only one value could be read"); | |
+ free(line); | |
+} | |
diff --git a/tsv.h b/tsv.h | |
@@ -0,0 +1,22 @@ | |
+#ifndef TSV_H | |
+#define TSV_H | |
+ | |
+#include <stdio.h> | |
+#include <time.h> | |
+ | |
+/* | |
+ * List of values and timestamps. Both have their dedicated buffer | |
+ * so that the timestamp buffer can be shared across tsv objects. | |
+ */ | |
+struct tsv { | |
+ time_t *t; /* array of timestamps */ | |
+ double *v; /* array of values */ | |
+ size_t n; /* number of values */ | |
+ char label[64]; /* for the legend */ | |
+}; | |
+ | |
+void tsv_labels(FILE *, struct tsv **, size_t *); | |
+void tsv_values(FILE *, struct tsv *, size_t); | |
+int tsv_min_max(struct tsv *, int, time_t *, time_t *, double *, double… | |
+ | |
+#endif |