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

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

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

projs/dtats/trunk/projs/20180112_ifsfscan/c_main.c revision 150 by dashley, Fri Jan 12 06:21:29 2018 UTC projs/dtats/trunk/projs/2018/20180112_ifsfscan/c_main.c revision 196 by dashley, Sat Jul 14 21:26:30 2018 UTC
# Line 1  Line 1 
1  //$Header$  //$Header$
2  //-------------------------------------------------------------------------------------------------  //-------------------------------------------------------------------------------------------------
3  //This file is part of "ifsfscan", a program for identifying and correcting gross formatting  //Copyright (c) 2018, David T. Ashley
4  //anomalies in source files.  //
5  //-------------------------------------------------------------------------------------------------  //This file is part of "ifsfscan", a program for identifying gross formatting anomalies in source
6  //This source code and any program in which it is compiled/used is provided under the MIT License,  //files (Windows/ASCII text files only).
7    //
8    //This source code and any program in which it is compiled/used is licensed under the MIT License,
9  //reproduced below.  //reproduced below.
10  //-------------------------------------------------------------------------------------------------  //
11  //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
12  //this software and associated documentation files(the "Software"), to deal in the  //this software and associated documentation files(the "Software"), to deal in the
13  //Software without restriction, including without limitation the rights to use,  //Software without restriction, including without limitation the rights to use,
# Line 18  Line 20 
20  //  //
21  //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
22  //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE  //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
24  //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  //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
27  //SOFTWARE.  //SOFTWARE.
28  //-------------------------------------------------------------------------------------------------  //-------------------------------------------------------------------------------------------------
29  #include <stdio.h>  #include <stdio.h>
30    #include <stdlib.h>
31    #include <string.h>
32    #include <time.h>
33    
34    #define FCMIOF_HORIZONTAL_BAR_SEP_CHAR    ('-')
35    #define FCMIOF_LINE_LEN                   (78)
36    
37    //The last column allowed for a characters below is Column 82 (or it will be
38    //less than aesthetic).
39    const char * const license_preamble[] =
40    {
41       "ifsfscan, (c) 2018 David T. Ashley (dashley@gmail.com)",
42       "This program's source files, executable files, and all other related files",
43       "(such as Visual Studio project files) are licensed under \"The MIT License\",",
44       "reproduced below."
45    };
46    
47    const char * const license_text[] =
48    {
49            "Permission is hereby granted, free of charge, to any person obtaining a copy",
50            "of this software and associated documentation files(the \"Software\"), to deal",
51            "in the Software without restriction, including without limitation the rights",
52            "to use, copy, modify, merge, publish, distribute, sublicense, and / or sell",
53            "copies of the Software, and to permit persons to whom the Software is",
54            "furnished to do so, subject to the following conditions:",
55            "",
56            "The above copyright notice and this permission notice shall be included in",
57            "all copies or substantial portions of the Software.",
58            "",
59            "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
60            "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
61            "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE",
62            "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
63            "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",
64            "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE",
65            "SOFTWARE."
66    };
67    
68    const char * const prog_desc_text[] =
69    {
70            "ifsfscan (mnemonic: Ill-Formed Source File SCAN) is a program for detecting",
71            "gross formatting errors in source files (Windows/ASCII text files only).  The",
72       "errors detected are non-ASCII characters, tab characters, abnormal",
73       "end-of-line characters, and trailing whitespace on lines.",
74    };
75    
76    const char * const prog_help_text[] =
77    {
78            "Usage:  ifsfscan [filename_or_wildcard [filename_or_wildcard [...]]]",
79            "",
80            "Notes:",
81       "   (1) : Wildcards (\"*\", \"?\") are processed by Windows, so Windows is",
82       "         the arbiter of which wildcards are accepted and how they expand.",
83       "   (2) : This program never writes to a file, so it cannot destroy data",
84            "         (except, possibly, by stdout output redirected to a file).",
85            "   (3) : This program accepts no options (like \"-help\" or \"-verbose\").",
86            "   (4) : This program accepts only Windows line endings (13-10).",
87            "         This program is incompatible with *nix and *nix files.",
88       "   (5) : This program accepts only the ASCII character set (it will not",
89       "         process UTF-8 or any other encodings).",
90    };
91    
92    //--------------------------------------------------------------------------------
93    //  T E R M I N A T I O N    F U N C T I O N S
94    //--------------------------------------------------------------------------------
95    void CCMFATAL_fatal(const char *desc, const char *file, size_t line)
96    {
97       printf("\n");
98            printf("Fatal error.  Must terminate execution.\n");
99            printf("File: %s, Line: %zu.\n", file, line);
100            printf("Error description: %s\n", desc);
101            exit(4);  //Error code 4 for error termination.
102    }
103    
104    //--------------------------------------------------------------------------------
105    //  A S S E R T I O N    F U N C T I O N S
106    //--------------------------------------------------------------------------------
107    void USERASSERT_assert(int assertion, const char *file, size_t line)
108    {
109       if (! assertion)
110       {
111          printf("\n");
112          printf("Assertion failed.  It is necessary to use the source code to diagnose\n");
113          printf("and resolve this error.\n");
114          printf("File: %s, Line: %zu.\n", file, line);
115          exit(4);  //Error code 4 for error termination.
116       }
117    }
118    
119    //--------------------------------------------------------------------------------
120    //  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
121    //--------------------------------------------------------------------------------
122    //These functions form a layer over the standard library so that conditions of
123    //concern can be more easily trapped.
124    //--------------------------------------------------------------------------------
125    void *CCMALLOC_malloc(size_t size)
126    {
127            void *rv;
128    
129            rv = malloc(size);
130    
131            if (!rv)
132            {
133                    CCMFATAL_fatal("NULL pointer from malloc()--probable out of memory.",
134                            __FILE__,
135                            __LINE__);
136            }
137    
138       memset(rv, 0, size);
139    
140            return(rv);
141    }
142    
143    void *CCMALLOC_calloc(size_t num, size_t size)
144    {
145            void *rv;
146    
147            rv = calloc(num, size);
148    
149            if (!rv)
150            {
151                    CCMFATAL_fatal("NULL pointer from calloc()--probable out of memory.",
152                            __FILE__,
153                            __LINE__);
154            }
155    
156       memset(rv, 0, size);
157    
158            return(rv);
159    }
160    
161    void *CCMALLOC_realloc(void *memblock, size_t size)
162    {
163            void *rv;
164    
165            rv = realloc(memblock, size);
166    
167            if ((!rv) && (size))
168            {
169                    CCMFATAL_fatal("NULL pointer from realloc()--probable out of memory.",
170                            __FILE__,
171                            __LINE__);
172            }
173    
174            return(rv);
175    }
176    
177    
178    void CCMALLOC_free(void *memblock)
179    {
180            free(memblock);
181    }
182    
183    //--------------------------------------------------------------------------------
184    //  C H A R A C T E R    F U N C T I O N S
185    //--------------------------------------------------------------------------------
186    int CHARFUNC_digit_to_val(char digit)
187    {
188            switch (digit)
189            {
190            case '0':  return(0);
191                    break;
192            case '1':  return(1);
193                    break;
194            case '2':  return(2);
195                    break;
196            case '3':  return(3);
197                    break;
198            case '4':  return(4);
199                    break;
200            case '5':  return(5);
201                    break;
202            case '6':  return(6);
203                    break;
204            case '7':  return(7);
205                    break;
206            case '8':  return(8);
207                    break;
208            case '9':  return(9);
209                    break;
210            default:   return(-1);
211                    break;
212            }
213    }
214    
215    char CHARFUNC_nibble_to_lc_hex_digit(int nibble)
216    {
217            switch (nibble & 0x0F)
218            {
219            case  0:
220                    return('0');
221                    break;
222            case  1:
223                    return('1');
224                    break;
225            case  2:
226                    return('2');
227                    break;
228            case  3:
229                    return('3');
230                    break;
231            case  4:
232                    return('4');
233                    break;
234            case  5:
235                    return('5');
236                    break;
237            case  6:
238                    return('6');
239                    break;
240            case  7:
241                    return('7');
242                    break;
243            case  8:
244                    return('8');
245                    break;
246            case  9:
247                    return('9');
248                    break;
249            case 10:
250                    return('a');
251                    break;
252            case 11:
253                    return('b');
254                    break;
255            case 12:
256                    return('c');
257                    break;
258            case 13:
259                    return('d');
260                    break;
261            case 14:
262                    return('e');
263                    break;
264            case 15:
265                    return('f');
266                    break;
267            default:
268          USERASSERT_assert(0, __FILE__, __LINE__);
269                    return('?');
270                    break;
271            }
272    }
273    
274    void CHARFUNC_int_to_lc_hex_rev(int arg, char *s)
275    {
276            int i;
277    
278       USERASSERT_assert(s != NULL, __FILE__, __LINE__);
279    
280       for (i = 0; i<8; i++)
281            {
282                    s[i] = CHARFUNC_nibble_to_lc_hex_digit(arg);
283                    arg >>= 4;
284            }
285    }
286    
287    //--------------------------------------------------------------------------------
288    //  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
289    //--------------------------------------------------------------------------------
290    int STRING_contains_wildcard(const char *s)
291    {
292       if (strchr(s, '?') != NULL)
293          return(1);
294       else if (strchr(s, '*') != NULL)
295          return(1);
296       else
297          return(0);
298    }
299    
300    int STRING_is_longer_than_maxpath(const char *s)
301    {
302       if (_MAX_PATH <= 5)
303          return(1);
304       else if (strlen(s) > (_MAX_PATH - 5))
305          return(1);
306       else
307          return(0);
308    }
309    
310    int STRING_contains_terminating_backslash(const char *s)
311    {
312       size_t i;
313    
314       i = strlen(s);
315    
316       if (i == 0)
317       {
318          return(0);
319       }
320       else
321       {
322          do
323          {
324             i--;
325             if (s[i] == '\\')
326                return(1);
327             else if ((s[i] != ' ') && (s[i] != '\t'))
328                return(0);
329          } while (i != 0);
330          return(0);
331       }
332    }
333    
334    const char *STRING_vcinfo(size_t which)
335    {
336       static const char * const vcinfo[] =
337       {
338          "$Author$",
339          "$Date$",
340          "$Header$",
341          "$HeadURL$",
342          "$Id$",
343          "$Revision$",
344          "$URL$",
345       };
346    
347    }
348    
349    //--------------------------------------------------------------------------------
350    //  F O R M A T T E D    O U T P U T    F U N C T I O N S
351    //--------------------------------------------------------------------------------
352    int FCMIOF_get_line_len(void)
353    {
354            return(FCMIOF_LINE_LEN);
355    }
356    
357    void FCMIOF_stream_repchar(FILE *s, char c, unsigned n)
358    {
359       USERASSERT_assert(s != NULL, __FILE__, __LINE__);
360    
361            while (n--)
362                    fprintf(s, "%c", c);
363    }
364    
365    void FCMIOF_repchar(char c, unsigned n)
366    {
367            while (n--)
368                    printf("%c", c);
369    }
370    
371    void FCMIOF_hline(void)
372    {
373            FCMIOF_repchar(FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);
374            printf("\n");
375    }
376    
377    void FCMIOF_stream_hline(FILE *s)
378    {
379       USERASSERT_assert(s != NULL, __FILE__, __LINE__);
380    
381            FCMIOF_stream_repchar(s, FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);
382            fprintf(s, "\n");
383    }
384    
385    void FCMIOF_stream_bannerheading(FILE *f,
386            char *s,
387            int n_extra_lines)
388    {
389            const int lr_padding = 3;
390            /* The number of spaces on each side of what is printed.
391            */
392            int i;
393            /* General iteration variable.
394            */
395    
396            int n_asterisks;
397            int input_arg_len;
398            int n_left_spaces;
399            int n_right_spaces;
400    
401            /* Check the file pointer, string pointer, and other par.
402            */
403       USERASSERT_assert(f != NULL, __FILE__, __LINE__);
404       USERASSERT_assert(s != NULL, __FILE__, __LINE__);
405       USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);
406    
407            /* Print the right number of solid lines of asterisks to the
408            ** standard output.
409            */
410            for (i = 0; i<n_extra_lines; i++)
411            {
412                    FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN);
413                    fprintf(f, "\n");
414            }
415    
416            /* Figure out how many asterisks to print on each side of the
417            ** argument, and how many spaces.  We also need to figure out
418            ** how many characters of the input argument to print--if there
419            ** are too many characters, we need to truncate.
420            */
421            input_arg_len = strlen(s);
422            if (input_arg_len > (FCMIOF_LINE_LEN - 2 * lr_padding - 2))
423                    input_arg_len = FCMIOF_LINE_LEN - 2 * lr_padding - 2;
424    
425            n_asterisks = (FCMIOF_LINE_LEN - 2 * lr_padding - input_arg_len) / 2;
426    
427            n_left_spaces = lr_padding;
428    
429            if ((FCMIOF_LINE_LEN - 2 * lr_padding - input_arg_len) % 2)
430            {
431                    /* Odd, need to pad the right by one. */
432                    n_right_spaces = lr_padding + 1;
433            }
434            else
435            {
436                    n_right_spaces = lr_padding;
437            }
438    
439            /* Print the text. */
440            FCMIOF_stream_repchar(f, '*', n_asterisks);
441            FCMIOF_stream_repchar(f, ' ', n_left_spaces);
442            for (i = 0; i<input_arg_len; i++)
443                    fprintf(f, "%c", s[i]);
444            FCMIOF_stream_repchar(f, ' ', n_right_spaces);
445            FCMIOF_stream_repchar(f, '*', n_asterisks);
446            fprintf(f, "\n");
447    
448            /* Print the right number of solid lines of asterisks to the
449            ** standard output.
450            */
451            for (i = 0; i<n_extra_lines; i++)
452            {
453                    FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN);
454                    fprintf(f, "\n");
455            }
456    }
457    
458    void FCMIOF_bannerheading(char *s, int n_extra_lines)
459    {
460       USERASSERT_assert(s != NULL, __FILE__, __LINE__);
461       USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);
462    
463            FCMIOF_stream_bannerheading(stdout, s, n_extra_lines);
464    }
465    
466    void FCMIOF_time_stream(FILE *s, time_t ltime)
467    {
468            char *p;
469    
470       USERASSERT_assert(s != NULL, __FILE__, __LINE__);
471    
472            time(&ltime);
473    
474            p = ctime(&ltime);
475    
476            if (p)
477            {
478                    int i;
479    
480                    for (i = 11; i<19; i++)
481                            fprintf(s, "%c", p[i]);
482                    fprintf(s, " ");
483                    for (i = 0; i<10; i++)
484                            fprintf(s, "%c", p[i]);
485                    fprintf(s, " ");
486                    for (i = 20; i<24; i++)
487                            fprintf(s, "%c", p[i]);
488            }
489            else
490            {
491                    fprintf(s, "??? ??? ?? ??:??:?? ????");
492            }
493    }
494    
495    void process_filename_or_wildcard(const char *fname_or_wildcard)
496    {
497       //Incoming pointer is worthy of an assertion.  The OS should not every deliver
498       //a NULL pointer or empty string to us.
499       USERASSERT_assert(fname_or_wildcard != NULL,     __FILE__, __LINE__);
500       USERASSERT_assert(strlen(fname_or_wildcard) > 0, __FILE__, __LINE__);
501    
502    }
503    
504    void emit_no_par_documentation(void)
505    {
506       size_t i;
507    
508       FCMIOF_stream_hline(stdout);
509       for (i = 0; i < (sizeof(prog_desc_text) / sizeof(prog_desc_text[0])); i++)
510          printf("%s\n", prog_desc_text[i]);
511       FCMIOF_stream_hline(stdout);
512       for (i = 0; i < (sizeof(license_preamble) / sizeof(license_preamble[0])); i++)
513          printf("%s\n", license_preamble[i]);
514       FCMIOF_stream_hline(stdout);
515       for (i = 0; i < (sizeof(license_text) / sizeof(license_text[0])); i++)
516          printf("%s\n", license_text[i]);
517       FCMIOF_stream_hline(stdout);
518       for (i = 0; i < (sizeof(prog_help_text) / sizeof(prog_help_text[0])); i++)
519          printf("%s\n", prog_help_text[i]);
520       FCMIOF_stream_hline(stdout);
521    }
522    
523    void emit_execution_preamble(void)
524    {
525       FCMIOF_stream_hline(stdout);
526       printf("Use \"ifsfscan\" with no parameters to obtain license and help information.\n");
527       FCMIOF_stream_hline(stdout);
528    }
529    
530  int c_main(int argc, char **argv)  int c_main(int argc, char **argv)
531  {  {
532       int i;
533    
534     if (argc <= 1)     if (argc <= 1)
535     {     {
536        //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.
537        //Treat this the same as a request for help.        //Spit everything.
538          emit_no_par_documentation();
539       }
540       else
541       {
542          emit_execution_preamble();
543    
544          //Every argument beyond the program name has to be either a file name or
545          //wildcard.  Just process them in order.
546          for (i = 1; i < argc; i++)
547             process_filename_or_wildcard(argv[i]);
548    
549          FCMIOF_stream_hline(stdout);
550     }     }
551    
552     return 0;     return 0;

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

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25