]> andersk Git - splint.git/blame - src/flags.c
unrecognizeddirective->unrecogdirective
[splint.git] / src / flags.c
CommitLineData
616915dd 1/*
11db3170 2** Splint - annotation-assisted static program checker
77d37419 3** Copyright (C) 1994-2002 University of Virginia,
616915dd 4** Massachusetts Institute of Technology
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** This program is distributed in the hope that it will be useful, but
12** WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14** General Public License for more details.
15**
16** The GNU General Public License is available from http://www.gnu.org/ or
17** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18** MA 02111-1307, USA.
19**
20** For information on lclint: lclint-request@cs.virginia.edu
21** To report a bug: lclint-bug@cs.virginia.edu
11db3170 22** For more information: http://www.splint.org
616915dd 23*/
24/*
25** flags.c
26*/
27
28# include "lclintMacros.nf"
29# include "basic.h"
30# include "portab.h"
31
32/*
33** from the CC man page:
34**
35** -Idir Search for #include files whose names do not begin with a
36** slash (/) in the following order: (1) in the directory of
37** the dir argument, (2) in the directories specified by -I
38** options, (3) in the standard directory (/usr/include).
39*/
40
41/* needed for string literals literals */
42
43typedef struct {
44 flagkind kind;
45 /*@null@*/ /*@observer@*/ char *name;
46 /*@null@*/ /*@observer@*/ char *describe;
47} flagcatinfo;
48
49static flagcatinfo categories[] =
50{
51 { FK_ABSTRACT, "abstract", "abstraction violations, representation access" } ,
52 { FK_ALIAS, "aliasing", "unexpected or dangerous aliasing" } ,
53 { FK_USE, "alluse", "all declarations are used" } ,
54 { FK_ANSI, "ansi", "violations of constraints imposed by ANSI/ISO standard" } ,
55 { FK_ARRAY, "arrays", "special checking involving arrays" } ,
56 { FK_BOOL, "booleans", "checking and naming of boolean types" } ,
28bf4b0b 57 { FK_COMMENTS, "comments", "interpretation of semantic comments" } ,
616915dd 58 { FK_COMPLETE, "complete", "completely defined, used, or specified system" } ,
59 { FK_CONTROL, "controlflow", "suspicious control structures" } ,
28bf4b0b 60 { FK_DEBUG, "debug", "flags for debugging lclint" } ,
616915dd 61 { FK_DECL, "declarations", "consistency of declarations" } ,
62 { FK_DEF, "definition", "undefined storage errors" } ,
63 { FK_DIRECT, "directories", "set directores" } ,
64 { FK_DISPLAY, "display", "control what is displayed" } ,
65 { FK_EFFECT, "effect", "statements with no effects" } ,
66 { FK_ERRORS, "errors", "control expected errors, summary reporting" } ,
67 { FK_EXPORT, "export", "control what may be exported" } ,
68 { FK_EXPOSURE, "exposure", "representation exposure" } ,
69 { FK_FILES, "files", "control system files" } ,
70 { FK_FORMAT, "format", "control format of warning messages" } ,
71 { FK_GLOBALS, "globals", "use of global and file static variables" },
72 { FK_HEADERS, "headers", "control inclusion and generation of header files" },
73 { FK_HELP, "help", "on-line help" },
74 { FK_IMPLICIT, "implicit", "control implicit annotations and interpretations" } ,
75 { FK_INIT, "initializations", "initialization files" } ,
76 { FK_ITER, "iterators", "checking iterator definitions and uses" } ,
77 { FK_LEAK, "leaks", "memory leaks" } ,
78 { FK_LIBS, "libraries", "loading and dumping of user and standard libraries" } ,
79 { FK_LIMITS, "limits", "violations of set limits" } ,
80 { FK_MACROS, "macros", "expansion, definition and use of macros" },
81 { FK_MEMORY, "memory", "memory management" } ,
82 { FK_MODIFIES, "modification", "modification errors" } ,
83 { FK_NAMES, "names", "naming conventions and limits" } ,
84 { FK_NULL, "null", "misuses of null pointers" } ,
85 { FK_NUMBERS, "numbers", "control type-checking of numeric types" } ,
86 { FK_OPS, "operations", "checking of primitive operations" } ,
87 { FK_PARAMS, "parameters", "function and macro parameters" } ,
88 { FK_SPEED, "performance", "speeding up checking" } ,
89 { FK_POINTER, "pointers", "pointers" } ,
90 { FK_PRED, "predicates", "condition test expressions" } ,
91 { FK_PREFIX, "prefixes", "set naming prefixes and control checking" } ,
92 { FK_PREPROC, "preproc", "defines and undefines for the preprocessor" } ,
93 { FK_PROTOS, "prototypes", "function prototypes" } ,
94 { FK_DEAD, "released", "using storage that has been deallocated" } ,
95 { FK_IGNORERET, "returnvals", "ignored return values" },
28bf4b0b 96 { FK_SECURITY, "security", "possible security vulnerability" },
616915dd 97 { FK_SPEC, "specifications", "checks involving .lcl specifications" } ,
98 { FK_SUPPRESS, "suppress", "local and global suppression of messages" } ,
99 { FK_TYPEEQ, "typeequivalence", "control what types are equivalent" } ,
100 { FK_BEHAVIOR, "undefined", "code with undefined or implementation-defined behavior" } ,
101 { FK_UNRECOG, "unrecognized", "unrecognized identifiers" } ,
102 { FK_UNSPEC, "unconstrained", "checking in the presence of unconstrained functions" } ,
28bf4b0b 103 { FK_WARNUSE, "warnuse", "use of possibly problematic function" } ,
616915dd 104 { FK_SYNTAX, NULL, NULL } ,
105 { FK_TYPE, NULL, NULL } ,
106 { FK_SECRET, NULL, NULL } ,
107 { FK_OBSOLETE, NULL, NULL } ,
108 { FK_NONE, NULL, NULL } /* must be last */
109} ;
110
111typedef enum {
112 ARG_NONE,
113 ARG_VALUE,
114 ARG_STRING,
115 ARG_SPECIAL
116} argcode;
117
118typedef struct {
119 flagkind main;
120 flagkind sub;
121 bool isSpecial; /* setting this flag may set other flags (or values) */
122 bool isIdem; /* idempotent - always sets to TRUE */
123 bool isGlobal; /* cannot be set locally (using control comments) */
124 bool isModeFlag; /* set by modes */
125 argcode argtype;
126 /*@observer@*/ char *flag;
127 flagcode code;
128 /*@observer@*/ /*@null@*/ char *desc;
129 bn_mstring hint;
130 int nreported;
131 int nsuppressed;
132} fflag;
133
134typedef fflag flaglist[];
135
136# include "flags.def"
137
138/*@iter allFlags (yield observer fflag f); @*/
139# define allFlags(m_f) \
140 { /*@+enumint@*/ flagcode m_i; for (m_i = 0; m_i < NUMFLAGS; m_i++) { fflag m_f = flags[m_i]; /*@=enumint@*/
141# define end_allFlags }}
142
143static bn_mstring mode_names[] =
144{
145 "weak", "standard", "checks", "strict", NULL,
146};
147
148/*@iter allModes (yield bn_mstring modename)@*/
149# define allModes(m_m) \
150 { int m_ii = 0; while (mstring_isDefined (mode_names[m_ii])) \
151 { bn_mstring m_m = mode_names[m_ii]; m_ii++;
152
153# define end_allModes }}
154
155/*@+enumint@*/
156
157static cstring describeFlagCode (flagcode p_flag) /*@*/ ;
158static cstringSList sortedFlags (void) /*@*/ ;
159static /*@observer@*/ cstring categoryName (flagkind p_kind) /*@*/ ;
8250fa4a 160
a956d444 161static flagcode flags_identifyFlagAux (cstring p_s, bool p_quiet) /*@modifies g_msgstream@*/ ;
162
8250fa4a 163# if 0
616915dd 164static /*@unused@*/ cstring listModes (void) /*@*/ ;
8250fa4a 165# endif
616915dd 166
167bool flagcode_isSpecialFlag (flagcode f)
168{
169 return (flags[f].isSpecial);
170}
171
172bool flagcode_isGlobalFlag (flagcode f)
173{
174 return (flags[f].isGlobal);
175}
176
177bool flagcode_isIdemFlag (flagcode f)
178{
179 return (flags[f].isIdem);
180}
181
182bool flagcode_isModeFlag (flagcode f)
183{
184 return (flags[f].isModeFlag);
185}
186
187bool flagcode_isNameChecksFlag (flagcode f)
188{
189 return (flags[f].main == FK_NAMES);
190}
191
192/*
193** Internal consistency check on the flags.
194*/
195
196void flags_initMod ()
197{
198 allFlagCodes (code)
199 {
200 /*@+enumint@*/
201 if (flags[code].code != code)
202 {
28bf4b0b 203 fprintf (stderr,
204 "*** ERROR: inconsistent flag %s / %d / %d",
205 flags[code].flag,
206 flags[code].code, code);
207
616915dd 208 llbug (message ("*** ERROR: inconsistent flag %s / %d / %d",
209 cstring_fromChars (flags[code].flag),
210 flags[code].code, code));
211 }
212 /*@=enumint@*/
213 } end_allFlagCodes;
214}
215
216void
217summarizeErrors ()
218{
219 bool hadOne = FALSE;
220 int sumrep = 0;
221 int sumsup = 0;
222
223 char *buf = mstring_create (128);
224
225 allFlags (f)
226 {
227 if (f.nreported > 0 || f.nsuppressed > 0)
228 {
229 int nrep = f.nreported;
230 int nsup = f.nsuppressed;
231 cstring fs = cstring_fill (cstring_fromChars (f.flag), 23);
232
233 if (!hadOne)
234 {
235 llmsgplain (cstring_makeLiteral
236 ("\nError Type Reported Suppressed\n"
237 "=================== ======== ========="));
238 hadOne = TRUE;
239 }
240
241 sprintf (buf, "%s%7d %9d", cstring_toCharsSafe (fs), nrep, nsup);
242
243 sumrep += nrep;
244 sumsup += nsup;
245
246 cstring_free (fs);
247 llmsg (cstring_copy (cstring_fromChars (buf)));
248 }
249 } end_allFlags;
250
251 if (hadOne)
252 {
253 cstring ts = cstring_fill (cstring_makeLiteralTemp ("Total"), 23);
254
255 llmsglit (" ======== =========");
256
257 sprintf (buf, "%s%7d %9d", cstring_toCharsSafe (ts), sumrep, sumsup);
258 cstring_free (ts);
259 llmsgplain (cstring_copy (cstring_fromChars (buf)));
260 }
261
262 sfree (buf);
263}
264
265/*@+enumindex@*/
266
267void
268flagcode_recordError (flagcode f)
269{
270 if (f != INVALID_FLAG)
271 {
272 if (f == FLG_WARNFLAGS)
273 {
274 ; /* don't count these */
275 }
276 else
277 {
278 flags[f].nreported = flags[f].nreported + 1;
279 }
280 }
281 else
282 {
283 llcontbug (message ("flagcode_recordError: invalid flag: %d", (int) f));
284 }
285}
286
287void
288flagcode_recordSuppressed (flagcode f)
289{
290 llassertprint (f != INVALID_FLAG, ("flagcode: %s", flagcode_unparse (f)));
291
292 flags[f].nsuppressed = flags[f].nsuppressed + 1;
293}
294
295int
296flagcode_numReported (flagcode f)
297{
298 llassert (f != INVALID_FLAG);
299
300 return (flags[f].nreported);
301}
302
303/*@observer@*/ cstring
304flagcodeHint (flagcode f)
305{
306 llassert (f != INVALID_FLAG);
307
308 if (mstring_isDefined (flags[f].hint))
309 {
310 return (cstring_fromChars (flags[f].hint));
311 }
312 else
313 {
314 return (cstring_fromChars (flags[f].desc));
315 }
316}
317
318static int categorySize (flagkind kind) /*@*/
319{
320 int n = 0;
321
322
323 allFlags (f)
324 {
325 if (f.main == kind || f.sub == kind)
326 {
327 n++;
328 }
329 } end_allFlags;
330
331 return n;
332}
333
334flagkind identifyCategory (cstring s)
335{
336 int i;
337
338 for (i = 0; categories[i].kind != FK_NONE; i++)
339 {
340 if (mstring_isDefined (categories[i].name))
341 {
342 if (cstring_equalLit (s, categories[i].name))
343 {
344 return categories[i].kind;
345 }
346 }
347 }
348
349 return FK_NONE;
350}
351
352static /*@observer@*/ cstring categoryName (flagkind kind)
353{
354 int i;
355
356 for (i = 0; categories[i].kind != FK_NONE; i++)
357 {
358 if (categories[i].kind == kind)
359 {
360 return (cstring_fromChars (categories[i].name));
361 }
362 }
363
364 return (cstring_makeLiteralTemp ("<No Category>"));
365}
366
367static int categoryIndex (flagkind kind)
368{
369 int i;
370
371 for (i = 0; categories[i].kind != FK_NONE; i++)
372 {
373 if (categories[i].kind == kind)
374 {
375 return i;
376 }
377 }
378
379 return -1;
380}
381
382void printCategory (flagkind kind)
383{
384 int index = categoryIndex (kind);
385
386 llassert (index >= 0);
387
388 llmsg (message ("%s (%d flags)\n\3%s\n\n",
389 cstring_fromChars (categories[index].name),
390 categorySize (kind),
391 cstring_fromChars (categories[index].describe)));
392
393 allFlags (f)
394 {
395 if (f.main == kind || f.sub == kind)
396 {
397 llmsg (message (" %s\n\6%q", cstring_fromChars (f.flag),
398 describeFlagCode (f.code)));
399 }
400 } end_allFlags;
401}
402
403void
404listAllCategories (void)
405{
406 int i;
407
408 for (i = 0; categories[i].kind != FK_NONE; i++)
409 {
410 flagkind kind = categories[i].kind ;
411
412 if (categories[i].describe != NULL)
413 {
414 llmsg (message ("%s (%d flags)\n\3%s",
415 categoryName (kind),
416 categorySize (kind),
417 cstring_fromChars (categories[i].describe)));
418 }
419 }
420}
421
422void
423printAllFlags (bool desc, bool full)
424{
425 if (full)
426 {
427 cstringSList fl = sortedFlags ();
428
429 cstringSList_elements (fl, el)
430 {
431 llmsg (message ("%q\n\n", describeFlag (el)));
432 } end_cstringSList_elements ;
433
434 cstringSList_free (fl);
435 }
436 else
437 {
438 allFlags (f)
439 {
440 if (f.code != INVALID_FLAG && f.main != FK_OBSOLETE)
441 {
442 if (mstring_isDefined (f.desc))
443 {
444 if (desc)
445 {
446 llmsg (message ("%s --- %s", cstring_fromChars (f.flag),
447 cstring_fromChars (f.desc)));
448 }
449 }
450 }
451 } end_allFlags;
452 }
453}
454
455cstring
456describeFlagCode (flagcode flag)
457{
458 cstring ret = cstring_undefined;
459 fflag f;
460
461 if (flagcode_isInvalid (flag))
462 {
463 return (cstring_makeLiteral ("<invalid>"));
464 }
465
466 context_resetAllFlags ();
467
468 f = flags[flag];
469 ret = cstring_copy (cstring_fromChars (f.desc));
470
471
472 if (f.sub != FK_NONE)
473 {
474 ret = message ("%q\nCategories: %s, %s",
475 ret,
476 categoryName (f.main),
477 categoryName (f.sub));
478 }
479 else
480 {
481 if (f.main != FK_NONE)
482 {
483 cstring cname = categoryName (f.main);
484
485 if (cstring_isDefined (cname))
486 {
487 ret = message ("%q\nCategory: %s",
488 ret, cname);
489 }
490 }
491 }
492
493 if (f.isModeFlag)
494 {
495 bool first = TRUE;
496
497 allModes (mname)
498 {
499 context_setMode (cstring_fromChars (mname));
500
501 if (first)
502 {
503 ret = message ("%q\nMode Settings: %s %s",
504 ret, cstring_fromChars (mname),
505 cstring_makeLiteralTemp
506 (context_getFlag (flag) ? "+" : "-"));
507 first = FALSE;
508 }
509 else
510 {
511 ret = message ("%q, %s %s",
512 ret, cstring_fromChars (mname),
513 cstring_makeLiteralTemp
514 (context_getFlag (flag) ? "+" : "-"));
515 }
516 } end_allModes;
517 }
518 else
519 {
520 ret = message ("%q\nDefault Setting: %s",
521 ret,
522 cstring_makeLiteralTemp
523 (context_getFlag (flag) ? "+" : "-"));
524 }
525
526 if (f.isGlobal)
527 {
528 ret = message("%q\nSet globally only", ret);
529 }
530 else
531 {
532 ret = message("%q\nSet locally", ret);
533 }
534
535 switch (f.argtype)
536 {
537 case ARG_NONE:
538 case ARG_SPECIAL:
539 break;
540 case ARG_VALUE:
541 if (flag == FLG_COMMENTCHAR)
542 {
543 ret = message("%q\nCharacter Argument. Default: %h",
544 ret, (char) context_getValue (flag));
545 }
546 else
547 {
548 ret = message("%q\nNumeric Argument. Default: %d",
549 ret,
550 context_getValue (flag));
551 }
552 break;
553 case ARG_STRING:
554 if (cstring_isDefined (context_getString (flag)))
555 {
556 ret = message("%q\nString Argument. Default: %s",
557 ret,
558 context_getString (flag));
559 }
560 else
561 {
562 ret = message("%q\nString Argument. No default.", ret);
563 }
564 break;
565 }
566
567 if (mstring_isDefined (f.hint))
568 {
569 ret = message("%q\n\3%s", ret, cstring_fromChars (f.hint));
570 }
571
572 return ret;
573}
574
575cstring
576describeFlag (cstring flagname)
577{
578 cstring oflagname = cstring_copy (flagname);
a956d444 579 flagcode f = flags_identifyFlag (flagname);
616915dd 580
581 if (flagcode_isSkip (f))
582 {
583 cstring_free (oflagname);
584 return cstring_undefined;
585 }
586 else if (flagcode_isValid (f))
587 {
588 if (cstring_equal (flagname, oflagname))
589 {
590 cstring_free (oflagname);
591 return (message ("%s\n\3%q", flagname, describeFlagCode (f)));
592 }
593 else
594 {
595 return (message ("%q (standardized name: %s)\n\3%q",
596 oflagname, flagname, describeFlagCode (f)));
597 }
598 }
599 else
600 {
601 if (isMode (flagname))
602 {
603 cstring_free (oflagname);
604
605 return
606 (message ("%s: predefined mode (see User's Guide for information)",
607 flagname));
608 }
609 else
610 {
611 return (message ("%q: <invalid flag>", oflagname));
612 }
613 }
614}
615
616static cstringSList
617sortedFlags (void)
618{
619 cstringSList s = cstringSList_new ();
620
621 allFlags (f)
622 {
623 if (f.desc != NULL)
624 {
625 s = cstringSList_add (s, cstring_fromChars (f.flag));
626 }
627 } end_allFlags;
628
629 cstringSList_alphabetize (s);
630
631 return s;
632}
633
634void printAlphaFlags ()
635{
636 cstringSList fl = sortedFlags ();
637
638 cstringSList_printSpaced (fl, 3, 1, context_getLineLen () - 25);
639 cstringSList_free (fl);
640}
28bf4b0b 641
616915dd 642/*@observer@*/ cstring
28bf4b0b 643flagcode_unparse (flagcode code)
616915dd 644{
7272a1c1 645 if (code == INVALID_FLAG)
646 {
647 return cstring_makeLiteralTemp ("<invalid flag>");
648 }
649
616915dd 650 return cstring_fromChars (flags[code].flag);
651}
652
653/*
654** Transforms a flag into its cannonical form.
655**
656** The following transformations are made:
657**
658** function -> fcn
659** variable -> var
660** constant -> const
661** iterator -> iter
662** parameter -> param
663** unrecognized -> unrecog
664** qualifier -> qual
665** declaration -> decl
666** globalias -> (no change)
667** global -> glob
668** modifies -> mods
669** modify -> mod
670** pointer -> ptr
671** implies -> imp
672** implicit -> imp
673** implied -> imp
674** unconstrained -> unspec
675** unconst -> unspec
676** memory -> mem
677** length -> len
678*/
679
680static void
681canonicalizeFlag (cstring s)
682{
683 int i = 0;
684 static bn_mstring transform[] =
685 {
686 "function", "fcn",
687 "variable", "var",
688 "constant", "const",
689 "iterator", "iter",
690 "parameter", "param",
691 "unrecognized", "unrecog",
692 "qualifier", "qual",
693 "declaration", "decl",
694 "globals", "globs",
695 "modifies", "mods",
696 "modify", "mod",
697 "pointer", "ptr",
698 "implies", "imp",
699 "implicit", "imp",
700 "implied", "imp",
701 "unconstrained", "uncon",
702 "unconst", "uncon",
703 "memory", "mem",
704 "length", "len",
705 "return", "ret",
706 "system", "sys",
707 NULL
708 } ;
709 char *current;
710
711 while ((current = transform[i]) != NULL)
712 {
713 if (cstring_containsLit (s, current))
714 {
715 cstring_replaceLit (s, current, transform[i+1]);
716 }
717 i += 2;
718 }
719
720 /* remove whitespace, -'s, and _'s */
721 cstring_stripChars (s, " -_");
722}
723
724flagcode
a956d444 725flags_identifyFlag (cstring s)
726{
727 return flags_identifyFlagAux (s, FALSE);
728}
729
730flagcode
731flags_identifyFlagQuiet (cstring s)
732{
733 return flags_identifyFlagAux (s, TRUE);
734}
735
736static flagcode
737flags_identifyFlagAux (cstring s, bool quiet)
616915dd 738{
739 if (cstring_length (s) == 0) {
740 /* evs 2000-06-25: A malformed flag. */
741 return INVALID_FLAG;
742 }
743
744 if (cstring_firstChar (s) == 'I')
745 {
746 return FLG_INCLUDEPATH; /* no space after -I */
747 }
748
749 if (cstring_firstChar (s) == 'S')
750 {
751 return FLG_SPECPATH; /* no space after -S */
752 }
753
754 if (cstring_firstChar (s) == 'D')
755 {
756 return FLG_DEFINE; /* no space after -D */
757 }
758
759 if (cstring_firstChar (s) == 'U')
760 {
761 return FLG_UNDEFINE; /* no space after -D */
762 }
763
764 canonicalizeFlag (s);
765
766 allFlags (f)
767 {
768 if (cstring_equal (cstring_fromChars (f.flag), s))
769 {
770 return (f.code);
771 }
772 } end_allFlags;
773
774 /*
775 ** Synonyms
776 */
777
778 if (cstring_equalLit (s, "pred"))
779 {
780 return FLG_PREDBOOL;
781 }
782
783 if (cstring_equalLit (s, "modobserverstrict"))
784 {
785 return FLG_MODOBSERVERUNCON;
786 }
787
788 if (cstring_equalLit (s, "czechnames"))
789 {
790 return FLG_CZECH;
791 }
792
793 if (cstring_equalLit (s, "slovaknames"))
794 {
795 return FLG_SLOVAK;
796 }
797
798 if (cstring_equalLit (s, "czechoslovaknames"))
799 {
800 return FLG_CZECHOSLOVAK;
801 }
802
803 if (cstring_equalLit (s, "globunspec")
804 || cstring_equalLit (s, "globuncon"))
805 {
806 return FLG_GLOBUNSPEC;
807 }
808
809 if (cstring_equalLit (s, "modglobsunspec")
810 || cstring_equalLit (s, "modglobsuncon")
811 || cstring_equalLit (s, "modglobsnomods"))
812 {
813 return FLG_MODGLOBSUNSPEC;
814 }
815
816 if (cstring_equalLit (s, "export"))
817 {
818 return FLG_EXPORTANY;
819 }
820
821 if (cstring_equalLit (s, "macrospec"))
822 {
823 return FLG_MACRODECL;
824 }
825
826 if (cstring_equalLit (s, "ansireservedlocal"))
827 {
828 return FLG_ANSIRESERVEDLOCAL;
829 }
830
831 if (cstring_equalLit (s, "warnposix"))
832 {
833 return FLG_WARNPOSIX;
834 }
835
836 if (cstring_equalLit (s, "defuse"))
837 {
838 return FLG_USEDEF;
839 }
840
841 if (cstring_equalLit (s, "macroundef"))
842 {
843 return FLG_MACROUNDEF;
844 }
845
846 if (cstring_equalLit (s, "showcol"))
847 {
848 return FLG_SHOWCOL;
849 }
850
851 if (cstring_equalLit (s, "intbool"))
852 {
853 return FLG_BOOLINT;
854 }
855
856 if (cstring_equalLit (s, "intchar"))
857 {
858 return FLG_CHARINT;
859 }
860
861 if (cstring_equalLit (s, "intenum"))
862 {
863 return FLG_ENUMINT;
864 }
865
866 /*
27c9e640 867 ** Backwards compatibility for our American friends...
616915dd 868 */
869
27c9e640 870 if (cstring_equalLit (s, "ansilib"))
616915dd 871 {
872 return FLG_ANSILIB;
873 }
874
616915dd 875 if (cstring_equalLit (s, "ansistrictlib"))
876 {
877 return FLG_STRICTLIB;
878 }
879
27c9e640 880 if (cstring_equalLit (s, "skipansiheaders"))
616915dd 881 {
882 return FLG_SKIPANSIHEADERS;
883 }
884
27c9e640 885 if (cstring_equalLit (s, "ansireserved"))
616915dd 886 {
887 return FLG_ANSIRESERVED;
888 }
889
27c9e640 890 if (cstring_equalLit (s, "ansireservedinternal"))
616915dd 891 {
892 return FLG_ANSIRESERVEDLOCAL;
893 }
894
616915dd 895 /*
896 ** Obsolete Flags
897 */
898
899 if (cstring_equalLit (s, "accessunspec"))
900 {
a956d444 901 if (!quiet)
902 {
903 llerror_flagWarning
904 (cstring_makeLiteral
905 ("accessunspec flag is no longer supported. It has been replaced by accessmodule, accessfile and "
906 "accessfunction to provide more precise control of accessibility "
907 "of representations. For more information, "
908 "see lclint -help accessmodule"));
909 }
616915dd 910
27c9e640 911 return SKIP_FLAG;
912 }
913 else if (cstring_equalLit (s, "ansilimits"))
914 {
915 llerror_flagWarning
916 (cstring_makeLiteral
917 ("ansilimits flag is no longer supported. It has been replaced by ansi89limits and "
918 "iso99limits to select either the lower translation limits imposed by the ANSI89 "
919 "standard or the typically higher limits prescribed by ISO C99."));
920
616915dd 921 return SKIP_FLAG;
922 }
a956d444 923 else if (cstring_equalLit (s, "staticmods"))
924 {
925 if (!quiet)
926 {
927 llerror_flagWarning
928 (cstring_makeLiteral
929 ("staticmods flag is obsolete. You probably "
930 "want impcheckmodstatics. For more information, "
931 "see lclint -help impcheckmodstatics"));
932 }
616915dd 933
a956d444 934 return SKIP_FLAG;
935 }
936 else if (cstring_equalLit (s, "bool"))
616915dd 937 {
a956d444 938 if (!quiet)
939 {
940 llerror_flagWarning
941 (cstring_makeLiteral ("bool flag is obsolete. It never really "
942 "made sense in the first place."));
943 }
616915dd 944
945 return SKIP_FLAG;
946 }
a956d444 947 else if (cstring_equalLit (s, "shiftsigned"))
616915dd 948 {
a956d444 949 if (!quiet)
950 {
951 llerror_flagWarning
952 (cstring_makeLiteral ("shiftsigned flag is obsolete. You probably "
953 "want bitwisesigned, shiftnegative or shiftsize."));
954 }
616915dd 955
956 return SKIP_FLAG;
957 }
a956d444 958 else if (cstring_equalLit (s, "ansi"))
616915dd 959 {
a956d444 960 if (!quiet)
961 {
962 llerror_flagWarning
963 (cstring_makeLiteral ("ansi flag is obsolete. You probably "
964 "want noparams and/or oldstyle."));
965 }
616915dd 966
967 return SKIP_FLAG;
968 }
a956d444 969 else if (cstring_equalLit (s, "stdio"))
970 {
971 if (!quiet)
972 {
973 llerror_flagWarning
974 (cstring_makeLiteral
975 ("stdio flag is obsolete. You may "
976 "want strictlib or one of the gloabls "
977 "checking flags. For more information, "
978 "see lclint -help strictlib or lclint -help flags globals"));
979 }
616915dd 980
981 return SKIP_FLAG;
982 }
a956d444 983 else
984 {
985 return INVALID_FLAG;
986 }
616915dd 987}
988
989void setValueFlag (flagcode opt, cstring arg)
990{
991 switch (opt)
992 {
993 case FLG_EXPECT:
994 case FLG_LCLEXPECT:
995 case FLG_LIMIT:
996 case FLG_LINELEN:
28bf4b0b 997 case FLG_INDENTSPACES:
998 case FLG_BUGSLIMIT:
616915dd 999 case FLG_EXTERNALNAMELEN:
1000 case FLG_INTERNALNAMELEN:
1001 case FLG_CONTROLNESTDEPTH:
1002 case FLG_STRINGLITERALLEN:
1003 case FLG_NUMSTRUCTFIELDS:
1004 case FLG_NUMENUMMEMBERS:
1005 case FLG_INCLUDENEST:
1006 {
1007 int val = cstring_toPosInt (arg);
1008
1009 if (val < 0)
1010 {
1011 llerror
1012 (FLG_BADFLAG,
1013 message
1014 ("Flag %s must be followed by a positive number number. "
1015 "Followed by %s",
1016 flagcode_unparse (opt), arg));
1017 }
1018 else
1019 {
28bf4b0b 1020 context_setValueAndFlag (opt, val);
616915dd 1021 }
1022 }
1023 break;
1024 case FLG_COMMENTCHAR:
1025 {
1026 if (cstring_length (arg) != 1)
1027 {
1028 llfatalerrorLoc
1029 (message
1030 ("Flag %s should be followed by a single character. Followed by %s",
1031 flagcode_unparse (opt), arg));
1032 }
1033 else
1034 {
1035 context_setCommentMarkerChar (cstring_firstChar (arg));
1036 }
1037 }
1038 break;
1039 BADDEFAULT;
1040 }
1041}
1042
1043void setStringFlag (flagcode opt, /*@only@*/ cstring arg)
1044{
1045 switch (opt)
1046 {
1047 case FLG_TMPDIR:
1048 {
1049 if (cstring_lastChar (arg) == CONNECTCHAR)
1050 {
1051 context_setString (opt, arg);
1052 }
1053 else
1054 {
1055 context_setString (opt, cstring_appendChar (arg, CONNECTCHAR));
1056 }
1057 break;
1058 }
1059 default:
1060 {
1061 context_setString (opt, arg);
1062 break;
1063 }
1064 }
1065}
1066
1067cstring
1068describeModes ()
1069{
1070 cstring s = cstring_makeLiteral ("Flag ");
1071 cstringSList sflags = sortedFlags ();
1072
1073 allModes (modename)
1074 {
1075 s = message ("%q%9s", s, cstring_fromChars (modename));
1076 } end_allModes;
1077
1078 s = message ("%q\n", s);
1079
1080 cstringSList_elements (sflags, flagname)
1081 {
a956d444 1082 flagcode code = flags_identifyFlag (flagname);
616915dd 1083 fflag currentflag = flags[code];
1084
1085 if (mstring_isDefined (currentflag.desc) && flagcode_isModeFlag (code))
1086 {
1087 s = message ("%q\n%27s", s,
1088 cstring_fromChars (currentflag.flag));
1089
1090 allModes (modename)
1091 {
1092 context_setMode (cstring_fromChars (modename));
1093
1094 if (context_getFlag (code))
1095 {
1096 s = message ("%q%9s", s, cstring_makeLiteralTemp ("+"));
1097 }
1098 else
1099 {
1100 s = message ("%q%9s", s, cstring_makeLiteralTemp (" "));
1101 }
1102
1103 context_resetModeFlags ();
1104 } end_allModes;
1105 }
1106 } end_cstringSList_elements;
1107
1108 cstringSList_free (sflags);
1109
1110 s = cstring_appendChar (s, '\n');
1111
1112 return (s);
1113}
1114
8250fa4a 1115# if 0
ee229125 1116static /*@unused@*/ cstring
616915dd 1117listModes (void)
1118{
1119 cstring s = cstring_makeLiteral ("\t");
1120 int i = 0;
1121
1122 allModes (modename)
1123 {
1124 if (i != 0 && (i % 4 == 0))
1125 {
1126 s = message ("%q\n\t%15s", s, cstring_fromChars (modename));
1127 }
1128 else
1129 {
1130 s = message ("%q%15s", s, cstring_fromChars (modename));
1131 }
1132 i++;
1133 } end_allModes;
1134
1135 return s;
1136}
8250fa4a 1137# endif
616915dd 1138
1139bool
1140isMode (cstring s)
1141{
1142 allModes (modename)
1143 {
1144 if (mstring_isDefined (modename))
1145 {
1146 if (cstring_equalLit (s, modename))
1147 {
1148 return TRUE;
1149 }
1150 }
1151 } end_allModes;
1152
1153 return FALSE;
1154}
1155
1156extern bool flagcode_hasArgument (flagcode f)
1157{
1158 return (flags[f].argtype != ARG_NONE);
1159}
1160
1161extern bool flagcode_hasValue (flagcode f)
1162{
1163 return (flags[f].argtype == ARG_VALUE);
1164}
1165
1166extern bool flagcode_hasString (flagcode f)
1167{
1168 return (flags[f].argtype == ARG_STRING);
1169}
1170
1171extern int flagcode_valueIndex (flagcode f)
1172{
1173 /*@unchecked@*/ static bool initialized = FALSE;
1174 int i;
1175 /*@unchecked@*/ static flagcode valueFlags[NUMVALUEFLAGS];
616915dd 1176
1177 if (!initialized)
1178 {
1179 int nv = 0;
1180
1181 allFlagCodes (code)
1182 {
1183 if (flagcode_hasValue (code))
1184 {
1185 llassert (nv < NUMVALUEFLAGS);
28bf4b0b 1186 DPRINTF (("Value flag: %s [%d]", flagcode_unparse (code), (int) code));
616915dd 1187 valueFlags[nv] = code;
28bf4b0b 1188 nv++;
616915dd 1189 }
1190 } end_allFlagCodes;
1191
1192 llassertprint (nv == NUMVALUEFLAGS,
28bf4b0b 1193 ("Number of value flags: %d (expected %d)",
1194 nv, (int) NUMVALUEFLAGS));
616915dd 1195 initialized = TRUE;
1196 }
1197
1198 for (i = 0; i < NUMVALUEFLAGS; i++)
1199 {
1200 /* static valueFlags must be defined */
1201 /*@-usedef@*/ if (f == valueFlags[i]) /*@=usedef@*/
1202 {
1203 return i;
1204 }
1205 }
1206
28bf4b0b 1207 fprintf (stderr, "Cannot find value flag: %d", (int) f);
1208 exit (EXIT_FAILURE);
1209 /* Cannot do this...might call recursively...
1210 llfatalbug (message ("Cannot fine value flag: %d", (int) f));
616915dd 1211 BADEXIT;
28bf4b0b 1212 */
616915dd 1213}
1214
1215extern int flagcode_stringIndex (flagcode f)
1216{
1217 /*@unchecked@*/ static bool initialized = FALSE;
1218 /*@unchecked@*/ static flagcode stringFlags[NUMSTRINGFLAGS];
1219 int i;
1220
1221
1222 if (!initialized)
1223 {
1224 int nv = 0;
1225
1226 allFlagCodes (code)
1227 {
1228 if (flagcode_hasString (code))
1229 {
1230 llassertprint (nv < NUMSTRINGFLAGS, ("Incorrect number of string flags: %d (need at least %d)", NUMSTRINGFLAGS, nv));
1231 stringFlags[nv] = code;
1232 nv++;
1233 }
1234 } end_allFlagCodes;
1235
1236 llassertprint (nv == NUMSTRINGFLAGS,
1237 ("number of string flags: %d (expected %d)",
1238 nv, NUMSTRINGFLAGS));
1239 initialized = TRUE;
1240 }
1241
1242 for (i = 0; i < NUMSTRINGFLAGS; i++)
1243 {
1244 /*@-usedef@*/ if (f == stringFlags[i]) /*@=usedef@*/
1245 {
1246 return i;
1247 }
1248 }
1249
1250 llbug (message ("Bad string flag: %s", flagcode_unparse (f)));
1251 BADEXIT;
1252}
1253
1254bool flagcode_isNamePrefixFlag (flagcode f)
1255{
1256 switch (f)
1257 {
1258 case FLG_MACROVARPREFIX:
1259 case FLG_TAGPREFIX:
1260 case FLG_ENUMPREFIX:
1261 case FLG_FILESTATICPREFIX:
1262 case FLG_GLOBPREFIX:
1263 case FLG_TYPEPREFIX:
1264 case FLG_EXTERNALPREFIX:
1265 case FLG_LOCALPREFIX:
1266 case FLG_UNCHECKEDMACROPREFIX:
1267 case FLG_CONSTPREFIX:
1268 case FLG_ITERPREFIX:
1269 case FLG_DECLPARAMPREFIX:
1270 return TRUE;
1271 default:
1272 return FALSE;
1273 }
1274}
1275
This page took 0.496316 seconds and 5 git commands to generate.