Root/
Source at commit 5fdea0e99a2e8543a59d508cf28e1f2ff3607f18 created 9 years 2 months ago. By Werner Almesberger, gui_canvas.c (key_press_event): make / rotate through packages as well | |
---|---|
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 | |
32 | char *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 | |
48 | int 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 | |
61 | int 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 | |
83 | void 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 | |
149 | void 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 | |
160 | void 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 | |
175 | static 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 | |
191 | void write_ps(const char *one) |
192 | { |
193 | do_write_ps(postscript, one); |
194 | } |
195 | |
196 | |
197 | void write_ps_fullpage(const char *one) |
198 | { |
199 | do_write_ps(postscript_fullpage, one); |
200 | } |
201 | |
202 | |
203 | void 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 |
Branches:
master