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

multiVal.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 ** multiVal.c
00026 */
00027 
00028 # include "lclintMacros.nf"
00029 # include "basic.h"
00030 
00031 /*@only@*/ multiVal multiVal_unknown ()
00032 {
00033   return multiVal_undefined;
00034 }
00035 
00036 static /*@special@*/ /*@notnull@*/ multiVal multiVal_create (mvkind kind)
00037    /*@defines result->kind@*/
00038 {
00039   multiVal mv = (multiVal) dmalloc (sizeof (*mv));
00040 
00041   mv->kind = kind;
00042   return mv;
00043 }
00044 
00045 /*@only@*/ multiVal multiVal_makeInt (long x)
00046 {
00047   multiVal mv = multiVal_create (MVLONG);
00048 
00049   mv->value.ival = x;
00050   return mv;
00051 }
00052 
00053 /*@only@*/ multiVal multiVal_makeChar (char x)
00054 {
00055   multiVal mv = multiVal_create (MVCHAR);
00056     mv->value.cval = x;
00057     return mv;
00058 }
00059 
00060 /*@only@*/ multiVal multiVal_makeDouble (double x)
00061 {
00062   multiVal mv = multiVal_create (MVDOUBLE);
00063 
00064     mv->value.fval = x;
00065     return mv;
00066 }
00067 
00068 /*@only@*/ multiVal multiVal_makeString (/*@only@*/ cstring s)
00069 {
00070   multiVal mv = multiVal_create (MVSTRING);
00071 
00072   mv->value.sval = s;
00073   return mv;
00074 }
00075 
00076 
00077 /*@only@*/ multiVal multiVal_copy (multiVal m)
00078 {
00079   multiVal r;
00080 
00081   if (multiVal_isUndefined (m))
00082     {
00083       return multiVal_undefined;
00084     }
00085 
00086   r = multiVal_create (m->kind);
00087       
00088   switch (m->kind)
00089     {
00090     case MVLONG:
00091       r->value.ival = m->value.ival;
00092       break;
00093     case MVCHAR:
00094       r->value.cval = m->value.cval;
00095       break;
00096     case MVDOUBLE:
00097       r->value.fval = m->value.fval;
00098       break;
00099     case MVSTRING:
00100       r->value.sval = cstring_copy (m->value.sval);
00101       break;
00102     }
00103   
00104   return r;
00105 }
00106 
00107 multiVal multiVal_invert (multiVal m)
00108 {
00109   if (multiVal_isUndefined (m))
00110     {
00111       return multiVal_undefined;
00112     }
00113       
00114   switch (m->kind)
00115     {
00116     case MVLONG:
00117       return multiVal_makeInt (-1 * m->value.ival);
00118     case MVCHAR:
00119       BADBRANCHCONT;
00120       return multiVal_undefined;
00121     case MVDOUBLE:
00122       return multiVal_makeDouble (-1.0 * m->value.fval);
00123     case MVSTRING:
00124       BADBRANCHCONT;
00125       return multiVal_undefined;
00126     }
00127 
00128   BADEXIT;
00129 }
00130 
00131 long multiVal_forceInt (multiVal m)
00132 {
00133   llassert (multiVal_isInt (m));
00134 
00135   return m->value.ival;
00136 }
00137 
00138 char multiVal_forceChar (multiVal m)
00139 {
00140   llassert (multiVal_isChar (m));
00141   
00142   return m->value.cval;
00143 }
00144 
00145 double multiVal_forceDouble (multiVal m)
00146 {
00147   llassert (multiVal_isDouble (m));
00148 
00149   return m->value.fval;
00150 }
00151 
00152 /*@dependent@*/ /*@observer@*/ cstring multiVal_forceString (multiVal m)
00153 {
00154   llassert (multiVal_isString (m));
00155 
00156   return m->value.sval;
00157 }
00158 
00159 bool multiVal_isInt (multiVal m)
00160 {
00161   return (multiVal_isDefined (m) && m->kind == MVLONG);
00162 }
00163 
00164 bool multiVal_isChar (multiVal m)
00165 {
00166   return (multiVal_isDefined (m) && m->kind == MVCHAR);
00167 }
00168 
00169 bool multiVal_isDouble (multiVal m)
00170 {
00171   return (multiVal_isDefined (m) && m->kind == MVDOUBLE);
00172 }
00173 
00174 bool multiVal_isString (multiVal m)
00175 {
00176   return (multiVal_isDefined (m) && m->kind == MVSTRING);
00177 }
00178 
00179 /*@only@*/ cstring multiVal_unparse (multiVal m)
00180 {
00181   if (multiVal_isDefined (m))
00182     {
00183       switch (m->kind)
00184         {
00185         case MVLONG:
00186           return message ("%d", (int)m->value.ival);
00187         case MVCHAR:
00188                   return message ("'%h'", m->value.cval);
00189         case MVDOUBLE:
00190           return message ("%f", (float)m->value.fval);
00191         case MVSTRING:
00192           return message ("%s", m->value.sval);
00193         }
00194       BADEXIT;
00195     }
00196   else
00197     {
00198       return (cstring_makeLiteral ("?"));
00199     }
00200 }
00201 
00202 /*@only@*/ cstring multiVal_dump (multiVal m)
00203 {
00204   if (multiVal_isDefined (m))
00205     {
00206       switch (m->kind)
00207         {
00208         case MVLONG:
00209           return (message ("i%d", (int)m->value.ival));
00210         case MVCHAR:
00211           return (message ("c%d", (int)m->value.cval));
00212         case MVDOUBLE:
00213           return (message ("d%f", (float)m->value.fval));
00214         case MVSTRING:
00215           return (message ("s%s", m->value.sval));
00216         }
00217       BADEXIT;
00218     }
00219   else
00220     {
00221       return (cstring_undefined);
00222     }
00223 }
00224 
00225 /*@only@*/ multiVal multiVal_undump (char **s)
00226 {
00227   char tchar = **s;
00228 
00229   switch (tchar)
00230     {
00231     case 'i':
00232       (*s)++;
00233       return multiVal_makeInt (getInt (s));
00234     case 'c':
00235       (*s)++;
00236       return multiVal_makeChar ((char) getInt (s));
00237     case 'd':
00238       (*s)++;
00239       return multiVal_makeDouble (getDouble (s));
00240     case 's':
00241       {
00242         cstring st = cstring_undefined;
00243 
00244         (*s)++;
00245         while (**s != '#')
00246           {
00247             st = cstring_appendChar (st, **s);
00248             (*s)++;
00249           }
00250 
00251         return multiVal_makeString (st);
00252       }
00253     case '@':
00254     case '#':
00255       return multiVal_unknown ();
00256     BADDEFAULT;
00257     }
00258   
00259   BADEXIT;
00260 }
00261 
00262 int multiVal_compare (multiVal m1, multiVal m2)
00263 {
00264   if (multiVal_isUndefined (m1))
00265     {
00266       if (multiVal_isUndefined (m2)) 
00267         {
00268           return 0;
00269         }
00270 
00271       else return -1;
00272     }
00273   if (multiVal_isUndefined (m2))
00274     {
00275       return -1;
00276     }
00277 
00278   COMPARERETURN (generic_compare (m1->kind, m2->kind));
00279 
00280   switch (m1->kind)
00281     {
00282     case MVLONG:   return (generic_compare (m1->value.ival, m2->value.ival));
00283     case MVCHAR:   return (generic_compare (m1->value.cval, m2->value.cval));
00284     case MVDOUBLE: return (generic_compare (m1->value.fval, m2->value.fval));
00285     case MVSTRING: return (cstring_compare (m1->value.sval, m2->value.sval));
00286     }
00287 
00288   BADEXIT;
00289 }
00290 
00291 void multiVal_free (/*@only@*/ multiVal m)
00292 {
00293   if (multiVal_isDefined (m))
00294     {
00295       if (m->kind == MVSTRING)
00296         {
00297           cstring_free (m->value.sval);
00298         }
00299       
00300       sfree (m);
00301     }
00302 }
00303 
00304 
00305 
00306 

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