/[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 196 - (show annotations) (download)
Sat Jul 14 21:26:30 2018 UTC (6 years, 5 months ago) by dashley
File MIME type: text/plain
File size: 14518 byte(s)
Correct keyword.
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 "$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)
531 {
532 int i;
533
534 if (argc <= 1)
535 {
536 //This is most likely someone trying to figure out what the program is or does.
537 //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;
553 }

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