HuntnGather – Diff between revs 37 and 38

Subversion Repositories:
Rev:
Only display areas with differencesRegard whitespace
Rev 37 Rev 38
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) 2021 Wizardry and Steamworks - License: MIT // 2 // Copyright (C) 2021 Wizardry and Steamworks - License: MIT //
3 /////////////////////////////////////////////////////////////////////////// 3 ///////////////////////////////////////////////////////////////////////////
4   4  
5 #include <stdio.h> 5 #include <stdio.h>
6 #include <stdlib.h> 6 #include <stdlib.h>
7 #include <string.h> 7 #include <string.h>
-   8 #include <ctype.h>
8 #if !defined ___AmigaOS___ 9 #if !defined ___AmigaOS___
9 #include <dirent.h> 10 #include <dirent.h>
10 #include <sys/stat.h> 11 #include <sys/stat.h>
11 #include <signal.h> 12 #include <signal.h>
12 #endif 13 #endif
13   14  
14 #include <sys/types.h> 15 #include <sys/types.h>
15 #include <sys/syslimits.h> 16 #include <sys/syslimits.h>
16   17  
17 #if defined ___AmigaOS___ 18 #if defined ___AmigaOS___
18 #include <proto/dos.h> 19 #include <proto/dos.h>
19 #include <proto/exec.h> 20 #include <proto/exec.h>
20 #include <proto/locale.h> 21 #include <proto/locale.h>
21 #include <clib/utility_protos.h> 22 #include <clib/utility_protos.h>
22 #endif 23 #endif
23   24  
24 #if defined ___AsyncIO___ 25 #if defined ___AsyncIO___
25 #include <asyncio.h> 26 #include <asyncio.h>
26 #endif 27 #endif
27   28  
28 #include "/shared/utilities.h" 29 #include "/shared/utilities.h"
29   30  
30 /* 31 /*
31 * 32 *
32 * Returns largest of strings. 33 * Returns largest of strings.
33 */ 34 */
34 #if defined ___AmigaOS___ 35 #if defined ___AmigaOS___
35 LONG StringLenMax(char *a, char *b) { 36 LONG StringLenMax(char *a, char *b) {
36 LONG p = strlen(a); 37 LONG p = strlen(a);
37 LONG q = strlen(b); 38 LONG q = strlen(b);
38 #else 39 #else
39 int StrlenMax(char *a, char *b) { 40 int StrlenMax(char *a, char *b) {
40 int q = strlen(a); 41 int q = strlen(a);
41 int p = strien(b); 42 int p = strlen(b);
42 #endif 43 #endif
43 return p > q ? p : q; 44 return p > q ? p : q;
44 } 45 }
45   46  
46 /* 47 /*
47 * 48 *
48 * Returns largest of strings. 49 * Returns largest of strings.
49 */ 50 */
50 #if defined ___AmigaOS___ 51 #if defined ___AmigaOS___
51 LONG StringLenMin(char *a, char *b) { 52 LONG StringLenMin(char *a, char *b) {
52 LONG p = strlen(a); 53 LONG p = strlen(a);
53 LONG q = strlen(b); 54 LONG q = strlen(b);
54 #else 55 #else
55 int StrlenMax(char *a, char *b) { 56 int StrlenMin(char *a, char *b) {
56 int q = strlen(a); 57 int q = strlen(a);
57 int p = strien(b); 58 int p = strlen(b);
58 #endif 59 #endif
59 return p > q ? q : p; 60 return p > q ? q : p;
60 } 61 }
61   62  
62 /* 63 /*
63 * 64 *
64 * Converts a string to case. 65 * Converts a string to case.
65 */ 66 */
66 void StrUpr(char *s) { 67 void StrUpr(char *s) {
67 while(*s != '\0') { 68 while(*s != '\0') {
68 #if defined ___AmigaOS___ 69 #if defined ___AmigaOS___
69 *s = ToUpper(*s); 70 *s = ToUpper(*s);
70 #else 71 #else
71 *s = toupper((unsigned char)*s); 72 *s = toupper((unsigned char)*s);
72 #endif 73 #endif
73 ++s; 74 ++s;
74 } 75 }
75 } 76 }
76   77  
77 /* 78 /*
78 * 79 *
79 * Gets the filesystem type of a file or directory. 80 * Gets the filesystem type of a file or directory.
80 */ 81 */
81 FS_TYPE GetFsType(char *path) { 82 FS_TYPE GetFsType(char *path) {
82 #if defined ___AmigaOS___ 83 #if defined ___AmigaOS___
83 struct FileInfoBlock *FIB; 84 struct FileInfoBlock *FIB;
84 BPTR lock; 85 BPTR lock;
85 #else 86 #else
86 struct stat dirStat; 87 struct stat dirStat;
87 #endif 88 #endif
88   89  
89 #if defined ___AmigaOS___ 90 #if defined ___AmigaOS___
90 if((lock = Lock(path, ACCESS_READ)) == NULL) { 91 if((lock = Lock(path, ACCESS_READ)) == NULL) {
91 fprintf(stderr, "Lock failed for path '%s'.\n", path); 92 fprintf(stderr, "Lock failed for path '%s'.\n", path);
92 return UNKNOWN; 93 return UNKNOWN;
93 } 94 }
94   95  
95 if((FIB = AllocDosObject(DOS_FIB, NULL)) == NULL) { 96 if((FIB = AllocDosObject(DOS_FIB, NULL)) == NULL) {
96 fprintf(stderr, "Could not allocated file information block for path '%s'.\n", path); 97 fprintf(stderr, "Could not allocated file information block for path '%s'.\n", path);
97 UnLock(lock); 98 UnLock(lock);
98 return UNKNOWN; 99 return UNKNOWN;
99 } 100 }
100   101  
101 if(Examine(lock, FIB) == FALSE) { 102 if(Examine(lock, FIB) == FALSE) {
102 fprintf(stderr, "Path '%s' could not be examined.\n", path); 103 fprintf(stderr, "Path '%s' could not be examined.\n", path);
103 UnLock(lock); 104 UnLock(lock);
104 FreeDosObject(DOS_FIB, FIB); 105 FreeDosObject(DOS_FIB, FIB);
-   106 FIB = NULL;
105 return UNKNOWN; 107 return UNKNOWN;
106 } 108 }
107   109  
108 if(FIB->fib_DirEntryType < 0) { 110 if(FIB->fib_DirEntryType < 0) {
109 UnLock(lock); 111 UnLock(lock);
110 FreeDosObject(DOS_FIB, FIB); 112 FreeDosObject(DOS_FIB, FIB);
-   113 FIB = NULL;
111 return REGULAR; 114 return REGULAR;
112 #else 115 #else
113 stat(path, &dirStat); 116 stat(path, &dirStat);
114 if(!S_ISDIR(dirStat.st_mode)) { 117 if(!S_ISDIR(dirStat.st_mode)) {
115 return REGULAR; 118 return REGULAR;
116 #endif 119 #endif
117 } 120 }
118   121  
119 #if defined ___AmigaOS___ 122 #if defined ___AmigaOS___
120 UnLock(lock); 123 UnLock(lock);
121 FreeDosObject(DOS_FIB, FIB); 124 FreeDosObject(DOS_FIB, FIB);
-   125 FIB = NULL;
122 #endif 126 #endif
123   127  
124 return DIRECTORY; 128 return DIRECTORY;
125 } 129 }
126   130  
127 /* 131 /*
128 * 132 *
129 * Counts the lines of a file. 133 * Counts the lines of a file.
130 */ 134 */
131 int CountFileLines(char *dbFile) { 135 int CountFileLines(char *dbFile) {
132 #if defined ___AsyncIO___ 136 #if defined ___AsyncIO___
133 struct AsyncFile *fp; 137 struct AsyncFile *fp;
134 LONG c; 138 LONG c;
135 #else 139 #else
136 FILE *fp; 140 FILE *fp;
137 char c; 141 char c;
138 #endif 142 #endif
139 int lines; 143 int lines;
140   144  
141 #if defined ___AsyncIO___ 145 #if defined ___AsyncIO___
142 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) { 146 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
143 #else 147 #else
144 if((fp = fopen(dbFile, "r")) == NULL) { 148 if((fp = fopen(dbFile, "r")) == NULL) {
145 #endif 149 #endif
146 fprintf(stderr, "Could not open file '%s' for reading.\n", dbFile); 150 fprintf(stderr, "Could not open file '%s' for reading.\n", dbFile);
147 return -1; 151 return -1;
148 } 152 }
149   153  
150 lines = 0; 154 lines = 0;
151 if(PROGRAM_VERBOSE) { 155 if(PROGRAM_VERBOSE) {
152 fprintf(stdout, "Counting lines in '%s'...\r", dbFile); 156 fprintf(stdout, "Counting lines in '%s'...\r", dbFile);
153 } 157 }
154   158  
155 #if defined ___AsyncIO___ 159 #if defined ___AsyncIO___
156 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) { 160 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) {
157 #else 161 #else
158 while(run && fscanf(fp, "%c", &c) == 1) { 162 while(PROGRAM_RUN && fscanf(fp, "%c", &c) == 1) {
159 #endif 163 #endif
160 #if defined ___AmigaOS___ 164 #if defined ___AmigaOS___
161 // Check if CTRL+C was pressed and abort the program. 165 // Check if CTRL+C was pressed and abort the program.
162 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 166 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
163 PROGRAM_RUN = FALSE; 167 PROGRAM_RUN = FALSE;
164 continue; 168 continue;
165 } 169 }
166 #endif 170 #endif
167 switch(c) { 171 switch(c) {
168 case '\n': 172 case '\n':
169 ++lines; 173 ++lines;
170   174  
171 if(PROGRAM_VERBOSE) { 175 if(PROGRAM_VERBOSE) {
172 fprintf(stdout, "Counting lines in '%s': %d.\r", dbFile, lines); 176 fprintf(stdout, "Counting lines in '%s': %d.\r", dbFile, lines);
173 } 177 }
174 break; 178 break;
175 } 179 }
176 } 180 }
177   181  
178 #if defined ___AsyncIO___ 182 #if defined ___AsyncIO___
179 CloseAsync(fp); 183 CloseAsync(fp);
180 #else 184 #else
181 fclose(fp); 185 fclose(fp);
182 #endif 186 #endif
183   187  
184 if(PROGRAM_VERBOSE) { 188 if(PROGRAM_VERBOSE) {
185 fprintf(stdout, "\n"); 189 fprintf(stdout, "\n");
186 } 190 }
187   191  
188 return lines; 192 return lines;
189 } 193 }
190   194  
191 /* 195 /*
192 * 196 *
193 * Gets the absolute path to file by name. 197 * Gets the absolute path to file by name.
194 */ 198 */
195 char *PathToAbsolute(char *path) { 199 char *PathToAbsolute(char *path) {
196 char *abs; 200 char *abs;
197 #if defined ___AmigaOS___ 201 #if defined ___AmigaOS___
198 BPTR lock; 202 BPTR lock;
199 #endif 203 #endif
200   204  
201 #if defined ___AmigaOS___ 205 #if defined ___AmigaOS___
202 if((abs = malloc(PATH_MAX * sizeof(*abs))) == NULL) { 206 if((abs = malloc(PATH_MAX * sizeof(*abs))) == NULL) {
203 fprintf(stderr, "Memory allocation failure.\n"); 207 fprintf(stderr, "Memory allocation failure.\n");
204 return NULL; 208 return NULL;
205 } 209 }
206 if((lock = Lock(path, SHARED_LOCK)) == 0) { 210 if((lock = Lock(path, SHARED_LOCK)) == 0) {
207 fprintf(stderr, "Lock failed for path '%s'.\n", path); 211 fprintf(stderr, "Lock failed for path '%s'.\n", path);
208 return NULL; 212 return NULL;
209 } 213 }
210 if(NameFromLock(lock, abs, PATH_MAX) == FALSE) { 214 if(NameFromLock(lock, abs, PATH_MAX) == FALSE) {
211 fprintf(stderr, "Full path for '%s' could not be retrieved.\n", path); 215 fprintf(stderr, "Full path for '%s' could not be retrieved.\n", path);
212 UnLock(lock); 216 UnLock(lock);
213 return NULL; 217 return NULL;
214 } 218 }
215 UnLock(lock); 219 UnLock(lock);
216 #else 220 #else
217 /* 221 /*
218 * On POSIX this should be: 222 * On POSIX this should be:
219 * abs = realpath(path, NULL); 223 * abs = realpath(path, NULL);
220 * 224 *
221 */ 225 */
222 if((abs = malloc((strlen(path) + 1) * sizeof(*abs))) == NULL) { 226 if((abs = malloc((strlen(path) + 1) * sizeof(*abs))) == NULL) {
223 fprintf(stderr, "Memory allocation failure.\n"); 227 fprintf(stderr, "Memory allocation failure.\n");
224 return NULL; 228 return NULL;
225 } 229 }
226 sprintf(abs, "%s", path); 230 sprintf(abs, "%s", path);
227 #endif 231 #endif
228   232  
229 return abs; 233 return abs;
230 } 234 }
231   235  
232 /* 236 /*
233 * 237 *
234 * Compares path parts for equality. 238 * Compares path parts for equality.
235 */ 239 */
236 #if defined ___AmigaOS___ 240 #if defined ___AmigaOS___
237 BOOL PathCompare(char *path, char *look) { 241 BOOL PathCompare(char *path, char *look) {
238 #else 242 #else
239 int PathCompare(char *path, char *look) { 243 int PathCompare(char *path, char *look) {
240 #endif 244 #endif
241 char *a; 245 char *a;
242 char *b; 246 char *b;
243   247  
244 for(a = path, b = look; *a != '\0' && *b != '\0'; ++a, ++b) { 248 for(a = path, b = look; *a != '\0' && *b != '\0'; ++a, ++b) {
245 if(*b != '\0' && *a != *b) { 249 if(*b != '\0' && *a != *b) {
246 return FALSE; 250 return FALSE;
247 } 251 }
248 } 252 }
249   253  
250 return *b == '\0'; 254 return *b == '\0';
251 } 255 }
252   256  
253 /* 257 /*
254 * 258 *
255 * Creates a temporary file and returns its name. 259 * Creates a temporary file and returns its name.
256 */ 260 */
257 char *CreateTemporaryFile(void) { 261 char *CreateTemporaryFile(void) {
258 char *name; 262 char *name;
259   263  
260 name = tmpnam(NULL); 264 name = tmpnam(NULL);
261   265  
262 return name; 266 return name;
263 } 267 }
264   268  
265 /* 269 /*
266 * 270 *
267 * Create multiple temporary files and return their names. 271 * Create multiple temporary files and return their names.
268 */ 272 */
269 char **CreateTemporaryFiles(int files) { 273 VECTOR *CreateTemporaryFiles(int files) {
270 char **tmpNames; 274 VECTOR *tmpNames;
-   275  
-   276 if((tmpNames = malloc(1 * sizeof(*tmpNames))) == NULL) {
-   277 fprintf(stderr, "Memory allocation failure.\n");
271 int count; 278 return NULL;
-   279 }
272   280  
273 if((tmpNames = malloc(files * sizeof(*tmpNames))) == NULL) { 281 if((tmpNames->array = malloc(files * sizeof(*tmpNames->array))) == NULL) {
274 fprintf(stderr, "Memory allocation failure.\n"); 282 fprintf(stderr, "Memory allocation failure.\n");
275 return NULL; 283 return NULL;
276 } 284 }
277   285  
278 if(PROGRAM_VERBOSE) { 286 if(PROGRAM_VERBOSE) {
279 fprintf(stdout, "Creating temporary files...\r"); 287 fprintf(stdout, "Creating temporary files...\r");
280 } 288 }
281   289  
282 count = files; 290 tmpNames->length = 0;
283 while(PROGRAM_RUN && --count > -1) { 291 while(PROGRAM_RUN && --files > -1) {
284 #if defined ___AmigaOS___ 292 #if defined ___AmigaOS___
285 // Check if CTRL+C was pressed and abort the program. 293 // Check if CTRL+C was pressed and abort the program.
286 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 294 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
287 PROGRAM_RUN = FALSE; 295 PROGRAM_RUN = FALSE;
288 continue; 296 continue;
289 } 297 }
290 #endif 298 #endif
291 tmpNames[count] = CreateTemporaryFile(); 299 tmpNames[files] = CreateTemporaryFile();
-   300 ++tmpNames->length;
292   301  
293 if(PROGRAM_VERBOSE) { 302 if(PROGRAM_VERBOSE) {
294 fprintf(stdout, "Creating temporary files: %d%%.\r", 100 - (int)(((float)count / files) * 100.0)); 303 fprintf(stdout, "Creating temporary files: %d%%.\r", 100 - (int)(((float)count / files) * 100.0));
295 } 304 }
296 } 305 }
297   306  
298 if(PROGRAM_VERBOSE) { 307 if(PROGRAM_VERBOSE) {
299 fprintf(stdout, "\n"); 308 fprintf(stdout, "\n");
300 } 309 }
301   310  
302 return tmpNames; 311 return tmpNames;
303 } 312 }
304   313  
305 /* 314 /*
306 * 315 *
307 * Skips a line in a file. 316 * Skips a line in a file.
308 */ 317 */
309 #if defined ___AsyncIO___ 318 #if defined ___AsyncIO___
310 void SkipLine(struct AsyncFile *fp) { 319 void SkipLine(struct AsyncFile *fp) {
311 LONG c; 320 LONG c;
312 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) { 321 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) {
313 #else 322 #else
314 void SkipLine(FILE *fp) { 323 void SkipLine(FILE *fp) {
315 char c; 324 char c;
316 while(PROGRAM_RUN && fscanf(fp, "%c", &c) == 1) { 325 while(PROGRAM_RUN && fscanf(fp, "%c", &c) == 1) {
317 #endif 326 #endif
318 #if defined ___AmigaOS___ 327 #if defined ___AmigaOS___
319 // Check if CTRL+C was pressed and abort the program. 328 // Check if CTRL+C was pressed and abort the program.
320 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 329 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
321 PROGRAM_RUN = FALSE; 330 PROGRAM_RUN = FALSE;
322 continue; 331 continue;
323 } 332 }
324 #endif 333 #endif
325 switch(c) { 334 switch(c) {
326 case '\n': 335 case '\n':
327 return; 336 return;
328 } 337 }
329 } 338 }
330 } 339 }
331   -  
332   340  
333 /* 341 /*
334 * 342 *
335 * Peeks at a line from a file. 343 * Peeks for the next line in a file.
336 */ 344 */
337 #if defined ___AsyncIO___ 345 #if defined ___AsyncIO___
338 char *PeekLine(struct AsyncFile *fp) { -  
339 LONG c; 346 dbLine *PeekLine(struct AsyncFile *fp) {
340 #else 347 #else
341 char *PeekLine(FILE *fp) { -  
342 char c; 348 dbLine *PeekLine(FILE *fp) {
343 #endif -  
344 char *line = NULL; -  
345 char *real = NULL; 349 #endif
346 int size; -  
347 int i; 350 dbLine *line;
348   351  
349 size = LINE_BUF; -  
350 if((line = malloc(size * sizeof(*line))) == NULL) { 352 // Read the next line.
351 fprintf(stderr, "Memory allocation failure.\n"); 353 if((line = ReadLine(fp)) == NULL) {
352 return NULL; 354 return NULL;
353 } 355 }
354   -  
355 i = 0; -  
356 #if defined ___AsyncIO___ -  
357 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) { -  
358 #else -  
359 while(PROGRAM_RUN && fscanf(fp, "%c", &c) == 1) { -  
360 #endif -  
361 #if defined ___AmigaOS___ -  
362 // Check if CTRL+C was pressed and abort the program. -  
363 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { -  
364 PROGRAM_RUN = FALSE; -  
365 continue; -  
366 } -  
367 #endif -  
368 switch(c) { -  
369 case '\n': 356  
370 // Rewind the file by the number of read characters. 357 // Rewind the file by the number of read characters.
371 #if defined ___AsyncIO___ 358 #if defined ___AsyncIO___
372 if(SeekAsync(fp, -(i + 1), MODE_CURRENT) == -1) { 359 if(SeekAsync(fp, -(line->length + 1), MODE_CURRENT) == -1) {
-   360 fprintf(stderr, "Could not seek in file.\n");
373 fprintf(stderr, "Could not seek in file.\n"); 361 free(line->string);
-   362 free(line);
374 free(line); 363 line = NULL;
375 return NULL; 364 return NULL;
376 } 365 }
377 #else 366 #else
378 if(fseek(fp, -(i + 1), SEEK_CUR) != 0) { 367 if(fseek(fp, -(line->length + 1), SEEK_CUR) != 0) {
379 fprintf(stderr, "Could not seek in file.\n"); 368 fprintf(stderr, "Could not seek in file.\n");
-   369 free(line->string);
380 free(line); 370 free(line);
-   371 line = NULL;
381 return NULL; 372 return NULL;
382 } 373 }
383 #endif 374 #endif
384 return line; -  
385 default: -  
386 if(strlen(line) == size) { -  
387 size = size * 1.5; -  
388 real = realloc(line, size * sizeof(*line)); -  
389 if(real == NULL) { -  
390 fprintf(stderr, "Memory reallocation failure.\n"); -  
391 free(line); -  
392 return NULL; -  
393 } -  
394 line = real; -  
395 } -  
396 line[i] = c; -  
397 line[i + 1] = '\0'; -  
398 break; -  
399 } -  
400 ++i; -  
401 } -  
402   -  
403 if(line != NULL) { -  
404 free(line); -  
405 } -  
406   375  
407 return NULL; 376 return line;
408 } 377 }
409   378  
410 /* 379 /*
411 * 380 *
412 * Read a line from a file. 381 * Reads the next line in a file.
413 */ 382 */
414 #if defined ___AsyncIO___ 383 #if defined ___AsyncIO___
415 char *ReadLine(struct AsyncFile *fp) { 384 dbLine *ReadLine(struct AsyncFile *fp) {
416 LONG c; 385 LONG c;
417 #else 386 #else
418 char *ReadLine(FILE *fp) { 387 dbLine *ReadLine(FILE *fp) {
419 char c; 388 char c;
420 #endif 389 #endif
421 char *line = NULL; -  
422 char *real = NULL; -  
423 int size; -  
424 int i; 390 int i;
425   -  
426 size = LINE_BUF; -  
427 if((line = malloc(size * sizeof(*line))) == NULL) { -  
428 fprintf(stderr, "Memory allocation failure.\n"); -  
429 return NULL; 391 dbLine *line;
430 } -  
431   392  
432 i = 0; 393 i = 0;
433 #if defined ___AsyncIO___ 394 #if defined ___AsyncIO___
434 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) { 395 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) {
435 #else 396 #else
436 while(PROGRAM_RUN && fscanf(fp, "%c", &c) == 1) { 397 while(PROGRAM_RUN && fscanf(fp, "%c", &c) == 1) {
437 #endif 398 #endif
438 #if defined ___AmigaOS___ 399 #if defined ___AmigaOS___
439 // Check if CTRL+C was pressed and abort the program. 400 // Check if CTRL+C was pressed and abort the program.
440 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 401 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
441 PROGRAM_RUN = FALSE; 402 PROGRAM_RUN = FALSE;
442 continue; 403 continue;
443 } 404 }
444 #endif 405 #endif
445 switch(c) { 406 switch(c) {
446 case '\n': 407 case '\n':
447 return line; -  
448 default: -  
449 if(strlen(line) == size) { 408 // Rewind the file by the number of read characters.
450 size = size * 1.5; 409 #if defined ___AsyncIO___
451 real = realloc(line, size * sizeof(*line)); 410 if(SeekAsync(fp, -(i + 1), MODE_CURRENT) == -1) {
452 if(real == NULL) { -  
453 fprintf(stderr, "Memory reallocation failure.\n"); 411 fprintf(stderr, "Could not seek in file.\n");
454 free(line); 412 fprintf(stderr, "index at: %d\n", i);
455 return NULL; 413 return NULL;
456 } 414 }
-   415 #else
-   416 if(fseek(fp, -(i + 1), SEEK_CUR) != 0) {
-   417 fprintf(stderr, "Could not seek in file.\n");
457 line = real; 418 return NULL;
458 } 419 }
459 line[i] = c; 420 #endif
460 line[i + 1] = '\0'; -  
461 break; 421 goto LINE;
462 } 422 }
-   423  
463 ++i; 424 ++i;
464 } 425 }
-   426  
-   427 LINE:
465   428  
-   429 if(i == 0) {
-   430 return NULL;
-   431 }
-   432  
-   433 if((line = malloc(1 * sizeof(*line))) == NULL) {
-   434 fprintf(stderr, "Memory allocation error.\n");
-   435 return NULL;
-   436 }
-   437  
-   438 if((line->string = malloc((i + 1) * sizeof(*line->string))) == NULL) {
466 if(line != NULL) { 439 fprintf(stderr, "Memory allocation error.\n");
-   440 free(line);
-   441 line = NULL;
467 free(line); 442 return NULL;
-   443 }
-   444  
-   445 #if defined ___AsyncIO___
-   446 if(ReadAsync(fp, line->string, i) != i) {
-   447 #else
-   448 if(fread(line->string, sizeof(char), i, fp) != i) {
-   449 #endif
-   450 fprintf(stderr, "Unable to read line.\n");
-   451 free(line->string);
468 } 452 free(line);
469   453 line = NULL;
470 return NULL; 454 return NULL;
471 } 455 }
-   456  
-   457 // Clear newline.
-   458 #if defined ___AsyncIO___
-   459 ReadCharAsync(fp);
-   460 #else
-   461 fgetc(fp);
-   462 #endif
-   463  
-   464 line->length = i;
-   465  
-   466 return line;
-   467 }
472   468  
473 /* 469 /*
474 * 470 *
475 * Delete a file. 471 * Delete a file.
476 */ 472 */
477 #if defined ___AmigaOS___ 473 #if defined ___AmigaOS___
478 BOOL RemoveFile(char *name) { 474 BOOL RemoveFile(char *name) {
479 return DeleteFile(name); 475 return DeleteFile(name);
480 #else 476 #else
481 int RemoveFile(char *name) { 477 int RemoveFile(char *name) {
482 return remove(name) == 0; 478 return remove(name) == 0;
483 #endif 479 #endif
484 } 480 }
485   481  
486   482  
487 /* 483 /*
488 * 484 *
489 * Deletes files. 485 * Deletes files.
490 */ 486 */
491 void RemoveFiles(char **names, int count) { 487 void RemoveFiles(char **names, int count) {
492 int i; 488 int i;
493 for(i = 0; i < count; ++i) { 489 for(i = 0; i < count; ++i) {
494 if(RemoveFile(names[i]) == FALSE) { 490 if(RemoveFile(names[i]) == FALSE) {
495 fprintf(stderr, "Could not remove file '%s'.\n", names[i]); 491 fprintf(stderr, "Could not remove file '%s'.\n", names[i]);
496 continue; 492 continue;
497 } 493 }
498 fprintf(stderr, "Removing file '%s'\n", names[i]); 494 fprintf(stderr, "Removing file '%s'\n", names[i]);
499 } 495 }
500 } 496 }
501   497  
502 /* 498 /*
503 * 499 *
504 * Copies a file to another file by name. 500 * Copies a file to another file by name.
505 */ 501 */
506 void CopyFile(char *a, char *b) { 502 void CopyFile(char *a, char *b) {
507 #if defined ___AsyncIO___ 503 #if defined ___AsyncIO___
508 struct AsyncFile *ap; 504 struct AsyncFile *ap;
509 struct AsyncFile *bp; 505 struct AsyncFile *bp;
510 LONG c; 506 LONG c;
511 #else 507 #else
512 FILE *ap; 508 FILE *ap;
513 FILE *bp; 509 FILE *bp;
514 char c; 510 char c;
515 #endif 511 #endif
516   512  
517 // Open database file for writing. 513 // Open database file for writing.
518 #if defined ___AsyncIO___ 514 #if defined ___AsyncIO___
519 if((ap = OpenAsync(a, MODE_READ, ASYNC_BUF)) == NULL) { 515 if((ap = OpenAsync(a, MODE_READ, ASYNC_BUF)) == NULL) {
520 #else 516 #else
521 if((ap = fopen(a, "r")) == NULL) { 517 if((ap = fopen(a, "r")) == NULL) {
522 #endif 518 #endif
523 fprintf(stderr, "Could not open file '%s' for reading.\n", a); 519 fprintf(stderr, "Could not open file '%s' for reading.\n", a);
524 return; 520 return;
525 } 521 }
526   522  
527 // Open temporary file for reading. 523 // Open temporary file for reading.
528 #if defined ___AsyncIO___ 524 #if defined ___AsyncIO___
529 if((bp = OpenAsync(b, MODE_WRITE, ASYNC_BUF)) == NULL) { 525 if((bp = OpenAsync(b, MODE_WRITE, ASYNC_BUF)) == NULL) {
530 #else 526 #else
531 if((bp = fopen(b, "w")) == NULL) { 527 if((bp = fopen(b, "w")) == NULL) {
532 #endif 528 #endif
533 fprintf(stderr, "Could not open file '%s' for writing.\n", b); 529 fprintf(stderr, "Could not open file '%s' for writing.\n", b);
534   530  
535 // Close database file. 531 // Close database file.
536 #if defined ___AsyncIO___ 532 #if defined ___AsyncIO___
537 CloseAsync(ap); 533 CloseAsync(ap);
538 #else 534 #else
539 fclose(ap); 535 fclose(ap);
540 #endif 536 #endif
541   537  
542 return; 538 return;
543 } 539 }
544   540  
545 #if defined ___AsyncIO___ 541 #if defined ___AsyncIO___
546 while(PROGRAM_RUN && (c = ReadCharAsync(ap)) != -1) { 542 while(PROGRAM_RUN && (c = ReadCharAsync(ap)) != -1) {
547 #else 543 #else
548 while(PROGRAM_RUN && fscanf(ap, "%c", &c) == 1) { 544 while(PROGRAM_RUN && fscanf(ap, "%c", &c) == 1) {
549 #endif 545 #endif
550 #if defined ___AmigaOS___ 546 #if defined ___AmigaOS___
551 // Check if CTRL+C was pressed and abort the program. 547 // Check if CTRL+C was pressed and abort the program.
552 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 548 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
553 PROGRAM_RUN = FALSE; 549 PROGRAM_RUN = FALSE;
554 continue; 550 continue;
555 } 551 }
556 #endif 552 #endif
557 #if defined ___AsyncIO___ 553 #if defined ___AsyncIO___
558 if(WriteCharAsync(bp, (UBYTE)c) != 1) { 554 if(WriteCharAsync(bp, (UBYTE)c) != 1) {
559 #else 555 #else
560 if(fprintf(bp, "%c", c) != 1) { 556 if(fprintf(bp, "%c", c) != 1) {
561 #endif 557 #endif
562 fprintf(stderr, "Could not write to file '%s'.\n", b); 558 fprintf(stderr, "Could not write to file '%s'.\n", b);
563 break; 559 break;
564 } 560 }
565 } 561 }
566   562  
567 #if defined ___AsyncIO___ 563 #if defined ___AsyncIO___
568 CloseAsync(ap); 564 CloseAsync(ap);
569 CloseAsync(bp); 565 CloseAsync(bp);
570 #else 566 #else
571 fclose(ap); 567 fclose(ap);
572 fclose(bp); 568 fclose(bp);
573 #endif 569 #endif
574 } 570 }
575   -  
576   571  
577 /* 572 /*
578 * 573 *
579 * Create a database entry from a line of text. 574 * Create a database entry from a line of text.
580 */ 575 */
581 dbEntry* CreateDatabaseEntry(char *line) { 576 dbEntry* CreateDatabaseEntry(dbLine *line) {
582 dbEntry *entry; 577 dbEntry *entry;
583 char *ptr; 578 char *ptr;
584 int side; 579 int side;
585 int i; 580 int i;
586 int j; 581 int j;
587   582  
588 if((entry = malloc(1 * sizeof(*entry))) == NULL) { 583 if((entry = malloc(1 * sizeof(*entry))) == NULL) {
589 fprintf(stderr, "Memory allocation failure.\n"); 584 fprintf(stderr, "Memory allocation failure.\n");
590 return NULL; 585 return NULL;
591 } 586 }
592   587  
593 if((entry->name = malloc((strlen(line) + 1) * sizeof(*entry->name))) == NULL) { 588 if((entry->name = malloc((line->length + 1) * sizeof(*entry->name))) == NULL) {
594 fprintf(stderr, "Memory allocation failure.\n"); 589 fprintf(stderr, "Memory allocation failure.\n");
595 return NULL; 590 return NULL;
596 } 591 }
597   592  
598 if((entry->path = malloc((strlen(line) + 1) * sizeof(*entry->path))) == NULL) { 593 if((entry->path = malloc((line->length + 1) * sizeof(*entry->path))) == NULL) {
599 fprintf(stderr, "Memory allocation failure.\n"); 594 fprintf(stderr, "Memory allocation failure.\n");
600 return NULL; 595 return NULL;
601 } 596 }
602   597  
603 for(ptr = line, side = 0, i = 0, j = 0; PROGRAM_RUN && *ptr != '\0'; ++ptr) { 598 for(ptr = line->string, side = 0, i = 0, j = 0; PROGRAM_RUN && *ptr != '\0'; ++ptr) {
604 #if defined ___AmigaOS___ 599 #if defined ___AmigaOS___
605 // Check if CTRL+C was pressed and abort the program. 600 // Check if CTRL+C was pressed and abort the program.
606 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { 601 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
607 PROGRAM_RUN = FALSE; 602 PROGRAM_RUN = FALSE;
608 continue; 603 continue;
609 } 604 }
610 #endif 605 #endif
611 switch(*ptr) { 606 switch(*ptr) {
612 case '\t': 607 case '\t':
613 entry->name[i] = '\0'; 608 entry->name[i] = '\0';
614 ++side; 609 ++side;
615 break; 610 break;
616 case '\n': 611 case '\n':
617 entry->path[j] = '\0'; 612 entry->path[j] = '\0';
618 return entry; 613 return entry;
619 default: 614 default:
620 switch(side) { 615 switch(side) {
621 case 0: 616 case 0:
622 entry->name[i++] = *ptr; 617 entry->name[i++] = *ptr;
623 break; 618 break;
624 case 1: 619 case 1:
625 entry->path[j++] = *ptr; 620 entry->path[j++] = *ptr;
626 break; 621 break;
627 } 622 }
628 break; 623 break;
629 } 624 }
630 } 625 }
631   626  
632 return entry; 627 return entry;
633 } 628 }
634   -  
635   629  
636 /* 630 /*
637 * Compare two strings. 631 * Compare two strings.
638 */ 632 */
639 #if defined ___AmigaOS___ 633 #if defined ___AmigaOS___
640 BOOL StringMatch(char *a, char *b) { 634 BOOL StringMatch(char *a, char *b) {
641 #else 635 #else
642 int StringMatch(char *a, char *b) { 636 int StringMatch(char *a, char *b) {
643 #endif 637 #endif
644 #if defined ___AmigaOS___ 638 #if defined ___AmigaOS___
645 ULONG size; 639 ULONG size;
646 BOOL success; 640 BOOL success;
647 UBYTE *pattern; 641 UBYTE *pattern;
648   642  
649 // "must be at least 2 times as large plus 2 bytes" 643 // "must be at least 2 times as large plus 2 bytes"
650 size = strlen(b) * 2 + 2; 644 size = strlen(b) * 2 + 2;
651   645  
652 success = FALSE; 646 success = FALSE;
653   647  
654 if(pattern = AllocVec(size, MEMF_ANY|MEMF_CLEAR)) { 648 if(pattern = AllocVec(size, MEMF_ANY|MEMF_CLEAR)) {
655 switch(ParsePatternNoCase(b, pattern, (LONG)size)) { 649 switch(ParsePatternNoCase(b, pattern, (LONG)size)) {
656 case 1: // the pattern contains wildcards 650 case 1: // the pattern contains wildcards
657 success = MatchPatternNoCase(pattern, a); 651 success = MatchPatternNoCase(pattern, a);
658   652  
659 break; 653 break;
660 case 0: // no wildcards so fall back to exact name match 654 case 0: // no wildcards so fall back to exact name match
661 #if defined ___NOCASE_FS___ 655 #if defined ___NOCASE_FS___
662 success = (Strnicmp(a, b, StringLenMax(a, b)) == 0); 656 success = (Strnicmp(a, b, StringLenMax(a, b)) == 0);
663 #else 657 #else
664 success = (StrnCmp(a, b, StringLenMax(a, b)) == 0); 658 success = (StrnCmp(a, b, StringLenMax(a, b)) == 0);
665 #endif 659 #endif
666   660  
667 break; 661 break;
668 } 662 }
669   663  
670 FreeVec(pattern); 664 FreeVec(pattern);
-   665 pattern = NULL;
671 } 666 }
672   667  
673 return success; 668 return success;
674 #else 669 #else
675 int success; 670 int success;
676 char *e = a; 671 char *e = a;
677 char *n = b; 672 char *n = b;
678   673  
679 success = FALSE; 674 success = FALSE;
680   675  
681 #if defined ___NOCASE_FS___ 676 #if defined ___NOCASE_FS___
682 e = StrUpr(e); 677 StrUpr(e);
683 n = StrUpr(n); 678 StrUpr(n);
684 #endif 679 #endif
685   680  
686 // search for substring 681 // search for substring
687 success = strstr(e, n) != NULL; 682 success = strstr(e, n) != NULL;
688   683  
689 return success; 684 return success;
690 #endif 685 #endif
691 } 686 }
692   687  
693   688  
694   689  
695   690  
696   691  
697   692