]> andersk Git - splint.git/blob - src/cprim.c
Fixed assert failure involving multiple redefines of library functions.
[splint.git] / src / cprim.c
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 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 splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
23 */
24 /*
25 ** cprim.c
26 */
27
28 # include "splintMacros.nf"
29 # include "basic.h"
30
31 static bool cprim_isReal (cprim c)
32 {
33   return (cprim_isAnyReal (c));
34 }
35
36 static bool cprim_isNumeric (cprim c)
37 {
38   return (cprim_isReal (c) || cprim_isInt (c));
39 }
40
41 cprim
42 cprim_fromInt (int i)
43 {
44   if (i < CTX_UNKNOWN || i > CTX_LAST)
45     {
46       llcontbug (message ("cprim_fromInt: out of range: %d", i));
47       return CTX_UNKNOWN;
48     }
49   return (cprim) i;
50 }
51
52
53 /*
54 ** not symmetric:  c1 := c2 or c2 is passed as c1
55 **    (if RELAXQUALS, c1 must be "bigger" than c2)
56 */
57
58 static bool cprim_closeEnoughAux (cprim p_c1, cprim p_c2, bool p_deep);
59
60 bool
61 cprim_closeEnoughDeep (cprim c1, cprim c2) 
62 {
63   /*
64   ** If * c2 is passed as * c1
65   ** Comparison is slightly different since it is safe to pass int as long,
66   ** but not to pass int * as long *!
67   **
68   ** For deep comparisons, +relaxquals does not permit the long/int break.
69   */
70
71   return cprim_closeEnoughAux (c1, c2, TRUE);
72 }
73
74 bool
75 cprim_closeEnough (cprim c1, cprim c2)
76 {
77   return cprim_closeEnoughAux (c1, c2, FALSE);
78 }
79
80 static bool
81 cprim_closeEnoughAux (cprim c1, cprim c2, bool deep)
82 {
83   if (c1 == c2) return TRUE;
84
85   if (c1 == CTX_ANYINTEGRAL)
86     {
87       if (context_getFlag (FLG_MATCHANYINTEGRAL)
88           || context_getFlag (FLG_IGNOREQUALS))
89         {
90           return (cprim_isAnyInt (c2)
91                   || (cprim_isAnyChar (c2) && context_msgCharInt ()));
92         }
93       else if (context_getFlag (FLG_LONGINTEGRAL))
94         {
95           return (cprim_closeEnough (CTX_LINT, c2));
96         }
97       else if (context_getFlag (FLG_LONGUNSIGNEDINTEGRAL))
98         {
99           return (cprim_closeEnough (CTX_ULINT, c2));
100         }
101       else
102         {
103           return FALSE;
104         }
105     }
106
107   if (c1 == CTX_UNSIGNEDINTEGRAL)
108     {
109       if (context_getFlag (FLG_MATCHANYINTEGRAL)
110           || context_getFlag (FLG_IGNOREQUALS))
111         {
112           if (context_getFlag (FLG_IGNORESIGNS)) 
113             {
114               return (cprim_isAnyUnsignedInt (c2)
115                       || (cprim_isUnsignedChar (c2) && context_msgCharInt ()));
116             }
117           else
118             {
119               return (cprim_isAnyInt (c2)
120                       || (cprim_isAnyChar (c2) && context_msgCharInt ()));
121             }
122         }
123       else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL))
124         {
125           return (cprim_closeEnough (CTX_ULINT, c2));
126         }
127       else
128         {
129           return FALSE;
130         }
131     }
132
133   if (c1 == CTX_SIGNEDINTEGRAL)
134     {
135       if (context_getFlag (FLG_MATCHANYINTEGRAL)
136           || context_getFlag (FLG_IGNOREQUALS))
137         {
138           return (cprim_isAnyInt (c2)
139                   || (cprim_isAnyChar (c2) && context_msgCharInt ()));
140         }
141       else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL))
142         {
143           return (cprim_closeEnough (CTX_LINT, c2));
144         }
145       else
146         {
147           return FALSE;
148         }
149     }
150
151   if (c2 == CTX_ANYINTEGRAL)
152     {
153       if (context_getFlag (FLG_MATCHANYINTEGRAL))
154         {
155           return (cprim_isAnyInt (c1)
156                   || (cprim_isAnyChar (c1) && context_msgCharInt ()));
157         }
158       else if (context_getFlag (FLG_LONGINTEGRAL))
159         {
160           return (cprim_closeEnough (c1, CTX_LINT));
161         }
162       else if (context_getFlag (FLG_LONGUNSIGNEDINTEGRAL))
163         {
164           return (cprim_closeEnough (c1, CTX_ULINT));
165         }
166       else
167         {
168           return FALSE;
169         }
170     }
171
172   if (c2 == CTX_UNSIGNEDINTEGRAL)
173     {
174       if (context_getFlag (FLG_MATCHANYINTEGRAL))
175         {
176           return (cprim_isAnyInt (c1)
177                   || (cprim_isAnyChar (c1) && context_msgCharInt ()));
178         }
179       else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL))
180         {
181           return (cprim_closeEnough (c1, CTX_ULINT));
182         }
183       else
184         {
185           return FALSE;
186         }
187     }
188
189   if (c2 == CTX_SIGNEDINTEGRAL)
190     {
191       if (context_getFlag (FLG_MATCHANYINTEGRAL))
192         {
193           return (cprim_isAnyInt (c2)
194                   || (cprim_isAnyChar (c2) && context_msgCharInt ()));
195         }
196       else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL))
197         {
198           return (cprim_closeEnough (c1, CTX_LINT));
199         }
200       else
201         {
202           return FALSE;
203         }
204     }
205
206   if (context_getFlag (FLG_RELAXTYPES))
207     {
208       if (cprim_isNumeric (c1) && cprim_isNumeric (c2)) return TRUE;
209     }
210
211   if (context_getFlag (FLG_IGNOREQUALS))
212     {
213       switch (c1)
214         {
215         case CTX_CHAR:
216         case CTX_UCHAR:
217           return (cprim_isAnyChar (c2) 
218                   || (cprim_isAnyInt (c2) && (context_msgCharInt ())));
219         case CTX_DOUBLE:
220         case CTX_FLOAT:
221         case CTX_LDOUBLE:
222           return (c2 == CTX_DOUBLE || c2 == CTX_FLOAT || c2 == CTX_LDOUBLE);
223         case CTX_INT:
224         case CTX_LINT:
225         case CTX_LLINT:
226         case CTX_ULLINT:
227         case CTX_SINT:
228         case CTX_UINT:
229         case CTX_ULINT:
230         case CTX_USINT:
231           return (cprim_isAnyInt (c2) 
232                   || (cprim_isAnyChar (c2) && context_msgCharInt ()));
233         default:
234           return FALSE;
235         }
236     }
237   else 
238     {
239       if (context_getFlag (FLG_IGNORESIGNS))
240         {
241           if (c1 == CTX_UCHAR)  
242             {
243               c1 = CTX_CHAR;
244             }
245           else if (c1 == CTX_UINT)  
246             {
247               c1 = CTX_INT;
248             }
249           else if (c1 == CTX_ULINT) 
250             {
251               c1 = CTX_LINT;
252             }
253           /* 2001-06-10: This fix provided by Jim Zelenka: */
254           else if (c1 == CTX_ULLINT) 
255             {
256               c1 = CTX_LLINT;
257             }
258           /* End fix */
259           else if (c1 == CTX_USINT)  
260             {
261               c1 = CTX_SINT;
262             }
263           else
264             {
265               ;
266             }
267
268           if (c2 == CTX_UCHAR)  
269             {
270               c2 = CTX_CHAR;
271             }
272           else if (c2 == CTX_UINT)   
273             {
274               c2 = CTX_INT;
275             }
276           else if (c2 == CTX_ULINT) 
277             {
278               c2 = CTX_LINT;
279             }
280           /* 2001-06-10: This fix provided by Jim Zelenka: */
281           else if (c2 == CTX_ULLINT)
282             {
283               c2 = CTX_LLINT;
284             }
285           /* End fix */
286           else if (c2 == CTX_USINT)  
287             {
288               c2 = CTX_SINT;
289             }
290           else
291             {
292               ;
293             }
294         }
295
296       if (c1 == c2) return TRUE;
297
298       if (context_getFlag (FLG_FLOATDOUBLE))
299         {
300           if (c1 == CTX_FLOAT && c2 == CTX_DOUBLE) 
301             {
302               return TRUE;
303             }
304           if (c2 == CTX_FLOAT && c1 == CTX_DOUBLE)
305             {
306               return TRUE;
307             }
308         }
309
310       if (!deep && context_getFlag (FLG_RELAXQUALS))
311         {
312           switch (c1)
313             {
314             case CTX_DOUBLE:
315               return (c2 == CTX_FLOAT);
316             case CTX_LDOUBLE:
317               return (c2 == CTX_DOUBLE || c2 == CTX_FLOAT);
318             case CTX_SINT:
319               return (c2 == CTX_CHAR && context_msgCharInt ());
320             case CTX_INT:
321               return (c2 == CTX_SINT
322                       || (cprim_isAnyChar (c2) && context_msgCharInt ()));
323             case CTX_LLINT:
324               return (c2 == CTX_SINT
325                       || c2 == CTX_INT 
326                       || c2 == CTX_LINT
327                       || (cprim_isAnyChar (c2) && context_msgCharInt ()));
328             case CTX_ULLINT:
329               return (c2 == CTX_USINT
330                       || c2 == CTX_UINT 
331                       || c2 == CTX_ULINT
332                       /* 2001-06-10: This fix provided by Jim Zelenka: */
333                       || (cprim_isAnyChar (c2) && context_msgCharInt ()));
334             case CTX_LINT:
335               return (c2 == CTX_SINT
336                       || c2 == CTX_INT 
337                       || (cprim_isAnyChar (c2) && context_msgCharInt ()));
338             case CTX_UINT:
339               return (c2 == CTX_USINT 
340                       || (c2 == CTX_UCHAR && context_msgCharInt ()));
341             case CTX_USINT:
342               return (c2 == CTX_UCHAR && context_msgCharInt ());
343             case CTX_ULINT:
344               /* 2001-06-10: This fix provided by Jim Zelenka: */
345               return (c2 == CTX_UINT || c2 == CTX_USINT
346                       || (c2 == CTX_UCHAR && context_msgCharInt()));
347             case CTX_UCHAR:
348               return (c2 == CTX_UINT && context_msgCharInt ());
349             case CTX_CHAR:
350               return ((c2 == CTX_INT || c2 == CTX_SINT)
351                       && context_msgCharInt ());
352             default:
353               return FALSE;
354             }
355         }
356       else
357         {
358           switch (c1)
359             {
360             case CTX_DOUBLE:
361             case CTX_LDOUBLE:
362               return FALSE;
363             case CTX_SINT:
364             case CTX_INT:
365             case CTX_LINT:
366             case CTX_LLINT:
367               return (c2 == CTX_CHAR && context_msgCharInt ());
368             case CTX_UINT:
369             case CTX_USINT:
370             case CTX_ULINT:
371             case CTX_ULLINT:
372               return (c2 == CTX_UCHAR && context_msgCharInt ());
373             case CTX_UCHAR:
374               return (c2 == CTX_UINT && context_msgCharInt ());
375             case CTX_CHAR:
376               return ((c2 == CTX_INT || c2 == CTX_SINT)
377                       && context_msgCharInt ());
378             default:
379               return FALSE;
380             }
381         }
382     }
383 }
384
385 /*@only@*/ cstring
386 cprim_unparse (cprim c)
387 {
388   switch (c)
389     {
390     case CTX_UNKNOWN:
391       return cstring_makeLiteral ("-");
392     case CTX_VOID:
393       return cstring_makeLiteral ("void");
394     case CTX_CHAR:
395       return cstring_makeLiteral ("char");
396     case CTX_UCHAR:
397       return cstring_makeLiteral ("unsigned char");
398    case CTX_DOUBLE:
399       return cstring_makeLiteral ("double");
400     case CTX_LDOUBLE:
401       return cstring_makeLiteral ("long double");
402     case CTX_FLOAT:
403       return cstring_makeLiteral ("float");
404     case CTX_INT:
405       return cstring_makeLiteral ("int");
406     case CTX_LINT:
407       return cstring_makeLiteral ("long int");
408     case CTX_LLINT:
409       return cstring_makeLiteral ("long long");
410     case CTX_ULLINT:
411       return cstring_makeLiteral ("unsigned long long");
412     case CTX_SINT:
413       return cstring_makeLiteral ("short int");
414     case CTX_UINT:
415       return cstring_makeLiteral ("unsigned int");
416     case CTX_ULINT:
417       return cstring_makeLiteral ("unsigned long int");
418     case CTX_USINT:
419       return cstring_makeLiteral ("unsigned short int");
420     case CTX_UNSIGNEDINTEGRAL:
421       return cstring_makeLiteral ("arbitrary unsigned integral type");
422     case CTX_SIGNEDINTEGRAL:
423       return cstring_makeLiteral ("arbitrary signed integral type");
424     case CTX_ANYINTEGRAL:
425       return cstring_makeLiteral ("arbitrary integral type");
426     default:
427       return cstring_makeLiteral ("unknown prim");
428     }
429 }
430
431 bool cprim_isInt (cprim c) 
432 {
433   return (cprim_isAnyInt (c)
434           || (cprim_isAnyChar (c) && context_msgCharInt ()));
435 }
436     
437
438
439
This page took 0.08559 seconds and 5 git commands to generate.