00001
00002
00003
00004
00005
00006
00007
00008 #include <ctype.h>
00009 #include <errno.h>
00010 #include <stdarg.h>
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <string.h>
00014
00015
00016
00017
00018
00019
00020 #define lauxlib_c
00021 #define LUA_LIB
00022
00023 #include "lua.h"
00024
00025 #include "lauxlib.h"
00026
00027
00028 #define FREELIST_REF 0
00029
00030
00031
00032 #define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
00033 lua_gettop(L) + (i) + 1)
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
00044 lua_Debug ar;
00045 if (!lua_getstack(L, 0, &ar))
00046 return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
00047 lua_getinfo(L, "n", &ar);
00048 if (strcmp(ar.namewhat, "method") == 0) {
00049 narg--;
00050 if (narg == 0)
00051 return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
00052 ar.name, extramsg);
00053 }
00054 if (ar.name == NULL)
00055 ar.name = "?";
00056 return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
00057 narg, ar.name, extramsg);
00058 }
00059
00060
00061 LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
00062 const char *msg = lua_pushfstring(L, "%s expected, got %s",
00063 tname, luaL_typename(L, narg));
00064 return luaL_argerror(L, narg, msg);
00065 }
00066
00067
00068 static void tag_error (lua_State *L, int narg, int tag) {
00069 luaL_typerror(L, narg, lua_typename(L, tag));
00070 }
00071
00072
00073 LUALIB_API void luaL_where (lua_State *L, int level) {
00074 lua_Debug ar;
00075 if (lua_getstack(L, level, &ar)) {
00076 lua_getinfo(L, "Sl", &ar);
00077 if (ar.currentline > 0) {
00078 lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
00079 return;
00080 }
00081 }
00082 lua_pushliteral(L, "");
00083 }
00084
00085
00086 LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
00087 va_list argp;
00088 va_start(argp, fmt);
00089 luaL_where(L, 1);
00090 lua_pushvfstring(L, fmt, argp);
00091 va_end(argp);
00092 lua_concat(L, 2);
00093 return lua_error(L);
00094 }
00095
00096
00097
00098
00099 LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
00100 const char *const lst[]) {
00101 const char *name = (def) ? luaL_optstring(L, narg, def) :
00102 luaL_checkstring(L, narg);
00103 int i;
00104 for (i=0; lst[i]; i++)
00105 if (strcmp(lst[i], name) == 0)
00106 return i;
00107 return luaL_argerror(L, narg,
00108 lua_pushfstring(L, "invalid option " LUA_QS, name));
00109 }
00110
00111
00112 LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
00113 lua_getfield(L, LUA_REGISTRYINDEX, tname);
00114 if (!lua_isnil(L, -1))
00115 return 0;
00116 lua_pop(L, 1);
00117 lua_newtable(L);
00118 lua_pushvalue(L, -1);
00119 lua_setfield(L, LUA_REGISTRYINDEX, tname);
00120 return 1;
00121 }
00122
00123
00124 LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
00125 void *p = lua_touserdata(L, ud);
00126 if (p != NULL) {
00127 if (lua_getmetatable(L, ud)) {
00128 lua_getfield(L, LUA_REGISTRYINDEX, tname);
00129 if (lua_rawequal(L, -1, -2)) {
00130 lua_pop(L, 2);
00131 return p;
00132 }
00133 }
00134 }
00135 luaL_typerror(L, ud, tname);
00136 return NULL;
00137 }
00138
00139
00140 LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
00141 if (!lua_checkstack(L, space))
00142 luaL_error(L, "stack overflow (%s)", mes);
00143 }
00144
00145
00146 LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
00147 if (lua_type(L, narg) != t)
00148 tag_error(L, narg, t);
00149 }
00150
00151
00152 LUALIB_API void luaL_checkany (lua_State *L, int narg) {
00153 if (lua_type(L, narg) == LUA_TNONE)
00154 luaL_argerror(L, narg, "value expected");
00155 }
00156
00157
00158 LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
00159 const char *s = lua_tolstring(L, narg, len);
00160 if (!s) tag_error(L, narg, LUA_TSTRING);
00161 return s;
00162 }
00163
00164
00165 LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
00166 const char *def, size_t *len) {
00167 if (lua_isnoneornil(L, narg)) {
00168 if (len)
00169 *len = (def ? strlen(def) : 0);
00170 return def;
00171 }
00172 else return luaL_checklstring(L, narg, len);
00173 }
00174
00175
00176 LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
00177 lua_Number d = lua_tonumber(L, narg);
00178 if (d == 0 && !lua_isnumber(L, narg))
00179 tag_error(L, narg, LUA_TNUMBER);
00180 return d;
00181 }
00182
00183
00184 LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
00185 return luaL_opt(L, luaL_checknumber, narg, def);
00186 }
00187
00188
00189 LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
00190 lua_Integer d = lua_tointeger(L, narg);
00191 if (d == 0 && !lua_isnumber(L, narg))
00192 tag_error(L, narg, LUA_TNUMBER);
00193 return d;
00194 }
00195
00196
00197 LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
00198 lua_Integer def) {
00199 return luaL_opt(L, luaL_checkinteger, narg, def);
00200 }
00201
00202
00203 LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
00204 if (!lua_getmetatable(L, obj))
00205 return 0;
00206 lua_pushstring(L, event);
00207 lua_rawget(L, -2);
00208 if (lua_isnil(L, -1)) {
00209 lua_pop(L, 2);
00210 return 0;
00211 }
00212 else {
00213 lua_remove(L, -2);
00214 return 1;
00215 }
00216 }
00217
00218
00219 LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
00220 obj = abs_index(L, obj);
00221 if (!luaL_getmetafield(L, obj, event))
00222 return 0;
00223 lua_pushvalue(L, obj);
00224 lua_call(L, 1, 1);
00225 return 1;
00226 }
00227
00228
00229 LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
00230 const luaL_Reg *l) {
00231 luaI_openlib(L, libname, l, 0);
00232 }
00233
00234
00235 static int libsize (const luaL_Reg *l) {
00236 int size = 0;
00237 for (; l->name; l++) size++;
00238 return size;
00239 }
00240
00241
00242 LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
00243 const luaL_Reg *l, int nup) {
00244 if (libname) {
00245 int size = libsize(l);
00246
00247 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);
00248 lua_getfield(L, -1, libname);
00249 if (!lua_istable(L, -1)) {
00250 lua_pop(L, 1);
00251
00252 if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
00253 luaL_error(L, "name conflict for module " LUA_QS, libname);
00254 lua_pushvalue(L, -1);
00255 lua_setfield(L, -3, libname);
00256 }
00257 lua_remove(L, -2);
00258 lua_insert(L, -(nup+1));
00259 }
00260 for (; l->name; l++) {
00261 int i;
00262 for (i=0; i<nup; i++)
00263 lua_pushvalue(L, -nup);
00264 lua_pushcclosure(L, l->func, nup);
00265 lua_setfield(L, -(nup+2), l->name);
00266 }
00267 lua_pop(L, nup);
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 #if defined(LUA_COMPAT_GETN)
00279
00280 static int checkint (lua_State *L, int topop) {
00281 int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
00282 lua_pop(L, topop);
00283 return n;
00284 }
00285
00286
00287 static void getsizes (lua_State *L) {
00288 lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
00289 if (lua_isnil(L, -1)) {
00290 lua_pop(L, 1);
00291 lua_newtable(L);
00292 lua_pushvalue(L, -1);
00293 lua_setmetatable(L, -2);
00294 lua_pushliteral(L, "kv");
00295 lua_setfield(L, -2, "__mode");
00296 lua_pushvalue(L, -1);
00297 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
00298 }
00299 }
00300
00301
00302 LUALIB_API void luaL_setn (lua_State *L, int t, int n) {
00303 t = abs_index(L, t);
00304 lua_pushliteral(L, "n");
00305 lua_rawget(L, t);
00306 if (checkint(L, 1) >= 0) {
00307 lua_pushliteral(L, "n");
00308 lua_pushinteger(L, n);
00309 lua_rawset(L, t);
00310 }
00311 else {
00312 getsizes(L);
00313 lua_pushvalue(L, t);
00314 lua_pushinteger(L, n);
00315 lua_rawset(L, -3);
00316 lua_pop(L, 1);
00317 }
00318 }
00319
00320
00321 LUALIB_API int luaL_getn (lua_State *L, int t) {
00322 int n;
00323 t = abs_index(L, t);
00324 lua_pushliteral(L, "n");
00325 lua_rawget(L, t);
00326 if ((n = checkint(L, 1)) >= 0) return n;
00327 getsizes(L);
00328 lua_pushvalue(L, t);
00329 lua_rawget(L, -2);
00330 if ((n = checkint(L, 2)) >= 0) return n;
00331 return (int)lua_objlen(L, t);
00332 }
00333
00334 #endif
00335
00336
00337
00338
00339
00340 LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
00341 const char *r) {
00342 const char *wild;
00343 size_t l = strlen(p);
00344 luaL_Buffer b;
00345 luaL_buffinit(L, &b);
00346 while ((wild = strstr(s, p)) != NULL) {
00347 luaL_addlstring(&b, s, wild - s);
00348 luaL_addstring(&b, r);
00349 s = wild + l;
00350 }
00351 luaL_addstring(&b, s);
00352 luaL_pushresult(&b);
00353 return lua_tostring(L, -1);
00354 }
00355
00356
00357 LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
00358 const char *fname, int szhint) {
00359 const char *e;
00360 lua_pushvalue(L, idx);
00361 do {
00362 e = strchr(fname, '.');
00363 if (e == NULL) e = fname + strlen(fname);
00364 lua_pushlstring(L, fname, e - fname);
00365 lua_rawget(L, -2);
00366 if (lua_isnil(L, -1)) {
00367 lua_pop(L, 1);
00368 lua_createtable(L, 0, (*e == '.' ? 1 : szhint));
00369 lua_pushlstring(L, fname, e - fname);
00370 lua_pushvalue(L, -2);
00371 lua_settable(L, -4);
00372 }
00373 else if (!lua_istable(L, -1)) {
00374 lua_pop(L, 2);
00375 return fname;
00376 }
00377 lua_remove(L, -2);
00378 fname = e + 1;
00379 } while (*e == '.');
00380 return NULL;
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 #define bufflen(B) ((B)->p - (B)->buffer)
00393 #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
00394
00395 #define LIMIT (LUA_MINSTACK/2)
00396
00397
00398 static int emptybuffer (luaL_Buffer *B) {
00399 size_t l = bufflen(B);
00400 if (l == 0) return 0;
00401 else {
00402 lua_pushlstring(B->L, B->buffer, l);
00403 B->p = B->buffer;
00404 B->lvl++;
00405 return 1;
00406 }
00407 }
00408
00409
00410 static void adjuststack (luaL_Buffer *B) {
00411 if (B->lvl > 1) {
00412 lua_State *L = B->L;
00413 int toget = 1;
00414 size_t toplen = lua_strlen(L, -1);
00415 do {
00416 size_t l = lua_strlen(L, -(toget+1));
00417 if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
00418 toplen += l;
00419 toget++;
00420 }
00421 else break;
00422 } while (toget < B->lvl);
00423 lua_concat(L, toget);
00424 B->lvl = B->lvl - toget + 1;
00425 }
00426 }
00427
00428
00429 LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
00430 if (emptybuffer(B))
00431 adjuststack(B);
00432 return B->buffer;
00433 }
00434
00435
00436 LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
00437 while (l--)
00438 luaL_addchar(B, *s++);
00439 }
00440
00441
00442 LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
00443 luaL_addlstring(B, s, strlen(s));
00444 }
00445
00446
00447 LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
00448 emptybuffer(B);
00449 lua_concat(B->L, B->lvl);
00450 B->lvl = 1;
00451 }
00452
00453
00454 LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
00455 lua_State *L = B->L;
00456 size_t vl;
00457 const char *s = lua_tolstring(L, -1, &vl);
00458 if (vl <= bufffree(B)) {
00459 memcpy(B->p, s, vl);
00460 B->p += vl;
00461 lua_pop(L, 1);
00462 }
00463 else {
00464 if (emptybuffer(B))
00465 lua_insert(L, -2);
00466 B->lvl++;
00467 adjuststack(B);
00468 }
00469 }
00470
00471
00472 LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
00473 B->L = L;
00474 B->p = B->buffer;
00475 B->lvl = 0;
00476 }
00477
00478
00479
00480
00481 LUALIB_API int luaL_ref (lua_State *L, int t) {
00482 int ref;
00483 t = abs_index(L, t);
00484 if (lua_isnil(L, -1)) {
00485 lua_pop(L, 1);
00486 return LUA_REFNIL;
00487 }
00488 lua_rawgeti(L, t, FREELIST_REF);
00489 ref = (int)lua_tointeger(L, -1);
00490 lua_pop(L, 1);
00491 if (ref != 0) {
00492 lua_rawgeti(L, t, ref);
00493 lua_rawseti(L, t, FREELIST_REF);
00494 }
00495 else {
00496 ref = (int)lua_objlen(L, t);
00497 ref++;
00498 }
00499 lua_rawseti(L, t, ref);
00500 return ref;
00501 }
00502
00503
00504 LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
00505 if (ref >= 0) {
00506 t = abs_index(L, t);
00507 lua_rawgeti(L, t, FREELIST_REF);
00508 lua_rawseti(L, t, ref);
00509 lua_pushinteger(L, ref);
00510 lua_rawseti(L, t, FREELIST_REF);
00511 }
00512 }
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 typedef struct LoadF {
00523 int extraline;
00524 FILE *f;
00525 char buff[LUAL_BUFFERSIZE];
00526 } LoadF;
00527
00528
00529 static const char *getF (lua_State *L, void *ud, size_t *size) {
00530 LoadF *lf = (LoadF *)ud;
00531 (void)L;
00532 if (lf->extraline) {
00533 lf->extraline = 0;
00534 *size = 1;
00535 return "\n";
00536 }
00537 if (feof(lf->f)) return NULL;
00538 *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
00539 return (*size > 0) ? lf->buff : NULL;
00540 }
00541
00542
00543 static int errfile (lua_State *L, const char *what, int fnameindex) {
00544 const char *serr = strerror(errno);
00545 const char *filename = lua_tostring(L, fnameindex) + 1;
00546 lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
00547 lua_remove(L, fnameindex);
00548 return LUA_ERRFILE;
00549 }
00550
00551
00552 LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
00553 LoadF lf;
00554 int status, readstatus;
00555 int c;
00556 int fnameindex = lua_gettop(L) + 1;
00557 lf.extraline = 0;
00558 if (filename == NULL) {
00559 lua_pushliteral(L, "=stdin");
00560 lf.f = stdin;
00561 }
00562 else {
00563 lua_pushfstring(L, "@%s", filename);
00564 lf.f = fopen(filename, "r");
00565 if (lf.f == NULL) return errfile(L, "open", fnameindex);
00566 }
00567 c = getc(lf.f);
00568 if (c == '#') {
00569 lf.extraline = 1;
00570 while ((c = getc(lf.f)) != EOF && c != '\n') ;
00571 if (c == '\n') c = getc(lf.f);
00572 }
00573 if (c == LUA_SIGNATURE[0] && filename) {
00574 lf.f = freopen(filename, "rb", lf.f);
00575 if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
00576
00577 while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
00578 lf.extraline = 0;
00579 }
00580 ungetc(c, lf.f);
00581 status = lua_load(L, getF, &lf, lua_tostring(L, -1));
00582 readstatus = ferror(lf.f);
00583 if (filename) fclose(lf.f);
00584 if (readstatus) {
00585 lua_settop(L, fnameindex);
00586 return errfile(L, "read", fnameindex);
00587 }
00588 lua_remove(L, fnameindex);
00589 return status;
00590 }
00591
00592
00593 typedef struct LoadS {
00594 const char *s;
00595 size_t size;
00596 } LoadS;
00597
00598
00599 static const char *getS (lua_State *L, void *ud, size_t *size) {
00600 LoadS *ls = (LoadS *)ud;
00601 (void)L;
00602 if (ls->size == 0) return NULL;
00603 *size = ls->size;
00604 ls->size = 0;
00605 return ls->s;
00606 }
00607
00608
00609 LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
00610 const char *name) {
00611 LoadS ls;
00612 ls.s = buff;
00613 ls.size = size;
00614 return lua_load(L, getS, &ls, name);
00615 }
00616
00617
00618 LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) {
00619 return luaL_loadbuffer(L, s, strlen(s), s);
00620 }
00621
00622
00623
00624
00625
00626
00627 static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
00628 (void)ud;
00629 (void)osize;
00630 if (nsize == 0) {
00631 free(ptr);
00632 return NULL;
00633 }
00634 else
00635 return realloc(ptr, nsize);
00636 }
00637
00638
00639 static int panic (lua_State *L) {
00640 (void)L;
00641 fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
00642 lua_tostring(L, -1));
00643 return 0;
00644 }
00645
00646
00647 LUALIB_API lua_State *luaL_newstate (void) {
00648 lua_State *L = lua_newstate(l_alloc, NULL);
00649 if (L) lua_atpanic(L, &panic);
00650 return L;
00651 }