]> andersk Git - splint.git/blame - src/multiVal.c
Updating to use the LEnsures and LRequires instead of the ensures requires so
[splint.git] / src / multiVal.c
CommitLineData
616915dd 1/*
2** LCLint - annotation-assisted static program checker
3** Copyright (C) 1994-2000 University of Virginia,
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
22** For more information: http://lclint.cs.virginia.edu
23*/
24/*
25** multiVal.c
26*/
27
28# include "lclintMacros.nf"
29# include "basic.h"
30
31/*@only@*/ multiVal multiVal_unknown ()
32{
33 return multiVal_undefined;
34}
35
36static /*@special@*/ /*@notnull@*/ multiVal multiVal_create (mvkind kind)
37 /*@defines result->kind@*/
38{
39 multiVal mv = (multiVal) dmalloc (sizeof (*mv));
40
41 mv->kind = kind;
42 return mv;
43}
44
45/*@only@*/ multiVal multiVal_makeInt (long x)
46{
47 multiVal mv = multiVal_create (MVLONG);
48
49 mv->value.ival = x;
50 return mv;
51}
52
53/*@only@*/ multiVal multiVal_makeChar (char x)
54{
55 multiVal mv = multiVal_create (MVCHAR);
56 mv->value.cval = x;
57 return mv;
58}
59
60/*@only@*/ multiVal multiVal_makeDouble (double x)
61{
62 multiVal mv = multiVal_create (MVDOUBLE);
63
64 mv->value.fval = x;
65 return mv;
66}
67
68/*@only@*/ multiVal multiVal_makeString (/*@only@*/ cstring s)
69{
70 multiVal mv = multiVal_create (MVSTRING);
71
72 mv->value.sval = s;
73 return mv;
74}
75
76
77/*@only@*/ multiVal multiVal_copy (multiVal m)
78{
79 multiVal r;
80
81 if (multiVal_isUndefined (m))
82 {
83 return multiVal_undefined;
84 }
85
86 r = multiVal_create (m->kind);
87
88 switch (m->kind)
89 {
90 case MVLONG:
91 r->value.ival = m->value.ival;
92 break;
93 case MVCHAR:
94 r->value.cval = m->value.cval;
95 break;
96 case MVDOUBLE:
97 r->value.fval = m->value.fval;
98 break;
99 case MVSTRING:
100 r->value.sval = cstring_copy (m->value.sval);
101 break;
102 }
103
104 return r;
105}
106
107multiVal multiVal_invert (multiVal m)
108{
109 if (multiVal_isUndefined (m))
110 {
111 return multiVal_undefined;
112 }
113
114 switch (m->kind)
115 {
116 case MVLONG:
117 return multiVal_makeInt (-1 * m->value.ival);
118 case MVCHAR:
119 BADBRANCHCONT;
120 return multiVal_undefined;
121 case MVDOUBLE:
122 return multiVal_makeDouble (-1.0 * m->value.fval);
123 case MVSTRING:
124 BADBRANCHCONT;
125 return multiVal_undefined;
126 }
127
128 BADEXIT;
129}
130
131long multiVal_forceInt (multiVal m)
132{
133 llassert (multiVal_isInt (m));
134
135 return m->value.ival;
136}
137
138char multiVal_forceChar (multiVal m)
139{
140 llassert (multiVal_isChar (m));
141
142 return m->value.cval;
143}
144
145double multiVal_forceDouble (multiVal m)
146{
147 llassert (multiVal_isDouble (m));
148
149 return m->value.fval;
150}
151
152/*@dependent@*/ /*@observer@*/ cstring multiVal_forceString (multiVal m)
153{
154 llassert (multiVal_isString (m));
155
156 return m->value.sval;
157}
158
159bool multiVal_isInt (multiVal m)
160{
161 return (multiVal_isDefined (m) && m->kind == MVLONG);
162}
163
164bool multiVal_isChar (multiVal m)
165{
166 return (multiVal_isDefined (m) && m->kind == MVCHAR);
167}
168
169bool multiVal_isDouble (multiVal m)
170{
171 return (multiVal_isDefined (m) && m->kind == MVDOUBLE);
172}
173
174bool multiVal_isString (multiVal m)
175{
176 return (multiVal_isDefined (m) && m->kind == MVSTRING);
177}
178
179/*@only@*/ cstring multiVal_unparse (multiVal m)
180{
181 if (multiVal_isDefined (m))
182 {
183 switch (m->kind)
184 {
185 case MVLONG:
186 return message ("%d", (int)m->value.ival);
187 case MVCHAR:
188 return message ("'%h'", m->value.cval);
189 case MVDOUBLE:
190 return message ("%f", (float)m->value.fval);
191 case MVSTRING:
192 return message ("%s", m->value.sval);
193 }
194 BADEXIT;
195 }
196 else
197 {
198 return (cstring_makeLiteral ("?"));
199 }
200}
201
202/*@only@*/ cstring multiVal_dump (multiVal m)
203{
204 if (multiVal_isDefined (m))
205 {
206 switch (m->kind)
207 {
208 case MVLONG:
209 return (message ("i%d", (int)m->value.ival));
210 case MVCHAR:
211 return (message ("c%d", (int)m->value.cval));
212 case MVDOUBLE:
213 return (message ("d%f", (float)m->value.fval));
214 case MVSTRING:
215 return (message ("s%s", m->value.sval));
216 }
217 BADEXIT;
218 }
219 else
220 {
221 return (cstring_undefined);
222 }
223}
224
225/*@only@*/ multiVal multiVal_undump (char **s)
226{
227 char tchar = **s;
228
229 switch (tchar)
230 {
231 case 'i':
232 (*s)++;
233 return multiVal_makeInt (getInt (s));
234 case 'c':
235 (*s)++;
236 return multiVal_makeChar ((char) getInt (s));
237 case 'd':
238 (*s)++;
239 return multiVal_makeDouble (getDouble (s));
240 case 's':
241 {
242 cstring st = cstring_undefined;
243
244 (*s)++;
245 while (**s != '#')
246 {
247 st = cstring_appendChar (st, **s);
248 (*s)++;
249 }
250
251 return multiVal_makeString (st);
252 }
253 case '@':
254 case '#':
255 return multiVal_unknown ();
256 BADDEFAULT;
257 }
258
259 BADEXIT;
260}
261
262int multiVal_compare (multiVal m1, multiVal m2)
263{
264 if (multiVal_isUndefined (m1))
265 {
266 if (multiVal_isUndefined (m2))
267 {
268 return 0;
269 }
270
271 else return -1;
272 }
273 if (multiVal_isUndefined (m2))
274 {
275 return -1;
276 }
277
278 COMPARERETURN (generic_compare (m1->kind, m2->kind));
279
280 switch (m1->kind)
281 {
282 case MVLONG: return (generic_compare (m1->value.ival, m2->value.ival));
283 case MVCHAR: return (generic_compare (m1->value.cval, m2->value.cval));
284 case MVDOUBLE: return (generic_compare (m1->value.fval, m2->value.fval));
285 case MVSTRING: return (cstring_compare (m1->value.sval, m2->value.sval));
286 }
287
288 BADEXIT;
289}
290
291void multiVal_free (/*@only@*/ multiVal m)
292{
293 if (multiVal_isDefined (m))
294 {
295 if (m->kind == MVSTRING)
296 {
297 cstring_free (m->value.sval);
298 }
299
300 sfree (m);
301 }
302}
303
304
305
306
This page took 0.085886 seconds and 5 git commands to generate.