/[dtapublic]/projs/dtats/trunk/projs/2018/20180718_ets_ifsfscan/c_main.c
ViewVC logotype

Contents of /projs/dtats/trunk/projs/2018/20180718_ets_ifsfscan/c_main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 199 - (show annotations) (download)
Sun Jul 15 03:07:20 2018 UTC (5 years, 8 months ago) by dashley
Original Path: projs/dtats/trunk/projs/2018/20180112_ifsfscan/c_main.c
File MIME type: text/plain
File size: 22572 byte(s)
Progress towards completion.
1 //$Header$
2 //{f0d952cc-7499-4d5c-9f46-d0b509c5701c}
3 //-------------------------------------------------------------------------------------------------
4 //Copyright (c) 2018, David T. Ashley
5 //
6 //This file is part of "ifsfscan", a program for identifying gross formatting anomalies in source
7 //files (Windows/ASCII text files only).
8 //
9 //This source code and any program in which it is compiled/used is licensed under the MIT License,
10 //reproduced below.
11 //
12 //Permission is hereby granted, free of charge, to any person obtaining a copy of
13 //this software and associated documentation files(the "Software"), to deal in the
14 //Software without restriction, including without limitation the rights to use,
15 //copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the
16 //Software, and to permit persons to whom the Software is furnished to do so,
17 //subject to the following conditions :
18 //
19 //The above copyright notice and this permission notice shall be included in all
20 //copies or substantial portions of the Software.
21 //
22 //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 //SOFTWARE.
29 //-------------------------------------------------------------------------------------------------
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <tchar.h>
34 #include <time.h>
35 #include <windows.h>
36
37
38 #define FCMIOF_HORIZONTAL_BAR_SEP_CHAR ('-')
39 #define FCMIOF_LINE_LEN (78)
40
41 //The last column allowed for a characters below is Column 82 (or it will be
42 //less than aesthetic).
43 const char * const license_preamble[] =
44 {
45 "ifsfscan, (c) 2018 David T. Ashley (dashley@gmail.com)",
46 "This program's source files, executable files, and all other related files",
47 "(such as Visual Studio project files) are licensed under \"The MIT License\",",
48 "reproduced below."
49 };
50
51 const char * const license_text[] =
52 {
53 "Permission is hereby granted, free of charge, to any person obtaining a copy",
54 "of this software and associated documentation files(the \"Software\"), to deal",
55 "in the Software without restriction, including without limitation the rights",
56 "to use, copy, modify, merge, publish, distribute, sublicense, and / or sell",
57 "copies of the Software, and to permit persons to whom the Software is",
58 "furnished to do so, subject to the following conditions:",
59 "",
60 "The above copyright notice and this permission notice shall be included in",
61 "all copies or substantial portions of the Software.",
62 "",
63 "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
64 "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
65 "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
66 "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
67 "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",
68 "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE",
69 "SOFTWARE."
70 };
71
72 const char * const prog_desc_text[] =
73 {
74 "ifsfscan (mnemonic: Ill-Formed Source File SCAN) is a program for detecting",
75 "gross formatting errors in source files (Windows/ASCII text files only). The",
76 "errors detected are non-ASCII characters, tab characters, abnormal",
77 "end-of-line characters, and trailing whitespace on lines.",
78 };
79
80 const char * const prog_help_text[] =
81 {
82 "Usage: ifsfscan [filename_or_wildcard [filename_or_wildcard [...]]]",
83 "",
84 "Notes:",
85 " (1) : Wildcards (\"*\", \"?\") are processed by Windows, so Windows is",
86 " the arbiter of which wildcards are accepted and how they expand.",
87 " (2) : This program never writes to a file, so it cannot destroy data",
88 " (except, possibly, by stdout output redirected to a file).",
89 " (3) : This program accepts no options (like \"-help\" or \"-verbose\").",
90 " (4) : This program accepts only Windows line endings (13-10).",
91 " This program is incompatible with *nix and *nix files.",
92 " (5) : This program accepts only the ASCII character set (it will not",
93 " process UTF-8 or any other encodings).",
94 };
95
96 //--------------------------------------------------------------------------------
97 // T E R M I N A T I O N F U N C T I O N S
98 //--------------------------------------------------------------------------------
99 void CCMFATAL_fatal(const char *desc, const char *file, size_t line)
100 {
101 printf("\n");
102 printf("Fatal error. Must terminate execution.\n");
103 printf("File: %s, Line: %zu.\n", file, line);
104 printf("Error description: %s\n", desc);
105 exit(4); //Error code 4 for error termination.
106 }
107
108 //--------------------------------------------------------------------------------
109 // A S S E R T I O N F U N C T I O N S
110 //--------------------------------------------------------------------------------
111 void USERASSERT_assert(int assertion, const char *file, size_t line)
112 {
113 if (! assertion)
114 {
115 printf("\n");
116 printf("Assertion failed. It is necessary to use the source code to diagnose\n");
117 printf("and resolve this error.\n");
118 printf("File: %s, Line: %zu.\n", file, line);
119 exit(4); //Error code 4 for error termination.
120 }
121 }
122
123 //--------------------------------------------------------------------------------
124 // M E M O R Y A L L O C A T I O N F U N C T I O N S
125 //--------------------------------------------------------------------------------
126 //These functions form a layer over the standard library so that conditions of
127 //concern can be more easily trapped.
128 //--------------------------------------------------------------------------------
129 void *CCMALLOC_malloc(size_t size)
130 {
131 void *rv;
132
133 rv = malloc(size);
134
135 if (!rv)
136 {
137 CCMFATAL_fatal("NULL pointer from malloc()--probable out of memory.",
138 __FILE__,
139 __LINE__);
140 }
141
142 memset(rv, 0, size);
143
144 return(rv);
145 }
146
147 void *CCMALLOC_calloc(size_t num, size_t size)
148 {
149 void *rv;
150
151 rv = calloc(num, size);
152
153 if (!rv)
154 {
155 CCMFATAL_fatal("NULL pointer from calloc()--probable out of memory.",
156 __FILE__,
157 __LINE__);
158 }
159
160 memset(rv, 0, size);
161
162 return(rv);
163 }
164
165 void *CCMALLOC_realloc(void *memblock, size_t size)
166 {
167 void *rv;
168
169 rv = realloc(memblock, size);
170
171 if ((!rv) && (size))
172 {
173 CCMFATAL_fatal("NULL pointer from realloc()--probable out of memory.",
174 __FILE__,
175 __LINE__);
176 }
177
178 return(rv);
179 }
180
181
182 void CCMALLOC_free(void *memblock)
183 {
184 free(memblock);
185 }
186
187 //--------------------------------------------------------------------------------
188 // C H A R A C T E R F U N C T I O N S
189 //--------------------------------------------------------------------------------
190 int CHARFUNC_digit_to_val(char digit)
191 {
192 switch (digit)
193 {
194 case '0': return(0);
195 break;
196 case '1': return(1);
197 break;
198 case '2': return(2);
199 break;
200 case '3': return(3);
201 break;
202 case '4': return(4);
203 break;
204 case '5': return(5);
205 break;
206 case '6': return(6);
207 break;
208 case '7': return(7);
209 break;
210 case '8': return(8);
211 break;
212 case '9': return(9);
213 break;
214 default: return(-1);
215 break;
216 }
217 }
218
219 char CHARFUNC_nibble_to_lc_hex_digit(int nibble)
220 {
221 switch (nibble & 0x0F)
222 {
223 case 0:
224 return('0');
225 break;
226 case 1:
227 return('1');
228 break;
229 case 2:
230 return('2');
231 break;
232 case 3:
233 return('3');
234 break;
235 case 4:
236 return('4');
237 break;
238 case 5:
239 return('5');
240 break;
241 case 6:
242 return('6');
243 break;
244 case 7:
245 return('7');
246 break;
247 case 8:
248 return('8');
249 break;
250 case 9:
251 return('9');
252 break;
253 case 10:
254 return('a');
255 break;
256 case 11:
257 return('b');
258 break;
259 case 12:
260 return('c');
261 break;
262 case 13:
263 return('d');
264 break;
265 case 14:
266 return('e');
267 break;
268 case 15:
269 return('f');
270 break;
271 default:
272 USERASSERT_assert(0, __FILE__, __LINE__);
273 return('?');
274 break;
275 }
276 }
277
278 void CHARFUNC_int_to_lc_hex_rev(int arg, char *s)
279 {
280 int i;
281
282 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
283
284 for (i = 0; i<8; i++)
285 {
286 s[i] = CHARFUNC_nibble_to_lc_hex_digit(arg);
287 arg >>= 4;
288 }
289 }
290
291 //--------------------------------------------------------------------------------
292 // S T R I N G A N D C H A R A C T E R A R R A Y F U N C T I O N S
293 //--------------------------------------------------------------------------------
294 int STRING_contains_wildcard(const char *s)
295 {
296 if (strchr(s, '?') != NULL)
297 return(1);
298 else if (strchr(s, '*') != NULL)
299 return(1);
300 else
301 return(0);
302 }
303
304 int STRING_is_longer_than_maxpath(const char *s)
305 {
306 if (_MAX_PATH <= 5)
307 return(1);
308 else if (strlen(s) > (_MAX_PATH - 5))
309 return(1);
310 else
311 return(0);
312 }
313
314 int STRING_contains_terminating_backslash(const char *s)
315 {
316 size_t i;
317
318 i = strlen(s);
319
320 if (i == 0)
321 {
322 return(0);
323 }
324 else
325 {
326 do
327 {
328 i--;
329 if (s[i] == '\\')
330 return(1);
331 else if ((s[i] != ' ') && (s[i] != '\t'))
332 return(0);
333 } while (i != 0);
334 return(0);
335 }
336 }
337
338 const char *STRING_vcinfo(size_t which)
339 {
340 static const char * const vcinfo[] =
341 {
342 "$HeadURL$",
343 "$Date$",
344 "$Revision$",
345 "$Author$",
346 "Project GUID: {f7d7586a-557c-43cb-bec5-b49765d96a5d}",
347 "c_main.c GUID: {f0d952cc-7499-4d5c-9f46-d0b509c5701c}",
348 "ifsfscan.cpp GUID: {2abd4437-101c-49eb-99ac-c1174f55b626}",
349 };
350
351 if (which < (sizeof(vcinfo) / sizeof(vcinfo[0])))
352 return(vcinfo[which]);
353 else
354 return(NULL);
355 }
356
357 //--------------------------------------------------------------------------------
358 // F O R M A T T E D O U T P U T F U N C T I O N S
359 //--------------------------------------------------------------------------------
360 int FCMIOF_get_line_len(void)
361 {
362 return(FCMIOF_LINE_LEN);
363 }
364
365 void FCMIOF_stream_repchar(FILE *s, char c, unsigned n)
366 {
367 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
368
369 while (n--)
370 fprintf(s, "%c", c);
371 }
372
373 void FCMIOF_repchar(char c, unsigned n)
374 {
375 while (n--)
376 printf("%c", c);
377 }
378
379 void FCMIOF_hline(void)
380 {
381 FCMIOF_repchar(FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);
382 printf("\n");
383 }
384
385 void FCMIOF_stream_hline(FILE *s)
386 {
387 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
388
389 FCMIOF_stream_repchar(s, FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);
390 fprintf(s, "\n");
391 }
392
393 void FCMIOF_stream_bannerheading(FILE *f,
394 char *s,
395 int n_extra_lines)
396 {
397 const int lr_padding = 3;
398 /* The number of spaces on each side of what is printed.
399 */
400 int i;
401 /* General iteration variable.
402 */
403
404 int n_asterisks;
405 int input_arg_len;
406 int n_left_spaces;
407 int n_right_spaces;
408
409 /* Check the file pointer, string pointer, and other par.
410 */
411 USERASSERT_assert(f != NULL, __FILE__, __LINE__);
412 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
413 USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);
414
415 /* Print the right number of solid lines of asterisks to the
416 ** standard output.
417 */
418 for (i = 0; i<n_extra_lines; i++)
419 {
420 FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN);
421 fprintf(f, "\n");
422 }
423
424 /* Figure out how many asterisks to print on each side of the
425 ** argument, and how many spaces. We also need to figure out
426 ** how many characters of the input argument to print--if there
427 ** are too many characters, we need to truncate.
428 */
429 input_arg_len = strlen(s);
430 if (input_arg_len > (FCMIOF_LINE_LEN - 2 * lr_padding - 2))
431 input_arg_len = FCMIOF_LINE_LEN - 2 * lr_padding - 2;
432
433 n_asterisks = (FCMIOF_LINE_LEN - 2 * lr_padding - input_arg_len) / 2;
434
435 n_left_spaces = lr_padding;
436
437 if ((FCMIOF_LINE_LEN - 2 * lr_padding - input_arg_len) % 2)
438 {
439 /* Odd, need to pad the right by one. */
440 n_right_spaces = lr_padding + 1;
441 }
442 else
443 {
444 n_right_spaces = lr_padding;
445 }
446
447 /* Print the text. */
448 FCMIOF_stream_repchar(f, '*', n_asterisks);
449 FCMIOF_stream_repchar(f, ' ', n_left_spaces);
450 for (i = 0; i<input_arg_len; i++)
451 fprintf(f, "%c", s[i]);
452 FCMIOF_stream_repchar(f, ' ', n_right_spaces);
453 FCMIOF_stream_repchar(f, '*', n_asterisks);
454 fprintf(f, "\n");
455
456 /* Print the right number of solid lines of asterisks to the
457 ** standard output.
458 */
459 for (i = 0; i<n_extra_lines; i++)
460 {
461 FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN);
462 fprintf(f, "\n");
463 }
464 }
465
466 void FCMIOF_bannerheading(char *s, int n_extra_lines)
467 {
468 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
469 USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);
470
471 FCMIOF_stream_bannerheading(stdout, s, n_extra_lines);
472 }
473
474 void FCMIOF_time_stream(FILE *s, time_t ltime)
475 {
476 char *p;
477
478 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
479
480 time(&ltime);
481
482 p = ctime(&ltime);
483
484 if (p)
485 {
486 int i;
487
488 for (i = 11; i<19; i++)
489 fprintf(s, "%c", p[i]);
490 fprintf(s, " ");
491 for (i = 0; i<10; i++)
492 fprintf(s, "%c", p[i]);
493 fprintf(s, " ");
494 for (i = 20; i<24; i++)
495 fprintf(s, "%c", p[i]);
496 }
497 else
498 {
499 fprintf(s, "??? ??? ?? ??:??:?? ????");
500 }
501 }
502
503 int is_legal_non_eol_character(char c)
504 {
505 if ((c >= 32) && (c <= 126))
506 return(1);
507 else
508 return(0);
509 }
510
511 int is_illegal_non_eol_character(char c)
512 {
513 if (((c < 32) || (c > 126)) && (c != 13) && (c != 10))
514 return(1);
515 else
516 return(0);
517 }
518
519 int is_tab(char c)
520 {
521 if (c == 9)
522 return(1);
523 else
524 return(0);
525 }
526
527 int is_cr(char c)
528 {
529 if (c == 13)
530 return(1);
531 else
532 return(0);
533 }
534
535 int is_lf(char c)
536 {
537 if (c == 10)
538 return(1);
539 else
540 return(0);
541 }
542
543 void emit_human_friendly_llu(unsigned long long arg)
544 {
545 size_t i, len;
546 char buffer[100];
547
548 sprintf(buffer, "%llu", arg);
549 len = strlen(buffer);
550
551 for (i = 0; i < len; i++)
552 {
553 printf("%c", buffer[i]);
554 if (((len-i-1) != 0) && (((len - i - 1) % 3) == 0))
555 printf(",");
556 }
557 }
558
559 void emit_file_pos_3tuple(unsigned long long line, unsigned long long col, unsigned long long offset)
560 {
561 printf(" Line: ");
562 emit_human_friendly_llu(line);
563 printf(", Col: ");
564 emit_human_friendly_llu(col);
565 printf(", Offset: ");
566 emit_human_friendly_llu(offset);
567 printf("\n");
568 }
569
570 void process_opened_handle(FILE *f)
571 {
572 unsigned long long char_no;
573 unsigned long long line_no;
574 unsigned long long col_no;
575 enum {PST_LINE, PST_CR_FOUND, PST_LF_FOUND} state = PST_LINE;
576 int exit_flag = 0;
577 char in_c, prev_c;
578 unsigned char in_uc;
579 int in_i;
580
581 in_i = fgetc(f);
582
583 if (in_i == EOF)
584 {
585 //Zero-length file or error. Because this tool isn't critical, no need to figure out which, exactly.
586 printf(" Zero-length file.\n");
587 return;
588 }
589
590 prev_c = ' ';
591 char_no = 0;
592 line_no = 1;
593 col_no = 1;
594 in_c = in_i & 0xff;
595 in_uc = in_i & 0xff;
596
597 do
598 {
599 //Illegal characters always get flagged.
600 if (is_illegal_non_eol_character(in_c))
601 {
602 emit_file_pos_3tuple(line_no, col_no, char_no);
603 printf(" Illegal character: 0x%02x.\n", ((unsigned)in_uc));
604 }
605
606 //printf("Character: %02x State: %u\n", in_c, (unsigned)state);
607
608 //Run through the state machine, which would look for bad EOL sequences.
609 switch (state)
610 {
611 case PST_LINE:
612 //Processing non-EOL characters.
613 if (is_lf(in_c))
614 {
615 if ((char_no != 0) && (prev_c == ' '))
616 {
617 emit_file_pos_3tuple(line_no, col_no, char_no);
618 printf(" Line contains trailing whitespace.\n");
619 }
620
621 //Line feeds not allowed without preceding carriage return.
622 emit_file_pos_3tuple(line_no, col_no, char_no);
623 printf(" Out of sequence line feed character (0x0a).\n");
624 line_no++;
625 col_no = 1;
626 state = PST_LF_FOUND;
627 }
628 else if (is_cr(in_c))
629 {
630 if ((char_no != 0) && (prev_c == ' '))
631 {
632 emit_file_pos_3tuple(line_no, col_no, char_no);
633 printf(" Line contains trailing whitespace.\n");
634 }
635
636 //Legal
637 state = PST_CR_FOUND;
638 }
639 else
640 {
641 //Ordinary character.
642 col_no++;
643 }
644 break;
645 case PST_CR_FOUND:
646 if (is_lf(in_c))
647 {
648 //Legal
649 line_no++;
650 col_no = 1;
651 state = PST_LF_FOUND;
652 }
653 else if (is_cr(in_c))
654 {
655 //Back-to-back carriage returns not allowed.
656 emit_file_pos_3tuple(line_no, col_no, char_no);
657 printf(" Out of sequence carriage return character (0x0D).\n");
658 col_no++;
659 }
660 else
661 {
662 //Ordinary character. Illegal, because LF must follow CR.
663 emit_file_pos_3tuple(line_no, col_no, char_no);
664 printf(" Carriage return followed by 0x%02x rather than LF.\n", (unsigned)in_uc);
665 col_no++;
666 }
667 break;
668 case PST_LF_FOUND:
669 if (is_lf(in_c))
670 {
671 //Illegal. Back-to-back line feeds not allowed.
672 emit_file_pos_3tuple(line_no, col_no, char_no);
673 printf(" Out of sequence line feed character (0x0A).\n");
674 line_no++;
675 col_no = 1;
676 }
677 else if (is_cr(in_c))
678 {
679 //Legal. Blank lines are fine.
680 col_no++;
681 state = PST_CR_FOUND;
682 }
683 else
684 {
685 //Ordinary character. Legal.
686 col_no++;
687 state = PST_LINE;
688 }
689 break;
690 default:
691 USERASSERT_assert(0, __FILE__, __LINE__);
692 break;
693 }
694
695 in_i = fgetc(f);
696 prev_c = in_c;
697 in_c = in_i & 0xff;
698 in_uc = in_i & 0xff;
699 char_no++;
700 if (in_i == EOF)
701 {
702 if (state != PST_LF_FOUND)
703 {
704 emit_file_pos_3tuple(line_no, col_no, char_no-1);
705 printf(" Final line of file does not have CR/LF sequence.\n");
706 }
707 if ((state == PST_LINE) && (prev_c == ' '))
708 {
709 emit_file_pos_3tuple(line_no, col_no, char_no - 1);
710 printf(" Final line contains trailing whitespace.\n");
711 }
712
713 exit_flag = 1;
714 }
715 } while (!exit_flag);
716 }
717
718 void process_file_by_name(const char *s)
719 {
720 FILE *f;
721
722 printf(" %s\n", s);
723
724 f = fopen(s, "rb");
725
726 if (!f)
727 {
728 printf(" fopen() failed.\n");
729 }
730 else
731 {
732 process_opened_handle(f);
733
734 if (fclose(f))
735 {
736 printf(" fclose() failed.\n");
737 }
738 }
739 }
740
741 void process_filename_or_wildcard(const char *fname_or_wildcard)
742 {
743 HANDLE hFind;
744 WIN32_FIND_DATA FindFileData;
745
746 //Incoming pointer is worthy of an assertion. The OS should not every deliver
747 //a NULL pointer or empty string to us.
748 USERASSERT_assert(fname_or_wildcard != NULL, __FILE__, __LINE__);
749 USERASSERT_assert(strlen(fname_or_wildcard) > 0, __FILE__, __LINE__);
750
751 printf("%s\n", fname_or_wildcard);
752
753 if (STRING_is_longer_than_maxpath(fname_or_wildcard))
754 {
755 printf(" Specified filename or wildcard too long--cannot process.\n");
756 }
757 else if (STRING_contains_terminating_backslash(fname_or_wildcard))
758 {
759 printf(" Specified filename or wildcard contains terminating \"\\\"--cannot process.\n");
760 }
761 else if (STRING_contains_wildcard(fname_or_wildcard))
762 {
763 hFind = FindFirstFile((TCHAR *)fname_or_wildcard, &FindFileData);
764
765 if (hFind == INVALID_HANDLE_VALUE)
766 {
767 printf(" Wildcard does not match existing files or is invalid.\n");
768 }
769 else
770 {
771 char path_drive[_MAX_PATH + 5];
772 char path_dir[_MAX_PATH + 5];
773 char path_fname[_MAX_PATH + 5];
774 char path_ext[_MAX_PATH + 5];
775 char path_full[_MAX_PATH + 5];
776
777 if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
778 {
779 _splitpath(fname_or_wildcard, path_drive, path_dir, path_fname, path_ext);
780
781 strcpy(path_full, path_drive);
782 strcat(path_full, path_dir);
783 strcat(path_full, FindFileData.cFileName);
784
785 process_file_by_name(path_full);
786 }
787
788 while (FindNextFile(hFind, &FindFileData) != 0)
789 {
790 if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
791 {
792 _splitpath(fname_or_wildcard, path_drive, path_dir, path_fname, path_ext);
793
794 strcpy(path_full, path_drive);
795 strcat(path_full, path_dir);
796 strcat(path_full, FindFileData.cFileName);
797
798 process_file_by_name(path_full);
799 }
800 }
801 }
802
803 if (hFind != INVALID_HANDLE_VALUE)
804 {
805 FindClose(hFind);
806 }
807 }
808 else
809 {
810 process_file_by_name(fname_or_wildcard);
811 }
812 }
813
814 void emit_no_par_documentation(void)
815 {
816 size_t i;
817
818 FCMIOF_stream_hline(stdout);
819 for (i = 0; i < (sizeof(prog_desc_text) / sizeof(prog_desc_text[0])); i++)
820 printf("%s\n", prog_desc_text[i]);
821 FCMIOF_stream_hline(stdout);
822 for (i = 0; i < (sizeof(license_preamble) / sizeof(license_preamble[0])); i++)
823 printf("%s\n", license_preamble[i]);
824 FCMIOF_stream_hline(stdout);
825 for (i = 0; i < (sizeof(license_text) / sizeof(license_text[0])); i++)
826 printf("%s\n", license_text[i]);
827 FCMIOF_stream_hline(stdout);
828 printf("Program built on %s at %s.\n", __DATE__, __TIME__);
829 i = 0;
830 while (STRING_vcinfo(i))
831 {
832 printf("%s\n", STRING_vcinfo(i));
833 i++;
834 }
835 FCMIOF_stream_hline(stdout);
836 for (i = 0; i < (sizeof(prog_help_text) / sizeof(prog_help_text[0])); i++)
837 printf("%s\n", prog_help_text[i]);
838 FCMIOF_stream_hline(stdout);
839 }
840
841 void emit_execution_preamble(void)
842 {
843 FCMIOF_stream_hline(stdout);
844 printf("Use \"ifsfscan\" with no parameters to obtain license and help information.\n");
845 FCMIOF_stream_hline(stdout);
846 }
847
848 int c_main(int argc, char **argv)
849 {
850 int i;
851
852 if (argc <= 1)
853 {
854 //This is most likely someone trying to figure out what the program is or does.
855 //Spit everything.
856 emit_no_par_documentation();
857 }
858 else
859 {
860 emit_execution_preamble();
861
862 //Every argument beyond the program name has to be either a file name or
863 //wildcard. Just process them in order.
864 for (i = 1; i < argc; i++)
865 process_filename_or_wildcard(argv[i]);
866
867 FCMIOF_stream_hline(stdout);
868 }
869
870 return 0;
871 }

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision URL Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25