/[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 197 - (show annotations) (download)
Sun Jul 15 01:26:18 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: 21349 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 printf("%llu", arg);
546 }
547
548 void emit_file_pos_3tuple(unsigned long long line, unsigned long long col, unsigned long long offset)
549 {
550 printf(" Line: ");
551 emit_human_friendly_llu(line);
552 printf(", Col: ");
553 emit_human_friendly_llu(col);
554 printf(", Offset: ");
555 emit_human_friendly_llu(offset);
556 printf("\n");
557 }
558
559 void process_opened_handle(FILE *f)
560 {
561 unsigned long long char_no;
562 unsigned long long line_no;
563 unsigned long long col_no;
564 enum {PST_LINE, PST_CR_FOUND, PST_LF_FOUND} state = PST_LINE;
565 int exit_flag = 0;
566 char in_c, prev_c;
567 unsigned char in_uc;
568 int in_i;
569
570 in_i = fgetc(f);
571
572 if (in_i == EOF)
573 {
574 //Zero-length file or error. Because this tool isn't critical, no need to figure out which, exactly.
575 printf(" Zero-length file.\n");
576 return;
577 }
578
579 prev_c = ' ';
580 char_no = 0;
581 line_no = 1;
582 col_no = 1;
583 in_c = in_i & 0xFF;
584 in_uc = in_i & 0xFF;
585
586 do
587 {
588 //Illegal characters always get flagged.
589 if (is_illegal_non_eol_character(in_c))
590 {
591 emit_file_pos_3tuple(line_no, col_no, char_no);
592 printf(" Illegal character: 0x%02x.\n", ((unsigned)in_uc));
593 }
594
595 //Run through the state machine, which would look for bad EOL sequences.
596 switch (state)
597 {
598 case PST_LINE:
599 if (is_lf(in_c))
600 {
601 //Line feeds not allowed without preceding carriage return.
602 emit_file_pos_3tuple(line_no, col_no, char_no);
603 printf(" Out of sequence line feed character (0x0a)\n");
604 line_no++;
605 col_no = 1;
606 state = PST_LF_FOUND;
607 }
608 else if (is_cr(in_c))
609 {
610 //Legal
611 state = PST_CR_FOUND;
612 }
613 else
614 {
615 //Ordinary character.
616 col_no++;
617 }
618 break;
619 case PST_CR_FOUND:
620 if (is_lf(in_c))
621 {
622 //Legal
623 line_no++;
624 col_no = 1;
625 state = PST_LF_FOUND;
626 }
627 else if (is_cr(in_c))
628 {
629 //Back-to-back carriage returns not allowed.
630 emit_file_pos_3tuple(line_no, col_no, char_no);
631 printf(" Out of sequence carriage return character (0x0D)\n");
632 col_no++;
633 }
634 else
635 {
636 //Ordinary character. Illegal, because LF must follow CR.
637 emit_file_pos_3tuple(line_no, col_no, char_no);
638 printf(" Carriage return followed by 0x%02x rather than LF.\n", (unsigned)in_uc);
639 col_no++;
640 }
641 break;
642 case PST_LF_FOUND:
643 if (is_lf(in_c))
644 {
645 //Illegal. Back-to-back line feeds not allowed.
646 emit_file_pos_3tuple(line_no, col_no, char_no);
647 printf(" Out of sequence line feed character (0x0A).\n");
648 line_no++;
649 col_no = 1;
650 }
651 else if (is_cr(in_c))
652 {
653 //Legal. Blank lines are fine.
654 col_no++;
655 state = PST_LF_FOUND;
656 }
657 else
658 {
659 //Ordinary character. Legal.
660 col_no++;
661 state = PST_LINE;
662 }
663 break;
664 default:
665 USERASSERT_assert(0, __FILE__, __LINE__);
666 break;
667 }
668
669
670 in_i = fgetc(f);
671 char_no++;
672 if (in_i == EOF)
673 exit_flag = 1;
674 in_c = in_i & 0xff;
675 in_uc = in_i & 0xff;
676
677 } while (!exit_flag);
678
679 }
680
681 void process_file_by_name(const char *s)
682 {
683 FILE *f;
684
685 printf(" %s\n", s);
686
687 f = fopen(s, "rb");
688
689 if (!f)
690 {
691 printf(" fopen() failed.\n");
692 }
693 else
694 {
695 process_opened_handle(f);
696
697 if (fclose(f))
698 {
699 printf(" fclose() failed.\n");
700 }
701 }
702 }
703
704 void process_filename_or_wildcard(const char *fname_or_wildcard)
705 {
706 HANDLE hFind;
707 WIN32_FIND_DATA FindFileData;
708
709 //Incoming pointer is worthy of an assertion. The OS should not every deliver
710 //a NULL pointer or empty string to us.
711 USERASSERT_assert(fname_or_wildcard != NULL, __FILE__, __LINE__);
712 USERASSERT_assert(strlen(fname_or_wildcard) > 0, __FILE__, __LINE__);
713
714 printf("%s\n", fname_or_wildcard);
715
716 if (STRING_is_longer_than_maxpath(fname_or_wildcard))
717 {
718 printf(" Specified filename or wildcard too long--cannot process.\n");
719 }
720 else if (STRING_contains_terminating_backslash(fname_or_wildcard))
721 {
722 printf(" Specified filename or wildcard contains terminating \"\\\"--cannot process.\n");
723 }
724 else if (STRING_contains_wildcard(fname_or_wildcard))
725 {
726 hFind = FindFirstFile((TCHAR *)fname_or_wildcard, &FindFileData);
727
728 if (hFind == INVALID_HANDLE_VALUE)
729 {
730 printf(" Wildcard does not match existing files or is invalid.\n");
731 }
732 else
733 {
734 char path_drive[_MAX_PATH + 5];
735 char path_dir[_MAX_PATH + 5];
736 char path_fname[_MAX_PATH + 5];
737 char path_ext[_MAX_PATH + 5];
738 char path_full[_MAX_PATH + 5];
739
740 if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
741 {
742 _splitpath(fname_or_wildcard, path_drive, path_dir, path_fname, path_ext);
743
744 strcpy(path_full, path_drive);
745 strcat(path_full, path_dir);
746 strcat(path_full, FindFileData.cFileName);
747
748 process_file_by_name(path_full);
749 }
750
751 while (FindNextFile(hFind, &FindFileData) != 0)
752 {
753 if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
754 {
755 _splitpath(fname_or_wildcard, path_drive, path_dir, path_fname, path_ext);
756
757 strcpy(path_full, path_drive);
758 strcat(path_full, path_dir);
759 strcat(path_full, FindFileData.cFileName);
760
761 process_file_by_name(path_full);
762 }
763 }
764 }
765
766 if (hFind != INVALID_HANDLE_VALUE)
767 {
768 FindClose(hFind);
769 }
770 }
771 else
772 {
773 process_file_by_name(fname_or_wildcard);
774 }
775 }
776
777 void emit_no_par_documentation(void)
778 {
779 size_t i;
780
781 FCMIOF_stream_hline(stdout);
782 for (i = 0; i < (sizeof(prog_desc_text) / sizeof(prog_desc_text[0])); i++)
783 printf("%s\n", prog_desc_text[i]);
784 FCMIOF_stream_hline(stdout);
785 for (i = 0; i < (sizeof(license_preamble) / sizeof(license_preamble[0])); i++)
786 printf("%s\n", license_preamble[i]);
787 FCMIOF_stream_hline(stdout);
788 for (i = 0; i < (sizeof(license_text) / sizeof(license_text[0])); i++)
789 printf("%s\n", license_text[i]);
790 FCMIOF_stream_hline(stdout);
791 printf("Program built on %s at %s.\n", __DATE__, __TIME__);
792 i = 0;
793 while (STRING_vcinfo(i))
794 {
795 printf("%s\n", STRING_vcinfo(i));
796 i++;
797 }
798 FCMIOF_stream_hline(stdout);
799 for (i = 0; i < (sizeof(prog_help_text) / sizeof(prog_help_text[0])); i++)
800 printf("%s\n", prog_help_text[i]);
801 FCMIOF_stream_hline(stdout);
802 }
803
804 void emit_execution_preamble(void)
805 {
806 FCMIOF_stream_hline(stdout);
807 printf("Use \"ifsfscan\" with no parameters to obtain license and help information.\n");
808 FCMIOF_stream_hline(stdout);
809 }
810
811 int c_main(int argc, char **argv)
812 {
813 int i;
814
815 if (argc <= 1)
816 {
817 //This is most likely someone trying to figure out what the program is or does.
818 //Spit everything.
819 emit_no_par_documentation();
820 }
821 else
822 {
823 emit_execution_preamble();
824
825 //Every argument beyond the program name has to be either a file name or
826 //wildcard. Just process them in order.
827 for (i = 1; i < argc; i++)
828 process_filename_or_wildcard(argv[i]);
829
830 FCMIOF_stream_hline(stdout);
831 }
832
833 return 0;
834 }

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