2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
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.
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.
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.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
28 # include "splintMacros.nf"
31 static /*@only@*/ flagSpecItem flagSpecItem_create (/*@only@*/ cstring fname)
33 flagSpecItem res = (flagSpecItem) dmalloc (sizeof (*res));
\r
34 DPRINTF (("Creating item: [%p]", fname));
\r
35 DPRINTF (("The name is: %s", fname));
\r
38 res->code = flags_identifyFlag (fname);
39 /* Invalid flag okay for now... */
43 static void flagSpecItem_free (/*@only@*/ flagSpecItem fitem)
45 cstring_free (fitem->name);
49 static /*@only@*/ flagSpec flagSpec_create (/*@only@*/ flagSpecItem fitem,
50 /*@only@*/ flagSpec frest)
52 flagSpec res = (flagSpec) dmalloc (sizeof (*res));
55 DPRINTF (("New flag spec: %s", flagSpec_unparse (res)));
59 flagSpec flagSpec_createPlain (cstring fname)
61 flagSpecItem fitem = flagSpecItem_create (fname);
\r
62 flagSpec res = flagSpec_create (fitem, flagSpec_undefined);
63 DPRINTF (("New flag spec: %s", flagSpec_unparse (res)));
\r
67 flagSpec flagSpec_createOr (cstring fname, flagSpec f)
69 return flagSpec_create (flagSpecItem_create (fname), f);
72 void flagSpec_free (flagSpec f)
74 if (flagSpec_isDefined (f))
76 flagSpecItem_free (f->tspec);
77 if (flagSpec_isDefined (f->trest))
79 flagSpec_free (f->trest);
86 flagSpec flagSpec_copy (flagSpec f)
88 if (flagSpec_isDefined (f))
90 if (flagSpec_isDefined (f->trest))
92 return flagSpec_createOr (cstring_copy (f->tspec->name),
93 flagSpec_copy (f->trest));
97 return flagSpec_createPlain (cstring_copy (f->tspec->name));
102 return flagSpec_undefined;
106 cstring flagSpec_unparse (flagSpec f)
108 if (flagSpec_isDefined (f))
110 if (flagSpec_isDefined (f->trest))
112 return message ("%s | %q", f->tspec->name, flagSpec_unparse (f->trest));
116 return cstring_copy (f->tspec->name);
121 return cstring_makeLiteral ("<*** flagSpec undefined ***>");
125 cstring flagSpec_dump (flagSpec f)
127 llassert (flagSpec_isDefined (f));
128 llassert (!cstring_containsChar (f->tspec->name, '|'));
129 llassert (!cstring_containsChar (f->tspec->name, '#'));
131 if (flagSpec_isDefined (f->trest))
133 return message ("%s|%q", f->tspec->name, flagSpec_dump (f->trest));
137 return cstring_copy (f->tspec->name);
142 flagSpec_undump (char **s)
145 flagname = reader_readUntilOne (s, "#|");
147 if (reader_optCheckChar (s, '|'))
149 return flagSpec_createOr (flagname, flagSpec_undump (s));
153 return flagSpec_createPlain (flagname);
158 flagSpec_getDominant (flagSpec fs)
160 llassert (flagSpec_isDefined (fs));
163 return fs->tspec->code;
167 flagSpec_isOn (flagSpec fs, fileloc loc)
169 llassert (flagSpec_isDefined (fs));
171 if (context_flagOn (fs->tspec->code, loc))
175 else if (flagSpec_isDefined (fs->trest))
177 return flagSpec_isOn (fs->trest, loc);
186 flagSpec_getFirstOn (flagSpec fs, fileloc loc)
188 llassert (flagSpec_isDefined (fs));
190 if (context_flagOn (fs->tspec->code, loc))
192 return fs->tspec->code;
194 else if (flagSpec_isDefined (fs->trest))
196 return flagSpec_getFirstOn (fs->trest, loc);
203 BADBRANCHRET (INVALID_FLAG);