/* * p2d_gnuplot.c - File I/O in gnuplot format * * Written 2012, 2015 by Werner Almesberger * Copyright 2012, 2015 Werner Almesberger * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. */ #include #include #include #include #include #include "poly2d.h" #define EPSILON 1e-6 static void check_closed(struct p2d *p) { if (!p) return; if (hypot(p->v->x-p->last->x, p->v->y-p->last->y) > EPSILON) return; free(p->last); p->last = p->v; } struct p2d *p2d_read_gnuplot(FILE *file) { struct p2d *res = NULL, **last = &res, *p = NULL; char buf[1024]; double x, y; int n; while (fgets(buf, sizeof(buf), file)) { if (*buf == '#') continue; n = sscanf(buf, "%lf %lf\n", &x, &y); switch (n) { case -1: check_closed(p); p = NULL; break; case 2: break; default: errno = EINVAL; return NULL; } if (!p) { p = p2d_new(); *last = p; last = &p->next; } p2d_append(p, v2d_new(x, y)); } check_closed(p); return res; } bool p2d_write_gnuplot(FILE *file, const struct p2d *p) { const struct v2d *v; v = p->v; while (v) { if (fprintf(file, "%g %g\n", v->x, v->y) < 0) return 0; v = v->next; if (v == p->v) { if (fprintf(file, "%g %g\n", v->x, v->y) < 0) return 0; break; } } return fprintf(file, "\n") >= 0; } bool p2d_write_gnuplot_all(FILE *file, const struct p2d *p) { while (p) { if (!p2d_write_gnuplot(file, p)) return 0; p = p->next; } return 1; }