00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 # include "lclintMacros.nf"
00029 # include "basic.h"
00030
00031 multiVal multiVal_unknown ()
00032 {
00033 return multiVal_undefined;
00034 }
00035
00036 static multiVal multiVal_create (mvkind kind)
00037
00038 {
00039 multiVal mv = (multiVal) dmalloc (sizeof (*mv));
00040
00041 mv->kind = kind;
00042 return mv;
00043 }
00044
00045 multiVal multiVal_makeInt (long x)
00046 {
00047 multiVal mv = multiVal_create (MVLONG);
00048
00049 mv->value.ival = x;
00050 return mv;
00051 }
00052
00053 multiVal multiVal_makeChar (char x)
00054 {
00055 multiVal mv = multiVal_create (MVCHAR);
00056 mv->value.cval = x;
00057 return mv;
00058 }
00059
00060 multiVal multiVal_makeDouble (double x)
00061 {
00062 multiVal mv = multiVal_create (MVDOUBLE);
00063
00064 mv->value.fval = x;
00065 return mv;
00066 }
00067
00068 multiVal multiVal_makeString ( cstring s)
00069 {
00070 multiVal mv = multiVal_create (MVSTRING);
00071
00072 mv->value.sval = s;
00073 return mv;
00074 }
00075
00076
00077 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 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 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 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 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 ( 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