fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 289 lines 5.1 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/lib/path.c * 7 * Created: 2008-11-06 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2008-2009 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 <config.h> 24 25#include <stdlib.h> 26#include <stdio.h> 27#include <string.h> 28 29#include <libini/libini.h> 30 31#include <lib/path.h> 32 33 34static unsigned par_path_cnt = 0; 35static char **par_path_dir = NULL; 36 37 38static 39char *pce_path_strdup (const char *str) 40{ 41 unsigned n; 42 char *ret; 43 44 n = strlen (str); 45 46 ret = malloc (n + 1); 47 if (ret == NULL) { 48 return (NULL); 49 } 50 51 memcpy (ret, str, n); 52 ret[n] = 0; 53 54 return (ret); 55} 56 57static 58char *pce_path_cat (const char *str1, const char *str2) 59{ 60 unsigned n1, n2; 61 char *ret; 62 63 if (str1 == NULL) { 64 return (pce_path_strdup (str2)); 65 } 66 67 n1 = strlen (str1); 68 n2 = strlen (str2); 69 70 ret = malloc (n1 + n2 + 2); 71 if (ret == NULL) { 72 return (NULL); 73 } 74 75 memcpy (ret, str1, n1); 76 ret[n1] = PCE_DIR_SEP; 77 memcpy (ret + n1 + 1, str2, n2); 78 79 ret[n1 + n2 + 1] = 0; 80 81 return (ret); 82} 83 84static 85int pce_path_is_absolute (const char *str) 86{ 87 if (*str == PCE_DIR_SEP) { 88 return (1); 89 } 90 91 return (0); 92} 93 94void pce_path_clear (void) 95{ 96 unsigned i; 97 98 for (i = 0; i < par_path_cnt; i++) { 99 free (par_path_dir[i]); 100 } 101 102 free (par_path_dir); 103 104 par_path_cnt = 0; 105 par_path_dir = NULL; 106} 107 108int pce_path_add (const char *dir, int atend) 109{ 110 unsigned i, n; 111 char **tmp; 112 char *str; 113 114 n = strlen (dir); 115 116 while ((n > 0) && (dir[n - 1] == PCE_DIR_SEP)) { 117 n -= 1; 118 } 119 120 if ((n == 0) || ((n == 1) && (dir[0] == '.'))) { 121 str = NULL; 122 } 123 else { 124 str = malloc (n + 1); 125 if (str == NULL) { 126 return (1); 127 } 128 129 memcpy (str, dir, n); 130 str[n] = 0; 131 } 132 133 tmp = realloc (par_path_dir, (par_path_cnt + 1) * sizeof (char *)); 134 if (tmp == NULL) { 135 free (str); 136 return (1); 137 } 138 139 if (atend) { 140 tmp[par_path_cnt] = str; 141 } 142 else { 143 for (i = par_path_cnt; i > 0; i--) { 144 tmp[i] = tmp[i - 1]; 145 } 146 147 tmp[0] = str; 148 } 149 150 par_path_cnt += 1; 151 par_path_dir = tmp; 152 153 return (0); 154} 155 156int pce_path_set (const char *dir) 157{ 158 int atend; 159 160 atend = 1; 161 162 if (*dir == '+') { 163 dir += 1; 164 } 165 else if (*dir == '-') { 166 dir += 1; 167 atend = 0; 168 } 169 else if (*dir == '=') { 170 dir += 1; 171 pce_path_clear(); 172 } 173 174 return (pce_path_add (dir, atend)); 175} 176 177char *pce_path_get (const char *fname) 178{ 179 unsigned i; 180 char *str, *tmp; 181 FILE *fp; 182 183 if (fname == NULL) { 184 return (NULL); 185 } 186 187 str = pce_path_strdup (fname); 188 if (str == NULL) { 189 return (NULL); 190 } 191 192 if (pce_path_is_absolute (str)) { 193 return (str); 194 } 195 196 for (i = 0; i < par_path_cnt; i++) { 197 tmp = pce_path_cat (par_path_dir[i], str); 198 if (tmp == NULL) { 199 free (str); 200 return (NULL); 201 } 202 203 fp = fopen (tmp, "r"); 204 205 if (fp != NULL) { 206 fclose (fp); 207 free (str); 208 return (tmp); 209 } 210 211 free (tmp); 212 } 213 214 return (str); 215} 216 217FILE *pce_fopen_inp (const char *fname, const char *mode, char **path) 218{ 219 unsigned i; 220 char *str; 221 FILE *fp; 222 223 if (pce_path_is_absolute (fname)) { 224 if (path != NULL) { 225 *path = pce_path_strdup (fname); 226 } 227 228 return (fopen (fname, mode)); 229 } 230 231 for (i = 0; i < par_path_cnt; i++) { 232 str = pce_path_cat (par_path_dir[i], fname); 233 if (str == NULL) { 234 return (NULL); 235 } 236 237 fp = fopen (str, mode); 238 239 if (fp != NULL) { 240 if (path != NULL) { 241 *path = str; 242 } 243 else { 244 free (str); 245 } 246 247 return (fp); 248 } 249 250 free (str); 251 } 252 253 if (path != NULL) { 254 *path = pce_path_strdup (fname); 255 } 256 257 return (fopen (fname, mode)); 258} 259 260FILE *pce_fopen_out (const char *fname, const char *mode) 261{ 262 return (fopen (fname, mode)); 263} 264 265int pce_path_ini (ini_sct_t *sct) 266{ 267 const char *str; 268 ini_val_t *val; 269 270 val = NULL; 271 while (1) { 272 val = ini_next_val (sct, val, "path"); 273 274 if (val == NULL) { 275 break; 276 } 277 278 str = ini_val_get_str (val); 279 if (str == NULL) { 280 return (1); 281 } 282 283 if (pce_path_set (str)) { 284 return (1); 285 } 286 } 287 288 return (0); 289}