]> andersk Git - splint.git/blame - src/multiVal.c
Modified tests to account for bool being defined in the standard library.
[splint.git] / src / multiVal.c
CommitLineData
616915dd 1/*
11db3170 2** Splint - annotation-assisted static program checker
c59f5181 3** Copyright (C) 1994-2003 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**
155af98d 20** For information on splint: info@splint.org
21** To report a bug: splint-bug@splint.org
11db3170 22** For more information: http://www.splint.org
616915dd 23*/
24/*
25** multiVal.c
26*/
27
1b8ae690 28# include "splintMacros.nf"
616915dd 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);
4dd72714 56 mv->value.cval = x;
57 return mv;
616915dd 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)++;
28bf4b0b 233 return multiVal_makeInt (reader_getInt (s));
616915dd 234 case 'c':
235 (*s)++;
28bf4b0b 236 return multiVal_makeChar ((char) reader_getInt (s));
616915dd 237 case 'd':
238 (*s)++;
28bf4b0b 239 return multiVal_makeDouble (reader_getDouble (s));
616915dd 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
a956d444 291multiVal multiVal_add (multiVal m1, multiVal m2)
292{
293 if (multiVal_isUndefined (m1) || multiVal_isUndefined (m2) || m1->kind != m2->kind)
294 {
295 return multiVal_undefined;
296 }
297
298 switch (m1->kind)
299 {
300 case MVLONG: return (multiVal_makeInt (m1->value.ival + m2->value.ival));
4dd72714 301 case MVCHAR: return (multiVal_makeChar ((char) (m1->value.cval + m2->value.cval)));
a956d444 302 case MVDOUBLE: return (multiVal_makeDouble (m1->value.fval + m2->value.fval));
303 case MVSTRING: return multiVal_undefined;
304 }
305
306 BADEXIT;
307}
308
309multiVal multiVal_subtract (multiVal m1, multiVal m2)
310{
311 if (multiVal_isUndefined (m1) || multiVal_isUndefined (m2) || m1->kind != m2->kind)
312 {
313 return multiVal_undefined;
314 }
315
316 switch (m1->kind)
317 {
318 case MVLONG: return (multiVal_makeInt (m1->value.ival - m2->value.ival));
4dd72714 319 case MVCHAR: return (multiVal_makeChar ((char) (m1->value.cval - m2->value.cval)));
a956d444 320 case MVDOUBLE: return (multiVal_makeDouble (m1->value.fval - m2->value.fval));
321 case MVSTRING: return multiVal_undefined;
322 }
323
324 BADEXIT;
325}
326
327multiVal multiVal_multiply (multiVal m1, multiVal m2)
328{
329 if (multiVal_isUndefined (m1) || multiVal_isUndefined (m2) || m1->kind != m2->kind)
330 {
331 return multiVal_undefined;
332 }
333
334 switch (m1->kind)
335 {
336 case MVLONG: return (multiVal_makeInt (m1->value.ival * m2->value.ival));
4dd72714 337 case MVCHAR: return (multiVal_makeChar ((char) (m1->value.cval * m2->value.cval)));
a956d444 338 case MVDOUBLE: return (multiVal_makeDouble (m1->value.fval * m2->value.fval));
339 case MVSTRING: return multiVal_undefined;
340 }
341
342 BADEXIT;
343}
344
345multiVal multiVal_divide (multiVal m1, multiVal m2)
346{
347 if (multiVal_isUndefined (m1) || multiVal_isUndefined (m2) || m1->kind != m2->kind)
348 {
349 return multiVal_undefined;
350 }
351
352 switch (m1->kind)
353 {
91f027c7 354 case MVLONG:
355 if (m2->value.ival != 0)
356 {
357 return (multiVal_makeInt (m1->value.ival / m2->value.ival));
358 }
359 else
360 {
361 return multiVal_undefined;
362 }
363 case MVCHAR:
9dc8a5c1 364 if (m2->value.cval != (char) 0)
91f027c7 365 {
366 return (multiVal_makeChar ((char) (m1->value.cval / m2->value.cval)));
367 }
368 else
369 {
370 return multiVal_undefined;
371 }
372 case MVDOUBLE:
9dc8a5c1 373 return multiVal_undefined; /* Don't attempt to divide floats */
a956d444 374 case MVSTRING: return multiVal_undefined;
375 }
376
377 BADEXIT;
378}
379
616915dd 380void multiVal_free (/*@only@*/ multiVal m)
381{
382 if (multiVal_isDefined (m))
383 {
384 if (m->kind == MVSTRING)
385 {
386 cstring_free (m->value.sval);
387 }
388
389 sfree (m);
390 }
391}
392
393
394
395
This page took 0.116256 seconds and 5 git commands to generate.