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

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

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

projs/dtats/trunk/projs/2018/20180112_ifsfscan/c_main.c revision 164 by dashley, Sat Jul 7 20:34:59 2018 UTC projs/dtats/trunk/projs/2018/20180718_ets_ifsfscan/c_main.c revision 212 by dashley, Thu Jul 19 02:25:24 2018 UTC
# Line 1  Line 1 
1  //$Header$  //$Header$
2    //{9d0125ed-73c3-43f6-8435-8f161ab7ea6d}
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 "ets_ifsfscan", a program for identifying gross formatting anomalies in
7  //This source code and any program in which it is compiled/used is provided under the MIT License,  //source 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
# Line 26  Line 29 
29  //-------------------------------------------------------------------------------------------------  //-------------------------------------------------------------------------------------------------
30  #include <stdio.h>  #include <stdio.h>
31  #include <stdlib.h>  #include <stdlib.h>
32    #include <string.h>
33    #include <tchar.h>
34    #include <time.h>
35    #include <windows.h>
36    
37  static const char * const license_text[] =  #define FCMIOF_HORIZONTAL_BAR_SEP_CHAR    ('-')
38  {  #define FCMIOF_LINE_LEN                   (78)
39          "Permission is hereby granted, free of charge, to any person obtaining a copy of",  
40          "this software and associated documentation files(the \"Software\"), to deal in the",  //The last column allowed for a characters below is Column 82 (or it will be
41          "Software without restriction, including without limitation the rights to use,",  //less than aesthetic).
42          "copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the",  const char * const license_preamble[] =
43          "Software, and to permit persons to whom the Software is furnished to do so,"  {
44          "subject to the following conditions :",     "ets_ifsfscan, (c) 2018 David T. Ashley (dashley@gmail.com)",
45          "",     "This program's source files, executable files, and all other related files",
46          "The above copyright notice and this permission notice shall be included in all",     "(such as Visual Studio project files) are licensed under \"The MIT License\",",
47          "copies or substantial portions of the Software.",     "reproduced below."
         "",  
         "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",  
         "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",  
         "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE",  
         "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",  
         "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",  
         "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE"  
         "SOFTWARE."  
48  };  };
49    
50  static const char * const prog_desc_text[] =  const char * const license_text[] =
51  {  {
52          "ifsfscan (mnemonic: Ill-Formed Source File SCAN) is a program for detecting and",     "Permission is hereby granted, free of charge, to any person obtaining a copy",
53          "correcting gross formatting errors in source files.  The errors detected and",     "of this software and associated documentation files(the \"Software\"), to deal",
54          "corrected include non-ASCII characters, tab characters, trailing whitespace on",     "in the Software without restriction, including without limitation the rights",
55          "lines, and other errors.",     "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  static const char * const prog_help_text[] =  const char * const prog_desc_text[] =
72  {  {
73          "Usage:  ifsfscan <options> <files_no_wildcards>",     "ets_ifsfscan (mnemonic: Ill-Formed Source File SCAN) is a program for",
74          "",     "detecting gross formatting errors in source files (Windows/ASCII text",
75          "Options:",     "files only).  The errors detected are non-ASCII characters, tab characters,",
76          "   -fixall",     "abnormal end-of-line characters, and trailing whitespace on lines."
         "      Fixes all known formatting issues non-interactively.  For users who",  
         "      understand the program's behavior, this is the most common option used.",  
         "   -fixnone (default)",  
         "      Identifies formatting issues, but does make any corrections.",  
         "",  
         "Notes:",  
         "   ( 1) : THIS PROGRAM CAN DESTROY DATA.  This program does not make backup",  
         "          files.  If this program were used to make \"corrections\" on a binary",  
         "          file, the file would likely be irreparably corrupted.",  
         "   ( 2) : This program does not process wildcards.",  
         "   ( 3) : This program is limited by available memory.  This program parses a",  
         "          source file, writing the corrected file to a RAM buffer, then finally",  
         "          overwrites the source file from the RAM buffer.  The practical limit",  
         "          for the size of the file that can be corrected using this program is",  
         "          probably a couple gigabytes.",  
         "   ( 4) : The license of this program does not prohibit copying the source code",  
         "          to another version control repository or simply \"stealing\" the",  
         "          program and source code for any other use.  The MIT License is a very",  
         "          unrestrictive open-source license."  
77  };  };
78    
79    const char * const prog_help_text[] =
80    {
81       "Usage:  ets_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  //  T E R M I N A T I O N    F U N C T I O N S
97  //--------------------------------------------------------------------------------  //--------------------------------------------------------------------------------
98  static void CCMFATAL_fatal(const char *desc, const char *file, size_t line)  void CCMFATAL_fatal(const char *desc, const char *file, size_t line)
99  {  {
100          printf("Fatal error.  Must terminate execution.\n");     printf("\n");
101          printf("File: %s, Line: %zu.\n", file, line);     printf("Fatal error.  Must terminate execution.\n");
102          printf("Error description: %s\n", desc);     printf("File: %s, Line: %zu.\n", file, line);
103          exit(4);  //Error code 4 for error termination.     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  //  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  //--------------------------------------------------------------------------------  //--------------------------------------------------------------------------------
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  //  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
 //--------------------------------------------------------------------------------  
 //These functions form a layer over the standard library so that conditions of  
 //concern can be more easily trapped.  
125  //--------------------------------------------------------------------------------  //--------------------------------------------------------------------------------
126  void *CCMALLOC_malloc(size_t size)  int STRING_contains_wildcard(const char *s)
127  {  {
128          void *rv;     if (strchr(s, '?') != NULL)
129          return(1);
130          rv = malloc(size);     else if (strchr(s, '*') != NULL)
131          return(1);
132       else
133          return(0);
134    }
135    
136          if (!rv)  int STRING_is_longer_than_maxpath(const char *s)
137          {  {
138                  CCMFATAL_fatal("NULL pointer from malloc()--probable out of memory.",     if (_MAX_PATH <= 5)
139                          __FILE__,        return(1);
140                          __LINE__);     else if (strlen(s) > (_MAX_PATH - 5))
141          }        return(1);
142       else
143          return(rv);        return(0);
 }  
   
 void *CCMALLOC_calloc(size_t num, size_t size)  
 {  
         void *rv;  
   
         rv = calloc(num, size);  
   
         if (!rv)  
         {  
                 CCMFATAL_fatal("NULL pointer from calloc()--probable out of memory.",  
                         __FILE__,  
                         __LINE__);  
         }  
   
         return(rv);  
 }  
   
 void *CCMALLOC_realloc(void *memblock, size_t size)  
 {  
         void *rv;  
   
         rv = realloc(memblock, size);  
   
         if ((!rv) && (size))  
         {  
                 CCMFATAL_fatal("NULL pointer from realloc()--probable out of memory.",  
                         __FILE__,  
                         __LINE__);  
         }  
   
         return(rv);  
 }  
   
   
 void CCMALLOC_free(void *memblock)  
 {  
         free(memblock);  
 }  
   
 #if 0  
   
 int CHARFUNC_digit_to_val(char digit)  
 {  
         switch (digit)  
         {  
         case '0':  return(0);  
                 break;  
         case '1':  return(1);  
                 break;  
         case '2':  return(2);  
                 break;  
         case '3':  return(3);  
                 break;  
         case '4':  return(4);  
                 break;  
         case '5':  return(5);  
                 break;  
         case '6':  return(6);  
                 break;  
         case '7':  return(7);  
                 break;  
         case '8':  return(8);  
                 break;  
         case '9':  return(9);  
                 break;  
         default:   return(-1);  
                 break;  
         }  
 }  
   
   
 char CHARFUNC_nibble_to_lc_hex_digit(int nibble)  
 {  
         switch (nibble & 0x0F)  
         {  
         case  0:  
                 return('0');  
                 break;  
         case  1:  
                 return('1');  
                 break;  
         case  2:  
                 return('2');  
                 break;  
         case  3:  
                 return('3');  
                 break;  
         case  4:  
                 return('4');  
                 break;  
         case  5:  
                 return('5');  
                 break;  
         case  6:  
                 return('6');  
                 break;  
         case  7:  
                 return('7');  
                 break;  
         case  8:  
                 return('8');  
                 break;  
         case  9:  
                 return('9');  
                 break;  
         case 10:  
                 return('a');  
                 break;  
         case 11:  
                 return('b');  
                 break;  
         case 12:  
                 return('c');  
                 break;  
         case 13:  
                 return('d');  
                 break;  
         case 14:  
                 return('e');  
                 break;  
         case 15:  
                 return('f');  
                 break;  
         default:  
                 assert(0);  
                 return('?');  
                 break;  
         }  
 }  
   
   
 void CHARFUNC_int_to_lc_hex_rev(int arg, char *s)  
 {  
         int i;  
   
         assert(s != NULL);  
   
         for (i = 0; i<8; i++)  
         {  
                 s[i] = CHARFUNC_nibble_to_lc_hex_digit(arg);  
                 arg >>= 4;  
         }  
144  }  }
145    
146  #define FCMIOF_HORIZONTAL_BAR_SEP_CHAR    ('-')  int STRING_contains_terminating_backslash(const char *s)
147  #define FCMIOF_LINE_LEN                   (78)  {
148       size_t i;
149    
150       i = strlen(s);
151    
152  //08/16/01:  Visual inspection OK.     if (i == 0)
153  int FCMIOF_get_line_len(void)     {
154          return(0);
155       }
156       else
157       {
158          do
159          {
160             i--;
161             if (s[i] == '\\')
162                return(1);
163             else if ((s[i] != ' ') && (s[i] != '\t'))
164                return(0);
165          } while (i != 0);
166          return(0);
167       }
168    }
169    
170    const char *STRING_vcinfo(size_t which)
171  {  {
172          return(FCMIOF_LINE_LEN);     static const char * const vcinfo[] =
173       {
174          "$HeadURL$",
175          "$Date$",
176          "$Revision$",
177          "$Author$",
178          "Project GUID:           {beb3d945-d010-41c4-b7b5-7d4b84203408}",
179          "c_main.c GUID:          {9d0125ed-73c3-43f6-8435-8f161ab7ea6d}",
180          "ets_ifsfscan.cpp GUID:  {aa3777d0-4cd3-46e5-b84e-03f01957cc71}",
181       };
182    
183       if (which < (sizeof(vcinfo) / sizeof(vcinfo[0])))
184          return(vcinfo[which]);
185       else
186          return(NULL);
187  }  }
188    
189    //--------------------------------------------------------------------------------
190    //  F O R M A T T E D    O U T P U T    F U N C T I O N S
191    //--------------------------------------------------------------------------------
192    int FCMIOF_get_line_len(void)
193    {
194       return(FCMIOF_LINE_LEN);
195    }
196    
 //08/16/01:  Visual inspection OK.  
197  void FCMIOF_stream_repchar(FILE *s, char c, unsigned n)  void FCMIOF_stream_repchar(FILE *s, char c, unsigned n)
198  {  {
199          assert(s != NULL);     USERASSERT_assert(s != NULL, __FILE__, __LINE__);
200    
201          while (n--)     while (n--)
202                  fprintf(s, "%c", c);        fprintf(s, "%c", c);
203  }  }
204    
   
 //08/16/01:  Visual inspection OK.  
205  void FCMIOF_repchar(char c, unsigned n)  void FCMIOF_repchar(char c, unsigned n)
206  {  {
207          while (n--)     while (n--)
208                  printf("%c", c);        printf("%c", c);
209  }  }
210    
   
 //08/16/01:  Visual inspection OK.  
211  void FCMIOF_hline(void)  void FCMIOF_hline(void)
212  {  {
213          FCMIOF_repchar(FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);     FCMIOF_repchar(FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);
214          printf("\n");     printf("\n");
215  }  }
216    
   
 //08/16/01:  Visual inspection OK.  
217  void FCMIOF_stream_hline(FILE *s)  void FCMIOF_stream_hline(FILE *s)
218  {  {
219          assert(s != NULL);     USERASSERT_assert(s != NULL, __FILE__, __LINE__);
220    
221       FCMIOF_stream_repchar(s, FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);
222       fprintf(s, "\n");
223    }
224    
225    int is_legal_non_eol_character(char c)
226    {
227       if ((c >= 32) && (c <= 126))
228          return(1);
229       else
230          return(0);
231    }
232    
233    int is_illegal_non_eol_character(char c)
234    {
235       if (((c < 32) || (c > 126)) && (c != 13) && (c != 10))
236          return(1);
237       else
238          return(0);
239    }
240    
241    int is_tab(char c)
242    {
243       if (c == 9)
244          return(1);
245       else
246          return(0);
247    }
248    
249    int is_cr(char c)
250    {
251       if (c == 13)
252          return(1);
253       else
254          return(0);
255    }
256    
257    int is_lf(char c)
258    {
259       if (c == 10)
260          return(1);
261       else
262          return(0);
263    }
264    
265          FCMIOF_stream_repchar(s, FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);  void emit_human_friendly_llu(unsigned long long arg)
266          fprintf(s, "\n");  {
267       size_t i, len;
268       char buffer[100];
269    
270       sprintf_s(buffer, sizeof(buffer)/sizeof(buffer[0]), "%llu", arg);
271       len = strlen(buffer);
272    
273       for (i = 0; i < len; i++)
274       {
275          printf("%c", buffer[i]);
276          if (((len-i-1) != 0) && (((len - i - 1) % 3) == 0))
277             printf(",");
278       }
279  }  }
280    
281    void emit_file_pos_3tuple(unsigned long long line, unsigned long long col, unsigned long long offset)
282    {
283       printf("      Line: ");
284       emit_human_friendly_llu(line);
285       printf(", Col: ");
286       emit_human_friendly_llu(col);
287       printf(", Offset: ");
288       emit_human_friendly_llu(offset);
289       printf("\n");
290    }
291    
292    void process_opened_handle(FILE *f)
293    {
294       unsigned long long char_no;
295       unsigned long long line_no;
296       unsigned long long col_no;
297       enum {PST_LINE, PST_CR_FOUND, PST_LF_FOUND} state = PST_LINE;
298       int exit_flag = 0;
299       char in_c, prev_c;
300       unsigned char in_uc;
301       int in_i;
302    
303       in_i = fgetc(f);
304    
305       if (in_i == EOF)
306       {
307          //Zero-length file or error.  Because this tool isn't critical, no need to figure out which, exactly.
308          printf("      Zero-length file.\n");
309          return;
310       }
311    
312       prev_c = ' ';
313       char_no = 0;
314       line_no = 1;
315       col_no  = 1;
316       in_c    = in_i & 0xff;
317       in_uc   = in_i & 0xff;
318    
319  //08/16/01:  Visual inspection OK.     do
320  void FCMIOF_stream_bannerheading(FILE *f,     {
321          char *s,        //Illegal characters always get flagged.
322          int n_extra_lines)        if (is_illegal_non_eol_character(in_c))
323  {        {
324          const int lr_padding = 3;           emit_file_pos_3tuple(line_no, col_no, char_no);
325          /* The number of spaces on each side of what is printed.           printf("         Illegal character: 0x%02x.\n", ((unsigned)in_uc));
326          */        }
327          int i;  
328          /* General iteration variable.        //printf("Character: %02x  State: %u\n", in_c, (unsigned)state);
329          */  
330          //Run through the state machine, which would look for bad EOL sequences.
331          int n_asterisks;        switch (state)
332          int input_arg_len;        {
333          int n_left_spaces;        case PST_LINE:
334          int n_right_spaces;           //Processing non-EOL characters.
335             if (is_lf(in_c))
336          /* Check the file pointer, string pointer, and other par.           {
337          */              if ((char_no != 0) && (prev_c == ' '))
338          assert(f != NULL);              {
339          assert(s != NULL);                 emit_file_pos_3tuple(line_no, col_no, char_no);
340          assert(n_extra_lines >= 0);                 printf("         Line contains trailing whitespace.\n");
341                }
342          /* Print the right number of solid lines of asterisks to the  
343          ** standard output.              //Line feeds not allowed without preceding carriage return.
344          */              emit_file_pos_3tuple(line_no, col_no, char_no);
345          for (i = 0; i<n_extra_lines; i++)              printf("         Out of sequence line feed character (0x0a).\n");
346          {              line_no++;
347                  FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN);              col_no = 1;
348                  fprintf(f, "\n");              state = PST_LF_FOUND;
349          }           }
350             else if (is_cr(in_c))
351          /* Figure out how many asterisks to print on each side of the           {
352          ** argument, and how many spaces.  We also need to figure out              if ((char_no != 0) && (prev_c == ' '))
353          ** how many characters of the input argument to print--if there              {
354          ** are too many characters, we need to truncate.                 emit_file_pos_3tuple(line_no, col_no, char_no);
355          */                 printf("         Line contains trailing whitespace.\n");
356          input_arg_len = strlen(s);              }
357          if (input_arg_len > (FCMIOF_LINE_LEN - 2 * lr_padding - 2))  
358                  input_arg_len = FCMIOF_LINE_LEN - 2 * lr_padding - 2;              //Legal
359                state = PST_CR_FOUND;
360          n_asterisks = (FCMIOF_LINE_LEN - 2 * lr_padding - input_arg_len) / 2;           }
361             else
362          n_left_spaces = lr_padding;           {
363                //Ordinary character.
364          if ((FCMIOF_LINE_LEN - 2 * lr_padding - input_arg_len) % 2)              col_no++;
365          {           }
366                  /* Odd, need to pad the right by one. */           break;
367                  n_right_spaces = lr_padding + 1;        case PST_CR_FOUND:
368          }           if (is_lf(in_c))
369          else           {
370          {              //Legal
371                  n_right_spaces = lr_padding;              line_no++;
372          }              col_no = 1;
373                state = PST_LF_FOUND;
374          /* Print the text. */           }
375          FCMIOF_stream_repchar(f, '*', n_asterisks);           else if (is_cr(in_c))
376          FCMIOF_stream_repchar(f, ' ', n_left_spaces);           {
377          for (i = 0; i<input_arg_len; i++)              //Back-to-back carriage returns not allowed.
378                  fprintf(f, "%c", s[i]);              emit_file_pos_3tuple(line_no, col_no, char_no);
379          FCMIOF_stream_repchar(f, ' ', n_right_spaces);              printf("         Out of sequence carriage return character (0x0D).\n");
380          FCMIOF_stream_repchar(f, '*', n_asterisks);              col_no++;
381          fprintf(f, "\n");           }
382             else
383          /* Print the right number of solid lines of asterisks to the           {
384          ** standard output.              //Ordinary character.  Illegal, because LF must follow CR.
385          */              emit_file_pos_3tuple(line_no, col_no, char_no);
386          for (i = 0; i<n_extra_lines; i++)              printf("         Carriage return followed by 0x%02x rather than LF.\n", (unsigned)in_uc);
387          {              col_no++;
388                  FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN);           }
389                  fprintf(f, "\n");           break;
390          }        case PST_LF_FOUND:
391  }           if (is_lf(in_c))
392             {
393                //Illegal.  Back-to-back line feeds not allowed.
394  //08/16/01:  Visual inspection OK.              emit_file_pos_3tuple(line_no, col_no, char_no);
395  void FCMIOF_bannerheading(char *s, int n_extra_lines)              printf("         Out of sequence line feed character (0x0A).\n");
396  {              line_no++;
397          assert(s != NULL);              col_no = 1;
398          assert(n_extra_lines >= 0);           }
399             else if (is_cr(in_c))
400          FCMIOF_stream_bannerheading(stdout, s, n_extra_lines);           {
401  }              //Legal.  Blank lines are fine.
402                col_no++;
403                state = PST_CR_FOUND;
404  void FCMIOF_time_stream(FILE *s, time_t ltime)           }
405  {           else
406          char *p;           {
407                //Ordinary character.  Legal.
408          assert(s != NULL);              col_no++;
409                state = PST_LINE;
410          time(&ltime);           }
411             break;
412          p = ctime(&ltime);        default:
413             USERASSERT_assert(0, __FILE__, __LINE__);
414          if (p)           break;
415          {        }
416                  int i;  
417          in_i = fgetc(f);
418                  for (i = 11; i<19; i++)        prev_c = in_c;
419                          fprintf(s, "%c", p[i]);        in_c = in_i & 0xff;
420                  fprintf(s, " ");        in_uc = in_i & 0xff;
421                  for (i = 0; i<10; i++)        char_no++;
422                          fprintf(s, "%c", p[i]);        if (in_i == EOF)
423                  fprintf(s, " ");        {
424                  for (i = 20; i<24; i++)           if (state != PST_LF_FOUND)
425                          fprintf(s, "%c", p[i]);           {
426          }              emit_file_pos_3tuple(line_no, col_no, char_no-1);
427          else              printf("         Final line of file does not have CR/LF sequence.\n");
428          {           }
429                  fprintf(s, "??? ??? ?? ??:??:?? ????");           if ((state == PST_LINE) && (prev_c == ' '))
430          }           {
431                emit_file_pos_3tuple(line_no, col_no, char_no - 1);
432                printf("         Final line contains trailing whitespace.\n");
433             }
434    
435             exit_flag = 1;
436          }
437       } while (!exit_flag);
438    }
439    
440    void process_file_by_name(const char *s)
441    {
442       FILE *f;
443    
444       printf("   %s\n", s);
445    
446       f = fopen(s, "rb");
447    
448       if (!f)
449       {
450          printf("      fopen() failed.\n");
451       }
452       else
453       {
454          process_opened_handle(f);
455    
456          if (fclose(f))
457          {
458             printf("      fclose() failed.\n");
459          }
460       }
461  }  }
462    
463  #endif  void process_filename_or_wildcard(const char *fname_or_wildcard)
464    {
465       HANDLE hFind;
466       WIN32_FIND_DATA FindFileData;
467    
468       //Incoming pointer is worthy of an assertion.  The OS should not every deliver
469       //a NULL pointer or empty string to us.
470       USERASSERT_assert(fname_or_wildcard != NULL, __FILE__, __LINE__);
471       USERASSERT_assert(strlen(fname_or_wildcard) > 0, __FILE__, __LINE__);
472    
473       printf("%s\n", fname_or_wildcard);
474    
475       if (STRING_is_longer_than_maxpath(fname_or_wildcard))
476       {
477          printf("   Specified filename or wildcard too long--cannot process.\n");
478       }
479       else if (STRING_contains_terminating_backslash(fname_or_wildcard))
480       {
481          printf("   Specified filename or wildcard contains terminating \"\\\"--cannot process.\n");
482       }
483       else if (STRING_contains_wildcard(fname_or_wildcard))
484       {
485          hFind = FindFirstFile((TCHAR *)fname_or_wildcard, &FindFileData);
486    
487          if (hFind == INVALID_HANDLE_VALUE)
488          {
489             printf("   Wildcard does not match existing files or is invalid.\n");
490          }
491          else
492          {
493             char path_drive[_MAX_PATH + 5];
494             char path_dir[_MAX_PATH + 5];
495             char path_fname[_MAX_PATH + 5];
496             char path_ext[_MAX_PATH + 5];
497             char path_full[_MAX_PATH + 5];
498    
499             if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
500             {
501                _splitpath(fname_or_wildcard, path_drive, path_dir, path_fname, path_ext);
502    
503                strcpy(path_full, path_drive);
504                strcat(path_full, path_dir);
505                strcat(path_full, FindFileData.cFileName);
506    
507                process_file_by_name(path_full);
508             }
509    
510             while (FindNextFile(hFind, &FindFileData) != 0)
511             {
512                if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
513                {
514                   _splitpath(fname_or_wildcard, path_drive, path_dir, path_fname, path_ext);
515    
516                   strcpy(path_full, path_drive);
517                   strcat(path_full, path_dir);
518                   strcat(path_full, FindFileData.cFileName);
519    
520                   process_file_by_name(path_full);
521                }
522             }
523          }
524    
525          if (hFind != INVALID_HANDLE_VALUE)
526          {
527             FindClose(hFind);
528          }
529       }
530       else
531       {
532          process_file_by_name(fname_or_wildcard);
533       }
534    }
535    
536    void emit_no_par_documentation(void)
537    {
538       size_t i;
539    
540       FCMIOF_stream_hline(stdout);
541       for (i = 0; i < (sizeof(prog_desc_text) / sizeof(prog_desc_text[0])); i++)
542          printf("%s\n", prog_desc_text[i]);
543       FCMIOF_stream_hline(stdout);
544       for (i = 0; i < (sizeof(license_preamble) / sizeof(license_preamble[0])); i++)
545          printf("%s\n", license_preamble[i]);
546       FCMIOF_stream_hline(stdout);
547       for (i = 0; i < (sizeof(license_text) / sizeof(license_text[0])); i++)
548          printf("%s\n", license_text[i]);
549       FCMIOF_stream_hline(stdout);
550       printf("Program built on %s at %s.\n", __DATE__, __TIME__);
551       i = 0;
552       while (STRING_vcinfo(i))
553       {
554          printf("%s\n", STRING_vcinfo(i));
555          i++;
556       }
557       FCMIOF_stream_hline(stdout);
558       for (i = 0; i < (sizeof(prog_help_text) / sizeof(prog_help_text[0])); i++)
559          printf("%s\n", prog_help_text[i]);
560       FCMIOF_stream_hline(stdout);
561    }
562    
563    void emit_execution_preamble(void)
564    {
565       FCMIOF_stream_hline(stdout);
566       printf("Use \"ifsfscan\" with no parameters to obtain license and help information.\n");
567       FCMIOF_stream_hline(stdout);
568    }
569    
570  int c_main(int argc, char **argv)  int c_main(int argc, char **argv)
571  {  {
572       int i;
573    
574     if (argc <= 1)     if (argc <= 1)
575     {     {
576        //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.
577        //Treat this the same as a request for help.        //Spit everything.
578          emit_no_par_documentation();
579       }
580       else
581       {
582          emit_execution_preamble();
583    
584          //Every argument beyond the program name has to be either a file name or
585          //wildcard.  Just process them in order.
586          for (i = 1; i < argc; i++)
587             process_filename_or_wildcard(argv[i]);
588    
589          FCMIOF_stream_hline(stdout);
590     }     }
591    
592     return 0;     return 0;
 }  
593    }

Legend:
Removed from v.164  
changed lines
  Added in v.212

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25