Branch data Line data Source code
1 : : #include <string.h>
2 : : #include <stdio.h>
3 : :
4 : : /* Ensures portable headers are included such as inline. */
5 : : #include "config.h"
6 : : #include "fileio.h"
7 : : #include "pstrutil.h"
8 : :
9 : 116 : char *fb_copy_path_n(const char *path, size_t len)
10 : : {
11 : : size_t n;
12 : : char *s;
13 : :
14 : : n = strnlen(path, len);
15 [ + - ]: 116 : if ((s = malloc(n + 1))) {
16 : 116 : memcpy(s, path, n);
17 : 116 : s[n] = '\0';
18 : : }
19 : 116 : return s;
20 : : }
21 : :
22 : 207 : char *fb_copy_path(const char *path)
23 : : {
24 : : size_t n;
25 : : char *s;
26 : :
27 : 207 : n = strlen(path);
28 [ + - ]: 207 : if ((s = malloc(n + 1))) {
29 : 207 : memcpy(s, path, n);
30 : 207 : s[n] = '\0';
31 : : }
32 : 207 : return s;
33 : : }
34 : :
35 : 247 : size_t fb_chomp(const char *path, size_t len, const char *ext)
36 : : {
37 [ + - ]: 247 : size_t ext_len = ext ? strlen(ext) : 0;
38 [ + - ][ + - ]: 247 : if (len > ext_len && 0 == strncmp(path + len - ext_len, ext, ext_len)) {
39 : : len -= ext_len;
40 : : }
41 : 247 : return len;
42 : : }
43 : :
44 : 83 : char *fb_create_join_path_n(const char *prefix, size_t prefix_len,
45 : : const char *suffix, size_t suffix_len, const char *ext, int path_sep)
46 : : {
47 : : char *path;
48 [ + - ]: 83 : size_t ext_len = ext ? strlen(ext) : 0;
49 : : size_t n;
50 : :
51 [ + - ][ + - ]: 83 : if (!prefix ||
52 [ + - ][ + - ]: 83 : (suffix_len > 0 && (suffix[0] == '/' || suffix[0] == '\\')) ||
53 [ - + ]: 83 : (suffix_len > 1 && suffix[1] == ':')) {
54 : : prefix_len = 0;
55 : : }
56 [ + - ][ + - ]: 83 : if (path_sep && (prefix_len == 0 ||
[ + + ]
57 : 83 : (prefix[prefix_len - 1] == '/' || prefix[prefix_len - 1] == '\\'))) {
58 : : path_sep = 0;
59 : : }
60 : 83 : path = malloc(prefix_len + path_sep + suffix_len + ext_len + 1);
61 [ + - ]: 83 : if (!path) {
62 : : return 0;
63 : : }
64 : : n = 0;
65 : 83 : memcpy(path, prefix, prefix_len);
66 : : n += prefix_len;
67 [ + + ]: 83 : if (path_sep) {
68 : 65 : path[n++] = '/';
69 : : }
70 : 83 : memcpy(path + n, suffix, suffix_len);
71 : 83 : n += suffix_len;
72 : 83 : memcpy(path + n, ext, ext_len);
73 : 83 : n += ext_len;
74 : 83 : path[n] = '\0';
75 : 83 : return path;
76 : : }
77 : :
78 : 3 : char *fb_create_join_path(const char *prefix, const char *suffix, const char *ext, int path_sep)
79 : : {
80 [ + - ][ + - ]: 3 : return fb_create_join_path_n(prefix, prefix ? strlen(prefix) : 0,
81 : : suffix, suffix ? strlen(suffix) : 0, ext, path_sep);
82 : : }
83 : :
84 : 0 : char *fb_create_path_ext_n(const char *path, size_t path_len, const char *ext)
85 : : {
86 : 0 : return fb_create_join_path_n(0, 0, path, path_len, ext, 0);
87 : : }
88 : :
89 : 0 : char *fb_create_path_ext(const char *path, const char *ext)
90 : : {
91 : 0 : return fb_create_join_path(0, path, ext, 0);
92 : : }
93 : :
94 : 0 : char *fb_create_make_path_n(const char *path, size_t len)
95 : : {
96 : : size_t i, j, n;
97 : : char *s;
98 : :
99 [ # # ][ # # ]: 0 : if (len == 1 && (path[0] == ' ' || path[0] == '\\')) {
100 [ # # ]: 0 : if (!(s = malloc(3))) {
101 : : return 0;
102 : : }
103 : 0 : s[0] = '\\';
104 : 0 : s[1] = path[0];
105 : 0 : s[2] = '\0';
106 : 0 : return s;
107 : : }
108 [ # # ]: 0 : if (len <= 1) {
109 : 0 : return fb_copy_path_n(path, len);
110 : : }
111 [ # # ]: 0 : for (i = 0, n = len; i < len - 1; ++i) {
112 [ # # ][ # # ]: 0 : if (path[i] == '\\' && path[i + 1] == ' ') {
113 : 0 : ++n;
114 : : }
115 : 0 : n += path[i] == ' ';
116 : : }
117 : 0 : n += path[i] == ' ';
118 [ # # ]: 0 : if (!(s = malloc(n + 1))) {
119 : : return 0;
120 : : }
121 [ # # ]: 0 : for (i = 0, j = 0; i < len - 1; ++i, ++j) {
122 [ # # ][ # # ]: 0 : if (path[i] == '\\' && path[i + 1] == ' ') {
123 : 0 : s[j++] = '\\';
124 : : }
125 [ # # ]: 0 : if (path[i] == ' ') {
126 : 0 : s[j++] = '\\';
127 : : }
128 : 0 : s[j] = path[i];
129 : : }
130 [ # # ]: 0 : if (path[i] == ' ') {
131 : 0 : s[j++] = '\\';
132 : : }
133 : 0 : s[j++] = path[i];
134 : 0 : s[j] = 0;
135 : 0 : return s;
136 : : }
137 : :
138 : 0 : char *fb_create_make_path(const char *path)
139 : : {
140 : 0 : return fb_create_make_path_n(path, strlen(path));
141 : : }
142 : :
143 : 18 : size_t fb_find_basename(const char *path, size_t len)
144 : : {
145 : : char *p = (char *)path;
146 : :
147 : 247 : p += len;
148 [ + + ][ + - ]: 4698 : while(p != path) {
149 : 4483 : --p;
150 [ + + ][ + + ]: 4483 : if (*p == '/' || *p == '\\') {
151 : : ++p;
152 : : break;
153 : : }
154 : : }
155 : 265 : return p - path;
156 : : }
157 : :
158 : 247 : char *fb_create_basename(const char *path, size_t len, const char *ext)
159 : : {
160 : : size_t pos;
161 : : char *s;
162 : :
163 : : pos = fb_find_basename(path, len);
164 : : path += pos;
165 : 247 : len -= pos;
166 : 247 : len = fb_chomp(path, len, ext);
167 [ + - ]: 247 : if ((s = malloc(len + 1))) {
168 : 247 : memcpy(s, path, len);
169 : 247 : s[len] = '\0';
170 : : }
171 : 247 : return s;
172 : : }
173 : :
174 : 33 : char *fb_read_file(const char *filename, size_t max_size, size_t *size_out)
175 : : {
176 : : FILE *fp;
177 : : size_t size, pos, n, _out;
178 : : char *buf;
179 : :
180 [ + - ]: 33 : size_out = size_out ? size_out : &_out;
181 : :
182 : 33 : fp = fopen(filename, "rb");
183 : : size = 0;
184 : : buf = 0;
185 : :
186 [ + - ]: 33 : if (!fp) {
187 : : goto fail;
188 : : }
189 : 33 : fseek(fp, 0L, SEEK_END);
190 : 33 : size = ftell(fp);
191 : 33 : *size_out = size;
192 [ + - ]: 33 : if (max_size > 0 && size > max_size) {
193 : : goto fail;
194 : : }
195 : 33 : rewind(fp);
196 [ - + ]: 33 : buf = malloc(size ? size : 1);
197 [ + - ]: 33 : if (!buf) {
198 : : goto fail;
199 : : }
200 : : pos = 0;
201 [ + + ]: 66 : while ((n = fread(buf + pos, 1, size - pos, fp))) {
202 : 33 : pos += n;
203 : : }
204 [ + - ]: 33 : if (pos != size) {
205 : : goto fail;
206 : : }
207 : 33 : fclose(fp);
208 : 33 : *size_out = size;
209 : 33 : return buf;
210 : :
211 : : fail:
212 [ # # ]: 0 : if (fp) {
213 : 0 : fclose(fp);
214 : : }
215 [ # # ]: 0 : if (buf) {
216 : 0 : free(buf);
217 : : }
218 : 0 : *size_out = size;
219 : 0 : return 0;
220 : : }
|