Root/file.c

Source at commit 103933acf59927d84df7f99d9580dfc0f45059c2 created 2 years 10 months ago.
By Werner Almesberger, fix a few whitespace issues in previous commit
1/*
2 * file.c - File handling
3 *
4 * Written 2009-2012 by Werner Almesberger
5 * Copyright 2009-2012 by Werner Almesberger
6 * Copyright 2016, Erich Heinzle (gEDA additions)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14
15#include <stdlib.h>
16#include <stdio.h>
17#include <string.h>
18#include <errno.h>
19#include <sys/stat.h>
20
21#include "dump.h"
22#include "kicad.h"
23#include "geda.h"
24#include "postscript.h"
25#include "gnuplot.h"
26#include "util.h"
27#include "file.h"
28#include "fped.h"
29
30
31/* ----- general helper functions ------------------------------------------ */
32
33
34char *set_extension(const char *name, const char *ext)
35{
36    char *s = stralloc(name);
37    char *slash, *dot;
38    char *res;
39
40    slash = strrchr(s, '/');
41    dot = strrchr(slash ? slash : s, '.');
42    if (dot)
43        *dot = 0;
44    res = stralloc_printf("%s.%s", s, ext);
45    free(s);
46    return res;
47}
48
49
50int file_exists(const char *name)
51{
52    struct stat st;
53
54    if (stat(name, &st) >= 0)
55        return 1;
56    if (errno == ENOENT)
57        return 0;
58    perror(name);
59    return -1;
60}
61
62
63int save_to(const char *name, int (*fn)(FILE *file, const char *one),
64    const char *one)
65{
66    FILE *file;
67
68    file = fopen(name, "w");
69    if (!file) {
70        perror(name);
71        return 0;
72    }
73    if (!fn(file, one)) {
74        perror(name);
75        return 0;
76    }
77    if (fclose(file) == EOF) {
78        perror(name);
79        return 0;
80    }
81    return 1;
82}
83
84
85void save_with_backup(const char *name, int (*fn)(FILE *file, const char *one),
86    const char *one)
87{
88    char *s = stralloc(name);
89    char *back, *tmp;
90    char *slash, *dot;
91    int n, res;
92
93    /* save to temporary file */
94
95    slash = strrchr(s, '/');
96    if (!slash) {
97        tmp = stralloc_printf("~%s", s);
98    } else {
99        *slash = 0;
100        tmp = stralloc_printf("%s/~%s", s, slash+1);
101        *slash = '/';
102    }
103
104    if (!save_to(tmp, fn, one))
105        return;
106
107    /* move existing file out of harm's way */
108
109    dot = strrchr(slash ? slash : s, '.');
110    if (dot)
111        *dot = 0;
112    n = 0;
113    while (1) {
114        back = stralloc_printf("%s~%d%s%s",
115            s, n, dot ? "." : "", dot ? dot+1 : "");
116        res = file_exists(back);
117        if (!res)
118            break;
119        free(back);
120        if (res < 0)
121            return;
122        n++;
123    }
124    if (rename(name, back) < 0) {
125        if (errno != ENOENT) {
126            perror(name);
127            free(back);
128            return;
129        }
130    } else {
131        fprintf(stderr, "renamed %s to %s\n", name, back);
132    }
133    free(back);
134
135    /* rename to final name */
136
137    if (rename(tmp, name) < 0) {
138        perror(name);
139        free(tmp);
140        return;
141    }
142    free(tmp);
143
144    fprintf(stderr, "saved to %s\n", name);
145}
146
147
148/* ----- application-specific save handlers -------------------------------- */
149
150
151void save_fpd(void)
152{
153    if (save_file_name) {
154        save_with_backup(save_file_name, dump, NULL);
155    } else {
156        if (!dump(stdout, NULL))
157            perror("stdout");
158    }
159}
160
161
162void write_kicad(void)
163{
164    char *name;
165
166    if (save_file_name) {
167        name = set_extension(save_file_name, "mod");
168        save_to(name, kicad, NULL);
169        free(name);
170    } else {
171        if (!kicad(stdout, NULL))
172            perror("stdout");
173    }
174}
175
176void write_geda(void)
177{
178    char *name;
179
180    if (save_file_name) {
181        name = set_extension(save_file_name, "pcb");
182        save_to(name, geda, NULL);
183        free(name);
184    } else {
185        if (!geda(stdout, NULL))
186            perror("stdout");
187    }
188}
189
190
191static void do_write_ps(int (*fn)(FILE *file, const char *one),
192    const char *one)
193{
194    char *name;
195
196    if (save_file_name) {
197        name = set_extension(save_file_name, "ps");
198        save_to(name, fn, one);
199        free(name);
200    } else {
201        if (!fn(stdout, one))
202            perror("stdout");
203    }
204}
205
206
207void write_ps(const char *one)
208{
209    do_write_ps(postscript, one);
210}
211
212
213void write_ps_fullpage(const char *one)
214{
215    do_write_ps(postscript_fullpage, one);
216}
217
218
219void write_gnuplot(const char *one)
220{
221    char *name;
222
223    if (save_file_name) {
224        name = set_extension(save_file_name, "gp");
225        save_to(name, gnuplot, one);
226        free(name);
227    } else {
228        if (!gnuplot(stdout, one))
229            perror("stdout");
230    }
231}
232

Archive Download this file

Branches:
master



interactive