/[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 193 by dashley, Sat Jul 14 21:20:02 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  //Copyright (c) 2018, David T. Ashley  //Copyright (c) 2018, David T. Ashley
5  //  //
6  //This file is part of "ifsfscan", a program for identifying gross formatting anomalies in source  //This file is part of "ets_ifsfscan", a program for identifying gross formatting anomalies in
7  //files (Windows/ASCII text files only).  //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,  //This source code and any program in which it is compiled/used is licensed under the MIT License,
10  //reproduced below.  //reproduced below.
# Line 29  Line 30 
30  #include <stdio.h>  #include <stdio.h>
31  #include <stdlib.h>  #include <stdlib.h>
32  #include <string.h>  #include <string.h>
33    #include <tchar.h>
34  #include <time.h>  #include <time.h>
35    #include <windows.h>
36    
37  #define FCMIOF_HORIZONTAL_BAR_SEP_CHAR    ('-')  #define FCMIOF_HORIZONTAL_BAR_SEP_CHAR    ('-')
38  #define FCMIOF_LINE_LEN                   (78)  #define FCMIOF_LINE_LEN                   (78)
# Line 38  Line 41 
41  //less than aesthetic).  //less than aesthetic).
42  const char * const license_preamble[] =  const char * const license_preamble[] =
43  {  {
44     "ifsfscan, (c) 2018 David T. Ashley (dashley@gmail.com)",     "ets_ifsfscan, (c) 2018 David T. Ashley (dashley@gmail.com)",
45     "This program's source files, executable files, and all other related files",     "This program's source files, executable files, and all other related files",
46     "(such as Visual Studio project files) are licensed under \"The MIT License\",",     "(such as Visual Studio project files) are licensed under \"The MIT License\",",
47     "reproduced below."     "reproduced below."
# Line 46  const char * const license_preamble[] = Line 49  const char * const license_preamble[] =
49    
50  const char * const license_text[] =  const char * const license_text[] =
51  {  {
52          "Permission is hereby granted, free of charge, to any person obtaining a copy",     "Permission is hereby granted, free of charge, to any person obtaining a copy",
53          "of this software and associated documentation files(the \"Software\"), to deal",     "of this software and associated documentation files(the \"Software\"), to deal",
54          "in the Software without restriction, including without limitation the rights",     "in the Software without restriction, including without limitation the rights",
55          "to use, copy, modify, merge, publish, distribute, sublicense, and / or sell",     "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",     "copies of the Software, and to permit persons to whom the Software is",
57          "furnished to do so, subject to the following conditions:",     "furnished to do so, subject to the following conditions:",
58          "",     "",
59          "The above copyright notice and this permission notice shall be included in",     "The above copyright notice and this permission notice shall be included in",
60          "all copies or substantial portions of the Software.",     "all copies or substantial portions of the Software.",
61          "",     "",
62          "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",
63          "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",     "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
64          "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE",     "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",     "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,",     "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",     "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE",
68          "SOFTWARE."     "SOFTWARE."
69  };  };
70    
71  const char * const prog_desc_text[] =  const char * const prog_desc_text[] =
72  {  {
73          "ifsfscan (mnemonic: Ill-Formed Source File SCAN) is a program for detecting",     "ets_ifsfscan (mnemonic: Ill-Formed Source File SCAN) is a program for",
74          "gross formatting errors in source files (Windows/ASCII text files only).  The",     "detecting gross formatting errors in source files (Windows/ASCII text",
75     "errors detected are non-ASCII characters, tab characters, abnormal",     "files only).  The errors detected are non-ASCII characters, tab characters,",
76     "end-of-line characters, and trailing whitespace on lines.",     "abnormal end-of-line characters, and trailing whitespace on lines."
77  };  };
78    
79  const char * const prog_help_text[] =  const char * const prog_help_text[] =
80  {  {
81          "Usage:  ifsfscan [filename_or_wildcard [filename_or_wildcard [...]]]",     "Usage:  ets_ifsfscan [filename_or_wildcard [filename_or_wildcard [...]]]",
82          "",     "",
83          "Notes:",     "Notes:",
84     "   (1) : Wildcards (\"*\", \"?\") are processed by Windows, so Windows is",     "   (1) : Wildcards (\"*\", \"?\") are processed by Windows, so Windows is",
85     "         the arbiter of which wildcards are accepted and how they expand.",     "         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",     "   (2) : This program never writes to a file, so it cannot destroy data",
87          "         (except, possibly, by stdout output redirected to a file).",     "         (except, possibly, by stdout output redirected to a file).",
88          "   (3) : This program accepts no options (like \"-help\" or \"-verbose\").",     "   (3) : This program accepts no options (like \"-help\" or \"-verbose\").",
89          "   (4) : This program accepts only Windows line endings (13-10).",     "   (4) : This program accepts only Windows line endings (13-10).",
90          "         This program is incompatible with *nix and *nix files.",     "         This program is incompatible with *nix and *nix files.",
91     "   (5) : This program accepts only the ASCII character set (it will not",     "   (5) : This program accepts only the ASCII character set (it will not",
92     "         process UTF-8 or any other encodings).",     "         process UTF-8 or any other encodings).",
93  };  };
# Line 95  const char * const prog_help_text[] = Line 98  const char * const prog_help_text[] =
98  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("\n");     printf("\n");
101          printf("Fatal error.  Must terminate execution.\n");     printf("Fatal error.  Must terminate execution.\n");
102          printf("File: %s, Line: %zu.\n", file, line);     printf("File: %s, Line: %zu.\n", file, line);
103          printf("Error description: %s\n", desc);     printf("Error description: %s\n", desc);
104          exit(4);  //Error code 4 for error termination.     exit(4);  //Error code 4 for error termination.
105  }  }
106    
107  //--------------------------------------------------------------------------------  //--------------------------------------------------------------------------------
# Line 116  void USERASSERT_assert(int assertion, co Line 119  void USERASSERT_assert(int assertion, co
119     }     }
120  }  }
121    
 //--------------------------------------------------------------------------------  
 //  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  
 //--------------------------------------------------------------------------------  
 //These functions form a layer over the standard library so that conditions of  
 //concern can be more easily trapped.  
 //--------------------------------------------------------------------------------  
 void *CCMALLOC_malloc(size_t size)  
 {  
         void *rv;  
   
         rv = malloc(size);  
   
         if (!rv)  
         {  
                 CCMFATAL_fatal("NULL pointer from malloc()--probable out of memory.",  
                         __FILE__,  
                         __LINE__);  
         }  
   
    memset(rv, 0, size);  
   
         return(rv);  
 }  
   
 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__);  
         }  
   
    memset(rv, 0, size);  
   
         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);  
 }  
   
 //--------------------------------------------------------------------------------  
 //  C H A R A C T E R    F U N C T I O N S  
 //--------------------------------------------------------------------------------  
 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:  
       USERASSERT_assert(0, __FILE__, __LINE__);  
                 return('?');  
                 break;  
         }  
 }  
   
 void CHARFUNC_int_to_lc_hex_rev(int arg, char *s)  
 {  
         int i;  
   
    USERASSERT_assert(s != NULL, __FILE__, __LINE__);  
   
    for (i = 0; i<8; i++)  
         {  
                 s[i] = CHARFUNC_nibble_to_lc_hex_digit(arg);  
                 arg >>= 4;  
         }  
 }  
