]> andersk Git - splint.git/blame - src/multiVal.c
Fixed problem with shadow parameters.
[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{
909cf5eb 133 if (multiVal_isInt (m)) {
134 return m->value.ival;
135 } else {
136 llcontbug (message ("Multival is not int: %s", multiVal_unparse (m)));
137 return 0;
138 }
616915dd 139}
140
141char multiVal_forceChar (multiVal m)
142{
143 llassert (multiVal_isChar (m));
144
145 return m->value.cval;
146}
147
148double multiVal_forceDouble (multiVal m)
149{
150 llassert (multiVal_isDouble (m));
151
152 return m->value.fval;
153}
154
155/*@dependent@*/ /*@observer@*/ cstring multiVal_forceString (multiVal m)
156{
157 llassert (multiVal_isString (m));
158
159 return m->value.sval;
160}
161
162bool multiVal_isInt (multiVal m)
163{
164 return (multiVal_isDefined (m) && m->kind == MVLONG);
165}
166
167bool multiVal_isChar (multiVal m)
168{
169 return (multiVal_isDefined (m) && m->kind == MVCHAR);
170}
171
172bool multiVal_isDouble (multiVal m)
173{
174 return (multiVal_isDefined (m) && m->kind == MVDOUBLE);
175}
176
177bool multiVal_isString (multiVal m)
178{
179 return (multiVal_isDefined (m) && m->kind == MVSTRING);
180}
181
182/*@only@*/ cstring multiVal_unparse (multiVal m)
183{
184 if (multiVal_isDefined (m))
185 {
186 switch (m->kind)
187 {
188 case MVLONG:
189 return message ("%d", (int)m->value.ival);
190 case MVCHAR:
191 return message ("'%h'", m->value.cval);
192 case MVDOUBLE:
193 return message ("%f", (float)m->value.fval);
194 case MVSTRING:
195 return message ("%s", m->value.sval);
196 }
197 BADEXIT;
198 }
199 else
200 {
201 return (cstring_makeLiteral ("?"));
202 }
203}
204
205/*@only@*/ cstring multiVal_dump (multiVal m)
206{
207 if (multiVal_isDefined (m))
208 {
209 switch (m->kind)
210 {
211 case MVLONG:
212 return (message ("i%d", (int)m->value.ival));
213 case MVCHAR:
214 return (message ("c%d", (int)m->value.cval));
215 case MVDOUBLE:
216 return (message ("d%f", (float)m->value.fval));
217 case MVSTRING:
218 return (message ("s%s", m->value.sval));
219 }
220 BADEXIT;
221 }
222 else
223 {
224 return (cstring_undefined);
225 }
226}
227
228/*@only@*/ multiVal multiVal_undump (char **s)
229{
230 char tchar = **s;
231
232 switch (tchar)
233 {
234 case 'i':
235 (*s)++;
28bf4b0b 236 return multiVal_makeInt (reader_getInt (s));
616915dd 237 case 'c':
238 (*s)++;
28bf4b0b 239 return multiVal_makeChar ((char) reader_getInt (s));
616915dd 240 case 'd':
241 (*s)++;
28bf4b0b 242 return multiVal_makeDouble (reader_getDouble (s));
616915dd 243 case 's':
244 {
245 cstring st = cstring_undefined;
246
247 (*s)++;
248 while (**s != '#')
249 {
250 st = cstring_appendChar (st, **s);
251 (*s)++;
252 }
253
254 return multiVal_makeString (st);
255 }
256 case '@':
257 case '#':
258 return multiVal_unknown ();
259 BADDEFAULT;
260 }
261
262 BADEXIT;
263}
264
265int multiVal_compare (multiVal m1, multiVal m2)
266{
267 if (multiVal_isUndefined (m1))
268 {
269 if (multiVal_isUndefined (m2))
270 {
271 return 0;
272 }
273
274 else return -1;
275 }
276 if (multiVal_isUndefined (m2))
277 {
278 return -1;
279 }
280
281 COMPARERETURN (generic_compare (m1->kind, m2->kind));
282
283 switch (m1->kind)
284 {
285 case MVLONG: return (generic_compare (m1->value.ival, m2->value.ival));
286 case MVCHAR: return (generic_compare (m1->value.cval, m2->value.cval));
287 case MVDOUBLE: return (generic_compare (m1->value.fval, m2->value.fval));
288 case MVSTRING: return (cstring_compare (m1->value.sval, m2->value.sval));
289 }
290
291 BADEXIT;
292}
293
a956d444 294multiVal multiVal_add (multiVal m1, multiVal m2)
295{
296 if (multiVal_isUndefined (m1) || multiVal_isUndefined (m2) || m1->kind != m2->kind)
297 {
298 return multiVal_undefined;
299 }
300
301 switch (m1->kind)
302 {
303 case MVLONG: return (multiVal_makeInt (m1->value.ival + m2->value.ival));
4dd72714 304 case MVCHAR: return (multiVal_makeChar ((char) (m1->value.cval + m2->value.cval)));
a956d444 305 case MVDOUBLE: return (multiVal_makeDouble (m1->value.fval + m2->value.fval));
306 case MVSTRING: return multiVal_undefined;
307 }
308
309 BADEXIT;
310}
311
312multiVal multiVal_subtract (multiVal m1, multiVal m2)
313{
314 if (multiVal_isUndefined (m1) || multiVal_isUndefined (m2) || m1->kind != m2->kind)
315 {
316 return multiVal_undefined;
317 }
318
319 switch (m1->kind)
320 {
321 case MVLONG: return (multiVal_makeInt (m1->value.ival - m2->value.ival));
4dd72714 322 case MVCHAR: return (multiVal_makeChar ((char) (m1->value.cval - m2->value.cval)));
a956d444 323 case MVDOUBLE: return (multiVal_makeDouble (m1->value.fval - m2->value.fval));
324 case MVSTRING: return multiVal_undefined;
325 }
326
327 BADEXIT;
328}
329
330multiVal multiVal_multiply (multiVal m1, multiVal m2)
331{
332 if (multiVal_isUndefined (m1) || multiVal_isUndefined (m2) || m1->kind != m2->kind)
333 {
334 return multiVal_undefined;
335 }
336
337 switch (m1->kind)
338 {
339 case MVLONG: return (multiVal_makeInt (m1->value.ival * m2->value.ival));
4dd72714 340 case MVCHAR: return (multiVal_makeChar ((char) (m1->value.cval * m2->value.cval)));
a956d444 341 case MVDOUBLE: return (multiVal_makeDouble (m1->value.fval * m2->value.fval));
342 case MVSTRING: return multiVal_undefined;
343 }
344
345 BADEXIT;
346}
347
348multiVal multiVal_divide (multiVal m1, multiVal m2)
349{
350 if (multiVal_isUndefined (m1) || multiVal_isUndefined (m2) || m1->kind != m2->kind)
351 {
352 return multiVal_undefined;
353 }
354
355 switch (m1->kind)
356 {
91f027c7 357 case MVLONG:
358 if (m2->value.ival != 0)
359 {
360 return (multiVal_makeInt (m1->value.ival / m2->value.ival));
361 }
362 else
363 {
364 return multiVal_undefined;
365 }
366 case MVCHAR:
9dc8a5c1 367 if (m2->value.cval != (char) 0)
91f027c7 368 {
369 return (multiVal_makeChar ((char) (m1->value.cval / m2->value.cval)));
370 }
371 else
372 {
373 return multiVal_undefined;
374 }
375 case MVDOUBLE:
9dc8a5c1 376 return multiVal_undefined; /* Don't attempt to divide floats */
a956d444 377 case MVSTRING: return multiVal_undefined;
378 }
379
380 BADEXIT;
381}
382
616915dd 383void multiVal_free (/*@only@*/ multiVal m)
384{
385 if (multiVal_isDefined (m))
386 {
387 if (m->kind == MVSTRING)
388 {
389 cstring_free (m->value.sval);
390 }
391
392 sfree (m);
393 }
394}
395
396
397
398
This page took 0.150926 seconds and 5 git commands to generate.