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

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