Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

cprim.c

Go to the documentation of this file.
00001 /*
00002 ** LCLint - annotation-assisted static program checker
00003 ** Copyright (C) 1994-2000 University of Virginia,
00004 **         Massachusetts Institute of Technology
00005 **
00006 ** This program is free software; you can redistribute it and/or modify it
00007 ** under the terms of the GNU General Public License as published by the
00008 ** Free Software Foundation; either version 2 of the License, or (at your
00009 ** option) any later version.
00010 ** 
00011 ** This program is distributed in the hope that it will be useful, but
00012 ** WITHOUT ANY WARRANTY; without even the implied warranty of
00013 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 ** General Public License for more details.
00015 ** 
00016 ** The GNU General Public License is available from http://www.gnu.org/ or
00017 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00018 ** MA 02111-1307, USA.
00019 **
00020 ** For information on lclint: lclint-request@cs.virginia.edu
00021 ** To report a bug: lclint-bug@cs.virginia.edu
00022 ** For more information: http://lclint.cs.virginia.edu
00023 */
00024 /*
00025 ** cprim.c
00026 */
00027 
00028 # include "lclintMacros.nf"
00029 # include "basic.h"
00030 
00031 static bool cprim_isReal (cprim c)
00032 {
00033   return (cprim_isAnyReal (c));
00034 }
00035 
00036 static bool cprim_isNumeric (cprim c)
00037 {
00038   return (cprim_isReal (c) || cprim_isInt (c));
00039 }
00040 
00041 cprim
00042 cprim_fromInt (int i)
00043 {
00044   if (i < CTX_UNKNOWN || i > CTX_LAST)
00045     {
00046       llcontbug (message ("cprim_fromInt: out of range: %d", i));
00047       return CTX_UNKNOWN;
00048     }
00049   return (cprim) i;
00050 }
00051 
00052 
00053 /*
00054 ** not symmetric:  c1 := c2 or c2 is passed as c1
00055 **    (if RELAXQUALS, c1 must be "bigger" than c2)
00056 */
00057 
00058 static bool cprim_closeEnoughAux (cprim p_c1, cprim p_c2, bool p_deep);
00059 
00060 bool
00061 cprim_closeEnoughDeep (cprim c1, cprim c2) 
00062 {
00063   /*
00064   ** If * c2 is passed as * c1
00065   ** Comparison is slightly different since it is safe to pass int as long,
00066   ** but not to pass int * as long *!
00067   **
00068   ** For deep comparisons, +relaxquals does not permit the long/int break.
00069   */
00070 
00071   return cprim_closeEnoughAux (c1, c2, TRUE);
00072 }
00073 
00074 bool
00075 cprim_closeEnough (cprim c1, cprim c2)
00076 {
00077   return cprim_closeEnoughAux (c1, c2, FALSE);
00078 }
00079 
00080 static bool
00081 cprim_closeEnoughAux (cprim c1, cprim c2, bool deep)
00082 {
00083   if (c1 == c2) return TRUE;
00084 
00085   if (c1 == CTX_ANYINTEGRAL)
00086     {
00087       if (context_getFlag (FLG_MATCHANYINTEGRAL)
00088           || context_getFlag (FLG_IGNOREQUALS))
00089         {
00090           return (cprim_isAnyInt (c2)
00091                   || (cprim_isAnyChar (c2) && context_msgCharInt ()));
00092         }
00093       else if (context_getFlag (FLG_LONGINTEGRAL))
00094         {
00095           return (cprim_closeEnough (CTX_LINT, c2));
00096         }
00097       else if (context_getFlag (FLG_LONGUNSIGNEDINTEGRAL))
00098         {
00099           return (cprim_closeEnough (CTX_ULINT, c2));
00100         }
00101       else
00102         {
00103           return FALSE;
00104         }
00105     }
00106 
00107   if (c1 == CTX_UNSIGNEDINTEGRAL)
00108     {
00109       if (context_getFlag (FLG_MATCHANYINTEGRAL)
00110           || context_getFlag (FLG_IGNOREQUALS))
00111         {
00112           return (cprim_isAnyInt (c2)
00113                   || (cprim_isAnyChar (c2) && context_msgCharInt ()));
00114         }
00115       else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL))
00116         {
00117           return (cprim_closeEnough (CTX_ULINT, c2));
00118         }
00119       else
00120         {
00121           return FALSE;
00122         }
00123     }
00124 
00125   if (c1 == CTX_SIGNEDINTEGRAL)
00126     {
00127       if (context_getFlag (FLG_MATCHANYINTEGRAL)
00128           || context_getFlag (FLG_IGNOREQUALS))
00129         {
00130           return (cprim_isAnyInt (c2)
00131                   || (cprim_isAnyChar (c2) && context_msgCharInt ()));
00132         }
00133       else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL))
00134         {
00135           return (cprim_closeEnough (CTX_LINT, c2));
00136         }
00137       else
00138         {
00139           return FALSE;
00140         }
00141     }
00142 
00143   if (c2 == CTX_ANYINTEGRAL)
00144     {
00145       if (context_getFlag (FLG_MATCHANYINTEGRAL))
00146         {
00147           return (cprim_isAnyInt (c1)
00148                   || (cprim_isAnyChar (c1) && context_msgCharInt ()));
00149         }
00150       else if (context_getFlag (FLG_LONGINTEGRAL))
00151         {
00152           return (cprim_closeEnough (c1, CTX_LINT));
00153         }
00154       else if (context_getFlag (FLG_LONGUNSIGNEDINTEGRAL))
00155         {
00156           return (cprim_closeEnough (c1, CTX_ULINT));
00157         }
00158       else
00159         {
00160           return FALSE;
00161         }
00162     }
00163 
00164   if (c2 == CTX_UNSIGNEDINTEGRAL)
00165     {
00166       if (context_getFlag (FLG_MATCHANYINTEGRAL))
00167         {
00168           return (cprim_isAnyInt (c1)
00169                   || (cprim_isAnyChar (c1) && context_msgCharInt ()));
00170         }
00171       else if (context_getFlag (FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL))
00172         {
00173           return (cprim_closeEnough (c1, CTX_ULINT));
00174         }
00175       else
00176         {
00177           return FALSE;
00178         }
00179     }
00180 
00181   if (c2 == CTX_SIGNEDINTEGRAL)
00182     {
00183       if (context_getFlag (FLG_MATCHANYINTEGRAL))
00184         {
00185           return (cprim_isAnyInt (c2)
00186                   || (cprim_isAnyChar (c2) && context_msgCharInt ()));
00187         }
00188       else if (context_getFlag (FLG_LONGSIGNEDINTEGRAL))
00189         {
00190           return (cprim_closeEnough (c1, CTX_LINT));
00191         }
00192       else
00193         {
00194           return FALSE;
00195         }
00196     }
00197 
00198   if (context_getFlag (FLG_RELAXTYPES))
00199     {
00200       if (cprim_isNumeric (c1) && cprim_isNumeric (c2)) return TRUE;
00201     }
00202 
00203   if (context_getFlag (FLG_IGNOREQUALS))
00204     {
00205       switch (c1)
00206         {
00207         case CTX_CHAR:
00208         case CTX_UCHAR:
00209           return (cprim_isAnyChar (c2) 
00210                   || (cprim_isAnyInt (c2) && (context_msgCharInt ())));
00211         case CTX_DOUBLE:
00212         case CTX_FLOAT:
00213         case CTX_LDOUBLE:
00214           return (c2 == CTX_DOUBLE || c2 == CTX_FLOAT || c2 == CTX_LDOUBLE);
00215         case CTX_INT:
00216         case CTX_LINT:
00217         case CTX_LLINT:
00218         case CTX_ULLINT:
00219         case CTX_SINT:
00220         case CTX_UINT:
00221         case CTX_ULINT:
00222         case CTX_USINT:
00223           return (cprim_isAnyInt (c2) 
00224                   || (cprim_isAnyChar (c2) && context_msgCharInt ()));
00225         default:
00226           return FALSE;
00227         }
00228     }
00229   else 
00230     {
00231       if (context_getFlag (FLG_IGNORESIGNS))
00232         {
00233           if (c1 == CTX_UCHAR)  
00234             {
00235               c1 = CTX_CHAR;
00236             }
00237           else if (c1 == CTX_UINT)  
00238             {
00239               c1 = CTX_INT;
00240             }
00241           else if (c1 == CTX_ULINT) 
00242             {
00243               c1 = CTX_LINT;
00244             }
00245           else if (c1 == CTX_USINT)  
00246             {
00247               c1 = CTX_SINT;
00248             }
00249           else
00250             {
00251               ;
00252             }
00253 
00254           if (c2 == CTX_UCHAR)  
00255             {
00256               c2 = CTX_CHAR;
00257             }
00258           else if (c2 == CTX_UINT)   
00259             {
00260               c2 = CTX_INT;
00261             }
00262           else if (c2 == CTX_ULINT) 
00263             {
00264               c2 = CTX_LINT;
00265             }
00266           else if (c2 == CTX_USINT)  
00267             {
00268               c2 = CTX_SINT;
00269             }
00270           else
00271             {
00272               ;
00273             }
00274         }
00275 
00276       if (c1 == c2) return TRUE;
00277 
00278       if (context_getFlag (FLG_FLOATDOUBLE))
00279         {
00280           if (c1 == CTX_FLOAT && c2 == CTX_DOUBLE) 
00281             {
00282               return TRUE;
00283             }
00284           if (c2 == CTX_FLOAT && c1 == CTX_DOUBLE)
00285             {
00286               return TRUE;
00287             }
00288         }
00289 
00290       if (!deep && context_getFlag (FLG_RELAXQUALS))
00291         {
00292           switch (c1)
00293             {
00294             case CTX_DOUBLE:
00295               return (c2 == CTX_FLOAT);
00296             case CTX_LDOUBLE:
00297               return (c2 == CTX_DOUBLE || c2 == CTX_FLOAT);
00298             case CTX_SINT:
00299               return (c2 == CTX_CHAR && context_msgCharInt ());
00300             case CTX_INT:
00301               return (c2 == CTX_SINT
00302                       || (cprim_isAnyChar (c2) && context_msgCharInt ()));
00303             case CTX_LLINT:
00304               return (c2 == CTX_SINT
00305                       || c2 == CTX_INT 
00306                       || c2 == CTX_LINT
00307                       || (cprim_isAnyChar (c2) && context_msgCharInt ()));
00308             case CTX_ULLINT:
00309               return (c2 == CTX_USINT
00310                       || c2 == CTX_UINT 
00311                       || c2 == CTX_ULINT);
00312             case CTX_LINT:
00313               return (c2 == CTX_SINT
00314                       || c2 == CTX_INT 
00315                       || (cprim_isAnyChar (c2) && context_msgCharInt ()));
00316             case CTX_UINT:
00317               return (c2 == CTX_USINT 
00318                       || (c2 == CTX_UCHAR && context_msgCharInt ()));
00319             case CTX_USINT:
00320               return (c2 == CTX_UCHAR && context_msgCharInt ());
00321             case CTX_ULINT:
00322               return (c2 == CTX_UINT || c2 == CTX_USINT);
00323             case CTX_UCHAR:
00324               return (c2 == CTX_UINT && context_msgCharInt ());
00325             case CTX_CHAR:
00326               return ((c2 == CTX_INT || c2 == CTX_SINT)
00327                       && context_msgCharInt ());
00328             default:
00329               return FALSE;
00330             }
00331         }
00332       else
00333         {
00334           switch (c1)
00335             {
00336             case CTX_DOUBLE:
00337             case CTX_LDOUBLE:
00338               return FALSE;
00339             case CTX_SINT:
00340             case CTX_INT:
00341             case CTX_LINT:
00342             case CTX_LLINT:
00343               return (c2 == CTX_CHAR && context_msgCharInt ());
00344             case CTX_UINT:
00345             case CTX_USINT:
00346             case CTX_ULINT:
00347             case CTX_ULLINT:
00348               return (c2 == CTX_UCHAR && context_msgCharInt ());
00349             case CTX_UCHAR:
00350               return (c2 == CTX_UINT && context_msgCharInt ());
00351             case CTX_CHAR:
00352               return ((c2 == CTX_INT || c2 == CTX_SINT)
00353                       && context_msgCharInt ());
00354             default:
00355               return FALSE;
00356             }
00357         }
00358     }
00359 }
00360 
00361 /*@only@*/ cstring
00362 cprim_unparse (cprim c)
00363 {
00364   switch (c)
00365     {
00366     case CTX_UNKNOWN:
00367       return cstring_makeLiteral ("-");
00368     case CTX_VOID:
00369       return cstring_makeLiteral ("void");
00370     case CTX_CHAR:
00371       return cstring_makeLiteral ("char");
00372     case CTX_UCHAR:
00373       return cstring_makeLiteral ("unsigned char");
00374    case CTX_DOUBLE:
00375       return cstring_makeLiteral ("double");
00376     case CTX_LDOUBLE:
00377       return cstring_makeLiteral ("long double");
00378     case CTX_FLOAT:
00379       return cstring_makeLiteral ("float");
00380     case CTX_INT:
00381       return cstring_makeLiteral ("int");
00382     case CTX_LINT:
00383       return cstring_makeLiteral ("long int");
00384     case CTX_LLINT:
00385       return cstring_makeLiteral ("long long");
00386     case CTX_ULLINT:
00387       return cstring_makeLiteral ("unsigned long long");
00388     case CTX_SINT:
00389       return cstring_makeLiteral ("short int");
00390     case CTX_UINT:
00391       return cstring_makeLiteral ("unsigned int");
00392     case CTX_ULINT:
00393       return cstring_makeLiteral ("unsigned long int");
00394     case CTX_USINT:
00395       return cstring_makeLiteral ("unsigned short int");
00396     case CTX_UNSIGNEDINTEGRAL:
00397       return cstring_makeLiteral ("arbitrary unsigned integral type");
00398     case CTX_SIGNEDINTEGRAL:
00399       return cstring_makeLiteral ("arbitrary signed integral type");
00400     case CTX_ANYINTEGRAL:
00401       return cstring_makeLiteral ("arbitrary integral type");
00402     default:
00403       return cstring_makeLiteral ("unknown prim");
00404     }
00405 }
00406 
00407 bool cprim_isInt (cprim c) 
00408 {
00409   return (cprim_isAnyInt (c)
00410           || (cprim_isAnyChar (c) && context_msgCharInt ()));
00411 }
00412     
00413 
00414 
00415 

Generated at Fri Nov 3 18:57:40 2000 for LCLint by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000