|
@@ -1,33 +1,36 @@
|
|
|
/*
|
|
|
-** $Id: lauxlib.c,v 1.70 2002/05/15 18:57:44 roberto Exp roberto $
|
|
|
+** $Id: lauxlib.c,v 1.71 2002/05/16 18:39:46 roberto Exp roberto $
|
|
|
** Auxiliary functions for building Lua libraries
|
|
|
** See Copyright Notice in lua.h
|
|
|
*/
|
|
|
|
|
|
|
|
|
+#include <ctype.h>
|
|
|
#include <stdarg.h>
|
|
|
#include <stdio.h>
|
|
|
#include <string.h>
|
|
|
|
|
|
+#ifndef lua_filerror
|
|
|
+#include <errno.h>
|
|
|
+#define lua_fileerror (strerror(errno))
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
/* This file uses only the official API of Lua.
|
|
|
** Any function declared here could be written as an application function.
|
|
|
-** With care, these functions can be used by other libraries.
|
|
|
*/
|
|
|
|
|
|
#include "lua.h"
|
|
|
|
|
|
#include "lauxlib.h"
|
|
|
#include "luadebug.h"
|
|
|
-#include "lualib.h"
|
|
|
|
|
|
|
|
|
-LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
|
|
|
- int i;
|
|
|
- for (i=0; list[i]; i++)
|
|
|
- if (strcmp(list[i], name) == 0)
|
|
|
- return i;
|
|
|
- return -1; /* name not found */
|
|
|
-}
|
|
|
+/*
|
|
|
+** {======================================================
|
|
|
+** Error-report functions
|
|
|
+** =======================================================
|
|
|
+*/
|
|
|
|
|
|
|
|
|
LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
|
|
@@ -54,6 +57,33 @@ static void tag_error (lua_State *L, int narg, int tag) {
|
|
|
}
|
|
|
|
|
|
|
|
|
+LUALIB_API int luaL_verror (lua_State *L, const char *fmt, ...) {
|
|
|
+ lua_Debug ar;
|
|
|
+ const char *msg;
|
|
|
+ va_list argp;
|
|
|
+ va_start(argp, fmt);
|
|
|
+ msg = lua_pushvfstring(L, fmt, argp);
|
|
|
+ va_end(argp);
|
|
|
+ if (lua_getstack(L, 1, &ar)) { /* check calling function */
|
|
|
+ lua_getinfo(L, "Snl", &ar);
|
|
|
+ if (ar.currentline > 0)
|
|
|
+ lua_pushfstring(L, "%s:%d: %s", ar.short_src, ar.currentline, msg);
|
|
|
+ }
|
|
|
+ return lua_errorobj(L);
|
|
|
+}
|
|
|
+
|
|
|
+/* }====================================================== */
|
|
|
+
|
|
|
+
|
|
|
+LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
|
|
|
+ int i;
|
|
|
+ for (i=0; list[i]; i++)
|
|
|
+ if (strcmp(list[i], name) == 0)
|
|
|
+ return i;
|
|
|
+ return -1; /* name not found */
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
LUALIB_API void luaL_check_stack (lua_State *L, int space, const char *mes) {
|
|
|
if (!lua_checkstack(L, space))
|
|
|
luaL_verror(L, "stack overflow (%s)", mes);
|
|
@@ -143,21 +173,6 @@ LUALIB_API void luaL_opennamedlib (lua_State *L, const char *libname,
|
|
|
}
|
|
|
|
|
|
|
|
|
-LUALIB_API int luaL_verror (lua_State *L, const char *fmt, ...) {
|
|
|
- lua_Debug ar;
|
|
|
- const char *msg;
|
|
|
- va_list argp;
|
|
|
- va_start(argp, fmt);
|
|
|
- msg = lua_pushvfstring(L, fmt, argp);
|
|
|
- va_end(argp);
|
|
|
- if (lua_getstack(L, 1, &ar)) { /* check calling function */
|
|
|
- lua_getinfo(L, "Snl", &ar);
|
|
|
- if (ar.currentline > 0)
|
|
|
- lua_pushfstring(L, "%s:%d: %s", ar.short_src, ar.currentline, msg);
|
|
|
- }
|
|
|
- return lua_errorobj(L);
|
|
|
-}
|
|
|
-
|
|
|
|
|
|
/*
|
|
|
** {======================================================
|
|
@@ -284,3 +299,144 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+/*
|
|
|
+** {======================================================
|
|
|
+** Load functions
|
|
|
+** =======================================================
|
|
|
+*/
|
|
|
+
|
|
|
+typedef struct LoadF {
|
|
|
+ FILE *f;
|
|
|
+ char buff[LUAL_BUFFERSIZE];
|
|
|
+} LoadF;
|
|
|
+
|
|
|
+
|
|
|
+static const char *getF (void *ud, size_t *size) {
|
|
|
+ LoadF *lf = (LoadF *)ud;
|
|
|
+ *size = fread(lf->buff, 1, LUAL_BUFFERSIZE, lf->f);
|
|
|
+ return (*size > 0) ? lf->buff : NULL;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static int errfile (lua_State *L, const char *filename) {
|
|
|
+ if (filename == NULL) filename = "stdin";
|
|
|
+ lua_pushfstring(L, "cannot read %s: %s", filename, lua_fileerror);
|
|
|
+ return LUA_ERRFILE;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
|
|
|
+ LoadF lf;
|
|
|
+ int status;
|
|
|
+ int c;
|
|
|
+ int old_top = lua_gettop(L);
|
|
|
+ lf.f = (filename == NULL) ? stdin : fopen(filename, "r");
|
|
|
+ if (lf.f == NULL) return errfile(L, filename); /* unable to open file */
|
|
|
+ c = ungetc(getc(lf.f), lf.f);
|
|
|
+ if (!(isspace(c) || isprint(c)) && lf.f != stdin) { /* binary file? */
|
|
|
+ fclose(lf.f);
|
|
|
+ lf.f = fopen(filename, "rb"); /* reopen in binary mode */
|
|
|
+ if (lf.f == NULL) return errfile(L, filename); /* unable to reopen file */
|
|
|
+ }
|
|
|
+ if (filename == NULL)
|
|
|
+ lua_pushliteral(L, "=stdin");
|
|
|
+ else
|
|
|
+ lua_pushfstring(L, "@%s", filename);
|
|
|
+ status = lua_load(L, getF, &lf, lua_tostring(L, -1));
|
|
|
+ lua_remove(L, old_top+1); /* remove filename from stack */
|
|
|
+ if (ferror(lf.f)) {
|
|
|
+ lua_settop(L, old_top); /* ignore results from `lua_load' */
|
|
|
+ return errfile(L, filename);
|
|
|
+ }
|
|
|
+ if (lf.f != stdin)
|
|
|
+ fclose(lf.f);
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+typedef struct LoadS {
|
|
|
+ const char *s;
|
|
|
+ size_t size;
|
|
|
+} LoadS;
|
|
|
+
|
|
|
+
|
|
|
+static const char *getS (void *ud, size_t *size) {
|
|
|
+ LoadS *ls = (LoadS *)ud;
|
|
|
+ if (ls->size == 0) return NULL;
|
|
|
+ *size = ls->size;
|
|
|
+ ls->size = 0;
|
|
|
+ return ls->s;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
|
|
|
+ const char *name) {
|
|
|
+ LoadS ls;
|
|
|
+ ls.s = buff;
|
|
|
+ ls.size = size;
|
|
|
+ return lua_load(L, getS, &ls, name);
|
|
|
+}
|
|
|
+
|
|
|
+/* }====================================================== */
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+** {======================================================
|
|
|
+** compatibility code
|
|
|
+** =======================================================
|
|
|
+*/
|
|
|
+
|
|
|
+
|
|
|
+static void callalert (lua_State *L, int status) {
|
|
|
+ if (status != 0) {
|
|
|
+ int top = lua_gettop(L);
|
|
|
+ lua_getglobal(L, "_ALERT");
|
|
|
+ lua_insert(L, -2);
|
|
|
+ lua_pcall(L, 1, 0, 0);
|
|
|
+ lua_settop(L, top-1);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+LUALIB_API int lua_call (lua_State *L, int nargs, int nresults) {
|
|
|
+ int status;
|
|
|
+ int errpos = lua_gettop(L) - nargs;
|
|
|
+ lua_getglobal(L, "_ERRORMESSAGE");
|
|
|
+ lua_insert(L, errpos); /* put below function and args */
|
|
|
+ status = lua_pcall(L, nargs, nresults, errpos);
|
|
|
+ lua_remove(L, errpos);
|
|
|
+ callalert(L, status);
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static int aux_do (lua_State *L, int status) {
|
|
|
+ if (status == 0) { /* parse OK? */
|
|
|
+ int err = lua_gettop(L);
|
|
|
+ lua_getglobal(L, "_ERRORMESSAGE");
|
|
|
+ lua_insert(L, err);
|
|
|
+ status = lua_pcall(L, 0, LUA_MULTRET, err); /* call main */
|
|
|
+ lua_remove(L, err); /* remove error function */
|
|
|
+ }
|
|
|
+ callalert(L, status);
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+LUALIB_API int lua_dofile (lua_State *L, const char *filename) {
|
|
|
+ return aux_do(L, luaL_loadfile(L, filename));
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t size,
|
|
|
+ const char *name) {
|
|
|
+ return aux_do(L, luaL_loadbuffer(L, buff, size, name));
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+LUALIB_API int lua_dostring (lua_State *L, const char *str) {
|
|
|
+ return lua_dobuffer(L, str, strlen(str), str);
|
|
|
+}
|
|
|
+
|
|
|
+/* }====================================================== */
|