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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 194 - (show annotations) (download)
Sat Jul 14 21:21:38 2018 UTC (6 years ago) by dashley
File MIME type: text/plain
File size: 14501 byte(s)
Enable all keyword expansion.
1 //$Header$
2 //-------------------------------------------------------------------------------------------------
3 //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 //reproduced below.
10 //
11 //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 //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
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 #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 "$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 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 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
359
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 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
379
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 USERASSERT_assert(f != NULL, __FILE__, __LINE__);
403 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
404 USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);
405
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 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
460 USERASSERT_assert(n_extra_lines >= 0, __FILE__, __LINE__);
461
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 USERASSERT_assert(s != NULL, __FILE__, __LINE__);
470
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 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
501 }
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 int c_main(int argc, char **argv)
530 {
531 int i;
532
533 if (argc <= 1)
534 {
535 //This is most likely someone trying to figure out what the program is or does.
536 //Spit everything.
537 emit_no_par_documentation();
538 }
539 else
540 {
541 emit_execution_preamble();
542
543 //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 return 0;
552 }

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision URL Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25