00001
00002
00003
00004
00005
00006
00007
00008 #include <errno.h>
00009 #include <stdarg.h>
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013
00014
00015
00016
00017
00018
00019 #define lauxlib_c
00020 #define LUA_LIB
00021
00022 #include "lua.h"
00023
00024 #include "lauxlib.h"
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #define LEVELS1 12
00035 #define LEVELS2 10
00036
00037
00038
00039
00040
00041
00042
00043 static int findfield (lua_State *L, int objidx, int level) {
00044 if (level == 0 || !lua_istable(L, -1))
00045 return 0;
00046 lua_pushnil(L);
00047 while (lua_next(L, -2)) {
00048 if (lua_type(L, -2) == LUA_TSTRING) {
00049 if (lua_rawequal(L, objidx, -1)) {
00050 lua_pop(L, 1);
00051 return 1;
00052 }
00053 else if (findfield(L, objidx, level - 1)) {
00054 lua_remove(L, -2);
00055 lua_pushliteral(L, ".");
00056 lua_insert(L, -2);
00057 lua_concat(L, 3);
00058 return 1;
00059 }
00060 }
00061 lua_pop(L, 1);
00062 }
00063 return 0;
00064 }
00065
00066
00067 static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
00068 int top = lua_gettop(L);
00069 lua_getinfo(L, "f", ar);
00070 lua_pushglobaltable(L);
00071 if (findfield(L, top + 1, 2)) {
00072 lua_copy(L, -1, top + 1);
00073 lua_pop(L, 2);
00074 return 1;
00075 }
00076 else {
00077 lua_settop(L, top);
00078 return 0;
00079 }
00080 }
00081
00082
00083 static void pushfuncname (lua_State *L, lua_Debug *ar) {
00084 if (*ar->namewhat != '\0')
00085 lua_pushfstring(L, "function " LUA_QS, ar->name);
00086 else if (*ar->what == 'm')
00087 lua_pushfstring(L, "main chunk");
00088 else if (*ar->what == 'C') {
00089 if (pushglobalfuncname(L, ar)) {
00090 lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
00091 lua_remove(L, -2);
00092 }
00093 else
00094 lua_pushliteral(L, "?");
00095 }
00096 else
00097 lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
00098 }
00099
00100
00101 static int countlevels (lua_State *L) {
00102 lua_Debug ar;
00103 int li = 1, le = 1;
00104
00105 while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
00106
00107 while (li < le) {
00108 int m = (li + le)/2;
00109 if (lua_getstack(L, m, &ar)) li = m + 1;
00110 else le = m;
00111 }
00112 return le - 1;
00113 }
00114
00115
00116 LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
00117 const char *msg, int level) {
00118 lua_Debug ar;
00119 int top = lua_gettop(L);
00120 int numlevels = countlevels(L1);
00121 int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0;
00122 if (msg) lua_pushfstring(L, "%s\n", msg);
00123 lua_pushliteral(L, "stack traceback:");
00124 while (lua_getstack(L1, level++, &ar)) {
00125 if (level == mark) {
00126 lua_pushliteral(L, "\n\t...");
00127 level = numlevels - LEVELS2;
00128 }
00129 else {
00130 lua_getinfo(L1, "Slnt", &ar);
00131 lua_pushfstring(L, "\n\t%s:", ar.short_src);
00132 if (ar.currentline > 0)
00133 lua_pushfstring(L, "%d:", ar.currentline);
00134 lua_pushliteral(L, " in ");
00135 pushfuncname(L, &ar);
00136 if (ar.istailcall)
00137 lua_pushliteral(L, "\n\t(...tail calls...)");
00138 lua_concat(L, lua_gettop(L) - top);
00139 }
00140 }
00141 lua_concat(L, lua_gettop(L) - top);
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
00154 lua_Debug ar;
00155 if (!lua_getstack(L, 0, &ar))
00156 return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
00157 lua_getinfo(L, "n", &ar);
00158 if (strcmp(ar.namewhat, "method") == 0) {
00159 narg--;
00160 if (narg == 0)
00161 return luaL_error(L, "calling " LUA_QS " on bad self", ar.name);
00162 }
00163 if (ar.name == NULL)
00164 ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
00165 return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
00166 narg, ar.name, extramsg);
00167 }
00168
00169
00170 static int typeerror (lua_State *L, int narg, const char *tname) {
00171 const char *msg = lua_pushfstring(L, "%s expected, got %s",
00172 tname, luaL_typename(L, narg));
00173 return luaL_argerror(L, narg, msg);
00174 }
00175
00176 LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
00177 return typeerror(L, narg, tname);
00178 }
00179
00180 static void tag_error (lua_State *L, int narg, int tag) {
00181 typeerror(L, narg, lua_typename(L, tag));
00182 }
00183
00184
00185 LUALIB_API void luaL_where (lua_State *L, int level) {
00186 lua_Debug ar;
00187 if (lua_getstack(L, level, &ar)) {
00188 lua_getinfo(L, "Sl", &ar);
00189 if (ar.currentline > 0) {
00190 lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
00191 return;
00192 }
00193 }
00194 lua_pushliteral(L, "");
00195 }
00196
00197
00198 LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
00199 va_list argp;
00200 va_start(argp, fmt);
00201 luaL_where(L, 1);
00202 lua_pushvfstring(L, fmt, argp);
00203 va_end(argp);
00204 lua_concat(L, 2);
00205 return lua_error(L);
00206 }
00207
00208
00209 LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
00210 int en = errno;
00211 if (stat) {
00212 lua_pushboolean(L, 1);
00213 return 1;
00214 }
00215 else {
00216 lua_pushnil(L);
00217 if (fname)
00218 lua_pushfstring(L, "%s: %s", fname, strerror(en));
00219 else
00220 lua_pushfstring(L, "%s", strerror(en));
00221 lua_pushinteger(L, en);
00222 return 3;
00223 }
00224 }
00225
00226
00227 #if !defined(inspectstat)
00228
00229 #if defined(LUA_USE_POSIX)
00230
00231 #include <sys/wait.h>
00232
00233
00234
00235
00236 #define inspectstat(stat,what) \
00237 if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
00238 else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
00239
00240 #else
00241
00242 #define inspectstat(stat,what)
00243
00244 #endif
00245
00246 #endif
00247
00248
00249 LUALIB_API int luaL_execresult (lua_State *L, int stat) {
00250 const char *what = "exit";
00251 if (stat == -1)
00252 return luaL_fileresult(L, 0, NULL);
00253 else {
00254 inspectstat(stat, what);
00255 if (*what == 'e' && stat == 0)
00256 lua_pushboolean(L, 1);
00257 else
00258 lua_pushnil(L);
00259 lua_pushstring(L, what);
00260 lua_pushinteger(L, stat);
00261 return 3;
00262 }
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
00275 luaL_getmetatable(L, tname);
00276 if (!lua_isnil(L, -1))
00277 return 0;
00278 lua_pop(L, 1);
00279 lua_newtable(L);
00280 lua_pushvalue(L, -1);
00281 lua_setfield(L, LUA_REGISTRYINDEX, tname);
00282 return 1;
00283 }
00284
00285
00286 LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) {
00287 luaL_getmetatable(L, tname);
00288 lua_setmetatable(L, -2);
00289 }
00290
00291
00292 LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
00293 void *p = lua_touserdata(L, ud);
00294 if (p != NULL) {
00295 if (lua_getmetatable(L, ud)) {
00296 luaL_getmetatable(L, tname);
00297 if (!lua_rawequal(L, -1, -2))
00298 p = NULL;
00299 lua_pop(L, 2);
00300 return p;
00301 }
00302 }
00303 return NULL;
00304 }
00305
00306
00307 LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
00308 void *p = luaL_testudata(L, ud, tname);
00309 if (p == NULL) typeerror(L, ud, tname);
00310 return p;
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
00323 const char *const lst[]) {
00324 const char *name = (def) ? luaL_optstring(L, narg, def) :
00325 luaL_checkstring(L, narg);
00326 int i;
00327 for (i=0; lst[i]; i++)
00328 if (strcmp(lst[i], name) == 0)
00329 return i;
00330 return luaL_argerror(L, narg,
00331 lua_pushfstring(L, "invalid option " LUA_QS, name));
00332 }
00333
00334
00335 LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
00336
00337 const int extra = LUA_MINSTACK;
00338 if (!lua_checkstack(L, space + extra)) {
00339 if (msg)
00340 luaL_error(L, "stack overflow (%s)", msg);
00341 else
00342 luaL_error(L, "stack overflow");
00343 }
00344 }
00345
00346
00347 LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
00348 if (lua_type(L, narg) != t)
00349 tag_error(L, narg, t);
00350 }
00351
00352
00353 LUALIB_API void luaL_checkany (lua_State *L, int narg) {
00354 if (lua_type(L, narg) == LUA_TNONE)
00355 luaL_argerror(L, narg, "value expected");
00356 }
00357
00358
00359 LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
00360 const char *s = lua_tolstring(L, narg, len);
00361 if (!s) tag_error(L, narg, LUA_TSTRING);
00362 return s;
00363 }
00364
00365
00366 LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
00367 const char *def, size_t *len) {
00368 if (lua_isnoneornil(L, narg)) {
00369 if (len)
00370 *len = (def ? strlen(def) : 0);
00371 return def;
00372 }
00373 else return luaL_checklstring(L, narg, len);
00374 }
00375
00376
00377 LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
00378 int isnum;
00379 lua_Number d = lua_tonumberx(L, narg, &isnum);
00380 if (!isnum)
00381 tag_error(L, narg, LUA_TNUMBER);
00382 return d;
00383 }
00384
00385
00386 LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
00387 return luaL_opt(L, luaL_checknumber, narg, def);
00388 }
00389
00390
00391 LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
00392 int isnum;
00393 lua_Integer d = lua_tointegerx(L, narg, &isnum);
00394 if (!isnum)
00395 tag_error(L, narg, LUA_TNUMBER);
00396 return d;
00397 }
00398
00399
00400 LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) {
00401 int isnum;
00402 lua_Unsigned d = lua_tounsignedx(L, narg, &isnum);
00403 if (!isnum)
00404 tag_error(L, narg, LUA_TNUMBER);
00405 return d;
00406 }
00407
00408
00409 LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
00410 lua_Integer def) {
00411 return luaL_opt(L, luaL_checkinteger, narg, def);
00412 }
00413
00414
00415 LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg,
00416 lua_Unsigned def) {
00417 return luaL_opt(L, luaL_checkunsigned, narg, def);
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433 #define buffonstack(B) ((B)->b != (B)->initb)
00434
00435
00436
00437
00438
00439 LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
00440 lua_State *L = B->L;
00441 if (B->size - B->n < sz) {
00442 char *newbuff;
00443 size_t newsize = B->size * 2;
00444 if (newsize - B->n < sz)
00445 newsize = B->n + sz;
00446 if (newsize < B->n || newsize - B->n < sz)
00447 luaL_error(L, "buffer too large");
00448
00449 newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char));
00450
00451 memcpy(newbuff, B->b, B->n * sizeof(char));
00452 if (buffonstack(B))
00453 lua_remove(L, -2);
00454 B->b = newbuff;
00455 B->size = newsize;
00456 }
00457 return &B->b[B->n];
00458 }
00459
00460
00461 LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
00462 char *b = luaL_prepbuffsize(B, l);
00463 memcpy(b, s, l * sizeof(char));
00464 luaL_addsize(B, l);
00465 }
00466
00467
00468 LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
00469 luaL_addlstring(B, s, strlen(s));
00470 }
00471
00472
00473 LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
00474 lua_State *L = B->L;
00475 lua_pushlstring(L, B->b, B->n);
00476 if (buffonstack(B))
00477 lua_remove(L, -2);
00478 }
00479
00480
00481 LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
00482 luaL_addsize(B, sz);
00483 luaL_pushresult(B);
00484 }
00485
00486
00487 LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
00488 lua_State *L = B->L;
00489 size_t l;
00490 const char *s = lua_tolstring(L, -1, &l);
00491 if (buffonstack(B))
00492 lua_insert(L, -2);
00493 luaL_addlstring(B, s, l);
00494 lua_remove(L, (buffonstack(B)) ? -2 : -1);
00495 }
00496
00497
00498 LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
00499 B->L = L;
00500 B->b = B->initb;
00501 B->n = 0;
00502 B->size = LUAL_BUFFERSIZE;
00503 }
00504
00505
00506 LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
00507 luaL_buffinit(L, B);
00508 return luaL_prepbuffsize(B, sz);
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 #define freelist 0
00522
00523
00524 LUALIB_API int luaL_ref (lua_State *L, int t) {
00525 int ref;
00526 t = lua_absindex(L, t);
00527 if (lua_isnil(L, -1)) {
00528 lua_pop(L, 1);
00529 return LUA_REFNIL;
00530 }
00531 lua_rawgeti(L, t, freelist);
00532 ref = (int)lua_tointeger(L, -1);
00533 lua_pop(L, 1);
00534 if (ref != 0) {
00535 lua_rawgeti(L, t, ref);
00536 lua_rawseti(L, t, freelist);
00537 }
00538 else
00539 ref = (int)lua_rawlen(L, t) + 1;
00540 lua_rawseti(L, t, ref);
00541 return ref;
00542 }
00543
00544
00545 LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
00546 if (ref >= 0) {
00547 t = lua_absindex(L, t);
00548 lua_rawgeti(L, t, freelist);
00549 lua_rawseti(L, t, ref);
00550 lua_pushinteger(L, ref);
00551 lua_rawseti(L, t, freelist);
00552 }
00553 }
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 typedef struct LoadF {
00565 int n;
00566 FILE *f;
00567 char buff[LUAL_BUFFERSIZE];
00568 } LoadF;
00569
00570
00571 static const char *getF (lua_State *L, void *ud, size_t *size) {
00572 LoadF *lf = (LoadF *)ud;
00573 (void)L;
00574 if (lf->n > 0) {
00575 *size = lf->n;
00576 lf->n = 0;
00577 }
00578 else {
00579
00580
00581
00582 if (feof(lf->f)) return NULL;
00583 *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
00584 }
00585 return lf->buff;
00586 }
00587
00588
00589 static int errfile (lua_State *L, const char *what, int fnameindex) {
00590 const char *serr = strerror(errno);
00591 const char *filename = lua_tostring(L, fnameindex) + 1;
00592 lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
00593 lua_remove(L, fnameindex);
00594 return LUA_ERRFILE;
00595 }
00596
00597
00598 static int skipBOM (LoadF *lf) {
00599 const char *p = "\xEF\xBB\xBF";
00600 int c;
00601 lf->n = 0;
00602 do {
00603 c = getc(lf->f);
00604 if (c == EOF || c != *(unsigned char *)p++) return c;
00605 lf->buff[lf->n++] = c;
00606 } while (*p != '\0');
00607 lf->n = 0;
00608 return getc(lf->f);
00609 }
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619 static int skipcomment (LoadF *lf, int *cp) {
00620 int c = *cp = skipBOM(lf);
00621 if (c == '#') {
00622 while ((c = getc(lf->f)) != EOF && c != '\n') ;
00623 *cp = getc(lf->f);
00624 return 1;
00625 }
00626 else return 0;
00627 }
00628
00629
00630 LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
00631 const char *mode) {
00632 LoadF lf;
00633 int status, readstatus;
00634 int c;
00635 int fnameindex = lua_gettop(L) + 1;
00636 if (filename == NULL) {
00637 lua_pushliteral(L, "=stdin");
00638 lf.f = stdin;
00639 }
00640 else {
00641 lua_pushfstring(L, "@%s", filename);
00642 lf.f = fopen(filename, "r");
00643 if (lf.f == NULL) return errfile(L, "open", fnameindex);
00644 }
00645 if (skipcomment(&lf, &c))
00646 lf.buff[lf.n++] = '\n';
00647 if (c == LUA_SIGNATURE[0] && filename) {
00648 lf.f = freopen(filename, "rb", lf.f);
00649 if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
00650 skipcomment(&lf, &c);
00651 }
00652 if (c != EOF)
00653 lf.buff[lf.n++] = c;
00654 status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
00655 readstatus = ferror(lf.f);
00656 if (filename) fclose(lf.f);
00657 if (readstatus) {
00658 lua_settop(L, fnameindex);
00659 return errfile(L, "read", fnameindex);
00660 }
00661 lua_remove(L, fnameindex);
00662 return status;
00663 }
00664
00665
00666 typedef struct LoadS {
00667 const char *s;
00668 size_t size;
00669 } LoadS;
00670
00671
00672 static const char *getS (lua_State *L, void *ud, size_t *size) {
00673 LoadS *ls = (LoadS *)ud;
00674 (void)L;
00675 if (ls->size == 0) return NULL;
00676 *size = ls->size;
00677 ls->size = 0;
00678 return ls->s;
00679 }
00680
00681
00682 LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
00683 const char *name, const char *mode) {
00684 LoadS ls;
00685 ls.s = buff;
00686 ls.size = size;
00687 return lua_load(L, getS, &ls, name, mode);
00688 }
00689
00690
00691 LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
00692 return luaL_loadbuffer(L, s, strlen(s), s);
00693 }
00694
00695
00696
00697
00698
00699 LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
00700 if (!lua_getmetatable(L, obj))
00701 return 0;
00702 lua_pushstring(L, event);
00703 lua_rawget(L, -2);
00704 if (lua_isnil(L, -1)) {
00705 lua_pop(L, 2);
00706 return 0;
00707 }
00708 else {
00709 lua_remove(L, -2);
00710 return 1;
00711 }
00712 }
00713
00714
00715 LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
00716 obj = lua_absindex(L, obj);
00717 if (!luaL_getmetafield(L, obj, event))
00718 return 0;
00719 lua_pushvalue(L, obj);
00720 lua_call(L, 1, 1);
00721 return 1;
00722 }
00723
00724
00725 LUALIB_API int luaL_len (lua_State *L, int idx) {
00726 int l;
00727 int isnum;
00728 lua_len(L, idx);
00729 l = (int)lua_tointegerx(L, -1, &isnum);
00730 if (!isnum)
00731 luaL_error(L, "object length is not a number");
00732 lua_pop(L, 1);
00733 return l;
00734 }
00735
00736
00737 LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
00738 if (!luaL_callmeta(L, idx, "__tostring")) {
00739 switch (lua_type(L, idx)) {
00740 case LUA_TNUMBER:
00741 case LUA_TSTRING:
00742 lua_pushvalue(L, idx);
00743 break;
00744 case LUA_TBOOLEAN:
00745 lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false"));
00746 break;
00747 case LUA_TNIL:
00748 lua_pushliteral(L, "nil");
00749 break;
00750 default:
00751 lua_pushfstring(L, "%s: %p", luaL_typename(L, idx),
00752 lua_topointer(L, idx));
00753 break;
00754 }
00755 }
00756 return lua_tolstring(L, -1, len);
00757 }
00758
00759
00760
00761
00762
00763
00764
00765 #if defined(LUA_COMPAT_MODULE)
00766
00767 static const char *luaL_findtable (lua_State *L, int idx,
00768 const char *fname, int szhint) {
00769 const char *e;
00770 if (idx) lua_pushvalue(L, idx);
00771 do {
00772 e = strchr(fname, '.');
00773 if (e == NULL) e = fname + strlen(fname);
00774 lua_pushlstring(L, fname, e - fname);
00775 lua_rawget(L, -2);
00776 if (lua_isnil(L, -1)) {
00777 lua_pop(L, 1);
00778 lua_createtable(L, 0, (*e == '.' ? 1 : szhint));
00779 lua_pushlstring(L, fname, e - fname);
00780 lua_pushvalue(L, -2);
00781 lua_settable(L, -4);
00782 }
00783 else if (!lua_istable(L, -1)) {
00784 lua_pop(L, 2);
00785 return fname;
00786 }
00787 lua_remove(L, -2);
00788 fname = e + 1;
00789 } while (*e == '.');
00790 return NULL;
00791 }
00792
00793
00794
00795
00796
00797 static int libsize (const luaL_Reg *l) {
00798 int size = 0;
00799 for (; l && l->name; l++) size++;
00800 return size;
00801 }
00802
00803
00804
00805
00806
00807
00808
00809
00810 LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
00811 int sizehint) {
00812 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);
00813 lua_getfield(L, -1, modname);
00814 if (!lua_istable(L, -1)) {
00815 lua_pop(L, 1);
00816
00817 lua_pushglobaltable(L);
00818 if (luaL_findtable(L, 0, modname, sizehint) != NULL)
00819 luaL_error(L, "name conflict for module " LUA_QS, modname);
00820 lua_pushvalue(L, -1);
00821 lua_setfield(L, -3, modname);
00822 }
00823 lua_remove(L, -2);
00824 }
00825
00826
00827 LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
00828 const luaL_Reg *l, int nup) {
00829 luaL_checkversion(L);
00830 if (libname) {
00831 luaL_pushmodule(L, libname, libsize(l));
00832 lua_insert(L, -(nup + 1));
00833 }
00834 if (l)
00835 luaL_setfuncs(L, l, nup);
00836 else
00837 lua_pop(L, nup);
00838 }
00839
00840 #endif
00841
00842
00843
00844
00845
00846
00847
00848 LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
00849 luaL_checkstack(L, nup, "too many upvalues");
00850 for (; l->name != NULL; l++) {
00851 int i;
00852 for (i = 0; i < nup; i++)
00853 lua_pushvalue(L, -nup);
00854 lua_pushcclosure(L, l->func, nup);
00855 lua_setfield(L, -(nup + 2), l->name);
00856 }
00857 lua_pop(L, nup);
00858 }
00859
00860
00861
00862
00863
00864
00865 LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
00866 lua_getfield(L, idx, fname);
00867 if (lua_istable(L, -1)) return 1;
00868 else {
00869 idx = lua_absindex(L, idx);
00870 lua_pop(L, 1);
00871 lua_newtable(L);
00872 lua_pushvalue(L, -1);
00873 lua_setfield(L, idx, fname);
00874 return 0;
00875 }
00876 }
00877
00878
00879
00880
00881
00882
00883
00884
00885 LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
00886 lua_CFunction openf, int glb) {
00887 lua_pushcfunction(L, openf);
00888 lua_pushstring(L, modname);
00889 lua_call(L, 1, 1);
00890 luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
00891 lua_pushvalue(L, -2);
00892 lua_setfield(L, -2, modname);
00893 lua_pop(L, 1);
00894 if (glb) {
00895 lua_pushglobaltable(L);
00896 lua_pushvalue(L, -2);
00897 lua_setfield(L, -2, modname);
00898 lua_pop(L, 1);
00899 }
00900 }
00901
00902
00903 LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
00904 const char *r) {
00905 const char *wild;
00906 size_t l = strlen(p);
00907 luaL_Buffer b;
00908 luaL_buffinit(L, &b);
00909 while ((wild = strstr(s, p)) != NULL) {
00910 luaL_addlstring(&b, s, wild - s);
00911 luaL_addstring(&b, r);
00912 s = wild + l;
00913 }
00914 luaL_addstring(&b, s);
00915 luaL_pushresult(&b);
00916 return lua_tostring(L, -1);
00917 }
00918
00919
00920 static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
00921 (void)ud; (void)osize;
00922 if (nsize == 0) {
00923 free(ptr);
00924 return NULL;
00925 }
00926 else
00927 return realloc(ptr, nsize);
00928 }
00929
00930
00931 static int panic (lua_State *L) {
00932 luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
00933 lua_tostring(L, -1));
00934 return 0;
00935 }
00936
00937
00938 LUALIB_API lua_State *luaL_newstate (void) {
00939 lua_State *L = lua_newstate(l_alloc, NULL);
00940 if (L) lua_atpanic(L, &panic);
00941 return L;
00942 }
00943
00944
00945 LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) {
00946 const lua_Number *v = lua_version(L);
00947 if (v != lua_version(NULL))
00948 luaL_error(L, "multiple Lua VMs detected");
00949 else if (*v != ver)
00950 luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
00951 ver, *v);
00952
00953 lua_pushnumber(L, -(lua_Number)0x1234);
00954 if (lua_tointeger(L, -1) != -0x1234 ||
00955 lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234)
00956 luaL_error(L, "bad conversion number->int;"
00957 " must recompile Lua with proper settings");
00958 lua_pop(L, 1);
00959 }
00960