Root/cameo/gnuplot.c

1/*
2 * gnuplot.c - Gnuplot file input/output
3 *
4 * Written 2010-2011 by Werner Almesberger
5 * Copyright 2010-2011 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stdlib.h>
15#include <stdio.h>
16#include <string.h>
17#include <sys/stat.h>
18
19#include "util.h"
20#include "path.h"
21#include "gnuplot.h"
22
23
24struct path *gnuplot_read(const char *name, double r_tool_default)
25{
26    FILE *file;
27    int lineno = 0;
28    char buf[1024];
29    char *id = NULL, *s;
30    double x, y, z, tmp;
31    double r_tool = r_tool_default;
32    int outside = 0, notch = 0;
33    int n;
34    struct path *paths = NULL, *path = NULL;
35    struct path **lnk = &paths;
36
37    file = name ? fopen(name, "r") : stdin;
38    if (!file) {
39        perror(name);
40        exit(1);
41    }
42
43    while (fgets(buf, sizeof(buf), file)) {
44        lineno++;
45        if (sscanf(buf, "#%%r_tool=%lf\n", &tmp) == 1)
46            r_tool = tmp;
47        if (!strcmp(buf, "#%outside\n"))
48            outside = 1;
49        if (!strcmp(buf, "#%notch\n"))
50            notch = 1;
51        if (!strncmp(buf, "#%id=", 5)) {
52            free(id);
53            id = stralloc(buf+5);
54            s = strchr(id, '\n');
55            if (s)
56                *s = 0;
57        }
58        if (*buf == '#')
59            continue;
60        n = sscanf(buf, "%lf %lf %lf\n", &x, &y, &z);
61        switch (n) {
62        case -1:
63            path = NULL;
64            r_tool = r_tool_default;
65            outside = notch = 0;
66            continue;
67        case 2:
68            z = 0;
69            /* fall through */
70        case 3:
71            break;
72        default:
73            fprintf(stderr, "invalid data at %s line %d\n",
74                name ? name : "(stdin)", lineno);
75            exit(1);
76        }
77
78        if (!path) {
79            path = path_new(r_tool, id);
80            path->outside = outside;
81            path->notch = notch;
82            *lnk = path;
83            lnk = &path->next;
84        }
85        path_add(path, x, y, z);
86    }
87    fclose(file);
88    return path_connect(paths);
89}
90
91
92static int gnuplot_do_write(FILE *file, const struct path *paths)
93{
94    const struct path *path;
95    const struct point *p;
96
97    for (path = paths; path; path = path->next) {
98        if (path != paths)
99            if (fprintf(file, "\n") < 0)
100                return 0;
101        if (path->id &&
102            fprintf(file, "#%%id=%s\n", path->id) < 0)
103            return 0;
104        if (path->r_tool &&
105            fprintf(file, "#%%r_tool=%f\n", path->r_tool) < 0)
106            return 0;
107        if (path->outside && fprintf(file, "#%%outside\n") < 0)
108            return 0;
109        if (path->notch && fprintf(file, "#%%notch\n") < 0)
110            return 0;
111        for (p = path->first; p; p = p->next)
112            if (fprintf(file, "%f %f %f\n", p->x, p->y, p->z) < 0)
113                return 0;
114    }
115    if (file == stdout) {
116        if (fflush(file) == EOF)
117            return 0;
118    } else {
119        if (fclose(file) < 0)
120            return 0;
121    }
122    return 1;
123}
124
125
126void gnuplot_write(const char *name, const struct path *paths)
127{
128    FILE *file;
129
130    file = name ? fopen(name, "w") : stdout;
131    if (!file) {
132        perror(name);
133        exit(1);
134    }
135    if (!gnuplot_do_write(file, paths)) {
136        perror(name ? name : "(stdout)");
137        exit(1);
138    }
139}
140
141
142void gnuplot_append(const char *name, const struct path *paths)
143{
144    FILE *file;
145    struct stat st;
146
147    if (!name) {
148        printf("\n");
149        gnuplot_write(NULL, paths);
150        return;
151    }
152    file = fopen(name, "a");
153    if (!file) {
154        perror(name);
155        exit(1);
156    }
157    if (stat(name, &st) < 0) {
158        perror("lstat");
159        exit(1);
160    }
161    if (!S_ISREG(st.st_mode) || st.st_size)
162        fprintf(file, "\n");
163    if (!gnuplot_do_write(file, paths)) {
164        perror(name);
165        exit(1);
166    }
167}
168

Archive Download this file

Branches:
master



interactive