]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/lib.c
Clamp pitch values rather than just dumping an error message.
[simgear.git] / simgear / nasal / lib.c
1 #include "nasal.h"
2
3 // No need to include <string.h> just for this:
4 // It needs a funny name because MSVC wants to treat "strlen" as a
5 // special symbol.  Ugh...
6 static int StrLen(char* s)
7 {
8     char* s0 = s;
9     while(*s) s++;
10     return s - s0;
11 }
12
13 static naRef size(naContext c, naRef args)
14 {
15     naRef r;
16     if(naVec_size(args) == 0) return naNil();
17     r = naVec_get(args, 0);
18     if(naIsString(r)) return naNum(naStr_len(r));
19     if(naIsVector(r)) return naNum(naVec_size(r));
20     if(naIsHash(r)) return naNum(naHash_size(r));
21     return naNil();
22 }
23
24 static naRef keys(naContext c, naRef args)
25 {
26     naRef v, h = naVec_get(args, 0);
27     if(!naIsHash(h)) return naNil();
28     v = naNewVector(c);
29     naHash_keys(v, h);
30     return v;
31 }
32
33 static naRef append(naContext c, naRef args)
34 {
35     naRef v = naVec_get(args, 0);
36     naRef e = naVec_get(args, 1);
37     if(!naIsVector(v)) return naNil();
38     naVec_append(v, e);
39     return v;
40 }
41
42 static naRef pop(naContext c, naRef args)
43 {
44     naRef v = naVec_get(args, 0);
45     if(!naIsVector(v)) return naNil();
46     return naVec_removelast(v);
47 }
48
49 static naRef setsize(naContext c, naRef args)
50 {
51     naRef v = naVec_get(args, 0);
52     int sz = (int)naNumValue(naVec_get(args, 1)).num;
53     if(!naIsVector(v)) return naNil();
54     naVec_setsize(v, sz);
55     return v;
56 }
57
58 static naRef subvec(naContext c, naRef args)
59 {
60     int i;
61     naRef nlen, result, v = naVec_get(args, 0);
62     int len = 0, start = (int)naNumValue(naVec_get(args, 1)).num;
63     nlen = naNumValue(naVec_get(args, 2));
64     if(!naIsNil(nlen))
65         len = (int)naNumValue(naVec_get(args, 2)).num;
66     if(!naIsVector(v) || start < 0 || start >= naVec_size(v) || len < 0)
67         return naNil();
68     if(len == 0 || len > naVec_size(v) - start) len = naVec_size(v) - start;
69     result = naNewVector(c);
70     naVec_setsize(result, len);
71     for(i=0; i<len; i++)
72         naVec_set(result, i, naVec_get(v, start + i));
73     return result;
74 }
75
76 static naRef delete(naContext c, naRef args)
77 {
78     naRef h = naVec_get(args, 0);
79     naRef k = naVec_get(args, 1);
80     if(naIsHash(h)) naHash_delete(h, k);
81     return naNil();
82 }
83
84 static naRef intf(naContext c, naRef args)
85 {
86     naRef n = naNumValue(naVec_get(args, 0));
87     if(!naIsNil(n)) n.num = (int)n.num;
88     return n;
89 }
90
91 static naRef num(naContext c, naRef args)
92 {
93     return naNumValue(naVec_get(args, 0));
94 }
95
96 static naRef streq(naContext c, naRef args)
97 {
98     int i;
99     naRef a = naVec_get(args, 0);
100     naRef b = naVec_get(args, 1);
101     if(!naIsString(a) || !naIsString(b)) return naNil();
102     if(naStr_len(a) != naStr_len(b)) return naNum(0);
103     for(i=0; i<naStr_len(a); i++)
104         if(naStr_data(a)[i] != naStr_data(b)[i])
105             return naNum(0);
106     return naNum(1);
107 }
108
109 static naRef substr(naContext c, naRef args)
110 {
111     naRef src = naVec_get(args, 0);
112     naRef startR = naVec_get(args, 1);
113     naRef lenR = naVec_get(args, 2);
114     int start, len;
115     if(!naIsString(src)) return naNil();
116     startR = naNumValue(startR);
117     if(naIsNil(startR)) return naNil();
118     start = (int)startR.num;
119     if(naIsNil(lenR)) {
120         len = naStr_len(src) - start;
121     } else {
122         lenR = naNumValue(lenR);
123         if(naIsNil(lenR)) return naNil();
124         len = (int)lenR.num;
125     }
126     return naStr_substr(naNewString(c), src, start, len);
127 }
128
129 static naRef contains(naContext c, naRef args)
130 {
131     naRef hash = naVec_get(args, 0);
132     naRef key = naVec_get(args, 1);
133     if(naIsNil(hash) || naIsNil(key)) return naNil();
134     if(!naIsHash(hash)) return naNil();
135     return naHash_get(hash, key, &key) ? naNum(1) : naNum(0);
136 }
137
138 static naRef typeOf(naContext c, naRef args)
139 {
140     naRef r = naVec_get(args, 0);
141     char* t = "unknown";
142     if(naIsNil(r)) t = "nil";
143     else if(naIsNum(r)) t = "scalar";
144     else if(naIsString(r)) t = "scalar";
145     else if(naIsVector(r)) t = "vector";
146     else if(naIsHash(r)) t = "hash";
147     else if(naIsFunc(r)) t = "func";
148     else if(naIsGhost(r)) t = "ghost";
149     r = naStr_fromdata(naNewString(c), t, StrLen(t));
150     return r;
151 }
152
153 struct func { char* name; naCFunction func; };
154 static struct func funcs[] = {
155     { "size", size },
156     { "keys", keys }, 
157     { "append", append }, 
158     { "pop", pop }, 
159     { "setsize", setsize }, 
160     { "subvec", subvec }, 
161     { "delete", delete }, 
162     { "int", intf },
163     { "num", num },
164     { "streq", streq },
165     { "substr", substr },
166     { "contains", contains },
167     { "typeof", typeOf },
168 };
169
170 naRef naStdLib(naContext c)
171 {
172     naRef namespace = naNewHash(c);
173     int i, n = sizeof(funcs)/sizeof(struct func);
174     for(i=0; i<n; i++) {
175         naRef code = naNewCCode(c, funcs[i].func);
176         naRef name = naStr_fromdata(naNewString(c),
177                                     funcs[i].name, StrLen(funcs[i].name));
178         naHash_set(namespace, name, naNewFunc(c, code));
179     }
180     return namespace;
181 }