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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 193 - (hide annotations) (download)
Sat Jul 14 21:20:02 2018 UTC (6 years, 5 months ago) by dashley
File MIME type: text/plain
File size: 14501 byte(s)
Change to release configuration.  Change to statically linked executable.
Progress towards completion.
1 dashley 150 //$Header$
2     //-------------------------------------------------------------------------------------------------
3 dashley 193 //Copyright (c) 2018, David T. Ashley
4     //
5     //This file is part of "ifsfscan", a program for identifying gross formatting anomalies in source
6     //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 dashley 150 //reproduced below.
10 dashley 193 //
11 dashley 150 //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
13     //Software without restriction, including without limitation the rights to use,
14     //copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the
15     //Software, and to permit persons to whom the Software is furnished to do so,
16     //subject to the following conditions :
17     //
18     //The above copyright notice and this permission notice shall be included in all
19     //copies or substantial portions of the Software.
20     //
21     //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22     //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 dashley 193 //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 dashley 150 //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,
26     //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27     //SOFTWARE.
28     //-------------------------------------------------------------------------------------------------
29     #include <stdio.h>
30 dashley 151 #include <stdlib.h>
31 dashley 193 #include <string.h>
32     #include <time.h>
33 dashley 150
34 dashley 193 #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 dashley 151 {
41 dashley 193 "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 dashley 151 "",
56 dashley 193 "The above copyright notice and this permission notice shall be included in",
57     "all copies or substantial portions of the Software.",
58 dashley 151 "",
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 dashley 193 "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
62 dashley 151 "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 dashley 193 "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE",
65 dashley 151 "SOFTWARE."
66     };
67    
68 dashley 193 const char * const prog_desc_text[] =
69 dashley 151 {
70 dashley 193 "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 dashley 151 };
75    
76 dashley 193 const char * const prog_help_text[] =
77 dashley 151 {
78 dashley 193 "Usage: ifsfscan [filename_or_wildcard [filename_or_wildcard [...]]]",
79 dashley 151 "",
80     "Notes:",
81 dashley 193 " (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 dashley 151 };
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 dashley 193 void CCMFATAL_fatal(const char *desc, const char *file, size_t line)
96 dashley 151 {
97 dashley 193 printf("\n");
98 dashley 151 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 dashley 193 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 dashley 151
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 dashley 193 memset(rv, 0, size);
139    
140 dashley 151 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 dashley 193 memset(rv, 0, size);
157    
158 dashley 151 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 dashley 193 //--------------------------------------------------------------------------------
184     // C H A R A C T E R F U N C T I O N S
185     //--------------------------------------------------------------------------------
186 dashley 151 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 dashley 193 USERASSERT_assert(0, __FILE__, __LINE__);
269 dashley 151 return('?');
270     break;
271     }
272     }
273    
274     void CHARFUNC_int_to_lc_hex_rev(int arg, char *s)
275     {
276     int i;
277    
278 dashley 193 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
279 dashley 151
280 dashley 193 for (i = 0; i<8; i++)
281 dashley 151 {
282     s[i] = CHARFUNC_nibble_to_lc_hex_digit(arg);
283     arg >>= 4;
284     }
285     }
286    
287 dashley 193 //--------------------------------------------------------------------------------
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 dashley 151
300 dashley 193 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 dashley 151
310 dashley 193 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     "$Header$",
339     "$Date$",
340     "$Revision$",
341     "$Author$",
342     "$HeadURL$",
343     "$Id"
344     };
345    
346     }
347    
348     //--------------------------------------------------------------------------------
349     // F O R M A T T E D O U T P U T F U N C T I O N S
350     //--------------------------------------------------------------------------------
351 dashley 151 int FCMIOF_get_line_len(void)
352     {
353     return(FCMIOF_LINE_LEN);
354     }
355    
356     void FCMIOF_stream_repchar(FILE *s, char c, unsigned n)
357     {
358 dashley 193 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
359 dashley 151
360     while (n--)
361     fprintf(s, "%c", c);
362     }
363    
364     void FCMIOF_repchar(char c, unsigned n)
365     {
366     while (n--)
367     printf("%c", c);
368     }
369    
370     void FCMIOF_hline(void)
371     {
372     FCMIOF_repchar(FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);
373     printf("\n");
374     }
375    
376     void FCMIOF_stream_hline(FILE *s)
377     {
378 dashley 193 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
379 dashley 151
380     FCMIOF_stream_repchar(s, FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN);
381     fprintf(s, "\n");
382     }
383    
384     void FCMIOF_stream_bannerheading(FILE *f,
385     char *s,
386     int n_extra_lines)
387     {
388     const int lr_padding = 3;
389     /* The number of spaces on each side of what is printed.
390     */
391     int i;
392     /* General iteration variable.
393     */
394    
395     int n_asterisks;
396     int input_arg_len;
397     int n_left_spaces;
398     int n_right_spaces;
399    
400     /* Check the file pointer, string pointer, and other par.
401     */
402 dashley 193 USERASSERT_assert(f != NULL, __FILE__, __LINE__);
403     USERASSERT_assert(s != NULL, __FILE__, __LINE__);
404     USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);
405 dashley 151
406     /* Print the right number of solid lines of asterisks to the
407     ** standard output.
408     */
409     for (i = 0; i<n_extra_lines; i++)
410     {
411     FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN);
412     fprintf(f, "\n");
413     }
414    
415     /* Figure out how many asterisks to print on each side of the
416     ** argument, and how many spaces. We also need to figure out
417     ** how many characters of the input argument to print--if there
418     ** are too many characters, we need to truncate.
419     */
420     input_arg_len = strlen(s);
421     if (input_arg_len > (FCMIOF_LINE_LEN - 2 * lr_padding - 2))
422     input_arg_len = FCMIOF_LINE_LEN - 2 * lr_padding - 2;
423    
424     n_asterisks = (FCMIOF_LINE_LEN - 2 * lr_padding - input_arg_len) / 2;
425    
426     n_left_spaces = lr_padding;
427    
428     if ((FCMIOF_LINE_LEN - 2 * lr_padding - input_arg_len) % 2)
429     {
430     /* Odd, need to pad the right by one. */
431     n_right_spaces = lr_padding + 1;
432     }
433     else
434     {
435     n_right_spaces = lr_padding;
436     }
437    
438     /* Print the text. */
439     FCMIOF_stream_repchar(f, '*', n_asterisks);
440     FCMIOF_stream_repchar(f, ' ', n_left_spaces);
441     for (i = 0; i<input_arg_len; i++)
442     fprintf(f, "%c", s[i]);
443     FCMIOF_stream_repchar(f, ' ', n_right_spaces);
444     FCMIOF_stream_repchar(f, '*', n_asterisks);
445     fprintf(f, "\n");
446    
447     /* Print the right number of solid lines of asterisks to the
448     ** standard output.
449     */
450     for (i = 0; i<n_extra_lines; i++)
451     {
452     FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN);
453     fprintf(f, "\n");
454     }
455     }
456    
457     void FCMIOF_bannerheading(char *s, int n_extra_lines)
458     {
459 dashley 193 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
460     USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);
461 dashley 151
462     FCMIOF_stream_bannerheading(stdout, s, n_extra_lines);
463     }
464    
465     void FCMIOF_time_stream(FILE *s, time_t ltime)
466     {
467     char *p;
468    
469 dashley 193 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
470 dashley 151
471     time(&ltime);
472    
473     p = ctime(&ltime);
474    
475     if (p)
476     {
477     int i;
478    
479     for (i = 11; i<19; i++)
480     fprintf(s, "%c", p[i]);
481     fprintf(s, " ");
482     for (i = 0; i<10; i++)
483     fprintf(s, "%c", p[i]);
484     fprintf(s, " ");
485     for (i = 20; i<24; i++)
486     fprintf(s, "%c", p[i]);
487     }
488     else
489     {
490     fprintf(s, "??? ??? ?? ??:??:?? ????");
491     }
492     }
493    
494 dashley 193 void process_filename_or_wildcard(const char *fname_or_wildcard)
495     {
496     //Incoming pointer is worthy of an assertion. The OS should not every deliver
497     //a NULL pointer or empty string to us.
498     USERASSERT_assert(fname_or_wildcard != NULL, __FILE__, __LINE__);
499     USERASSERT_assert(strlen(fname_or_wildcard) > 0, __FILE__, __LINE__);
500 dashley 151
501 dashley 193 }
502    
503     void emit_no_par_documentation(void)
504     {
505     size_t i;
506    
507     FCMIOF_stream_hline(stdout);
508     for (i = 0; i < (sizeof(prog_desc_text) / sizeof(prog_desc_text[0])); i++)
509     printf("%s\n", prog_desc_text[i]);
510     FCMIOF_stream_hline(stdout);
511     for (i = 0; i < (sizeof(license_preamble) / sizeof(license_preamble[0])); i++)
512     printf("%s\n", license_preamble[i]);
513     FCMIOF_stream_hline(stdout);
514     for (i = 0; i < (sizeof(license_text) / sizeof(license_text[0])); i++)
515     printf("%s\n", license_text[i]);
516     FCMIOF_stream_hline(stdout);
517     for (i = 0; i < (sizeof(prog_help_text) / sizeof(prog_help_text[0])); i++)
518     printf("%s\n", prog_help_text[i]);
519     FCMIOF_stream_hline(stdout);
520     }
521    
522     void emit_execution_preamble(void)
523     {
524     FCMIOF_stream_hline(stdout);
525     printf("Use \"ifsfscan\" with no parameters to obtain license and help information.\n");
526     FCMIOF_stream_hline(stdout);
527     }
528    
529 dashley 150 int c_main(int argc, char **argv)
530     {
531 dashley 193 int i;
532    
533 dashley 150 if (argc <= 1)
534     {
535 dashley 193 //This is most likely someone trying to figure out what the program is or does.
536     //Spit everything.
537     emit_no_par_documentation();
538 dashley 150 }
539 dashley 193 else
540     {
541     emit_execution_preamble();
542 dashley 150
543 dashley 193 //Every argument beyond the program name has to be either a file name or
544     //wildcard. Just process them in order.
545     for (i = 1; i < argc; i++)
546     process_filename_or_wildcard(argv[i]);
547    
548     FCMIOF_stream_hline(stdout);
549     }
550    
551 dashley 150 return 0;
552 dashley 149 }

Properties

Name Value
svn:eol-style native
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25