Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5205 | clevermous | 1 | /* |
2 | ** $Id: lbaselib.c,v 1.273 2011/11/30 13:03:24 roberto Exp $ |
||
3 | ** Basic library |
||
4 | ** See Copyright Notice in lua.h |
||
5 | */ |
||
6 | |||
7 | |||
8 | |||
9 | #include |
||
10 | #include |
||
11 | #include |
||
12 | #include |
||
13 | |||
14 | #define lbaselib_c |
||
15 | #define LUA_LIB |
||
16 | |||
17 | #include "lua.h" |
||
18 | |||
19 | #include "lauxlib.h" |
||
20 | #include "lualib.h" |
||
21 | |||
22 | #include "kolibri.h" |
||
23 | #include "console.c" |
||
24 | |||
25 | //KOS console |
||
26 | |||
27 | static int luaB__copen (lua_State *L){ |
||
28 | CONSOLE_INIT("Lua 5.2.0"); |
||
29 | return 0; |
||
30 | } |
||
31 | |||
32 | static int luaB__cclose (lua_State *L){ |
||
33 | _exit2(0); |
||
34 | return 0; |
||
35 | } |
||
36 | |||
37 | static int luaB__cprintf (lua_State *L){ |
||
38 | int n = lua_gettop(L); /* number of arguments */ |
||
39 | int i; |
||
40 | const char * s; |
||
41 | |||
42 | int r[n]; |
||
43 | lua_getglobal(L, "tostring"); |
||
44 | |||
45 | for (i=1; i<=n; i++) { |
||
46 | |||
47 | lua_pushvalue(L, -1); /* function to be called */ |
||
48 | lua_pushvalue(L, i); /* value to print */ |
||
49 | lua_call(L, 1, 1); |
||
50 | s = lua_tostring(L, -1); |
||
51 | kprintf ("%s",s); |
||
52 | lua_pop(L, 1); /* pop result */ |
||
53 | } |
||
54 | |||
55 | return 0; |
||
56 | |||
57 | } |
||
58 | |||
59 | static int luaB__cgets (lua_State *L){ |
||
60 | size_t nr; /* number of chars actually read */ |
||
61 | char *p; |
||
62 | luaL_Buffer b; |
||
63 | luaL_buffinit(L, &b); |
||
64 | p = luaL_prepbuffsize(&b, 255); /* prepare buffer to read whole block */ |
||
65 | kgets(p, 255); |
||
66 | nr = sizeof(p); /* try to read 'n' chars */ |
||
67 | luaL_addsize(&b, nr); |
||
68 | luaL_pushresult(&b); /* close buffer */ |
||
69 | return (nr > 0); /* true iff read something */ |
||
70 | |||
71 | } |
||
72 | |||
73 | |||
74 | //KolibriOS |
||
75 | |||
76 | static int luaB__sysexit (lua_State *L){ |
||
77 | kol_exit(); |
||
78 | return 0; |
||
79 | } |
||
80 | |||
81 | static int luaB__paintstart (lua_State *L){ |
||
82 | kol_paint_start(); |
||
83 | return 0; |
||
84 | } |
||
85 | |||
86 | static int luaB__paintend (lua_State *L){ |
||
87 | kol_paint_end(); |
||
88 | return 0; |
||
89 | } |
||
90 | |||
91 | |||
92 | static int luaB__checkevent (lua_State *L){ |
||
93 | lua_pushnumber(L, kol_event_check()); |
||
94 | return 1; |
||
95 | } |
||
96 | |||
97 | static int luaB__waitevent (lua_State *L){ |
||
98 | lua_pushnumber(L, kol_event_wait()); |
||
99 | return 1; |
||
100 | } |
||
101 | |||
102 | static int luaB__getkey (lua_State *L){ |
||
103 | lua_pushnumber(L, kol_key_get()); |
||
104 | return 1; |
||
105 | } |
||
106 | |||
107 | static int luaB__getbutton (lua_State *L){ |
||
108 | lua_pushnumber(L, kol_btn_get()); |
||
109 | return 1; |
||
110 | } |
||
111 | |||
112 | static int luaB__systime (lua_State *L){ |
||
113 | lua_pushnumber(L, kol_system_time_get()); |
||
114 | return 1; |
||
115 | } |
||
116 | |||
117 | static int luaB__sysdate (lua_State *L){ |
||
118 | lua_pushnumber(L, kol_system_date_get()); |
||
119 | return 1; |
||
120 | } |
||
121 | |||
122 | |||
123 | static int luaB__window (lua_State *L){ |
||
124 | int n = lua_gettop(L); /* number of arguments */ |
||
125 | int i; |
||
126 | const char * s; |
||
127 | int r[n]; |
||
128 | lua_getglobal(L, "tostring"); |
||
129 | for (i=1; i<=n; i++) { |
||
130 | |||
131 | lua_pushvalue(L, -1); /* function to be called */ |
||
132 | lua_pushvalue(L, i); /* value to print */ |
||
133 | lua_call(L, 1, 1); |
||
134 | s = lua_tostring(L, -1); |
||
135 | r[i]=atoi(s); |
||
136 | lua_pop(L, 1); /* pop result */ |
||
137 | } |
||
138 | kol_wnd_define (r[1],r[2],r[3],r[4],r[5]); |
||
139 | return 0; |
||
140 | |||
141 | } |
||
142 | |||
143 | static int luaB__makebutton (lua_State *L){ |
||
144 | int n = lua_gettop(L); /* number of arguments */ |
||
145 | int i; |
||
146 | const char * s; |
||
147 | int r[n]; |
||
148 | lua_getglobal(L, "tostring"); |
||
149 | for (i=1; i<=n; i++) { |
||
150 | |||
151 | lua_pushvalue(L, -1); /* function to be called */ |
||
152 | lua_pushvalue(L, i); /* value to print */ |
||
153 | lua_call(L, 1, 1); |
||
154 | s = lua_tostring(L, -1); |
||
155 | |||
156 | r[i]=atoi(s); |
||
157 | |||
158 | |||
159 | lua_pop(L, 1); /* pop result */ |
||
160 | } |
||
161 | kol_btn_define (r[1],r[2],r[3],r[4],r[5],r[6]); |
||
162 | return 0; |
||
163 | |||
164 | } |
||
165 | |||
166 | static int luaB__textout (lua_State *L){ |
||
167 | int n = lua_gettop(L); /* number of arguments */ |
||
168 | int i; |
||
169 | const char * s; |
||
170 | |||
171 | int r[n]; |
||
172 | lua_getglobal(L, "tostring"); |
||
173 | |||
174 | for (i=1; i<=n; i++) { |
||
175 | |||
176 | lua_pushvalue(L, -1); /* function to be called */ |
||
177 | lua_pushvalue(L, i); /* value to print */ |
||
178 | lua_call(L, 1, 1); |
||
179 | s = lua_tostring(L, -1); |
||
180 | r[i]=atoi(s); |
||
181 | |||
182 | |||
183 | |||
184 | lua_pop(L, 1); /* pop result */ |
||
185 | } |
||
186 | |||
187 | kol_paint_string (r[1],r[2],r[3],s, strlen(s)); |
||
188 | return 0; |
||
189 | |||
190 | } |
||
191 | |||
192 | /////exp |
||
193 | |||
194 | static int luaB__drawpixel (lua_State *L){ |
||
195 | int n = lua_gettop(L); /* number of arguments */ |
||
196 | int i; |
||
197 | const char * s; |
||
198 | int r[n]; |
||
199 | lua_getglobal(L, "tostring"); |
||
200 | for (i=1; i<=n; i++) { |
||
201 | |||
202 | lua_pushvalue(L, -1); /* function to be called */ |
||
203 | lua_pushvalue(L, i); /* value to print */ |
||
204 | lua_call(L, 1, 1); |
||
205 | s = lua_tostring(L, -1); |
||
206 | r[i]=atoi(s); |
||
207 | lua_pop(L, 1); /* pop result */ |
||
208 | } |
||
209 | kol_paint_pixel (r[1],r[2],r[3]); |
||
210 | return 0; |
||
211 | |||
212 | } |
||
213 | |||
214 | static int luaB__drawline (lua_State *L){ |
||
215 | int n = lua_gettop(L); /* number of arguments */ |
||
216 | int i; |
||
217 | const char * s; |
||
218 | int r[n]; |
||
219 | lua_getglobal(L, "tostring"); |
||
220 | for (i=1; i<=n; i++) { |
||
221 | |||
222 | lua_pushvalue(L, -1); /* function to be called */ |
||
223 | lua_pushvalue(L, i); /* value to print */ |
||
224 | lua_call(L, 1, 1); |
||
225 | s = lua_tostring(L, -1); |
||
226 | r[i]=atoi(s); |
||
227 | lua_pop(L, 1); /* pop result */ |
||
228 | } |
||
229 | kol_paint_line (r[1],r[2],r[3],r[4],r[5]); |
||
230 | return 0; |
||
231 | |||
232 | } |
||
233 | |||
234 | //KolibriOS |
||
235 | |||
236 | static int luaB_print (lua_State *L) { |
||
237 | int n = lua_gettop(L); /* number of arguments */ |
||
238 | int i; |
||
239 | lua_getglobal(L, "tostring"); |
||
240 | for (i=1; i<=n; i++) { |
||
241 | const char *s; |
||
242 | size_t l; |
||
243 | lua_pushvalue(L, -1); /* function to be called */ |
||
244 | lua_pushvalue(L, i); /* value to print */ |
||
245 | lua_call(L, 1, 1); |
||
246 | s = lua_tolstring(L, -1, &l); /* get result */ |
||
247 | if (s == NULL) |
||
248 | return luaL_error(L, |
||
249 | LUA_QL("tostring") " must return a string to " LUA_QL("print")); |
||
250 | if (i>1) luai_writestring("\t", 1); |
||
251 | luai_writestring(s, l); |
||
252 | lua_pop(L, 1); /* pop result */ |
||
253 | } |
||
254 | luai_writeline(); |
||
255 | return 0; |
||
256 | } |
||
257 | |||
258 | |||
259 | #define SPACECHARS " \f\n\r\t\v" |
||
260 | |||
261 | static int luaB_tonumber (lua_State *L) { |
||
262 | if (lua_isnoneornil(L, 2)) { /* standard conversion */ |
||
263 | int isnum; |
||
264 | lua_Number n = lua_tonumberx(L, 1, &isnum); |
||
265 | if (isnum) { |
||
266 | lua_pushnumber(L, n); |
||
267 | return 1; |
||
268 | } /* else not a number; must be something */ |
||
269 | luaL_checkany(L, 1); |
||
270 | } |
||
271 | else { |
||
272 | size_t l; |
||
273 | const char *s = luaL_checklstring(L, 1, &l); |
||
274 | const char *e = s + l; /* end point for 's' */ |
||
275 | int base = luaL_checkint(L, 2); |
||
276 | int neg = 0; |
||
277 | luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); |
||
278 | s += strspn(s, SPACECHARS); /* skip initial spaces */ |
||
279 | if (*s == '-') { s++; neg = 1; } /* handle signal */ |
||
280 | else if (*s == '+') s++; |
||
281 | if (isalnum((unsigned char)*s)) { |
||
282 | lua_Number n = 0; |
||
283 | do { |
||
284 | int digit = (isdigit((unsigned char)*s)) ? *s - '0' |
||
285 | : toupper((unsigned char)*s) - 'A' + 10; |
||
286 | if (digit >= base) break; /* invalid numeral; force a fail */ |
||
287 | n = n * (lua_Number)base + (lua_Number)digit; |
||
288 | s++; |
||
289 | } while (isalnum((unsigned char)*s)); |
||
290 | s += strspn(s, SPACECHARS); /* skip trailing spaces */ |
||
291 | if (s == e) { /* no invalid trailing characters? */ |
||
292 | lua_pushnumber(L, (neg) ? -n : n); |
||
293 | return 1; |
||
294 | } /* else not a number */ |
||
295 | } /* else not a number */ |
||
296 | } |
||
297 | lua_pushnil(L); /* not a number */ |
||
298 | return 1; |
||
299 | } |
||
300 | |||
301 | |||
302 | static int luaB_error (lua_State *L) { |
||
303 | int level = luaL_optint(L, 2, 1); |
||
304 | lua_settop(L, 1); |
||
305 | if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ |
||
306 | luaL_where(L, level); |
||
307 | lua_pushvalue(L, 1); |
||
308 | lua_concat(L, 2); |
||
309 | } |
||
310 | return lua_error(L); |
||
311 | } |
||
312 | |||
313 | |||
314 | static int luaB_getmetatable (lua_State *L) { |
||
315 | luaL_checkany(L, 1); |
||
316 | if (!lua_getmetatable(L, 1)) { |
||
317 | lua_pushnil(L); |
||
318 | return 1; /* no metatable */ |
||
319 | } |
||
320 | luaL_getmetafield(L, 1, "__metatable"); |
||
321 | return 1; /* returns either __metatable field (if present) or metatable */ |
||
322 | } |
||
323 | |||
324 | |||
325 | static int luaB_setmetatable (lua_State *L) { |
||
326 | int t = lua_type(L, 2); |
||
327 | luaL_checktype(L, 1, LUA_TTABLE); |
||
328 | luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, |
||
329 | "nil or table expected"); |
||
330 | if (luaL_getmetafield(L, 1, "__metatable")) |
||
331 | return luaL_error(L, "cannot change a protected metatable"); |
||
332 | lua_settop(L, 2); |
||
333 | lua_setmetatable(L, 1); |
||
334 | return 1; |
||
335 | } |
||
336 | |||
337 | |||
338 | static int luaB_rawequal (lua_State *L) { |
||
339 | luaL_checkany(L, 1); |
||
340 | luaL_checkany(L, 2); |
||
341 | lua_pushboolean(L, lua_rawequal(L, 1, 2)); |
||
342 | return 1; |
||
343 | } |
||
344 | |||
345 | |||
346 | static int luaB_rawlen (lua_State *L) { |
||
347 | int t = lua_type(L, 1); |
||
348 | luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, |
||
349 | "table or string expected"); |
||
350 | lua_pushinteger(L, lua_rawlen(L, 1)); |
||
351 | return 1; |
||
352 | } |
||
353 | |||
354 | |||
355 | static int luaB_rawget (lua_State *L) { |
||
356 | luaL_checktype(L, 1, LUA_TTABLE); |
||
357 | luaL_checkany(L, 2); |
||
358 | lua_settop(L, 2); |
||
359 | lua_rawget(L, 1); |
||
360 | return 1; |
||
361 | } |
||
362 | |||
363 | static int luaB_rawset (lua_State *L) { |
||
364 | luaL_checktype(L, 1, LUA_TTABLE); |
||
365 | luaL_checkany(L, 2); |
||
366 | luaL_checkany(L, 3); |
||
367 | lua_settop(L, 3); |
||
368 | lua_rawset(L, 1); |
||
369 | return 1; |
||
370 | } |
||
371 | |||
372 | |||
373 | static int luaB_collectgarbage (lua_State *L) { |
||
374 | static const char *const opts[] = {"stop", "restart", "collect", |
||
375 | "count", "step", "setpause", "setstepmul", |
||
376 | "setmajorinc", "isrunning", "generational", "incremental", NULL}; |
||
377 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, |
||
378 | LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, |
||
379 | LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; |
||
380 | int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; |
||
381 | int ex = luaL_optint(L, 2, 0); |
||
382 | int res = lua_gc(L, o, ex); |
||
383 | switch (o) { |
||
384 | case LUA_GCCOUNT: { |
||
385 | int b = lua_gc(L, LUA_GCCOUNTB, 0); |
||
386 | lua_pushnumber(L, res + ((lua_Number)b/1024)); |
||
387 | lua_pushinteger(L, b); |
||
388 | return 2; |
||
389 | } |
||
390 | case LUA_GCSTEP: case LUA_GCISRUNNING: { |
||
391 | lua_pushboolean(L, res); |
||
392 | return 1; |
||
393 | } |
||
394 | default: { |
||
395 | lua_pushinteger(L, res); |
||
396 | return 1; |
||
397 | } |
||
398 | } |
||
399 | } |
||
400 | |||
401 | |||
402 | static int luaB_type (lua_State *L) { |
||
403 | luaL_checkany(L, 1); |
||
404 | lua_pushstring(L, luaL_typename(L, 1)); |
||
405 | return 1; |
||
406 | } |
||
407 | |||
408 | |||
409 | static int pairsmeta (lua_State *L, const char *method, int iszero, |
||
410 | lua_CFunction iter) { |
||
411 | if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */ |
||
412 | luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ |
||
413 | lua_pushcfunction(L, iter); /* will return generator, */ |
||
414 | lua_pushvalue(L, 1); /* state, */ |
||
415 | if (iszero) lua_pushinteger(L, 0); /* and initial value */ |
||
416 | else lua_pushnil(L); |
||
417 | } |
||
418 | else { |
||
419 | lua_pushvalue(L, 1); /* argument 'self' to metamethod */ |
||
420 | lua_call(L, 1, 3); /* get 3 values from metamethod */ |
||
421 | } |
||
422 | return 3; |
||
423 | } |
||
424 | |||
425 | |||
426 | static int luaB_next (lua_State *L) { |
||
427 | luaL_checktype(L, 1, LUA_TTABLE); |
||
428 | lua_settop(L, 2); /* create a 2nd argument if there isn't one */ |
||
429 | if (lua_next(L, 1)) |
||
430 | return 2; |
||
431 | else { |
||
432 | lua_pushnil(L); |
||
433 | return 1; |
||
434 | } |
||
435 | } |
||
436 | |||
437 | |||
438 | static int luaB_pairs (lua_State *L) { |
||
439 | return pairsmeta(L, "__pairs", 0, luaB_next); |
||
440 | } |
||
441 | |||
442 | |||
443 | static int ipairsaux (lua_State *L) { |
||
444 | int i = luaL_checkint(L, 2); |
||
445 | luaL_checktype(L, 1, LUA_TTABLE); |
||
446 | i++; /* next value */ |
||
447 | lua_pushinteger(L, i); |
||
448 | lua_rawgeti(L, 1, i); |
||
449 | return (lua_isnil(L, -1)) ? 1 : 2; |
||
450 | } |
||
451 | |||
452 | |||
453 | static int luaB_ipairs (lua_State *L) { |
||
454 | return pairsmeta(L, "__ipairs", 1, ipairsaux); |
||
455 | } |
||
456 | |||
457 | |||
458 | static int load_aux (lua_State *L, int status) { |
||
459 | if (status == LUA_OK) |
||
460 | return 1; |
||
461 | else { |
||
462 | lua_pushnil(L); |
||
463 | lua_insert(L, -2); /* put before error message */ |
||
464 | return 2; /* return nil plus error message */ |
||
465 | } |
||
466 | } |
||
467 | |||
468 | |||
469 | static int luaB_loadfile (lua_State *L) { |
||
470 | const char *fname = luaL_optstring(L, 1, NULL); |
||
471 | const char *mode = luaL_optstring(L, 2, NULL); |
||
472 | int env = !lua_isnone(L, 3); /* 'env' parameter? */ |
||
473 | int status = luaL_loadfilex(L, fname, mode); |
||
474 | if (status == LUA_OK && env) { /* 'env' parameter? */ |
||
475 | lua_pushvalue(L, 3); |
||
476 | lua_setupvalue(L, -2, 1); /* set it as 1st upvalue of loaded chunk */ |
||
477 | } |
||
478 | return load_aux(L, status); |
||
479 | } |
||
480 | |||
481 | |||
482 | /* |
||
483 | ** {====================================================== |
||
484 | ** Generic Read function |
||
485 | ** ======================================================= |
||
486 | */ |
||
487 | |||
488 | |||
489 | /* |
||
490 | ** reserved slot, above all arguments, to hold a copy of the returned |
||
491 | ** string to avoid it being collected while parsed. 'load' has four |
||
492 | ** optional arguments (chunk, source name, mode, and environment). |
||
493 | */ |
||
494 | #define RESERVEDSLOT 5 |
||
495 | |||
496 | |||
497 | /* |
||
498 | ** Reader for generic `load' function: `lua_load' uses the |
||
499 | ** stack for internal stuff, so the reader cannot change the |
||
500 | ** stack top. Instead, it keeps its resulting string in a |
||
501 | ** reserved slot inside the stack. |
||
502 | */ |
||
503 | static const char *generic_reader (lua_State *L, void *ud, size_t *size) { |
||
504 | (void)(ud); /* not used */ |
||
505 | luaL_checkstack(L, 2, "too many nested functions"); |
||
506 | lua_pushvalue(L, 1); /* get function */ |
||
507 | lua_call(L, 0, 1); /* call it */ |
||
508 | if (lua_isnil(L, -1)) { |
||
509 | *size = 0; |
||
510 | return NULL; |
||
511 | } |
||
512 | else if (!lua_isstring(L, -1)) |
||
513 | luaL_error(L, "reader function must return a string"); |
||
514 | lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ |
||
515 | return lua_tolstring(L, RESERVEDSLOT, size); |
||
516 | } |
||
517 | |||
518 | |||
519 | static int luaB_load (lua_State *L) { |
||
520 | int status; |
||
521 | size_t l; |
||
522 | int top = lua_gettop(L); |
||
523 | const char *s = lua_tolstring(L, 1, &l); |
||
524 | const char *mode = luaL_optstring(L, 3, "bt"); |
||
525 | if (s != NULL) { /* loading a string? */ |
||
526 | const char *chunkname = luaL_optstring(L, 2, s); |
||
527 | status = luaL_loadbufferx(L, s, l, chunkname, mode); |
||
528 | } |
||
529 | else { /* loading from a reader function */ |
||
530 | const char *chunkname = luaL_optstring(L, 2, "=(load)"); |
||
531 | luaL_checktype(L, 1, LUA_TFUNCTION); |
||
532 | lua_settop(L, RESERVEDSLOT); /* create reserved slot */ |
||
533 | status = lua_load(L, generic_reader, NULL, chunkname, mode); |
||
534 | } |
||
535 | if (status == LUA_OK && top >= 4) { /* is there an 'env' argument */ |
||
536 | lua_pushvalue(L, 4); /* environment for loaded function */ |
||
537 | lua_setupvalue(L, -2, 1); /* set it as 1st upvalue */ |
||
538 | } |
||
539 | return load_aux(L, status); |
||
540 | } |
||
541 | |||
542 | /* }====================================================== */ |
||
543 | |||
544 | |||
545 | static int dofilecont (lua_State *L) { |
||
546 | return lua_gettop(L) - 1; |
||
547 | } |
||
548 | |||
549 | |||
550 | static int luaB_dofile (lua_State *L) { |
||
551 | const char *fname = luaL_optstring(L, 1, NULL); |
||
552 | lua_settop(L, 1); |
||
553 | if (luaL_loadfile(L, fname) != LUA_OK) lua_error(L); |
||
554 | lua_callk(L, 0, LUA_MULTRET, 0, dofilecont); |
||
555 | return dofilecont(L); |
||
556 | } |
||
557 | |||
558 | |||
559 | static int luaB_assert (lua_State *L) { |
||
560 | if (!lua_toboolean(L, 1)) |
||
561 | return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); |
||
562 | return lua_gettop(L); |
||
563 | } |
||
564 | |||
565 | |||
566 | static int luaB_select (lua_State *L) { |
||
567 | int n = lua_gettop(L); |
||
568 | if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { |
||
569 | lua_pushinteger(L, n-1); |
||
570 | return 1; |
||
571 | } |
||
572 | else { |
||
573 | int i = luaL_checkint(L, 1); |
||
574 | if (i < 0) i = n + i; |
||
575 | else if (i > n) i = n; |
||
576 | luaL_argcheck(L, 1 <= i, 1, "index out of range"); |
||
577 | return n - i; |
||
578 | } |
||
579 | } |
||
580 | |||
581 | |||
582 | static int finishpcall (lua_State *L, int status) { |
||
583 | if (!lua_checkstack(L, 1)) { /* no space for extra boolean? */ |
||
584 | lua_settop(L, 0); /* create space for return values */ |
||
585 | lua_pushboolean(L, 0); |
||
586 | lua_pushstring(L, "stack overflow"); |
||
587 | return 2; /* return false, msg */ |
||
588 | } |
||
589 | lua_pushboolean(L, status); /* first result (status) */ |
||
590 | lua_replace(L, 1); /* put first result in first slot */ |
||
591 | return lua_gettop(L); |
||
592 | } |
||
593 | |||
594 | |||
595 | static int pcallcont (lua_State *L) { |
||
596 | int status = lua_getctx(L, NULL); |
||
597 | return finishpcall(L, (status == LUA_YIELD)); |
||
598 | } |
||
599 | |||
600 | |||
601 | static int luaB_pcall (lua_State *L) { |
||
602 | int status; |
||
603 | luaL_checkany(L, 1); |
||
604 | lua_pushnil(L); |
||
605 | lua_insert(L, 1); /* create space for status result */ |
||
606 | status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont); |
||
607 | return finishpcall(L, (status == LUA_OK)); |
||
608 | } |
||
609 | |||
610 | |||
611 | static int luaB_xpcall (lua_State *L) { |
||
612 | int status; |
||
613 | int n = lua_gettop(L); |
||
614 | luaL_argcheck(L, n >= 2, 2, "value expected"); |
||
615 | lua_pushvalue(L, 1); /* exchange function... */ |
||
616 | lua_copy(L, 2, 1); /* ...and error handler */ |
||
617 | lua_replace(L, 2); |
||
618 | status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont); |
||
619 | return finishpcall(L, (status == LUA_OK)); |
||
620 | } |
||
621 | |||
622 | |||
623 | static int luaB_tostring (lua_State *L) { |
||
624 | luaL_checkany(L, 1); |
||
625 | luaL_tolstring(L, 1, NULL); |
||
626 | return 1; |
||
627 | } |
||
628 | |||
629 | |||
630 | static const luaL_Reg base_funcs[] = { |
||
631 | {"assert", luaB_assert}, |
||
632 | {"collectgarbage", luaB_collectgarbage}, |
||
633 | {"dofile", luaB_dofile}, |
||
634 | {"error", luaB_error}, |
||
635 | {"getmetatable", luaB_getmetatable}, |
||
636 | {"ipairs", luaB_ipairs}, |
||
637 | {"loadfile", luaB_loadfile}, |
||
638 | {"load", luaB_load}, |
||
639 | #if defined(LUA_COMPAT_LOADSTRING) |
||
640 | {"loadstring", luaB_load}, |
||
641 | #endif |
||
642 | {"next", luaB_next}, |
||
643 | {"pairs", luaB_pairs}, |
||
644 | {"pcall", luaB_pcall}, |
||
645 | {"print", luaB_print}, |
||
646 | {"rawequal", luaB_rawequal}, |
||
647 | {"rawlen", luaB_rawlen}, |
||
648 | {"rawget", luaB_rawget}, |
||
649 | {"rawset", luaB_rawset}, |
||
650 | {"select", luaB_select}, |
||
651 | {"setmetatable", luaB_setmetatable}, |
||
652 | {"tonumber", luaB_tonumber}, |
||
653 | {"tostring", luaB_tostring}, |
||
654 | {"type", luaB_type}, |
||
655 | {"xpcall", luaB_xpcall}, |
||
656 | {"sysexit", luaB__sysexit}, |
||
657 | {"paintstart", luaB__paintstart}, |
||
658 | {"paintend", luaB__paintend}, |
||
659 | {"window", luaB__window}, |
||
660 | {"checkevent", luaB__checkevent}, |
||
661 | {"waitevent", luaB__waitevent}, |
||
662 | {"getkey", luaB__getkey}, |
||
663 | {"getbutton", luaB__getbutton}, |
||
664 | {"makebutton", luaB__makebutton}, |
||
665 | {"textout", luaB__textout}, |
||
666 | {"sysdate", luaB__sysdate}, |
||
667 | {"systime", luaB__systime}, |
||
668 | {"drawline", luaB__drawline}, |
||
669 | {"drawpixel", luaB__drawpixel}, |
||
670 | {"copen", luaB__copen}, |
||
671 | {"cclose", luaB__cclose}, |
||
672 | {"cprintf", luaB__cprintf}, |
||
673 | {"cgets", luaB__cgets}, |
||
674 | {NULL, NULL} |
||
675 | }; |
||
676 | |||
677 | |||
678 | LUAMOD_API int luaopen_base (lua_State *L) { |
||
679 | /* set global _G */ |
||
680 | lua_pushglobaltable(L); |
||
681 | lua_pushglobaltable(L); |
||
682 | lua_setfield(L, -2, "_G"); |
||
683 | /* open lib into global table */ |
||
684 | luaL_setfuncs(L, base_funcs, 0); |
||
685 | lua_pushliteral(L, LUA_VERSION); |
||
686 | lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */ |
||
687 | return 1; |
||
688 | }=>>=>=>=n;>=n;>=n;>=n;>=n;>=n;>=n;> |
||
689 |