122    
123  //--------------------------------------------------------------------------------  //--------------------------------------------------------------------------------
124  //  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  //  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
# Line 335  const char *STRING_vcinfo(size_t which) Line 171  const char *STRING_vcinfo(size_t which)
171  {  {
172     static const char * const vcinfo[] =     static const char * const vcinfo[] =
173     {     {
174        "$Header$",        "$HeadURL$",
175        "$Date$",        "$Date$",
176        "$Revision$",        "$Revision$",
177        "$Author$",        "$Author$",
178        "$HeadURL$",        "Project GUID:           {beb3d945-d010-41c4-b7b5-7d4b84203408}",
179        "$Id"        "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  //--------------------------------------------------------------------------------  //--------------------------------------------------------------------------------
# Line 350  const char *STRING_vcinfo(size_t which) Line 191  const char *STRING_vcinfo(size_t which)
191  //--------------------------------------------------------------------------------  //--------------------------------------------------------------------------------
192  int FCMIOF_get_line_len(void)  int FCMIOF_get_line_len(void)
193  {  {
194          return(FCMIOF_LINE_LEN);     return(FCMIOF_LINE_LEN);
195  }  }
196    
197  void FCMIOF_stream_repchar(FILE *s, char c, unsigned n)  void FCMIOF_stream_repchar(FILE *s, char c, unsigned n)
198  {  {
199     USERASSERT_assert(s != NULL, __FILE__, __LINE__);     USERASSERT_assert(s != NULL, __FILE__, __LINE__);
200    
201          while (n--)     while (n--)
202                  fprintf(s, "%c", c);        fprintf(s, "%c", c);
203  }  }
204    
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    
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    
217  void FCMIOF_stream_hline(FILE *s)  void FCMIOF_stream_hline(FILE *s)
218  {  {
219     USERASSERT_assert(s != NULL, __FILE__, __LINE__);     USERASSERT_assert(s != NULL, __FILE__, __LINE__);
220    
221          FCMIOF_stream_repchar(s, FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);     FCMIOF_stream_repchar(s, FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);
222          fprintf(s, "\n");     fprintf(s, "\n");
223  }  }
224    
225  void FCMIOF_stream_bannerheading(FILE *f,  int is_legal_non_eol_character(char c)
226          char *s,  {
227          int n_extra_lines)     if ((c >= 32) && (c <= 126))
228  {        return(1);
229          const int lr_padding = 3;     else
230          /* The number of spaces on each side of what is printed.        return(0);
231          */  }
         int i;  
         /* General iteration variable.  
         */  
   
         int n_asterisks;  
         int input_arg_len;  
         int n_left_spaces;  
         int n_right_spaces;  
   
         /* Check the file pointer, string pointer, and other par.  
         */  
    USERASSERT_assert(f != NULL, __FILE__, __LINE__);  
    USERASSERT_assert(s != NULL, __FILE__, __LINE__);  
    USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);  
232    
233          /* Print the right number of solid lines of asterisks to the  int is_illegal_non_eol_character(char c)
234          ** standard output.  {
235          */     if (((c < 32) || (c > 126)) && (c != 13) && (c != 10))
236          for (i = 0; i<n_extra_lines; i++)        return(1);
237          {     else
238                  FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN);        return(0);
                 fprintf(f, "\n");  
         }  
   
         /* Figure out how many asterisks to print on each side of the  
         ** argument, and how many spaces.  We also need to figure out  
         ** how many characters of the input argument to print--if there  
         ** are too many characters, we need to truncate.  
         */  
         input_arg_len = strlen(s);  
         if (input_arg_len > (FCMIOF_LINE_LEN - 2 * lr_padding - 2))  
                 input_arg_len = FCMIOF_LINE_LEN - 2 * lr_padding - 2;  
   
         n_asterisks = (FCMIOF_LINE_LEN - 2 * lr_padding - input_arg_len) / 2;  
   
         n_left_spaces = lr_padding;  
   
         if ((FCMIOF_LINE_LEN - 2 * lr_padding - input_arg_len) % 2)  
         {  
                 /* Odd, need to pad the right by one. */  
                 n_right_spaces = lr_padding + 1;  
         }  
         else  
         {  
                 n_right_spaces = lr_padding;  
         }  
   
         /* Print the text. */  
         FCMIOF_stream_repchar(f, '*', n_asterisks);  
         FCMIOF_stream_repchar(f, ' ', n_left_spaces);  
         for (i = 0; i<input_arg_len; i++)  
                 fprintf(f, "%c", s[i]);  
         FCMIOF_stream_repchar(f, ' ', n_right_spaces);  
         FCMIOF_stream_repchar(f, '*', n_asterisks);  
         fprintf(f, "\n");  
   
         /* Print the right number of solid lines of asterisks to the  
         ** standard output.  
         */  
         for (i = 0; i<n_extra_lines; i++)  
         {  
                 FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN);  
                 fprintf(f, "\n");  
         }  
239  }  }
240    
241  void FCMIOF_bannerheading(char *s, int n_extra_lines)  int is_tab(char c)
242  {  {
243     USERASSERT_assert(s != NULL, __FILE__, __LINE__);     if (c == 9)
244     USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);        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          FCMIOF_stream_bannerheading(stdout, s, n_extra_lines);  int is_lf(char c)
258    {
259       if (c == 10)
260          return(1);
261       else
262          return(0);
263  }  }
264    
265  void FCMIOF_time_stream(FILE *s, time_t ltime)  void emit_human_friendly_llu(unsigned long long arg)
266  {  {
267          char *p;     size_t i, len;
268       char buffer[100];
269    
270     USERASSERT_assert(s != NULL, __FILE__, __LINE__);     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       do
320       {
321          //Illegal characters always get flagged.
322          if (is_illegal_non_eol_character(in_c))
323          {
324             emit_file_pos_3tuple(line_no, col_no, char_no);
325             printf("         Illegal character: 0x%02x.\n", ((unsigned)in_uc));
326          }
327    
328          //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          switch (state)
332          {
333          case PST_LINE:
334             //Processing non-EOL characters.
335             if (is_lf(in_c))
336             {
337                if ((char_no != 0) && (prev_c == ' '))
338                {
339                   emit_file_pos_3tuple(line_no, col_no, char_no);
340                   printf("         Line contains trailing whitespace.\n");
341                }
342    
343                //Line feeds not allowed without preceding carriage return.
344                emit_file_pos_3tuple(line_no, col_no, char_no);
345                printf("         Out of sequence line feed character (0x0a).\n");
346                line_no++;
347                col_no = 1;
348                state = PST_LF_FOUND;
349             }
350             else if (is_cr(in_c))
351             {
352                if ((char_no != 0) && (prev_c == ' '))
353                {
354                   emit_file_pos_3tuple(line_no, col_no, char_no);
355                   printf("         Line contains trailing whitespace.\n");
356                }
357    
358                //Legal
359                state = PST_CR_FOUND;
360             }
361             else
362             {
363                //Ordinary character.
364                col_no++;
365             }
366             break;
367          case PST_CR_FOUND:
368             if (is_lf(in_c))
369             {
370                //Legal
371                line_no++;
372                col_no = 1;
373                state = PST_LF_FOUND;
374             }
375             else if (is_cr(in_c))
376             {
377                //Back-to-back carriage returns not allowed.
378                emit_file_pos_3tuple(line_no, col_no, char_no);
379                printf("         Out of sequence carriage return character (0x0D).\n");
380                col_no++;
381             }
382             else
383             {
384                //Ordinary character.  Illegal, because LF must follow CR.
385                emit_file_pos_3tuple(line_no, col_no, char_no);
386                printf("         Carriage return followed by 0x%02x rather than LF.\n", (unsigned)in_uc);
387                col_no++;
388             }
389             break;
390          case PST_LF_FOUND:
391             if (is_lf(in_c))
392             {
393                //Illegal.  Back-to-back line feeds not allowed.
394                emit_file_pos_3tuple(line_no, col_no, char_no);
395                printf("         Out of sequence line feed character (0x0A).\n");
396                line_no++;
397                col_no = 1;
398             }
399             else if (is_cr(in_c))
400             {
401                //Legal.  Blank lines are fine.
402                col_no++;
403                state = PST_CR_FOUND;
404             }
405             else
406             {
407                //Ordinary character.  Legal.
408                col_no++;
409                state = PST_LINE;
410             }
411             break;
412          default:
413             USERASSERT_assert(0, __FILE__, __LINE__);
414             break;
415          }
416    
417          in_i = fgetc(f);
418          prev_c = in_c;
419          in_c = in_i & 0xff;
420          in_uc = in_i & 0xff;
421          char_no++;
422          if (in_i == EOF)
423          {
424             if (state != PST_LF_FOUND)
425             {
426                emit_file_pos_3tuple(line_no, col_no, char_no-1);
427                printf("         Final line of file does not have CR/LF sequence.\n");
428             }
429             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          time(&ltime);     f = fopen(s, "rb");
447    
448          p = ctime(&ltime);     if (!f)
449       {
450          printf("      fopen() failed.\n");
451       }
452       else
453       {
454          process_opened_handle(f);
455    
456          if (p)        if (fclose(f))
457          {        {
458                  int i;           printf("      fclose() failed.\n");
459          }
460                  for (i = 11; i<19; i++)     }
                         fprintf(s, "%c", p[i]);  
                 fprintf(s, " ");  
                 for (i = 0; i<10; i++)  
                         fprintf(s, "%c", p[i]);  
                 fprintf(s, " ");  
                 for (i = 20; i<24; i++)  
                         fprintf(s, "%c", p[i]);  
         }  
         else  
         {  
                 fprintf(s, "??? ??? ?? ??:??:?? ????");  
         }  
461  }  }
462    
463  void process_filename_or_wildcard(const char *fname_or_wildcard)  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     //Incoming pointer is worthy of an assertion.  The OS should not every deliver
469     //a NULL pointer or empty string to us.     //a NULL pointer or empty string to us.
470     USERASSERT_assert(fname_or_wildcard != NULL,     __FILE__, __LINE__);     USERASSERT_assert(fname_or_wildcard != NULL, __FILE__, __LINE__);
471     USERASSERT_assert(strlen(fname_or_wildcard) > 0, __FILE__, __LINE__);     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)  void emit_no_par_documentation(void)
# Line 514  void emit_no_par_documentation(void) Line 547  void emit_no_par_documentation(void)
547     for (i = 0; i < (sizeof(license_text) / sizeof(license_text[0])); i++)     for (i = 0; i < (sizeof(license_text) / sizeof(license_text[0])); i++)
548        printf("%s\n", license_text[i]);        printf("%s\n", license_text[i]);
549     FCMIOF_stream_hline(stdout);     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++)     for (i = 0; i < (sizeof(prog_help_text) / sizeof(prog_help_text[0])); i++)
559        printf("%s\n", prog_help_text[i]);        printf("%s\n", prog_help_text[i]);
560     FCMIOF_stream_hline(stdout);     FCMIOF_stream_hline(stdout);
# Line 549  int c_main(int argc, char **argv) Line 590  int c_main(int argc, char **argv)
590     }     }
591    
592     return 0;     return 0;
 }  
593    }

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

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25