]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/misc.c
Linux test_HTTP fixes.
[simgear.git] / simgear / nasal / misc.c
1 #include <string.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 #include "nasal.h"
6 #include "code.h"
7
8 void naFree(void* m) { free(m); }
9 void* naAlloc(int n) { return malloc(n); }
10 void* naRealloc(void* b, int n) { return realloc(b, n); }
11 void naBZero(void* m, int n) { memset(m, 0, n); }
12
13 void naTempSave(naContext c, naRef r)
14 {
15     int i;
16     if(!IS_OBJ(r)) return;
17     if(c->ntemps >= c->tempsz) {
18         struct naObj** newtemps;
19         c->tempsz *= 2;
20         newtemps = naAlloc(c->tempsz * sizeof(struct naObj*));
21         for(i=0; i<c->ntemps; i++)
22             newtemps[i] = c->temps[i];
23         naFree(c->temps);
24         c->temps = newtemps;
25     }
26     c->temps[c->ntemps++] = PTR(r).obj;
27 }
28
29 naRef naObj(int type, struct naObj* o)
30 {
31     naRef r;
32     SETPTR(r, o);
33     o->type = type;
34     return r;
35 }
36
37 int naTrue(naRef r)
38 {
39     if(IS_NIL(r)) return 0;
40     if(IS_NUM(r)) return r.num != 0;
41     if(IS_STR(r)) return 1;
42     return 0;
43 }
44
45 naRef naNumValue(naRef n)
46 {
47     double d;
48     if(IS_NUM(n)) return n;
49     if(IS_NIL(n)) return naNil();
50     if(IS_STR(n) && naStr_tonum(n, &d))
51         return naNum(d);
52     return naNil();
53 }
54
55 naRef naStringValue(naContext c, naRef r)
56 {
57     if(IS_NIL(r) || IS_STR(r)) return r;
58     if(IS_NUM(r)) {
59         naRef s = naNewString(c);
60         naStr_fromnum(s, r.num);
61         return s;
62     }
63     return naNil();
64 }
65
66 naRef naNew(struct Context* c, int type)
67 {
68     naRef result;
69     if(c->nfree[type] == 0)
70         c->free[type] = naGC_get(&globals->pools[type],
71                                  OBJ_CACHE_SZ, &c->nfree[type]);
72     result = naObj(type, c->free[type][--c->nfree[type]]);
73     naTempSave(c, result);
74     return result;
75 }
76
77 naRef naNewString(struct Context* c)
78 {
79     naRef s = naNew(c, T_STR);
80     PTR(s).str->emblen = 0;
81     PTR(s).str->data.ref.len = 0;
82     PTR(s).str->data.ref.ptr = 0;
83     PTR(s).str->hashcode = 0;
84     return s;
85 }
86
87 naRef naNewVector(struct Context* c)
88 {
89     naRef r = naNew(c, T_VEC);
90     PTR(r).vec->rec = 0;
91     return r;
92 }
93
94 naRef naNewHash(struct Context* c)
95 {
96     naRef r = naNew(c, T_HASH);
97     PTR(r).hash->rec = 0;
98     return r;
99 }
100
101 naRef naNewCode(struct Context* c)
102 {
103     return naNew(c, T_CODE);
104 }
105
106 naRef naNewCCode(struct Context* c, naCFunction fptr)
107 {
108     naRef r = naNew(c, T_CCODE);
109     PTR(r).ccode->fptr = fptr;
110     PTR(r).ccode->fptru = 0;
111     return r;
112 }
113
114 naRef naNewCCodeU(struct Context* c, naCFunctionU fptr, void* user_data)
115 {
116     return naNewCCodeUD(c, fptr, user_data, 0);
117 }
118
119 naRef naNewCCodeUD( struct Context* c,
120                     naCFunctionU fptr,
121                     void* user_data,
122                     void (*destroy)(void*) )
123 {
124     naRef r = naNew(c, T_CCODE);
125     PTR(r).ccode->fptru = fptr;
126     PTR(r).ccode->user_data = user_data;
127     PTR(r).ccode->destroy = destroy;
128     return r;
129 }
130
131 naRef naNewFunc(struct Context* c, naRef code)
132 {
133     naRef func = naNew(c, T_FUNC);
134     PTR(func).func->code = code;
135     PTR(func).func->namespace = naNil();
136     PTR(func).func->next = naNil();
137     return func;
138 }
139
140 naRef naNewGhost(naContext c, naGhostType* type, void* ptr)
141 {
142     naRef ghost;
143     // ensure 'simple' ghost users don't see garbage for these fields
144     type->get_member = 0;
145     type->set_member = 0;
146
147     ghost = naNew(c, T_GHOST);
148     PTR(ghost).ghost->gtype = type;
149     PTR(ghost).ghost->ptr = ptr;
150     PTR(ghost).ghost->data = naNil();
151     return ghost;
152 }
153
154 naRef naNewGhost2(naContext c, naGhostType* t, void* ptr)
155 {
156     naRef ghost = naNew(c, T_GHOST);
157     PTR(ghost).ghost->gtype = t;
158     PTR(ghost).ghost->ptr = ptr;
159     PTR(ghost).ghost->data = naNil();
160     return ghost;
161 }
162
163 naGhostType* naGhost_type(naRef ghost)
164 {
165     if(!IS_GHOST(ghost)) return 0;
166     return PTR(ghost).ghost->gtype;
167 }
168
169 void* naGhost_ptr(naRef ghost)
170 {
171     if(!IS_GHOST(ghost)) return 0;
172     return PTR(ghost).ghost->ptr;
173 }
174
175 void naGhost_setData(naRef ghost, naRef data)
176 {
177     if(IS_GHOST(ghost))
178         PTR(ghost).ghost->data = data;
179 }
180
181 naRef naGhost_data(naRef ghost)
182 {
183     if(!IS_GHOST(ghost)) return naNil();
184     return PTR(ghost).ghost->data;
185 }
186
187 naRef naNil()
188 {
189     naRef r;
190     SETPTR(r, 0);
191     return r;
192 }
193
194 naRef naNum(double num)
195 {
196     naRef r;
197     SETNUM(r, num);
198     return r;
199 }
200
201 int naEqual(naRef a, naRef b)
202 {
203     double na=0, nb=0;
204     if(IS_REF(a) && IS_REF(b) && PTR(a).obj == PTR(b).obj)
205         return 1; // Object identity (and nil == nil)
206     if(IS_NIL(a) || IS_NIL(b))
207         return 0;
208     if(IS_NUM(a) && IS_NUM(b) && a.num == b.num)
209         return 1; // Numeric equality
210     if(IS_STR(a) && IS_STR(b) && naStr_equal(a, b))
211         return 1; // String equality
212
213     // Numeric equality after conversion
214     if(IS_NUM(a)) { na = a.num; }
215     else if(!(IS_STR(a) && naStr_tonum(a, &na))) { return 0; }
216
217     if(IS_NUM(b)) { nb = b.num; }
218     else if(!(IS_STR(b) && naStr_tonum(b, &nb))) { return 0; }
219
220     return na == nb ? 1 : 0;
221 }
222
223 int naStrEqual(naRef a, naRef b)
224 {
225     int i;
226     char *ap, *bp;
227     if(!IS_STR(a) || !IS_STR(b) || naStr_len(a) != naStr_len(b))
228         return 0;
229     ap = naStr_data(a);
230     bp = naStr_data(b);
231     for(i=0; i<naStr_len(a); i++)
232         if(ap[i] != bp[i])
233             return 0;
234     return 1;
235 }
236
237 int naTypeSize(int type)
238 {
239     switch(type) {
240     case T_STR: return sizeof(struct naStr);
241     case T_VEC: return sizeof(struct naVec);
242     case T_HASH: return sizeof(struct naHash);
243     case T_CODE: return sizeof(struct naCode);
244     case T_FUNC: return sizeof(struct naFunc);
245     case T_CCODE: return sizeof(struct naCCode);
246     case T_GHOST: return sizeof(struct naGhost);
247     };
248     return 0x7fffffff; // Make sure the answer is nonsense :)
249 }
250
251 int naIsNil(naRef r)    { return IS_NIL(r); }
252 int naIsNum(naRef r)    { return IS_NUM(r); }
253 int naIsString(naRef r) { return IS_STR(r); }
254 int naIsScalar(naRef r) { return IS_SCALAR(r); }
255 int naIsVector(naRef r) { return IS_VEC(r); }
256 int naIsHash(naRef r)   { return IS_HASH(r); }
257 int naIsFunc(naRef r)   { return IS_FUNC(r); }
258 int naIsCode(naRef r)   { return IS_CODE(r); }
259 int naIsCCode(naRef r)  { return IS_CCODE(r); }
260 int naIsGhost(naRef r)  { return IS_GHOST(r); }
261 int naIsIdentical(naRef l, naRef r) { return IDENTICAL(l, r); }
262
263 void naSetUserData(naContext c, void* p) { c->userData = p; }
264 void* naGetUserData(naContext c)
265 {
266     if(c->userData) return c->userData;
267     return c->callParent ? naGetUserData(c->callParent) : 0;
268 }
269
270 void naAddSym(naContext c, naRef ns, char *sym, naRef val)
271 {
272     naRef name = naStr_fromdata(naNewString(c), sym, strlen(sym));
273     naHash_set(ns, naInternSymbol(name), val);
274 }
275
276 naRef naGenLib(naContext c, naCFuncItem *fns)
277 {
278     naRef ns = naNewHash(c);
279     for(/**/; fns->name; fns++)
280         naAddSym(c, ns, fns->name, naNewFunc(c, naNewCCode(c, fns->func)));
281     return ns;
282 }