/[dtapublic]/projs/dtats/trunk/projs/2018/20180112_ifsfscan/c_main.c
ViewVC logotype

Diff of /projs/dtats/trunk/projs/2018/20180112_ifsfscan/c_main.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

projs/dtats/trunk/projs/20180112_ifsfscan/c_main.c revision 150 by dashley, Fri Jan 12 06:21:29 2018 UTC projs/dtats/trunk/projs/2018/20180112_ifsfscan/c_main.c revision 197 by dashley, Sun Jul 15 01:26:18 2018 UTC
# Line 1  Line 1 
1  //$Header$  //$Header$
2    //{f0d952cc-7499-4d5c-9f46-d0b509c5701c}
3  //-------------------------------------------------------------------------------------------------  //-------------------------------------------------------------------------------------------------
4  //This file is part of "ifsfscan", a program for identifying and correcting gross formatting  //Copyright (c) 2018, David T. Ashley
5  //anomalies in source files.  //
6  //-------------------------------------------------------------------------------------------------  //This file is part of "ifsfscan", a program for identifying gross formatting anomalies in source
7  //This source code and any program in which it is compiled/used is provided under the MIT License,  //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.  //reproduced below.
11  //-------------------------------------------------------------------------------------------------  //
12  //Permission is hereby granted, free of charge, to any person obtaining a copy of  //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  //this software and associated documentation files(the "Software"), to deal in the
14  //Software without restriction, including without limitation the rights to use,  //Software without restriction, including without limitation the rights to use,
# Line 18  Line 21 
21  //  //
22  //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE  //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  //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,  //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  //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28  //SOFTWARE.  //SOFTWARE.
29  //-------------------------------------------------------------------------------------------------  //-------------------------------------------------------------------------------------------------
30  #include <stdio.h>  #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)  int c_main(int argc, char **argv)
812  {  {
813       int i;
814    
815     if (argc <= 1)     if (argc <= 1)
816     {     {
817        //This is most likely someone trying to figure out what the program is or does.        //This is  most likely someone trying to figure out what the program is or does.
818        //Treat this the same as a request for help.        //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;     return 0;

Legend:
Removed from v.150  
changed lines
  Added in v.197

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25