fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/arch/dos/path.c *
7 * Created: 2013-01-01 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2013-2015 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include "main.h"
24#include "dos.h"
25#include "path.h"
26
27#include <ctype.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31
32
33static
34int buf_set_size (void **buf, unsigned *cnt, unsigned *max, unsigned size)
35{
36 unsigned tmp;
37 void *ptr;
38
39 if (size <= *cnt) {
40 return (0);
41 }
42
43 if (size <= *max) {
44 *cnt = size;
45 return (0);
46 }
47
48 tmp = *max;
49
50 while (tmp < size) {
51 tmp = (tmp < 16) ? 16 : (tmp + tmp / 4);
52 }
53
54 if ((ptr = realloc (*buf, tmp)) == NULL) {
55 return (1);
56 }
57
58 *buf = ptr;
59 *cnt = size;
60 *max = tmp;
61
62 return (0);
63}
64
65void sim_buf_init (void **buf, unsigned *cnt, unsigned *max)
66{
67 *buf = NULL;
68 *cnt = 0;
69 *max = 0;
70}
71
72int sim_buf_add (void **buf, unsigned *cnt, unsigned *max, unsigned char val)
73{
74 unsigned char *ptr;
75
76 if (buf_set_size (buf, cnt, max, *cnt + 1)) {
77 return (1);
78 }
79
80 ptr = *buf;
81 ptr[*cnt - 1] = val;
82
83 return (0);
84}
85
86char *sim_get_dir_name (const char *src, char sep)
87{
88 unsigned i, n;
89 char *ret;
90
91 i = 0;
92 n = 0;
93 while (src[i] != 0) {
94 if (src[i] == sep) {
95 n = i;
96 }
97
98 i += 1;
99 }
100
101 if (src[n] != sep) {
102 src = ".";
103 n = 1;
104 }
105 else if (n == 0) {
106 n = 1;
107 }
108
109 if ((ret = malloc (n + 1)) == NULL) {
110 return (NULL);
111 }
112
113 memcpy (ret, src, n);
114
115 ret[n] = 0;
116
117 return (ret);
118}
119
120char *sim_make_path (const char *s1, const char *s2)
121{
122 size_t n1, n2;
123 char *ret;
124
125 n1 = strlen (s1);
126 n2 = strlen (s2);
127
128 while ((n1 > 0) && (s1[n1 - 1] == '/')) {
129 n1 -= 1;
130 }
131
132 while ((n2 > 0) && (s2[0] == '/')) {
133 s2 += 1;
134 n2 -= 1;
135 }
136
137 if ((ret = malloc (n1 + n2 + 2)) == NULL) {
138 return (NULL);
139 }
140
141 memcpy (ret, s1, n1);
142 memcpy (ret + n1 + 1, s2, n2);
143 ret[n1] = '/';
144 ret[n1 + n2 + 1] = 0;
145
146 return (ret);
147}
148
149int sim_get_dos_basename (char *dst, const char *src, char sep)
150{
151 unsigned i;
152 const char *tmp;
153
154 tmp = src;
155
156 while (*tmp != 0) {
157 if (*tmp == sep) {
158 src = tmp + 1;
159 }
160
161 tmp += 1;
162 }
163
164 for (i = 0; i < 8; i++) {
165 if ((*src == 0) || (*src == '.')) {
166 dst[i] = ' ';
167 }
168 else if (*src == '*') {
169 dst[i] = '?';
170 }
171 else {
172 dst[i] = *src;
173 src += 1;
174 }
175 }
176
177 if (*src == '*') {
178 src += 1;
179 }
180
181 if (*src == '.') {
182 src += 1;
183
184 for (i = 0; i < 3; i++) {
185 if (*src == 0) {
186 dst[8 + i] = ' ';
187 }
188 else if (*src == '*') {
189 dst[8 + i] = '?';
190 }
191 else {
192 dst[8 + i] = *src;
193 src += 1;
194 }
195 }
196 }
197 else {
198 dst[8] = ' ';
199 dst[9] = ' ';
200 dst[10] = ' ';
201 }
202
203 if (*src == '*') {
204 src += 1;
205 }
206
207 if (*src != 0) {
208 return (1);
209 }
210
211 return (0);
212}
213
214char *sim_get_dos_full_name (dos_t *sim, const char *name)
215{
216 unsigned i, j;
217 unsigned char c;
218 char *ret;
219 size_t n;
220
221 n = strlen (name);
222
223 ret = malloc (n + 4);
224
225 i = 0;
226 j = 0;
227
228 if ((name[0] != 0) && (name[1] == ':')) {
229 ret[j++] = toupper (name[i++]);
230 ret[j++] = name[i++];
231 }
232 else {
233 ret[j++] = sim->cur_drive + 'A';
234 ret[j++] = ':';
235 }
236
237 if ((name[i] == '/') || (name[i] == '\\')) {
238 i += 1;
239 }
240
241 ret[j++] = '\\';
242
243 while (name[i] != 0) {
244 if ((name[i] == '/') || (name[i] == '\\')) {
245 c = '\\';
246 }
247 else {
248 c = toupper (name[i]);
249 }
250
251 ret[j++] = c;
252 i += 1;
253 }
254
255 ret[j] = 0;
256
257 return (ret);
258}
259
260char *sim_get_host_name (dos_t *sim, const char *dosname)
261{
262 unsigned char c;
263 int issep;
264 unsigned drv;
265 const char *s;
266 void *ret;
267 unsigned cnt, max;
268
269 drv = sim->cur_drive;
270
271 if ((dosname[0] != 0) && (dosname[1] == ':')) {
272 c = toupper (*dosname);
273
274 if ((c >= 'A') && (c <= 'Z')) {
275 drv = c - 'A';
276 }
277 else {
278 return (NULL);
279 }
280
281 dosname += 2;
282 }
283
284 if ((drv >= sim->drive_cnt) || (sim->drive[drv] == NULL)) {
285 return (NULL);
286 }
287
288 sim_buf_init (&ret, &cnt, &max);
289
290 issep = 0;
291
292 s = sim->drive[drv];
293
294 while (*s != 0) {
295 if (*s == '/') {
296 while (s[1] == '/') {
297 s += 1;
298 }
299
300 issep = 1;
301 }
302 else {
303 issep = 0;
304 }
305
306 sim_buf_add (&ret, &cnt, &max, *s);
307
308 s += 1;
309 }
310
311 if (issep == 0) {
312 sim_buf_add (&ret, &cnt, &max, '/');
313 issep = 1;
314 }
315
316 while (*dosname != 0) {
317 c = *dosname;
318
319 if (c == '\\') {
320 c = '/';
321 }
322 else {
323 c = tolower (c);
324 }
325
326 if ((c != '/') || (issep == 0)) {
327 sim_buf_add (&ret, &cnt, &max, c);
328 }
329
330 s += 1;
331 issep = (c == '/');
332
333 dosname += 1;
334 }
335
336 sim_buf_add (&ret, &cnt, &max, 0);
337
338 return (ret);
339}