HuntnGather – Blame information for rev 33

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 *
48 * Converts a string to case.
49 */
50 void StrUpr(char *s) {
51 while(*s != '\0') {
52 #if defined ___AmigaOS___
53 *s = ToUpper(*s);
54 #else
55 *s = toupper((unsigned char)*s);
56 #endif
57 ++s;
58 }
59 }
60  
61 /*
62 *
63 * Gets the filesystem type of a file or directory.
64 */
65 FS_TYPE GetFsType(char *path) {
66 #if defined ___AmigaOS___
67 struct FileInfoBlock *FIB;
68 BPTR lock;
69 #else
70 struct stat dirStat;
71 #endif
72  
73 #if defined ___AmigaOS___
74 if((lock = Lock(path, ACCESS_READ)) == NULL) {
75 fprintf(stderr, "Lock failed for path '%s'.\n", path);
76 return UNKNOWN;
77 }
78  
79 if((FIB = AllocDosObject(DOS_FIB, NULL)) == NULL) {
80 fprintf(stderr, "Could not allocated file information block for path '%s'.\n", path);
81 UnLock(lock);
82 return UNKNOWN;
83 }
84  
85 if(Examine(lock, FIB) == FALSE) {
86 fprintf(stderr, "Path '%s' could not be examined.\n", path);
87 UnLock(lock);
88 FreeDosObject(DOS_FIB, FIB);
89 return UNKNOWN;
90 }
91  
92 if(FIB->fib_DirEntryType < 0) {
93 UnLock(lock);
94 FreeDosObject(DOS_FIB, FIB);
95 return REGULAR;
96 #else
97 stat(path, &dirStat);
98 if(!S_ISDIR(dirStat.st_mode)) {
99 return REGULAR;
100 #endif
101 }
102  
103 #if defined ___AmigaOS___
104 UnLock(lock);
105 FreeDosObject(DOS_FIB, FIB);
106 #endif
107  
108 return DIRECTORY;
109 }
110  
111 /*
112 *
113 * Counts the lines of a file.
114 */
115 int CountFileLines(char *dbFile) {
116 #if defined ___AsyncIO___
117 struct AsyncFile *fp;
118 LONG c;
119 #else
120 FILE *fp;
121 char c;
122 #endif
123 int lines;
124  
125 #if defined ___AsyncIO___
126 if((fp = OpenAsync(dbFile, MODE_READ, ASYNC_BUF)) == NULL) {
127 #else
128 if((fp = fopen(dbFile, "r")) == NULL) {
129 #endif
130 fprintf(stderr, "Could not open file '%s' for reading.\n", dbFile);
131 return -1;
132 }
133  
134 lines = 0;
135 if(PROGRAM_VERBOSE) {
136 fprintf(stdout, "Counting lines in '%s'...\r", dbFile);
137 }
138  
139 #if defined ___AsyncIO___
140 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) {
141 #else
142 while(run && fscanf(fp, "%c", &c) == 1) {
143 #endif
144 #if defined ___AmigaOS___
145 // Check if CTRL+C was pressed and abort the program.
146 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
147 PROGRAM_RUN = FALSE;
148 continue;
149 }
150 #endif
151 switch(c) {
152 case '\n':
153 ++lines;
154  
155 if(PROGRAM_VERBOSE) {
156 fprintf(stdout, "Counting lines in '%s': %d.\r", dbFile, lines);
157 }
158 break;
159 }
160 }
161  
162 #if defined ___AsyncIO___
163 CloseAsync(fp);
164 #else
165 fclose(fp);
166 #endif
167  
168 if(PROGRAM_VERBOSE) {
169 fprintf(stdout, "\n");
170 }
171  
172 return lines;
173 }
174  
175 /*
176 *
177 * Gets the absolute path to file by name.
178 */
179 char *PathToAbsolute(char *path) {
180 char *abs;
181 #if defined ___AmigaOS___
182 BPTR lock;
183 #endif
184  
185 #if defined ___AmigaOS___
186 if((abs = malloc(PATH_MAX * sizeof(*abs))) == NULL) {
187 fprintf(stderr, "Memory allocation failure.\n");
188 return NULL;
189 }
190 if((lock = Lock(path, SHARED_LOCK)) == 0) {
191 fprintf(stderr, "Lock failed for path '%s'.\n", path);
192 return NULL;
193 }
194 if(NameFromLock(lock, abs, PATH_MAX) == FALSE) {
195 fprintf(stderr, "Full path for '%s' could not be retrieved.\n", path);
196 UnLock(lock);
197 return NULL;
198 }
199 UnLock(lock);
200 #else
201 /*
202 * On POSIX this should be:
203 * abs = realpath(path, NULL);
204 *
205 */
206 if((abs = malloc((strlen(path) + 1) * sizeof(*abs))) == NULL) {
207 fprintf(stderr, "Memory allocation failure.\n");
208 return NULL;
209 }
210 sprintf(abs, "%s", path);
211 #endif
212  
213 return abs;
214 }
215  
216 /*
217 *
218 * Compares path parts for equality.
219 */
220 #if defined ___AmigaOS___
221 BOOL PathCompare(char *path, char *look) {
222 #else
223 int PathCompare(char *path, char *look) {
224 #endif
225 char *a;
226 char *b;
227  
228 for(a = path, b = look; *a != '\0' && *b != '\0'; ++a, ++b) {
229 if(*b != '\0' && *a != *b) {
230 return FALSE;
231 }
232 }
233  
234 return *b == '\0';
235 }
236  
237 /*
238 *
239 * Creates a temporary file and returns its name.
240 */
241 char *CreateTemporaryFile(void) {
242 char *name;
243  
244 name = tmpnam(NULL);
245  
246 return name;
247 }
248  
249 /*
250 *
251 * Create multiple temporary files and return their names.
252 */
253 char **CreateTemporaryFiles(int files) {
254 char **tmpNames;
255 int count;
256  
257 if((tmpNames = malloc(files * sizeof(*tmpNames))) == NULL) {
258 fprintf(stderr, "Memory allocation failure.\n");
259 return NULL;
260 }
261  
262 if(PROGRAM_VERBOSE) {
263 fprintf(stdout, "Creating temporary files...\r");
264 }
265  
266 count = files;
267 while(PROGRAM_RUN && --count > -1) {
268 #if defined ___AmigaOS___
269 // Check if CTRL+C was pressed and abort the program.
270 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
271 PROGRAM_RUN = FALSE;
272 continue;
273 }
274 #endif
275 tmpNames[count] = CreateTemporaryFile();
276  
277 if(PROGRAM_VERBOSE) {
278 fprintf(stdout, "Creating temporary files: %d%%.\r", 100 - (int)(((float)count / files) * 100.0));
279 }
280 }
281  
282 if(PROGRAM_VERBOSE) {
283 fprintf(stdout, "\n");
284 }
285  
286 return tmpNames;
287 }
288  
289 /*
290 *
291 * Skips a line in a file.
292 */
293 #if defined ___AsyncIO___
294 void SkipLine(struct AsyncFile *fp) {
295 LONG c;
296 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) {
297 #else
298 void SkipLine(FILE *fp) {
299 char c;
300 while(PROGRAM_RUN && fscanf(fp, "%c", &c) == 1) {
301 #endif
302 #if defined ___AmigaOS___
303 // Check if CTRL+C was pressed and abort the program.
304 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
305 PROGRAM_RUN = FALSE;
306 continue;
307 }
308 #endif
309 switch(c) {
310 case '\n':
311 return;
312 }
313 }
314 }
315  
316  
317 /*
318 *
319 * Peeks at a line from a file.
320 */
321 #if defined ___AsyncIO___
322 char *PeekLine(struct AsyncFile *fp) {
323 LONG c;
324 #else
325 char *PeekLine(FILE *fp) {
326 char c;
327 #endif
328 char *line = NULL;
329 char *real = NULL;
330 int size;
331 int i;
332  
333 size = LINE_BUF;
334 if((line = malloc(size * sizeof(*line))) == NULL) {
335 fprintf(stderr, "Memory allocation failure.\n");
336 return NULL;
337 }
338  
339 i = 0;
340 #if defined ___AsyncIO___
341 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) {
342 #else
343 while(PROGRAM_RUN && fscanf(fp, "%c", &c) == 1) {
344 #endif
345 #if defined ___AmigaOS___
346 // Check if CTRL+C was pressed and abort the program.
347 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
348 PROGRAM_RUN = FALSE;
349 continue;
350 }
351 #endif
352 switch(c) {
353 case '\n':
354 // Rewind the file by the number of read characters.
355 #if defined ___AsyncIO___
356 if(SeekAsync(fp, -(i + 1), MODE_CURRENT) == -1) {
357 fprintf(stderr, "Could not seek in file.\n");
358 free(line);
359 return NULL;
360 }
361 #else
362 if(fseek(fp, -(i + 1), SEEK_CUR) != 0) {
363 fprintf(stderr, "Could not seek in file.\n");
364 free(line);
365 return NULL;
366 }
367 #endif
368 return line;
369 default:
370 if(strlen(line) == size) {
371 size = size * 1.5;
372 real = realloc(line, size * sizeof(*line));
373 if(real == NULL) {
374 fprintf(stderr, "Memory reallocation failure.\n");
375 free(line);
376 return NULL;
377 }
378 line = real;
379 }
380 line[i] = c;
381 line[i + 1] = '\0';
382 break;
383 }
384 ++i;
385 }
386  
387 if(line != NULL) {
388 free(line);
389 }
390  
391 return NULL;
392 }
393  
394 /*
395 *
396 * Read a line from a file.
397 */
398 #if defined ___AsyncIO___
399 char *ReadLine(struct AsyncFile *fp) {
400 LONG c;
401 #else
402 char *ReadLine(FILE *fp) {
403 char c;
404 #endif
405 char *line = NULL;
406 char *real = NULL;
407 int size;
408 int i;
409  
410 size = LINE_BUF;
411 if((line = malloc(size * sizeof(*line))) == NULL) {
412 fprintf(stderr, "Memory allocation failure.\n");
413 return NULL;
414 }
415  
416 i = 0;
417 #if defined ___AsyncIO___
418 while(PROGRAM_RUN && (c = ReadCharAsync(fp)) != -1) {
419 #else
420 while(PROGRAM_RUN && fscanf(fp, "%c", &c) == 1) {
421 #endif
422 #if defined ___AmigaOS___
423 // Check if CTRL+C was pressed and abort the program.
424 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
425 PROGRAM_RUN = FALSE;
426 continue;
427 }
428 #endif
429 switch(c) {
430 case '\n':
431 return line;
432 default:
433 if(strlen(line) == size) {
434 size = size * 1.5;
435 real = realloc(line, size * sizeof(*line));
436 if(real == NULL) {
437 fprintf(stderr, "Memory reallocation failure.\n");
438 free(line);
439 return NULL;
440 }
441 line = real;
442 }
443 line[i] = c;
444 line[i + 1] = '\0';
445 break;
446 }
447 ++i;
448 }
449  
450 if(line != NULL) {
451 free(line);
452 }
453  
454 return NULL;
455 }
456  
457 /*
458 *
459 * Delete a file.
460 */
461 #if defined ___AmigaOS___
462 BOOL RemoveFile(char *name) {
463 return DeleteFile(name);
464 #else
465 int RemoveFile(char *name) {
466 return remove(name) == 0;
467 #endif
468 }
469  
470  
471 /*
472 *
473 * Deletes files.
474 */
475 void RemoveFiles(char **names, int count) {
476 int i;
477 for(i = 0; i < count; ++i) {
478 if(RemoveFile(names[i]) == FALSE) {
479 fprintf(stderr, "Could not remove file '%s'.\n", names[i]);
480 continue;
481 }
482 fprintf(stderr, "Removing file '%s'\n", names[i]);
483 }
484 }
485  
486 /*
487 *
488 * Copies a file to another file by name.
489 */
490 void CopyFile(char *a, char *b) {
491 #if defined ___AsyncIO___
492 struct AsyncFile *ap;
493 struct AsyncFile *bp;
494 LONG c;
495 #else
496 FILE *ap;
497 FILE *bp;
498 char c;
499 #endif
500  
501 // Open database file for writing.
502 #if defined ___AsyncIO___
503 if((ap = OpenAsync(a, MODE_READ, ASYNC_BUF)) == NULL) {
504 #else
505 if((ap = fopen(a, "r")) == NULL) {
506 #endif
507 fprintf(stderr, "Could not open file '%s' for reading.\n", a);
508 return;
509 }
510  
511 // Open temporary file for reading.
512 #if defined ___AsyncIO___
513 if((bp = OpenAsync(b, MODE_WRITE, ASYNC_BUF)) == NULL) {
514 #else
515 if((bp = fopen(b, "w")) == NULL) {
516 #endif
517 fprintf(stderr, "Could not open file '%s' for writing.\n", b);
518  
519 // Close database file.
520 #if defined ___AsyncIO___
521 CloseAsync(ap);
522 #else
523 fclose(ap);
524 #endif
525  
526 return;
527 }
528  
529 #if defined ___AsyncIO___
530 while(PROGRAM_RUN && (c = ReadCharAsync(ap)) != -1) {
531 #else
532 while(PROGRAM_RUN && fscanf(ap, "%c", &c) == 1) {
533 #endif
534 #if defined ___AmigaOS___
535 // Check if CTRL+C was pressed and abort the program.
536 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
537 PROGRAM_RUN = FALSE;
538 continue;
539 }
540 #endif
541 #if defined ___AsyncIO___
542 if(WriteCharAsync(bp, (UBYTE)c) != 1) {
543 #else
544 if(fprintf(bp, "%c", c) != 1) {
545 #endif
546 fprintf(stderr, "Could not write to file '%s'.\n", b);
547 break;
548 }
549 }
550  
551 #if defined ___AsyncIO___
552 CloseAsync(ap);
553 CloseAsync(bp);
554 #else
555 fclose(ap);
556 fclose(bp);
557 #endif
558 }
559  
560  
561 /*
562 *
563 * Create a database entry from a line of text.
564 */
565 dbEntry* CreateDatabaseEntry(char *line) {
566 dbEntry *entry;
567 char *ptr;
568 int side;
569 int i;
570 int j;
571  
572 if((entry = malloc(1 * sizeof(*entry))) == NULL) {
573 fprintf(stderr, "Memory allocation failure.\n");
574 return NULL;
575 }
576  
577 if((entry->name = malloc((strlen(line) + 1) * sizeof(*entry->name))) == NULL) {
578 fprintf(stderr, "Memory allocation failure.\n");
579 return NULL;
580 }
581  
582 if((entry->path = malloc((strlen(line) + 1) * sizeof(*entry->path))) == NULL) {
583 fprintf(stderr, "Memory allocation failure.\n");
584 return NULL;
585 }
586  
587 for(ptr = line, side = 0, i = 0, j = 0; PROGRAM_RUN && *ptr != '\0'; ++ptr) {
588 #if defined ___AmigaOS___
589 // Check if CTRL+C was pressed and abort the program.
590 if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
591 PROGRAM_RUN = FALSE;
592 continue;
593 }
594 #endif
595 switch(*ptr) {
596 case '\t':
597 entry->name[i] = '\0';
598 ++side;
599 break;
600 case '\n':
601 entry->path[j] = '\0';
602 return entry;
603 default:
604 switch(side) {
605 case 0:
606 entry->name[i++] = *ptr;
607 break;
608 case 1:
609 entry->path[j++] = *ptr;
610 break;
611 }
612 break;
613 }
614 }
615  
616 return entry;
617 }
618  
619  
620