Root/file.c

Source at commit a9ed5b30aa457704a4c0c912367bfe8c57db8d03 created 3 years 4 months ago.
By Werner Almesberger, fped.1: update for new options; fix typo; bump date
1/*
2 * file.c - File handling
3 *
4 * Written 2009-2012 by Werner Almesberger
5 * Copyright 2009-2012 by 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 <errno.h>
18#include <sys/stat.h>
19
20#include "dump.h"
21#include "kicad.h"
22#include "postscript.h"
23#include "gnuplot.h"
24#include "util.h"
25#include "file.h"
26#include "fped.h"
27
28
29/* ----- general helper functions ------------------------------------------ */
30
31
32char *set_extension(const char *name, const char *ext)
33{
34    char *s = stralloc(name);
35    char *slash, *dot;
36    char *res;
37
38    slash = strrchr(s, '/');
39    dot = strrchr(slash ? slash : s, '.');
40    if (dot)
41        *dot = 0;
42    res = stralloc_printf("%s.%s", s, ext);
43    free(s);
44    return res;
45}
46
47
48int file_exists(const char *name)
49{
50    struct stat st;
51
52    if (stat(name, &st) >= 0)
53        return 1;
54    if (errno == ENOENT)
55        return 0;
56    perror(name);
57    return -1;
58}
59
60
61int save_to(const char *name, int (*fn)(FILE *file, const char *one),
62    const char *one)
63{
64    FILE *file;
65
66    file = fopen(name, "w");
67    if (!file) {
68        perror(name);
69        return 0;
70    }
71    if (!fn(file, one)) {
72        perror(name);
73        return 0;
74    }
75    if (fclose(file) == EOF) {
76        perror(name);
77        return 0;
78    }
79    return 1;
80}
81
82
83void save_with_backup(const char *name, int (*fn)(FILE *file, const char *one),
84    const char *one)
85{
86    char *s = stralloc(name);
87    char *back, *tmp;
88    char *slash, *dot;
89    int n, res;
90
91    /* save to temporary file */
92
93    slash = strrchr(s, '/');
94    if (!slash) {
95        tmp = stralloc_printf("~%s", s);
96    } else {
97        *slash = 0;
98        tmp = stralloc_printf("%s/~%s", s, slash+1);
99        *slash = '/';
100    }
101
102    if (!save_to(tmp, fn, one))
103        return;
104
105    /* move existing file out of harm's way */
106
107    dot = strrchr(slash ? slash : s, '.');
108    if (dot)
109        *dot = 0;
110    n = 0;
111    while (1) {
112        back = stralloc_printf("%s~%d%s%s",
113            s, n, dot ? "." : "", dot ? dot+1 : "");
114        res = file_exists(back);
115        if (!res)
116            break;
117        free(back);
118        if (res < 0)
119            return;
120        n++;
121    }
122    if (rename(name, back) < 0) {
123        if (errno != ENOENT) {
124            perror(name);
125            free(back);
126            return;
127        }
128    } else {
129        fprintf(stderr, "renamed %s to %s\n", name, back);
130    }
131    free(back);
132
133    /* rename to final name */
134
135    if (rename(tmp, name) < 0) {
136        perror(name);
137        free(tmp);
138        return;
139    }
140    free(tmp);
141
142    fprintf(stderr, "saved to %s\n", name);
143}
144
145
146/* ----- application-specific save handlers -------------------------------- */
147
148
149void save_fpd(void)
150{
151    if (save_file_name) {
152        save_with_backup(save_file_name, dump, NULL);
153    } else {
154        if (!dump(stdout, NULL))
155            perror("stdout");
156    }
157}
158
159
160void write_kicad(void)
161{
162    char *name;
163
164    if (save_file_name) {
165        name = set_extension(save_file_name, "mod");
166        save_to(name, kicad, NULL);
167        free(name);
168    } else {
169        if (!kicad(stdout, NULL))
170            perror("stdout");
171    }
172}
173
174
175static void do_write_ps(int (*fn)(FILE *file, const char *one),
176    const char *one)
177{
178    char *name;
179
180    if (save_file_name) {
181        name = set_extension(save_file_name, "ps");
182        save_to(name, fn, one);
183        free(name);
184    } else {
185        if (!fn(stdout, one))
186            perror("stdout");
187    }
188}
189
190
191void write_ps(const char *one)
192{
193    do_write_ps(postscript, one);
194}
195
196
197void write_ps_fullpage(const char *one)
198{
199    do_write_ps(postscript_fullpage, one);
200}
201
202
203void write_gnuplot(const char *one)
204{
205    char *name;
206
207    if (save_file_name) {
208        name = set_extension(save_file_name, "gp");
209        save_to(name, gnuplot, one);
210        free(name);
211    } else {
212        if (!gnuplot(stdout, one))
213            perror("stdout");
214    }
215}
216

Archive Download this file

Branches:
master



interactive