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