2 ** $Id: lauxlib.c,v 1.43 2000/10/30 13:07:48 roberto Exp $
3 ** Auxiliary functions for building Lua libraries
4 ** See Copyright Notice in lua.h
12 /* This file uses only the official API of Lua.
13 ** Any function declared here could be written as an application function.
14 ** With care, these functions can be used by other libraries.
24 LUALIB_API
int luaL_findstring (const char *name
, const char *const list
[]) {
26 for (i
=0; list
[i
]; i
++)
27 if (strcmp(list
[i
], name
) == 0)
29 return -1; /* name not found */
32 LUALIB_API
void luaL_argerror (lua_State
*L
, int narg
, const char *extramsg
) {
34 lua_getstack(L
, 0, &ar
);
35 lua_getinfo(L
, "n", &ar
);
38 luaL_verror(L
, "bad argument #%d to `%.50s' (%.100s)",
39 narg
, ar
.name
, extramsg
);
43 static void type_error (lua_State
*L
, int narg
, int t
) {
45 sprintf(buff
, "%.8s expected, got %.8s", lua_typename(L
, t
),
46 lua_typename(L
, lua_type(L
, narg
)));
47 luaL_argerror(L
, narg
, buff
);
51 LUALIB_API
void luaL_checkstack (lua_State
*L
, int space
, const char *mes
) {
52 if (space
> lua_stackspace(L
))
53 luaL_verror(L
, "stack overflow (%.30s)", mes
);
57 LUALIB_API
void luaL_checktype(lua_State
*L
, int narg
, int t
) {
58 if (lua_type(L
, narg
) != t
)
59 type_error(L
, narg
, t
);
63 LUALIB_API
void luaL_checkany (lua_State
*L
, int narg
) {
64 if (lua_type(L
, narg
) == LUA_TNONE
)
65 luaL_argerror(L
, narg
, "value expected");
69 LUALIB_API
const char *luaL_check_lstr (lua_State
*L
, int narg
, size_t *len
) {
70 const char *s
= lua_tostring(L
, narg
);
71 if (!s
) type_error(L
, narg
, LUA_TSTRING
);
72 if (len
) *len
= lua_strlen(L
, narg
);
77 LUALIB_API
const char *luaL_opt_lstr (lua_State
*L
, int narg
, const char *def
, size_t *len
) {
78 if (lua_isnull(L
, narg
)) {
80 *len
= (def
? strlen(def
) : 0);
83 else return luaL_check_lstr(L
, narg
, len
);
87 LUALIB_API
double luaL_check_number (lua_State
*L
, int narg
) {
88 double d
= lua_tonumber(L
, narg
);
89 if (d
== 0 && !lua_isnumber(L
, narg
)) /* avoid extra test when d is not 0 */
90 type_error(L
, narg
, LUA_TNUMBER
);
95 LUALIB_API
double luaL_opt_number (lua_State
*L
, int narg
, double def
) {
96 if (lua_isnull(L
, narg
)) return def
;
97 else return luaL_check_number(L
, narg
);
101 LUALIB_API
void luaL_openlib (lua_State
*L
, const struct luaL_reg
*l
, int n
) {
104 lua_register(L
, l
[i
].name
, l
[i
].func
);
108 LUALIB_API
void luaL_verror (lua_State
*L
, const char *fmt
, ...) {
112 vsprintf(buff
, fmt
, argp
);
119 ** {======================================================
120 ** Generic Buffer manipulation
121 ** =======================================================
125 #define buffempty(B) ((B)->p == (B)->buffer)
126 #define bufflen(B) ((B)->p - (B)->buffer)
127 #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
129 #define LIMIT (LUA_MINSTACK/2)
132 static int emptybuffer (luaL_Buffer
*B
) {
133 size_t l
= bufflen(B
);
134 if (l
== 0) return 0; /* put nothing on stack */
136 lua_pushlstring(B
->L
, B
->buffer
, l
);
144 static void adjuststack (luaL_Buffer
*B
) {
147 int toget
= 1; /* number of levels to concat */
148 size_t toplen
= lua_strlen(L
, -1);
150 size_t l
= lua_strlen(L
, -(toget
+1));
151 if (B
->level
- toget
+ 1 >= LIMIT
|| toplen
> l
) {
156 } while (toget
< B
->level
);
158 lua_concat(L
, toget
);
159 B
->level
= B
->level
- toget
+ 1;
165 LUALIB_API
char *luaL_prepbuffer (luaL_Buffer
*B
) {
172 LUALIB_API
void luaL_addlstring (luaL_Buffer
*B
, const char *s
, size_t l
) {
174 luaL_putchar(B
, *s
++);
178 LUALIB_API
void luaL_addstring (luaL_Buffer
*B
, const char *s
) {
179 luaL_addlstring(B
, s
, strlen(s
));
183 LUALIB_API
void luaL_pushresult (luaL_Buffer
*B
) {
186 lua_pushlstring(B
->L
, NULL
, 0);
187 else if (B
->level
> 1)
188 lua_concat(B
->L
, B
->level
);
193 LUALIB_API
void luaL_addvalue (luaL_Buffer
*B
) {
195 size_t vl
= lua_strlen(L
, -1);
196 if (vl
<= bufffree(B
)) { /* fit into buffer? */
197 memcpy(B
->p
, lua_tostring(L
, -1), vl
); /* put it there */
199 lua_pop(L
, 1); /* remove from stack */
203 lua_insert(L
, -2); /* put buffer before new value */
204 B
->level
++; /* add new value into B stack */
210 LUALIB_API
void luaL_buffinit (lua_State
*L
, luaL_Buffer
*B
) {
216 /* }====================================================== */