fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 339 lines 5.6 kB view raw
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}