/[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/20180112_ifsfscan/c_main.c revision 148 by dashley, Fri Jan 12 05:45:39 2018 UTC projs/dtats/trunk/projs/2018/20180112_ifsfscan/c_main.c revision 202 by dashley, Sun Jul 15 17:17:37 2018 UTC
# Line 1  Line 1 
1  #include <stdio.h>  //$Header$
2    //{f0d952cc-7499-4d5c-9f46-d0b509c5701c}
3  int c_main(int argc, char **argv)  //-------------------------------------------------------------------------------------------------
4  {  //Copyright (c) 2018, David T. Ashley
5          printf("Hello, world.\n");  //
6    //This file is part of "ifsfscan", a program for identifying gross formatting anomalies in source
7      return 0;  //files (Windows/ASCII text files only).
8  }  //
9    //This source code and any program in which it is compiled/used is licensed under the MIT License,
10    //reproduced below.
11    //
12    //Permission is hereby granted, free of charge, to any person obtaining a copy of
13    //this software and associated documentation files(the "Software"), to deal in the
14    //Software without restriction, including without limitation the rights to use,
15    //copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the
16    //Software, and to permit persons to whom the Software is furnished to do so,
17    //subject to the following conditions :
18    //
19    //The above copyright notice and this permission notice shall be included in all
20    //copies or substantial portions of the Software.
21    //
22    //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23    //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24    //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25    //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26    //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27    //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28    //SOFTWARE.
29    //-------------------------------------------------------------------------------------------------
30    #include <stdio.h>
31    #include <stdlib.h>
32    #include <string.h>
33    #include <tchar.h>
34    #include <time.h>
35    #include <windows.h>
36    
37    #define FCMIOF_HORIZONTAL_BAR_SEP_CHAR    ('-')
38    #define FCMIOF_LINE_LEN                   (78)
39    
40    //The last column allowed for a characters below is Column 82 (or it will be
41    //less than aesthetic).
42    const char * const license_preamble[] =
43    {
44       "ifsfscan, (c) 2018 David T. Ashley (dashley@gmail.com)",
45       "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\",",
47       "reproduced below."
48    };
49    
50    const char * const license_text[] =
51    {
52       "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",
54       "in the Software without restriction, including without limitation the rights",
55       "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    const char * const prog_desc_text[] =
72    {
73       "ifsfscan (mnemonic: Ill-Formed Source File SCAN) is a program for detecting",
74       "gross formatting errors in source files (Windows/ASCII text files only).  The",
75       "errors detected are non-ASCII characters, tab characters, abnormal",
76       "end-of-line characters, and trailing whitespace on lines.",
77    };
78    
79    const char * const prog_help_text[] =
80    {
81       "Usage:  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
97    //--------------------------------------------------------------------------------
98    void CCMFATAL_fatal(const char *desc, const char *file, size_t line)
99    {
100       printf("\n");
101       printf("Fatal error.  Must terminate execution.\n");
102       printf("File: %s, Line: %zu.\n", file, line);
103       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
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    //  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
124    //--------------------------------------------------------------------------------
125    //These functions form a layer over the standard library so that conditions of
126    //concern can be more easily trapped.
127    //--------------------------------------------------------------------------------
128    void *CCMALLOC_malloc(size_t size)
129    {
130       void *rv;
131    
132       rv = malloc(size);
133    
134       if (!rv)
135       {
136          CCMFATAL_fatal("NULL pointer from malloc()--probable out of memory.",
137             __FILE__,
138             __LINE__);
139       }
140    
141       memset(rv, 0, size);
142    
143       return(rv);
144    }
145    
146    void *CCMALLOC_calloc(size_t num, size_t size)
147    {
148       void *rv;
149    
150       rv = calloc(num, size);
151    
152       if (!rv)
153       {
154          CCMFATAL_fatal("NULL pointer from calloc()--probable out of memory.",
155             __FILE__,
156             __LINE__);
157       }
158    
159       memset(rv, 0, size);
160    
161       return(rv);
162    }
163    
164    void *CCMALLOC_realloc(void *memblock, size_t size)
165    {
166       void *rv;
167    
168       rv = realloc(memblock, size);
169    
170       if ((!rv) && (size))
171       {
172          CCMFATAL_fatal("NULL pointer from realloc()--probable out of memory.",
173             __FILE__,
174             __LINE__);
175       }
176    
177       return(rv);
178    }
179    
180    void CCMALLOC_free(void *memblock)
181    {
182       free(memblock);
183    }
184    
185    //--------------------------------------------------------------------------------
186    //  C H A R A C T E R    F U N C T I O N S
187    //--------------------------------------------------------------------------------
188    int CHARFUNC_digit_to_val(char digit)
189    {
190       switch (digit)
191       {
192       case '0':  return(0);
193          break;
194       case '1':  return(1);
195          break;
196       case '2':  return(2);
197          break;
198       case '3':  return(3);
199          break;
200       case '4':  return(4);
201          break;
202       case '5':  return(5);
203          break;
204       case '6':  return(6);
205          break;
206       case '7':  return(7);
207          break;
208       case '8':  return(8);
209          break;
210       case '9':  return(9);
211          break;
212       default:   return(-1);
213          break;
214       }
215    }
216    
217    char CHARFUNC_nibble_to_lc_hex_digit(int nibble)
218    {
219       switch (nibble & 0x0F)
220       {
221       case  0:
222          return('0');
223          break;
224       case  1:
225          return('1');
226          break;
227       case  2:
228          return('2');
229          break;
230       case  3:
231          return('3');
232          break;
233       case  4:
234          return('4');
235          break;
236       case  5:
237          return('5');
238          break;
239       case  6:
240          return('6');
241          break;
242       case  7:
243          return('7');
244          break;
245       case  8:
246          return('8');
247          break;
248       case  9:
249          return('9');
250          break;
251       case 10:
252          return('a');
253          break;
254       case 11:
255          return('b');
256          break;
257       case 12:
258          return('c');
259          break;
260       case 13:
261          return('d');
262          break;
263       case 14:
264          return('e');
265          break;
266       case 15:
267          return('f');
268          break;
269       default:
270          USERASSERT_assert(0, __FILE__, __LINE__);
271          return('?');
272          break;
273       }
274    }
275    
276    void CHARFUNC_int_to_lc_hex_rev(int arg, char *s)
277    {
278       int i;
279    
280       USERASSERT_assert(s != NULL, __FILE__, __LINE__);
281    
282       for (i = 0; i<8; i++)
283       {
284          s[i] = CHARFUNC_nibble_to_lc_hex_digit(arg);
285          arg >>= 4;
286       }
287    }
288    
289    //--------------------------------------------------------------------------------
290    //  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
291    //--------------------------------------------------------------------------------
292    int STRING_contains_wildcard(const char *s)
293    {
294       if (strchr(s, '?') != NULL)
295          return(1);
296       else if (strchr(s, '*') != NULL)
297          return(1);
298       else
299          return(0);
300    }
301    
302    int STRING_is_longer_than_maxpath(const char *s)
303    {
304       if (_MAX_PATH <= 5)
305          return(1);
306       else if (strlen(s) > (_MAX_PATH - 5))
307          return(1);
308       else
309          return(0);
310    }
311    
312    int STRING_contains_terminating_backslash(const char *s)
313    {
314       size_t i;
315    
316       i = strlen(s);
317    
318       if (i == 0)
319       {
320          return(0);
321       }
322       else
323       {
324          do
325          {
326             i--;
327             if (s[i] == '\\')
328                return(1);
329             else if ((s[i] != ' ') && (s[i] != '\t'))
330                return(0);
331          } while (i != 0);
332          return(0);
333       }
334    }
335    
336    const char *STRING_vcinfo(size_t which)
337    {
338       static const char * const vcinfo[] =
339       {
340          "$HeadURL$",
341          "$Date$",
342          "$Revision$",
343          "$Author$",
344          "Project GUID:       {f7d7586a-557c-43cb-bec5-b49765d96a5d}",
345          "c_main.c GUID:      {f0d952cc-7499-4d5c-9f46-d0b509c5701c}",
346          "ifsfscan.cpp GUID:  {2abd4437-101c-49eb-99ac-c1174f55b626}",
347       };
348    
349       if (which < (sizeof(vcinfo) / sizeof(vcinfo[0])))
350          return(vcinfo[which]);
351       else
352          return(NULL);
353    }
354    
355    //--------------------------------------------------------------------------------
356    //  F O R M A T T E D    O U T P U T    F U N C T I O N S
357    //--------------------------------------------------------------------------------
358    int FCMIOF_get_line_len(void)
359    {
360       return(FCMIOF_LINE_LEN);
361    }
362    
363    void FCMIOF_stream_repchar(FILE *s, char c, unsigned n)
364    {
365       USERASSERT_assert(s != NULL, __FILE__, __LINE__);
366    
367       while (n--)
368          fprintf(s, "%c", c);
369    }
370    
371    void FCMIOF_repchar(char c, unsigned n)
372    {
373       while (n--)
374          printf("%c", c);
375    }
376    
377    void FCMIOF_hline(void)
378    {
379       FCMIOF_repchar(FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);
380       printf("\n");
381    }
382    
383    void FCMIOF_stream_hline(FILE *s)
384    {
385       USERASSERT_assert(s != NULL, __FILE__, __LINE__);
386    
387       FCMIOF_stream_repchar(s, FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);
388       fprintf(s, "\n");
389    }
390    
391    void FCMIOF_stream_bannerheading(FILE *f,
392       char *s,
393       int n_extra_lines)
394    {
395       const int lr_padding = 3;
396       /* The number of spaces on each side of what is printed.
397       */
398       int i;
399       /* General iteration variable.
400       */
401    
402       int n_asterisks;
403       int input_arg_len;
404       int n_left_spaces;
405       int n_right_spaces;
406    
407       /* Check the file pointer, string pointer, and other par.
408       */
409       USERASSERT_assert(f != NULL, __FILE__, __LINE__);
410       USERASSERT_assert(s != NULL, __FILE__, __LINE__);
411       USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);
412    
413       /* Print the right number of solid lines of asterisks to the
414       ** standard output.
415       */
416       for (i = 0; i<n_extra_lines; i++)
417       {
418          FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN);
419          fprintf(f, "\n");
420       }
421    
422       /* Figure out how many asterisks to print on each side of the
423       ** argument, and how many spaces.  We also need to figure out
424       ** how many characters of the input argument to print--if there
425       ** are too many characters, we need to truncate.
426       */
427       input_arg_len = strlen(s);
428       if (input_arg_len > (FCMIOF_LINE_LEN - 2 * lr_padding - 2))
429          input_arg_len = FCMIOF_LINE_LEN - 2 * lr_padding - 2;
430    
431       n_asterisks = (FCMIOF_LINE_LEN - 2 * lr_padding - input_arg_len) / 2;
432    
433       n_left_spaces = lr_padding;
434    
435       if ((FCMIOF_LINE_LEN - 2 * lr_padding - input_arg_len) % 2)
436       {
437          /* Odd, need to pad the right by one. */
438          n_right_spaces = lr_padding + 1;
439       }
440       else
441       {
442          n_right_spaces = lr_padding;
443       }
444    
445       /* Print the text. */
446       FCMIOF_stream_repchar(f, '*', n_asterisks);
447       FCMIOF_stream_repchar(f, ' ', n_left_spaces);
448       for (i = 0; i<input_arg_len; i++)
449          fprintf(f, "%c", s[i]);
450       FCMIOF_stream_repchar(f, ' ', n_right_spaces);
451       FCMIOF_stream_repchar(f, '*', n_asterisks);
452       fprintf(f, "\n");
453    
454       /* Print the right number of solid lines of asterisks to the
455       ** standard output.
456       */
457       for (i = 0; i<n_extra_lines; i++)
458       {
459          FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN);
460          fprintf(f, "\n");
461       }
462    }
463    
464    void FCMIOF_bannerheading(char *s, int n_extra_lines)
465    {
466       USERASSERT_assert(s != NULL, __FILE__, __LINE__);
467       USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);
468    
469       FCMIOF_stream_bannerheading(stdout, s, n_extra_lines);
470    }
471    
472    void FCMIOF_time_stream(FILE *s, time_t ltime)
473    {
474       char *p;
475    
476       USERASSERT_assert(s != NULL, __FILE__, __LINE__);
477    
478       time(&ltime);
479    
480       p = ctime(&ltime);
481    
482       if (p)
483       {
484          int i;
485    
486          for (i = 11; i<19; i++)
487             fprintf(s, "%c", p[i]);
488          fprintf(s, " ");
489          for (i = 0; i<10; i++)
490             fprintf(s, "%c", p[i]);
491          fprintf(s, " ");
492          for (i = 20; i<24; i++)
493             fprintf(s, "%c", p[i]);
494       }
495       else
496       {
497          fprintf(s, "??? ??? ?? ??:??:?? ????");
498       }
499    }
500    
501    int is_legal_non_eol_character(char c)
502    {
503       if ((c >= 32) && (c <= 126))
504          return(1);
505       else
506          return(0);
507    }
508    
509    int is_illegal_non_eol_character(char c)
510    {
511       if (((c < 32) || (c > 126)) && (c != 13) && (c != 10))
512          return(1);
513       else
514          return(0);
515    }
516    
517    int is_tab(char c)
518    {
519       if (c == 9)
520          return(1);
521       else
522          return(0);
523    }
524    
525    int is_cr(char c)
526    {
527       if (c == 13)
528          return(1);
529       else
530          return(0);
531    }
532    
533    int is_lf(char c)
534    {
535       if (c == 10)
536          return(1);
537       else
538          return(0);
539    }
540    
541    void emit_human_friendly_llu(unsigned long long arg)
542    {
543       size_t i, len;
544       char buffer[100];
545    
546       sprintf(buffer, "%llu", arg);
547       len = strlen(buffer);
548    
549       for (i = 0; i < len; i++)
550       {
551          printf("%c", buffer[i]);
552          if (((len-i-1) != 0) && (((len - i - 1) % 3) == 0))
553             printf(",");
554       }
555    }
556    
557    void emit_file_pos_3tuple(unsigned long long line, unsigned long long col, unsigned long long offset)
558    {
559       printf("      Line: ");
560       emit_human_friendly_llu(line);
561       printf(", Col: ");
562       emit_human_friendly_llu(col);
563       printf(", Offset: ");
564       emit_human_friendly_llu(offset);
565       printf("\n");
566    }
567    
568    void process_opened_handle(FILE *f)
569    {
570       unsigned long long char_no;
571       unsigned long long line_no;
572       unsigned long long col_no;
573       enum {PST_LINE, PST_CR_FOUND, PST_LF_FOUND} state = PST_LINE;
574       int exit_flag = 0;
575       char in_c, prev_c;
576       unsigned char in_uc;
577       int in_i;
578    
579       in_i = fgetc(f);
580    
581       if (in_i == EOF)
582       {
583          //Zero-length file or error.  Because this tool isn't critical, no need to figure out which, exactly.
584          printf("      Zero-length file.\n");
585          return;
586       }
587    
588       prev_c = ' ';
589       char_no = 0;
590       line_no = 1;
591       col_no  = 1;
592       in_c    = in_i & 0xff;
593       in_uc   = in_i & 0xff;
594    
595       do
596       {
597          //Illegal characters always get flagged.
598          if (is_illegal_non_eol_character(in_c))
599          {
600             emit_file_pos_3tuple(line_no, col_no, char_no);
601             printf("         Illegal character: 0x%02x.\n", ((unsigned)in_uc));
602          }
603    
604          //printf("Character: %02x  State: %u\n", in_c, (unsigned)state);
605    
606          //Run through the state machine, which would look for bad EOL sequences.
607          switch (state)
608          {
609          case PST_LINE:
610             //Processing non-EOL characters.
611             if (is_lf(in_c))
612             {
613                if ((char_no != 0) && (prev_c == ' '))
614                {
615                   emit_file_pos_3tuple(line_no, col_no, char_no);
616                   printf("         Line contains trailing whitespace.\n");
617                }
618    
619                //Line feeds not allowed without preceding carriage return.
620                emit_file_pos_3tuple(line_no, col_no, char_no);
621                printf("         Out of sequence line feed character (0x0a).\n");
622                line_no++;
623                col_no = 1;
624                state = PST_LF_FOUND;
625             }
626             else if (is_cr(in_c))
627             {
628                if ((char_no != 0) && (prev_c == ' '))
629                {
630                   emit_file_pos_3tuple(line_no, col_no, char_no);
631                   printf("         Line contains trailing whitespace.\n");
632                }
633    
634                //Legal
635                state = PST_CR_FOUND;
636             }
637             else
638             {
639                //Ordinary character.
640                col_no++;
641             }
642             break;
643          case PST_CR_FOUND:
644             if (is_lf(in_c))
645             {
646                //Legal
647                line_no++;
648                col_no = 1;
649                state = PST_LF_FOUND;
650             }
651             else if (is_cr(in_c))
652             {
653                //Back-to-back carriage returns not allowed.
654                emit_file_pos_3tuple(line_no, col_no, char_no);
655                printf("         Out of sequence carriage return character (0x0D).\n");
656                col_no++;
657             }
658             else
659             {
660                //Ordinary character.  Illegal, because LF must follow CR.
661                emit_file_pos_3tuple(line_no, col_no, char_no);
662                printf("         Carriage return followed by 0x%02x rather than LF.\n", (unsigned)in_uc);
663                col_no++;
664             }
665             break;
666          case PST_LF_FOUND:
667             if (is_lf(in_c))
668             {
669                //Illegal.  Back-to-back line feeds not allowed.
670                emit_file_pos_3tuple(line_no, col_no, char_no);
671                printf("         Out of sequence line feed character (0x0A).\n");
672                line_no++;
673                col_no = 1;
674             }
675             else if (is_cr(in_c))
676             {
677                //Legal.  Blank lines are fine.
678                col_no++;
679                state = PST_CR_FOUND;
680             }
681             else
682             {
683                //Ordinary character.  Legal.
684                col_no++;
685                state = PST_LINE;
686             }
687             break;
688          default:
689             USERASSERT_assert(0, __FILE__, __LINE__);
690             break;
691          }
692    
693          in_i = fgetc(f);
694          prev_c = in_c;
695          in_c = in_i & 0xff;
696          in_uc = in_i & 0xff;
697          char_no++;
698          if (in_i == EOF)
699          {
700             if (state != PST_LF_FOUND)
701             {
702                emit_file_pos_3tuple(line_no, col_no, char_no-1);
703                printf("         Final line of file does not have CR/LF sequence.\n");
704             }
705             if ((state == PST_LINE) && (prev_c == ' '))
706             {
707                emit_file_pos_3tuple(line_no, col_no, char_no - 1);
708                printf("         Final line contains trailing whitespace.\n");
709             }
710    
711             exit_flag = 1;
712          }
713       } while (!exit_flag);
714    }
715    
716    void process_file_by_name(const char *s)
717    {
718       FILE *f;
719    
720       printf("   %s\n", s);
721    
722       f = fopen(s, "rb");
723    
724       if (!f)
725       {
726          printf("      fopen() failed.\n");
727       }
728       else
729       {
730          process_opened_handle(f);
731    
732          if (fclose(f))
733          {
734             printf("      fclose() failed.\n");
735          }
736       }
737    }
738    
739    void process_filename_or_wildcard(const char *fname_or_wildcard)
740    {
741       HANDLE hFind;
742       WIN32_FIND_DATA FindFileData;
743    
744       //Incoming pointer is worthy of an assertion.  The OS should not every deliver
745       //a NULL pointer or empty string to us.
746       USERASSERT_assert(fname_or_wildcard != NULL, __FILE__, __LINE__);
747       USERASSERT_assert(strlen(fname_or_wildcard) > 0, __FILE__, __LINE__);
748    
749       printf("%s\n", fname_or_wildcard);
750    
751       if (STRING_is_longer_than_maxpath(fname_or_wildcard))
752       {
753          printf("   Specified filename or wildcard too long--cannot process.\n");
754       }
755       else if (STRING_contains_terminating_backslash(fname_or_wildcard))
756       {
757          printf("   Specified filename or wildcard contains terminating \"\\\"--cannot process.\n");
758       }
759       else if (STRING_contains_wildcard(fname_or_wildcard))
760       {
761          hFind = FindFirstFile((TCHAR *)fname_or_wildcard, &FindFileData);
762    
763          if (hFind == INVALID_HANDLE_VALUE)
764          {
765             printf("   Wildcard does not match existing files or is invalid.\n");
766          }
767          else
768          {
769             char path_drive[_MAX_PATH + 5];
770             char path_dir[_MAX_PATH + 5];
771             char path_fname[_MAX_PATH + 5];
772             char path_ext[_MAX_PATH + 5];
773             char path_full[_MAX_PATH + 5];
774    
775             if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
776             {
777                _splitpath(fname_or_wildcard, path_drive, path_dir, path_fname, path_ext);
778    
779                strcpy(path_full, path_drive);
780                strcat(path_full, path_dir);
781                strcat(path_full, FindFileData.cFileName);
782    
783                process_file_by_name(path_full);
784             }
785    
786             while (FindNextFile(hFind, &FindFileData) != 0)
787             {
788                if (!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
789                {
790                   _splitpath(fname_or_wildcard, path_drive, path_dir, path_fname, path_ext);
791    
792                   strcpy(path_full, path_drive);
793                   strcat(path_full, path_dir);
794                   strcat(path_full, FindFileData.cFileName);
795    
796                   process_file_by_name(path_full);
797                }
798             }
799          }
800    
801          if (hFind != INVALID_HANDLE_VALUE)
802          {
803             FindClose(hFind);
804          }
805       }
806       else
807       {
808          process_file_by_name(fname_or_wildcard);
809       }
810    }
811    
812    void emit_no_par_documentation(void)
813    {
814       size_t i;
815    
816       FCMIOF_stream_hline(stdout);
817       for (i = 0; i < (sizeof(prog_desc_text) / sizeof(prog_desc_text[0])); i++)
818          printf("%s\n", prog_desc_text[i]);
819       FCMIOF_stream_hline(stdout);
820       for (i = 0; i < (sizeof(license_preamble) / sizeof(license_preamble[0])); i++)
821          printf("%s\n", license_preamble[i]);
822       FCMIOF_stream_hline(stdout);
823       for (i = 0; i < (sizeof(license_text) / sizeof(license_text[0])); i++)
824          printf("%s\n", license_text[i]);
825       FCMIOF_stream_hline(stdout);
826       printf("Program built on %s at %s.\n", __DATE__, __TIME__);
827       i = 0;
828       while (STRING_vcinfo(i))
829       {
830          printf("%s\n", STRING_vcinfo(i));
831          i++;
832       }
833       FCMIOF_stream_hline(stdout);
834       for (i = 0; i < (sizeof(prog_help_text) / sizeof(prog_help_text[0])); i++)
835          printf("%s\n", prog_help_text[i]);
836       FCMIOF_stream_hline(stdout);
837    }
838    
839    void emit_execution_preamble(void)
840    {
841       FCMIOF_stream_hline(stdout);
842       printf("Use \"ifsfscan\" with no parameters to obtain license and help information.\n");
843       FCMIOF_stream_hline(stdout);
844    }
845    
846    int c_main(int argc, char **argv)
847    {
848       int i;
849    
850       if (argc <= 1)
851       {
852          //This is  most likely someone trying to figure out what the program is or does.
853          //Spit everything.
854          emit_no_par_documentation();
855       }
856       else
857       {
858          emit_execution_preamble();
859    
860          //Every argument beyond the program name has to be either a file name or
861          //wildcard.  Just process them in order.
862          for (i = 1; i < argc; i++)
863             process_filename_or_wildcard(argv[i]);
864    
865          FCMIOF_stream_hline(stdout);
866       }
867    
868       return 0;
869    }

Legend:
Removed from v.148  
changed lines
  Added in v.202

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25