URI: 
       tcsv.c - ploot - simple plotting tools
  HTML git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ploot
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
       ---
       tcsv.c (2343B)
       ---
            1 #include "csv.h"
            2 
            3 #include <errno.h>
            4 #include <assert.h>
            5 #include <string.h>
            6 #include <time.h>
            7 #include <stdlib.h>
            8 #include <limits.h>
            9 #include <time.h>
           10 
           11 #include "log.h"
           12 #include "util.h"
           13 
           14 /*
           15  * Read CSV data onto a set of (struct csv).
           16  */
           17 
           18 static void
           19 csv_addtime(struct csv *vl, time_t epoch)
           20 {
           21         assert(vl->t = realloc(vl->t, (vl->n + 1) * sizeof(*vl->t)));
           22         vl->t[vl->n] = epoch;
           23 }
           24 
           25 static void
           26 csv_addval(struct csv *vl, double field)
           27 {
           28         assert(vl->v = realloc(vl->v, (vl->n + 1) * sizeof(*vl->v)));
           29         vl->v[vl->n] = field;
           30 }
           31 
           32 /*
           33  * Add to each column the value on the current row.  The time_t
           34  * buffer is shared among all fields.
           35  */
           36 void
           37 csv_addrow(struct csv *vl, size_t ncol, char *line)
           38 {
           39         char *field;
           40         time_t *tbuf;
           41         long l;
           42         double d;
           43 
           44         field = strsep(&line, ",");
           45         if (!field)
           46                 die(1, "missing epoch at row %zu", vl->n);
           47 
           48         l = strtol(field, NULL, 10);
           49         if (errno)
           50                 die(100, "parsing number '%s'", field);
           51         csv_addtime(vl, l);
           52         tbuf = vl[0].t;
           53         for (; (field = strsep(&line, ",")); ncol--, vl->n++, vl++) {
           54                 if (ncol == 0)
           55                         die(1, "too many fields at line %zu", vl->n);
           56                 d = strtod(field, NULL);
           57                 if (errno)
           58                         die(100, "parsing double '%s'", field);
           59                 csv_addval(vl, d);
           60                 vl->t = tbuf;
           61         }
           62         if (ncol > 0)
           63                 die(1, "too few fields at line %zu", vl->n);
           64 }
           65  
           66 /*
           67  *       < *ncol >
           68  * epoch,label1,label2,label3
           69  */
           70 void
           71 csv_labels(FILE *fp, struct csv **vl, size_t *ncol)
           72 {
           73         char *field, *line, *cp;
           74         struct csv *col;
           75         size_t sz;
           76         ssize_t r;
           77 
           78         sz = 0, line = NULL;
           79         r = getline(&line, &sz, fp);
           80         if (ferror(fp))
           81                 die(111, "error while reading from file");
           82         if (r == -1)
           83                 die(100, "missing label line");
           84         strchomp(line);
           85 
           86         cp = line;
           87         if (strcmp(strsep(&cp, ","), "epoch") != 0)
           88                 die(1, "first label must be 'epoch'");
           89 
           90         *vl = NULL;
           91         *ncol = 0;
           92         while ((field = strsep(&cp, ","))) {
           93                 assert(*vl = realloc(*vl, sz += sizeof(**vl)));
           94                 col = (*vl) + (*ncol)++;
           95                 strlcpy(col->label, field, sizeof(col->label));
           96         }
           97 
           98         free(line);
           99 }
          100 
          101 /*
          102  *       < ncol >
          103  * epoch,a1,b1,c1  ^
          104  * epoch,a2,b2,c2 vl->n
          105  * epoch,a3,b3,c3  v
          106  */
          107 void
          108 csv_values(FILE *fp, struct csv *vl, size_t ncol)
          109 {
          110         char *line;
          111         size_t sz;
          112 
          113         sz = 0, line = NULL;
          114         while (getline(&line, &sz, fp) > -1)
          115                 csv_addrow(vl, ncol, line);
          116         if (vl->n == 0)
          117                 die(1, "no value could be read");
          118         if (vl->n == 1)
          119                 die(1, "only one value could be read");
          120 
          121         free(line);
          122 }