This source file includes following definitions.
- luaB_print
- luaB_tonumber
- luaB_error
- luaB_getmetatable
- luaB_setmetatable
- getfunc
- luaB_getfenv
- luaB_setfenv
- luaB_rawequal
- luaB_rawget
- luaB_rawset
- luaB_gcinfo
- luaB_collectgarbage
- luaB_type
- luaB_next
- luaB_pairs
- ipairsaux
- luaB_ipairs
- load_aux
- luaB_loadstring
- luaB_loadfile
- generic_reader
- luaB_load
- luaB_dofile
- luaB_assert
- luaB_unpack
- luaB_select
- luaB_pcall
- luaB_xpcall
- luaB_tostring
- luaB_newproxy
- costatus
- luaB_costatus
- auxresume
- luaB_coresume
- luaB_auxwrap
- luaB_cocreate
- luaB_cowrap
- luaB_yield
- luaB_corunning
- auxopen
- base_open
- luaopen_base
1
2
3
4
5
6
7
8
9 #include <ctype.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #ifndef HOST_LUA
14 #include <script.h>
15 #endif
16
17 #define lbaselib_c
18 #define LUA_LIB
19
20 #include "lua.h"
21
22 #include "lauxlib.h"
23 #include "lualib.h"
24
25
26
27
28
29
30
31
32
33
34 static int luaB_print (lua_State *L) {
35 int n = lua_gettop(L);
36 int i;
37 lua_getglobal(L, "tostring");
38 char buf[128];
39 const int max_buf_chars=sizeof(buf)-1;
40 char numbuf[16];
41 buf[0] = 0;
42 int buf_chars = 0;
43 for (i=1; i<=n; i++) {
44 const char *s;
45
46
47 if(lua_type(L,i) == LUA_TNUMBER) {
48 sprintf(numbuf,LUA_NUMBER_FMT,lua_tonumber(L,i));
49 s=numbuf;
50 }
51 else {
52 lua_pushvalue(L, -1);
53 lua_pushvalue(L, i);
54 lua_call(L, 1, 1);
55 s = lua_tostring(L, -1);
56 if (s == NULL)
57 return luaL_error(L, LUA_QL("tostring") " must return a string to "
58 LUA_QL("print"));
59 lua_pop(L, 1);
60 }
61 if(i>1) {
62 strcpy(buf+buf_chars," ");
63 ++buf_chars;
64 }
65 if(buf_chars+strlen(s) >= max_buf_chars) {
66 strncpy(buf+buf_chars,s,max_buf_chars-buf_chars);
67 buf[max_buf_chars]=0;
68 break;
69 }
70 strcpy(buf+buf_chars,s);
71 buf_chars = strlen(buf);
72 if(buf_chars >= max_buf_chars-1)
73 break;
74
75 }
76 #ifdef HOST_LUA
77 fprintf(stdout,"%s\n",buf);
78 #else
79 script_console_add_line((long)buf);
80 #endif
81
82 return 0;
83 }
84
85
86 static int luaB_tonumber (lua_State *L) {
87 int base = luaL_optint(L, 2, 10);
88 if (base == 10) {
89 luaL_checkany(L, 1);
90 if (lua_isnumber(L, 1)) {
91 lua_pushnumber(L, lua_tonumber(L, 1));
92 return 1;
93 }
94 }
95 else {
96 const char *s1 = luaL_checkstring(L, 1);
97 char *s2;
98 unsigned long n;
99 luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
100 n = strtoul(s1, &s2, base);
101 if (s1 != s2) {
102 while (isspace((unsigned char)(*s2))) s2++;
103 if (*s2 == '\0') {
104 lua_pushnumber(L, (lua_Number)n);
105 return 1;
106 }
107 }
108 }
109 lua_pushnil(L);
110 return 1;
111 }
112
113
114 static int luaB_error (lua_State *L) {
115 int level = luaL_optint(L, 2, 1);
116 lua_settop(L, 1);
117 if (lua_isstring(L, 1) && level > 0) {
118 luaL_where(L, level);
119 lua_pushvalue(L, 1);
120 lua_concat(L, 2);
121 }
122 return lua_error(L);
123 }
124
125
126 static int luaB_getmetatable (lua_State *L) {
127 luaL_checkany(L, 1);
128 if (!lua_getmetatable(L, 1)) {
129 lua_pushnil(L);
130 return 1;
131 }
132 luaL_getmetafield(L, 1, "__metatable");
133 return 1;
134 }
135
136
137 static int luaB_setmetatable (lua_State *L) {
138 int t = lua_type(L, 2);
139 luaL_checktype(L, 1, LUA_TTABLE);
140 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
141 "nil or table expected");
142 if (luaL_getmetafield(L, 1, "__metatable"))
143 luaL_error(L, "cannot change a protected metatable");
144 lua_settop(L, 2);
145 lua_setmetatable(L, 1);
146 return 1;
147 }
148
149
150 static void getfunc (lua_State *L, int opt) {
151 if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
152 else {
153 lua_Debug ar;
154 int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
155 luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
156 if (lua_getstack(L, level, &ar) == 0)
157 luaL_argerror(L, 1, "invalid level");
158 lua_getinfo(L, "f", &ar);
159 if (lua_isnil(L, -1))
160 luaL_error(L, "no function environment for tail call at level %d",
161 level);
162 }
163 }
164
165
166 static int luaB_getfenv (lua_State *L) {
167 getfunc(L, 1);
168 if (lua_iscfunction(L, -1))
169 lua_pushvalue(L, LUA_GLOBALSINDEX);
170 else
171 lua_getfenv(L, -1);
172 return 1;
173 }
174
175
176 static int luaB_setfenv (lua_State *L) {
177 luaL_checktype(L, 2, LUA_TTABLE);
178 getfunc(L, 0);
179 lua_pushvalue(L, 2);
180 if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
181
182 lua_pushthread(L);
183 lua_insert(L, -2);
184 lua_setfenv(L, -2);
185 return 0;
186 }
187 else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
188 luaL_error(L,
189 LUA_QL("setfenv") " cannot change environment of given object");
190 return 1;
191 }
192
193
194 static int luaB_rawequal (lua_State *L) {
195 luaL_checkany(L, 1);
196 luaL_checkany(L, 2);
197 lua_pushboolean(L, lua_rawequal(L, 1, 2));
198 return 1;
199 }
200
201
202 static int luaB_rawget (lua_State *L) {
203 luaL_checktype(L, 1, LUA_TTABLE);
204 luaL_checkany(L, 2);
205 lua_settop(L, 2);
206 lua_rawget(L, 1);
207 return 1;
208 }
209
210 static int luaB_rawset (lua_State *L) {
211 luaL_checktype(L, 1, LUA_TTABLE);
212 luaL_checkany(L, 2);
213 luaL_checkany(L, 3);
214 lua_settop(L, 3);
215 lua_rawset(L, 1);
216 return 1;
217 }
218
219
220 static int luaB_gcinfo (lua_State *L) {
221 lua_pushinteger(L, lua_getgccount(L));
222 return 1;
223 }
224
225
226 static int luaB_collectgarbage (lua_State *L) {
227 static const char *const opts[] = {"stop", "restart", "collect",
228 "count", "step", "setpause", "setstepmul", NULL};
229 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
230 LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
231 int o = luaL_checkoption(L, 1, "collect", opts);
232 int ex = luaL_optint(L, 2, 0);
233 int res = lua_gc(L, optsnum[o], ex);
234 switch (optsnum[o]) {
235 case LUA_GCCOUNT: {
236 int b = lua_gc(L, LUA_GCCOUNTB, 0);
237 lua_pushnumber(L, res + ((lua_Number)b/1024));
238 return 1;
239 }
240 case LUA_GCSTEP: {
241 lua_pushboolean(L, res);
242 return 1;
243 }
244 default: {
245 lua_pushnumber(L, res);
246 return 1;
247 }
248 }
249 }
250
251
252 static int luaB_type (lua_State *L) {
253 luaL_checkany(L, 1);
254 lua_pushstring(L, luaL_typename(L, 1));
255 return 1;
256 }
257
258
259 static int luaB_next (lua_State *L) {
260 luaL_checktype(L, 1, LUA_TTABLE);
261 lua_settop(L, 2);
262 if (lua_next(L, 1))
263 return 2;
264 else {
265 lua_pushnil(L);
266 return 1;
267 }
268 }
269
270
271 static int luaB_pairs (lua_State *L) {
272 luaL_checktype(L, 1, LUA_TTABLE);
273 lua_pushvalue(L, lua_upvalueindex(1));
274 lua_pushvalue(L, 1);
275 lua_pushnil(L);
276 return 3;
277 }
278
279
280 static int ipairsaux (lua_State *L) {
281 int i = luaL_checkint(L, 2);
282 luaL_checktype(L, 1, LUA_TTABLE);
283 i++;
284 lua_pushinteger(L, i);
285 lua_rawgeti(L, 1, i);
286 return (lua_isnil(L, -1)) ? 0 : 2;
287 }
288
289
290 static int luaB_ipairs (lua_State *L) {
291 luaL_checktype(L, 1, LUA_TTABLE);
292 lua_pushvalue(L, lua_upvalueindex(1));
293 lua_pushvalue(L, 1);
294 lua_pushinteger(L, 0);
295 return 3;
296 }
297
298
299 static int load_aux (lua_State *L, int status) {
300 if (status == 0)
301 return 1;
302 else {
303 lua_pushnil(L);
304 lua_insert(L, -2);
305 return 2;
306 }
307 }
308
309
310 static int luaB_loadstring (lua_State *L) {
311 size_t l;
312 const char *s = luaL_checklstring(L, 1, &l);
313 const char *chunkname = luaL_optstring(L, 2, s);
314 return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
315 }
316
317
318 static int luaB_loadfile (lua_State *L) {
319 const char *fname = luaL_optstring(L, 1, NULL);
320 return load_aux(L, luaL_loadfile(L, fname));
321 }
322
323
324
325
326
327
328
329
330 static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
331 (void)ud;
332 luaL_checkstack(L, 2, "too many nested functions");
333 lua_pushvalue(L, 1);
334 lua_call(L, 0, 1);
335 if (lua_isnil(L, -1)) {
336 *size = 0;
337 return NULL;
338 }
339 else if (lua_isstring(L, -1)) {
340 lua_replace(L, 3);
341 return lua_tolstring(L, 3, size);
342 }
343 else luaL_error(L, "reader function must return a string");
344 return NULL;
345 }
346
347
348 static int luaB_load (lua_State *L) {
349 int status;
350 const char *cname = luaL_optstring(L, 2, "=(load)");
351 luaL_checktype(L, 1, LUA_TFUNCTION);
352 lua_settop(L, 3);
353 status = lua_load(L, generic_reader, NULL, cname);
354 return load_aux(L, status);
355 }
356
357
358 static int luaB_dofile (lua_State *L) {
359 const char *fname = luaL_optstring(L, 1, NULL);
360 int n = lua_gettop(L);
361 if (luaL_loadfile(L, fname) != 0) lua_error(L);
362 lua_call(L, 0, LUA_MULTRET);
363 return lua_gettop(L) - n;
364 }
365
366
367 static int luaB_assert (lua_State *L) {
368 luaL_checkany(L, 1);
369 if (!lua_toboolean(L, 1))
370 return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
371 return lua_gettop(L);
372 }
373
374
375 static int luaB_unpack (lua_State *L) {
376 int i, e, n;
377 luaL_checktype(L, 1, LUA_TTABLE);
378 i = luaL_optint(L, 2, 1);
379 e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
380 if (i > e) return 0;
381 n = e - i + 1;
382 if (n <= 0 || !lua_checkstack(L, n))
383 return luaL_error(L, "too many results to unpack");
384 lua_rawgeti(L, 1, i);
385 while (i++ < e)
386 lua_rawgeti(L, 1, i);
387 return n;
388 }
389
390
391 static int luaB_select (lua_State *L) {
392 int n = lua_gettop(L);
393 if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
394 lua_pushinteger(L, n-1);
395 return 1;
396 }
397 else {
398 int i = luaL_checkint(L, 1);
399 if (i < 0) i = n + i;
400 else if (i > n) i = n;
401 luaL_argcheck(L, 1 <= i, 1, "index out of range");
402 return n - i;
403 }
404 }
405
406
407 static int luaB_pcall (lua_State *L) {
408 int status;
409 luaL_checkany(L, 1);
410 status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
411 lua_pushboolean(L, (status == 0));
412 lua_insert(L, 1);
413 return lua_gettop(L);
414 }
415
416
417 static int luaB_xpcall (lua_State *L) {
418 int status;
419 luaL_checkany(L, 2);
420 lua_settop(L, 2);
421 lua_insert(L, 1);
422 status = lua_pcall(L, 0, LUA_MULTRET, 1);
423 lua_pushboolean(L, (status == 0));
424 lua_replace(L, 1);
425 return lua_gettop(L);
426 }
427
428
429 static int luaB_tostring (lua_State *L) {
430 luaL_checkany(L, 1);
431 if (luaL_callmeta(L, 1, "__tostring"))
432 return 1;
433 switch (lua_type(L, 1)) {
434 case LUA_TNUMBER:
435 lua_pushstring(L, lua_tostring(L, 1));
436 break;
437 case LUA_TSTRING:
438 lua_pushvalue(L, 1);
439 break;
440 case LUA_TBOOLEAN:
441 lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
442 break;
443 case LUA_TNIL:
444 lua_pushliteral(L, "nil");
445 break;
446 default:
447 lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
448 break;
449 }
450 return 1;
451 }
452
453
454 static int luaB_newproxy (lua_State *L) {
455 lua_settop(L, 1);
456 lua_newuserdata(L, 0);
457 if (lua_toboolean(L, 1) == 0)
458 return 1;
459 else if (lua_isboolean(L, 1)) {
460 lua_newtable(L);
461 lua_pushvalue(L, -1);
462 lua_pushboolean(L, 1);
463 lua_rawset(L, lua_upvalueindex(1));
464 }
465 else {
466 int validproxy = 0;
467 if (lua_getmetatable(L, 1)) {
468 lua_rawget(L, lua_upvalueindex(1));
469 validproxy = lua_toboolean(L, -1);
470 lua_pop(L, 1);
471 }
472 luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
473 lua_getmetatable(L, 1);
474 }
475 lua_setmetatable(L, 2);
476 return 1;
477 }
478
479
480 static const luaL_Reg base_funcs[] = {
481 {"assert", luaB_assert},
482 {"collectgarbage", luaB_collectgarbage},
483 {"dofile", luaB_dofile},
484 {"error", luaB_error},
485 {"gcinfo", luaB_gcinfo},
486 {"getfenv", luaB_getfenv},
487 {"getmetatable", luaB_getmetatable},
488 {"loadfile", luaB_loadfile},
489 {"load", luaB_load},
490 {"loadstring", luaB_loadstring},
491 {"next", luaB_next},
492 {"pcall", luaB_pcall},
493 {"print", luaB_print},
494 {"rawequal", luaB_rawequal},
495 {"rawget", luaB_rawget},
496 {"rawset", luaB_rawset},
497 {"select", luaB_select},
498 {"setfenv", luaB_setfenv},
499 {"setmetatable", luaB_setmetatable},
500 {"tonumber", luaB_tonumber},
501 {"tostring", luaB_tostring},
502 {"type", luaB_type},
503 {"unpack", luaB_unpack},
504 {"xpcall", luaB_xpcall},
505 {NULL, NULL}
506 };
507
508
509
510
511
512
513
514
515
516
517
518 #ifdef HOST_LUA
519 #define CO_RUN 0
520 #define CO_SUS 1
521 #define CO_NOR 2
522 #define CO_DEAD 3
523
524 static const char *const statnames[] =
525 {"running", "suspended", "normal", "dead"};
526
527 static int costatus (lua_State *L, lua_State *co) {
528 if (L == co) return CO_RUN;
529 switch (lua_status(co)) {
530 case LUA_YIELD:
531 return CO_SUS;
532 case 0: {
533 lua_Debug ar;
534 if (lua_getstack(co, 0, &ar) > 0)
535 return CO_NOR;
536 else if (lua_gettop(co) == 0)
537 return CO_DEAD;
538 else
539 return CO_SUS;
540 }
541 default:
542 return CO_DEAD;
543 }
544 }
545
546
547 static int luaB_costatus (lua_State *L) {
548 lua_State *co = lua_tothread(L, 1);
549 luaL_argcheck(L, co, 1, "coroutine expected");
550 lua_pushstring(L, statnames[costatus(L, co)]);
551 return 1;
552 }
553
554
555 static int auxresume (lua_State *L, lua_State *co, int narg) {
556 int status = costatus(L, co);
557 if (!lua_checkstack(co, narg))
558 luaL_error(L, "too many arguments to resume");
559 if (status != CO_SUS) {
560 lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
561 return -1;
562 }
563 lua_xmove(L, co, narg);
564 lua_setlevel(L, co);
565 status = lua_resume(co, narg);
566 if (status == 0 || status == LUA_YIELD) {
567 int nres = lua_gettop(co);
568 if (!lua_checkstack(L, nres + 1))
569 luaL_error(L, "too many results to resume");
570 lua_xmove(co, L, nres);
571 return nres;
572 }
573 else {
574 lua_xmove(co, L, 1);
575 return -1;
576 }
577 }
578
579
580 static int luaB_coresume (lua_State *L) {
581 lua_State *co = lua_tothread(L, 1);
582 int r;
583 luaL_argcheck(L, co, 1, "coroutine expected");
584 r = auxresume(L, co, lua_gettop(L) - 1);
585 if (r < 0) {
586 lua_pushboolean(L, 0);
587 lua_insert(L, -2);
588 return 2;
589 }
590 else {
591 lua_pushboolean(L, 1);
592 lua_insert(L, -(r + 1));
593 return r + 1;
594 }
595 }
596
597
598 static int luaB_auxwrap (lua_State *L) {
599 lua_State *co = lua_tothread(L, lua_upvalueindex(1));
600 int r = auxresume(L, co, lua_gettop(L));
601 if (r < 0) {
602 if (lua_isstring(L, -1)) {
603 luaL_where(L, 1);
604 lua_insert(L, -2);
605 lua_concat(L, 2);
606 }
607 lua_error(L);
608 }
609 return r;
610 }
611
612
613 static int luaB_cocreate (lua_State *L) {
614 lua_State *NL = lua_newthread(L);
615 luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
616 "Lua function expected");
617 lua_pushvalue(L, 1);
618 lua_xmove(L, NL, 1);
619 return 1;
620 }
621
622
623 static int luaB_cowrap (lua_State *L) {
624 luaB_cocreate(L);
625 lua_pushcclosure(L, luaB_auxwrap, 1);
626 return 1;
627 }
628
629
630 static int luaB_yield (lua_State *L) {
631 return lua_yield(L, lua_gettop(L));
632 }
633
634
635 static int luaB_corunning (lua_State *L) {
636 if (lua_pushthread(L))
637 lua_pushnil(L);
638 return 1;
639 }
640
641
642 static const luaL_Reg co_funcs[] = {
643 {"create", luaB_cocreate},
644 {"resume", luaB_coresume},
645 {"running", luaB_corunning},
646 {"status", luaB_costatus},
647 {"wrap", luaB_cowrap},
648 {"yield", luaB_yield},
649 {NULL, NULL}
650 };
651
652
653 #endif
654
655 static void auxopen (lua_State *L, const char *name,
656 lua_CFunction f, lua_CFunction u) {
657 lua_pushcfunction(L, u);
658 lua_pushcclosure(L, f, 1);
659 lua_setfield(L, -2, name);
660 }
661
662
663 static void base_open (lua_State *L) {
664
665 lua_pushvalue(L, LUA_GLOBALSINDEX);
666 lua_setglobal(L, "_G");
667
668 luaL_register(L, "_G", base_funcs);
669 lua_pushliteral(L, LUA_VERSION);
670 lua_setglobal(L, "_VERSION");
671
672 auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
673 auxopen(L, "pairs", luaB_pairs, luaB_next);
674
675 lua_createtable(L, 0, 1);
676 lua_pushvalue(L, -1);
677 lua_setmetatable(L, -2);
678 lua_pushliteral(L, "kv");
679 lua_setfield(L, -2, "__mode");
680 lua_pushcclosure(L, luaB_newproxy, 1);
681 lua_setglobal(L, "newproxy");
682 }
683
684
685 LUALIB_API int luaopen_base (lua_State *L) {
686 base_open(L);
687
688 #ifdef HOST_LUA
689 luaL_register(L, LUA_COLIBNAME, co_funcs);
690 #endif
691 return 2;
692 }
693