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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 199 - (hide annotations) (download)
Sun Jul 15 03:07:20 2018 UTC (6 years, 2 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 dashley 150 //$Header$
2 dashley 197 //{f0d952cc-7499-4d5c-9f46-d0b509c5701c}
3 dashley 150 //-------------------------------------------------------------------------------------------------
4 dashley 193 //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 dashley 150 //reproduced below.
11 dashley 193 //
12 dashley 150 //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 dashley 193 //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 dashley 150 //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 dashley 151 #include <stdlib.h>
32 dashley 193 #include <string.h>
33 dashley 197 #include <tchar.h>
34 dashley 193 #include <time.h>
35 dashley 197 #include <windows.h>
36 dashley 150
37 dashley 197
38 dashley 193 #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 dashley 151 {
45 dashley 193 "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 dashley 151 "",
60 dashley 193 "The above copyright notice and this permission notice shall be included in",
61     "all copies or substantial portions of the Software.",
62 dashley 151 "",
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 dashley 193 "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
66 dashley 151 "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 dashley 193 "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE",
69 dashley 151 "SOFTWARE."
70     };
71    
72 dashley 193 const char * const prog_desc_text[] =
73 dashley 151 {
74 dashley 193 "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 dashley 151 };
79    
80 dashley 193 const char * const prog_help_text[] =
81 dashley 151 {
82 dashley 193 "Usage: ifsfscan [filename_or_wildcard [filename_or_wildcard [...]]]",
83 dashley 151 "",
84     "Notes:",
85 dashley 193 " (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 dashley 151 };
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 dashley 193 void CCMFATAL_fatal(const char *desc, const char *file, size_t line)
100 dashley 151 {
101 dashley 193 printf("\n");
102 dashley 151 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 dashley 193 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 dashley 151
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 dashley 193 memset(rv, 0, size);
143    
144 dashley 151 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 dashley 193 memset(rv, 0, size);
161    
162 dashley 151 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 dashley 193 //--------------------------------------------------------------------------------
188     // C H A R A C T E R F U N C T I O N S
189     //--------------------------------------------------------------------------------
190 dashley 151 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 dashley 193 USERASSERT_assert(0, __FILE__, __LINE__);
273 dashley 151 return('?');
274     break;
275     }
276     }
277    
278     void CHARFUNC_int_to_lc_hex_rev(int arg, char *s)
279     {
280     int i;
281    
282 dashley 193 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
283 dashley 151
284 dashley 193 for (i = 0; i<8; i++)
285 dashley 151 {
286     s[i] = CHARFUNC_nibble_to_lc_hex_digit(arg);
287     arg >>= 4;
288     }
289     }
290    
291 dashley 193 //--------------------------------------------------------------------------------
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 dashley 151
304 dashley 193 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 dashley 151
314 dashley 193 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 dashley 197 "$HeadURL$",
343 dashley 195 "$Date$",
344 dashley 193 "$Revision$",
345 dashley 197 "$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 dashley 193 };
350    
351 dashley 197 if (which < (sizeof(vcinfo) / sizeof(vcinfo[0])))
352     return(vcinfo[which]);
353     else
354     return(NULL);
355 dashley 193 }
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 dashley 151 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 dashley 193 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
368 dashley 151
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 dashley 193 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
388 dashley 151
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 dashley 193 USERASSERT_assert(f != NULL, __FILE__, __LINE__);
412     USERASSERT_assert(s != NULL, __FILE__, __LINE__);
413     USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);
414 dashley 151
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 dashley 193 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
469     USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);
470 dashley 151
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 dashley 193 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
479 dashley 151
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 dashley 197 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 dashley 199 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 dashley 197 }
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 dashley 199 in_c = in_i & 0xff;
595     in_uc = in_i & 0xff;
596 dashley 197
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 dashley 199 //printf("Character: %02x State: %u\n", in_c, (unsigned)state);
607    
608 dashley 197 //Run through the state machine, which would look for bad EOL sequences.
609     switch (state)
610     {
611     case PST_LINE:
612 dashley 199 //Processing non-EOL characters.
613 dashley 197 if (is_lf(in_c))
614     {
615 dashley 199 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 dashley 197 //Line feeds not allowed without preceding carriage return.
622     emit_file_pos_3tuple(line_no, col_no, char_no);
623 dashley 199 printf(" Out of sequence line feed character (0x0a).\n");
624 dashley 197 line_no++;
625     col_no = 1;
626     state = PST_LF_FOUND;
627     }
628     else if (is_cr(in_c))
629     {
630 dashley 199 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 dashley 197 //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 dashley 199 printf(" Out of sequence carriage return character (0x0D).\n");
658 dashley 197 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 dashley 199 state = PST_CR_FOUND;
682 dashley 197 }
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 dashley 199 prev_c = in_c;
697     in_c = in_i & 0xff;
698     in_uc = in_i & 0xff;
699 dashley 197 char_no++;
700     if (in_i == EOF)
701 dashley 199 {
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 dashley 197 exit_flag = 1;
714 dashley 199 }
715 dashley 197 } 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 dashley 193 void process_filename_or_wildcard(const char *fname_or_wildcard)
742     {
743 dashley 197 HANDLE hFind;
744     WIN32_FIND_DATA FindFileData;
745    
746 dashley 193 //Incoming pointer is worthy of an assertion. The OS should not every deliver
747     //a NULL pointer or empty string to us.
748 dashley 197 USERASSERT_assert(fname_or_wildcard != NULL, __FILE__, __LINE__);
749 dashley 193 USERASSERT_assert(strlen(fname_or_wildcard) > 0, __FILE__, __LINE__);
750 dashley 151
751 dashley 197 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 dashley 193 }
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 dashley 197 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 dashley 193 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 dashley 150 int c_main(int argc, char **argv)
849     {
850 dashley 193 int i;
851    
852 dashley 150 if (argc <= 1)
853     {
854 dashley 193 //This is most likely someone trying to figure out what the program is or does.
855     //Spit everything.
856     emit_no_par_documentation();
857 dashley 150 }
858 dashley 193 else
859     {
860     emit_execution_preamble();
861 dashley 150
862 dashley 193 //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 dashley 150 return 0;
871 dashley 149 }

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