/* * gnuplot.c - Gnuplot file input/output * * Written 2010-2011 by Werner Almesberger * Copyright 2010-2011 Werner Almesberger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include #include "util.h" #include "path.h" #include "gnuplot.h" struct path *gnuplot_read(const char *name, double r_tool_default) { FILE *file; int lineno = 0; char buf[1024]; char *id = NULL, *s; double x, y, z, tmp; double r_tool = r_tool_default; int outside = 0, notch = 0; int n; struct path *paths = NULL, *path = NULL; struct path **lnk = &paths; file = name ? fopen(name, "r") : stdin; if (!file) { perror(name); exit(1); } while (fgets(buf, sizeof(buf), file)) { lineno++; if (sscanf(buf, "#%%r_tool=%lf\n", &tmp) == 1) r_tool = tmp; if (!strcmp(buf, "#%outside\n")) outside = 1; if (!strcmp(buf, "#%notch\n")) notch = 1; if (!strncmp(buf, "#%id=", 5)) { free(id); id = stralloc(buf+5); s = strchr(id, '\n'); if (s) *s = 0; } if (*buf == '#') continue; n = sscanf(buf, "%lf %lf %lf\n", &x, &y, &z); switch (n) { case -1: path = NULL; r_tool = r_tool_default; outside = notch = 0; continue; case 2: z = 0; /* fall through */ case 3: break; default: fprintf(stderr, "invalid data at %s line %d\n", name ? name : "(stdin)", lineno); exit(1); } if (!path) { path = path_new(r_tool, id); path->outside = outside; path->notch = notch; *lnk = path; lnk = &path->next; } path_add(path, x, y, z); } fclose(file); return path_connect(paths); } static int gnuplot_do_write(FILE *file, const struct path *paths) { const struct path *path; const struct point *p; for (path = paths; path; path = path->next) { if (path != paths) if (fprintf(file, "\n") < 0) return 0; if (path->id && fprintf(file, "#%%id=%s\n", path->id) < 0) return 0; if (path->r_tool && fprintf(file, "#%%r_tool=%f\n", path->r_tool) < 0) return 0; if (path->outside && fprintf(file, "#%%outside\n") < 0) return 0; if (path->notch && fprintf(file, "#%%notch\n") < 0) return 0; for (p = path->first; p; p = p->next) if (fprintf(file, "%f %f %f\n", p->x, p->y, p->z) < 0) return 0; } if (file == stdout) { if (fflush(file) == EOF) return 0; } else { if (fclose(file) < 0) return 0; } return 1; } void gnuplot_write(const char *name, const struct path *paths) { FILE *file; file = name ? fopen(name, "w") : stdout; if (!file) { perror(name); exit(1); } if (!gnuplot_do_write(file, paths)) { perror(name ? name : "(stdout)"); exit(1); } } void gnuplot_append(const char *name, const struct path *paths) { FILE *file; struct stat st; if (!name) { printf("\n"); gnuplot_write(NULL, paths); return; } file = fopen(name, "a"); if (!file) { perror(name); exit(1); } if (stat(name, &st) < 0) { perror("lstat"); exit(1); } if (!S_ISREG(st.st_mode) || st.st_size) fprintf(file, "\n"); if (!gnuplot_do_write(file, paths)) { perror(name); exit(1); } }