source: cpp/gdk/extvalue.cpp @ 74

Last change on this file since 74 was 74, checked in by Maciej Komosinski, 12 years ago

improved documentation, compilation, and precision of numbers parsed

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1// This file is a part of the Framsticks GDK library.
2// Copyright (C) 2002-2011  Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#include "extvalue.h"
6#include "param.h"
7#include <math.h>
8
9SString ExtObject::toString()
10{
11if (isEmpty()) return SString("<empty object>");
12ParamInterface *p=getParamInterface();
13int tostr=p->findId("toString");
14if (tostr>=0)
15        {
16        return SString(p->getString(tostr));
17        }
18else
19        {
20        SString tmp("<");
21        tmp+=p->getName();
22        sprintf(tmp.directAppend(30)," object at %p>",
23                (object?object:paraminterface));
24        tmp.endAppend();
25        return tmp;
26        }
27}
28
29///////////////////////////////////////
30
31void ExtValue::set(const ExtValue& src)
32{
33switch(src.type)
34        {
35        case TString: sets(src.sdata()); break;
36        case TInt: seti(src.idata()); break;
37        case TDouble: setd(src.ddata()); break;
38        case TObj: seto(src.odata()); break;
39        case TInvalid: type=TInvalid; break;
40        }
41}
42
43void ExtValue::setEmpty()
44{
45switch(type)
46        {
47#ifdef EXTVALUEUNION
48        case TString: sdata().~SString(); break;
49        case TObj: odata().~ExtObject(); break;
50#else
51        case TString: delete s; break;
52        case TObj: delete o; break;
53#endif
54        }
55type=TUnknown;
56}
57
58static long longsign(long x)
59{
60if (x<0) return -1;
61if (x>0) return 1;
62return 0;
63}
64
65long ExtValue::compare(const ExtValue& src) const
66{
67if (type==TUnknown)
68        {
69        if (src.type==TDouble)
70                return (src.getDouble()!=0.0);
71        if (src.type==TString)
72                return 1;
73        return src.getInt()?1:0;
74        }
75else if (src.type==TUnknown)
76        {
77        if (type==TDouble)
78                return (getDouble()!=0.0);
79        if (type==TString)
80                return 1;
81        return getInt()?1:0;
82        }
83switch(type)
84        {
85        case TInt:
86        {
87        long t=src.getInt();
88        if (idata()>0)
89                {if (t>0) return longsign(idata()-t); else return +1;}
90        else
91                {if (t<=0) return longsign(idata()-t); else return -1;}
92        }
93        case TDouble:
94                {
95                double t=ddata()-src.getDouble();
96                if (t<0) return -1;
97                else if (t>0) return 1;
98                return 0;
99                }
100        case TString:
101        {
102        SString t=src.getString();
103        SString& t2=sdata();
104        const char* s1=(const char*)t2;
105        const char* s2=(const char*)t;
106        return longsign(strcmp(s1,s2));
107        }
108        case TObj:
109        {
110        if (src.type==TObj)
111                return !(odata()==src.odata());
112        return 1;
113        }
114        }
115return 1;
116}
117
118int ExtValue::operator==(const ExtValue& src) const
119{
120if (type!=src.type) return 0;
121switch(type)
122        {
123        case TInt: return idata()==src.idata();
124        case TDouble: return ddata()==src.ddata();
125        case TString: return sdata()==src.sdata();
126        case TObj: return odata()==src.odata();
127        }
128return 1;
129}
130
131void ExtValue::operator+=(const ExtValue& src)
132{
133switch(type)
134        {
135        case TInt: idata()+=src.getInt(); break;
136        case TDouble: ddata()+=src.getDouble(); break;
137        case TString: sdata()+=src.getString(); break;
138        }
139}
140
141void ExtValue::operator-=(const ExtValue& src)
142{
143switch(type)
144        {
145        case TInt: idata()-=src.getInt(); break;
146        case TDouble: ddata()-=src.getDouble(); break;
147        }
148}
149
150void ExtValue::operator*=(const ExtValue& src)
151{
152switch(type)
153        {
154        case TInt: idata()*=src.getInt(); break;
155        case TDouble: ddata()*=src.getDouble(); break;
156        }
157}
158
159#include "framsg.h"
160/*#include "fpu_control.h"
161#include <signal.h>
162
163static int fpuexception;
164void mathhandler(int sig)
165{
166printf("fpu exception!\n");
167fpuexception=1;
168signal(SIGFPE,SIG_IGN);
169} */
170
171void ExtValue::operator/=(const ExtValue& src)
172{
173switch(type)
174        {
175        case TInt:
176        { int a=src.getInt();
177//              idata()/=src.getInt();
178        if (a) idata()/=a;
179        else FMprintf("ExtValue","divide",FMLV_ERROR,"%s/0",(const char*)getString());
180        }
181                break;
182
183        case TDouble:
184// ugly ;-(
185#ifdef FPU_THROWS_EXCEPTIONS
186                try
187                        {
188                        ddata()/=src.getDouble();
189                        }
190                catch(...)
191                        {
192                        FMprintf("ExtValue","divide",FMLV_ERROR,"%s/0.0",(const char*)getString());
193                        }
194#else
195                {
196                double d=ddata();
197                d/=src.getDouble();
198                if (finite(d))
199                        ddata()=d;
200                else
201                        FMprintf("ExtValue","divide",FMLV_ERROR,"%s/0.0",(const char*)getString());
202                }
203#endif
204                break;
205        }
206}
207
208void ExtValue::operator%=(const ExtValue& src)
209{
210switch(type)
211        {
212        case TInt: idata()=idata()%src.getInt(); break;
213        case TDouble: ddata()=fmod(ddata(),src.getDouble()); break;
214        }
215}
216
217long ExtValue::getInt() const
218{
219switch(type)
220        {
221        case TInt: return idata();
222        case TDouble: return (int)ddata();
223        case TString:
224        {
225        const char* s=(const char*)sdata();
226        if ((s[0]=='0')&&(s[1]=='x'))
227                {
228                long val;
229                sscanf(s+2,"%lx",&val);
230                return val;
231                }
232        else
233                {
234                if (strchr(s,'e')||(strchr(s,'E')))
235                        return atof(s);
236                else
237                        return atol(s);
238                }
239        }
240        case TObj: return (long)odata().param;
241        }
242return 0;
243}
244double ExtValue::getDouble() const
245{
246switch(type)
247        {
248        case TDouble: return ddata();
249        case TInt: return (double)idata();
250        case TString:
251        {
252        const char* s=(const char*)sdata();
253        if ((s[0]=='0')&&(s[1]=='x'))
254                {
255                long val;
256                sscanf(s+2,"%lx",&val);
257                return val;
258                }
259        else
260                return atof(s);
261        }
262        case TObj: return (double)(long)odata().param;
263        }
264return 0.0;
265}
266SString ExtValue::getString() const
267{
268switch(type)
269        {
270        case TString: return sdata();
271        case TInt:
272                {
273                SString tmp;
274                sprintf(tmp.directAppend(20),"%d",idata());
275                tmp.endAppend();
276                return tmp;
277                }
278        case TDouble:
279                {
280                SString tmp;
281                sprintf(tmp.directAppend(20),"%.15g",ddata());
282                tmp.endAppend();
283                if ((!strchr(tmp,'.'))&&(!strchr(tmp,'e'))) tmp+=".0";
284                return tmp;
285                }
286        case TObj:
287                return odata().toString();
288        case TInvalid:
289                return SString("undefined");
290        default:
291                return SString("null");
292        }
293}
294
295ExtObject ExtValue::getObject() const
296{
297if (type==TObj) return odata();
298return ExtObject();
299}
300
301ExtValue ExtValue::getExtType()
302{
303if (getType()!=TObj) return ExtValue((long)getType());
304ExtObject& o=odata();
305return ExtValue(SString(o.isEmpty()?"":o.getParamInterface()->getName()));
306}
Note: See TracBrowser for help on using the repository browser.