HuntnGather – Blame information for rev 37

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