This source file includes following definitions.
- luaL_argerror
- luaL_typerror
- tag_error
- luaL_where
- luaL_error
- luaL_checkoption
- luaL_newmetatable
- luaL_checkudata
- luaL_checkstack
- luaL_checktype
- luaL_checkany
- luaL_checklstring
- luaL_optlstring
- luaL_checknumber
- luaL_optnumber
- luaL_checkinteger
- luaL_optinteger
- luaL_getmetafield
- luaL_callmeta
- libsize
- luaI_openlib
- checkint
- getsizes
- luaL_setn
- luaL_getn
- luaL_gsub
- luaL_findtable
- emptybuffer
- adjuststack
- luaL_prepbuffer
- luaL_addlstring
- luaL_addstring
- luaL_pushresult
- luaL_addvalue
- luaL_buffinit
- luaL_ref
- luaL_unref
- getF
- getF
- errfile
- luaL_loadfile
- luaL_loadfile
- getS
- luaL_loadbuffer
- l_alloc
- panic
- luaL_newstate
1
2
3
4
5
6
7
8 #include <ctype.h>
9 #include <errno.h>
10 #include <stdarg.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15
16
17
18
19
20 #define lauxlib_c
21 #define LUA_LIB
22
23 #include "lua.h"
24
25 #include "lauxlib.h"
26
27
28 #define FREELIST_REF 0
29
30
31
32 #define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
33 lua_gettop(L) + (i) + 1)
34
35
36
37
38
39
40
41
42
43 LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
44 lua_Debug ar;
45 if (!lua_getstack(L, 0, &ar))
46 return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
47 lua_getinfo(L, "n", &ar);
48 if (strcmp(ar.namewhat, "method") == 0) {
49 narg--;
50 if (narg == 0)
51 return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
52 ar.name, extramsg);
53 }
54 if (ar.name == NULL)
55 ar.name = "?";
56 return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
57 narg, ar.name, extramsg);
58 }
59
60
61 LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
62 const char *msg = lua_pushfstring(L, "%s expected, got %s",
63 tname, luaL_typename(L, narg));
64 return luaL_argerror(L, narg, msg);
65 }
66
67
68 static void tag_error (lua_State *L, int narg, int tag) {
69 luaL_typerror(L, narg, lua_typename(L, tag));
70 }
71
72
73 LUALIB_API void luaL_where (lua_State *L, int level) {
74 lua_Debug ar;
75 if (lua_getstack(L, level, &ar)) {
76 lua_getinfo(L, "Sl", &ar);
77 if (ar.currentline > 0) {
78 lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
79 return;
80 }
81 }
82 lua_pushliteral(L, "");
83 }
84
85
86 LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
87 va_list argp;
88 va_start(argp, fmt);
89 luaL_where(L, 1);
90 lua_pushvfstring(L, fmt, argp);
91 va_end(argp);
92 lua_concat(L, 2);
93 return lua_error(L);
94 }
95
96
97
98
99 LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
100 const char *const lst[]) {
101 const char *name = (def) ? luaL_optstring(L, narg, def) :
102 luaL_checkstring(L, narg);
103 int i;
104 for (i=0; lst[i]; i++)
105 if (strcmp(lst[i], name) == 0)
106 return i;
107 return luaL_argerror(L, narg,
108 lua_pushfstring(L, "invalid option " LUA_QS, name));
109 }
110
111
112 LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
113 lua_getfield(L, LUA_REGISTRYINDEX, tname);
114 if (!lua_isnil(L, -1))
115 return 0;
116 lua_pop(L, 1);
117 lua_newtable(L);
118 lua_pushvalue(L, -1);
119 lua_setfield(L, LUA_REGISTRYINDEX, tname);
120 return 1;
121 }
122
123
124 LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
125 void *p = lua_touserdata(L, ud);
126 if (p != NULL) {
127 if (lua_getmetatable(L, ud)) {
128 lua_getfield(L, LUA_REGISTRYINDEX, tname);
129 if (lua_rawequal(L, -1, -2)) {
130 lua_pop(L, 2);
131 return p;
132 }
133 }
134 }
135 luaL_typerror(L, ud, tname);
136 return NULL;
137 }
138
139
140 LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
141 if (!lua_checkstack(L, space))
142 luaL_error(L, "stack overflow (%s)", mes);
143 }
144
145
146 LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
147 if (lua_type(L, narg) != t)
148 tag_error(L, narg, t);
149 }
150
151
152 LUALIB_API void luaL_checkany (lua_State *L, int narg) {
153 if (lua_type(L, narg) == LUA_TNONE)
154 luaL_argerror(L, narg, "value expected");
155 }
156
157
158 LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
159 const char *s = lua_tolstring(L, narg, len);
160 if (!s) tag_error(L, narg, LUA_TSTRING);
161 return s;
162 }
163
164
165 LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
166 const char *def, size_t *len) {
167 if (lua_isnoneornil(L, narg)) {
168 if (len)
169 *len = (def ? strlen(def) : 0);
170 return def;
171 }
172 else return luaL_checklstring(L, narg, len);
173 }
174
175
176 LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
177 lua_Number d = lua_tonumber(L, narg);
178 if (d == 0 && !lua_isnumber(L, narg))
179 tag_error(L, narg, LUA_TNUMBER);
180 return d;
181 }
182
183
184 LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
185 return luaL_opt(L, luaL_checknumber, narg, def);
186 }
187
188
189 LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
190 lua_Integer d = lua_tointeger(L, narg);
191 if (d == 0 && !lua_isnumber(L, narg))
192 tag_error(L, narg, LUA_TNUMBER);
193 return d;
194 }
195
196
197 LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
198 lua_Integer def) {
199 return luaL_opt(L, luaL_checkinteger, narg, def);
200 }
201
202
203 LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
204 if (!lua_getmetatable(L, obj))
205 return 0;
206 lua_pushstring(L, event);
207 lua_rawget(L, -2);
208 if (lua_isnil(L, -1)) {
209 lua_pop(L, 2);
210 return 0;
211 }
212 else {
213 lua_remove(L, -2);
214 return 1;
215 }
216 }
217
218
219 LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
220 obj = abs_index(L, obj);
221 if (!luaL_getmetafield(L, obj, event))
222 return 0;
223 lua_pushvalue(L, obj);
224 lua_call(L, 1, 1);
225 return 1;
226 }
227
228
229 LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
230 const luaL_Reg *l) {
231 luaI_openlib(L, libname, l, 0);
232 }
233
234
235 static int libsize (const luaL_Reg *l) {
236 int size = 0;
237 for (; l->name; l++) size++;
238 return size;
239 }
240
241
242 LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
243 const luaL_Reg *l, int nup) {
244 if (libname) {
245 int size = libsize(l);
246
247 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);
248 lua_getfield(L, -1, libname);
249 if (!lua_istable(L, -1)) {
250 lua_pop(L, 1);
251
252 if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
253 luaL_error(L, "name conflict for module " LUA_QS, libname);
254 lua_pushvalue(L, -1);
255 lua_setfield(L, -3, libname);
256 }
257 lua_remove(L, -2);
258 lua_insert(L, -(nup+1));
259 }
260 for (; l->name; l++) {
261 int i;
262 for (i=0; i<nup; i++)
263 lua_pushvalue(L, -nup);
264 lua_pushcclosure(L, l->func, nup);
265 lua_setfield(L, -(nup+2), l->name);
266 }
267 lua_pop(L, nup);
268 }
269
270
271
272
273
274
275
276
277
278 #if defined(LUA_COMPAT_GETN)
279
280 static int checkint (lua_State *L, int topop) {
281 int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
282 lua_pop(L, topop);
283 return n;
284 }
285
286
287 static void getsizes (lua_State *L) {
288 lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
289 if (lua_isnil(L, -1)) {
290 lua_pop(L, 1);
291 lua_newtable(L);
292 lua_pushvalue(L, -1);
293 lua_setmetatable(L, -2);
294 lua_pushliteral(L, "kv");
295 lua_setfield(L, -2, "__mode");
296 lua_pushvalue(L, -1);
297 lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
298 }
299 }
300
301
302 LUALIB_API void luaL_setn (lua_State *L, int t, int n) {
303 t = abs_index(L, t);
304 lua_pushliteral(L, "n");
305 lua_rawget(L, t);
306 if (checkint(L, 1) >= 0) {
307 lua_pushliteral(L, "n");
308 lua_pushinteger(L, n);
309 lua_rawset(L, t);
310 }
311 else {
312 getsizes(L);
313 lua_pushvalue(L, t);
314 lua_pushinteger(L, n);
315 lua_rawset(L, -3);
316 lua_pop(L, 1);
317 }
318 }
319
320
321 LUALIB_API int luaL_getn (lua_State *L, int t) {
322 int n;
323 t = abs_index(L, t);
324 lua_pushliteral(L, "n");
325 lua_rawget(L, t);
326 if ((n = checkint(L, 1)) >= 0) return n;
327 getsizes(L);
328 lua_pushvalue(L, t);
329 lua_rawget(L, -2);
330 if ((n = checkint(L, 2)) >= 0) return n;
331 return (int)lua_objlen(L, t);
332 }
333
334 #endif
335
336
337
338
339 LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
340 const char *r) {
341 const char *wild;
342 size_t l = strlen(p);
343 luaL_Buffer b;
344 luaL_buffinit(L, &b);
345 while ((wild = strstr(s, p)) != NULL) {
346 luaL_addlstring(&b, s, wild - s);
347 luaL_addstring(&b, r);
348 s = wild + l;
349 }
350 luaL_addstring(&b, s);
351 luaL_pushresult(&b);
352 return lua_tostring(L, -1);
353 }
354
355 LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
356 const char *fname, int szhint) {
357 const char *e;
358 lua_pushvalue(L, idx);
359 do {
360 e = strchr(fname, '.');
361 if (e == NULL) e = fname + strlen(fname);
362 lua_pushlstring(L, fname, e - fname);
363 lua_rawget(L, -2);
364 if (lua_isnil(L, -1)) {
365 lua_pop(L, 1);
366 lua_createtable(L, 0, (*e == '.' ? 1 : szhint));
367 lua_pushlstring(L, fname, e - fname);
368 lua_pushvalue(L, -2);
369 lua_settable(L, -4);
370 }
371 else if (!lua_istable(L, -1)) {
372 lua_pop(L, 2);
373 return fname;
374 }
375 lua_remove(L, -2);
376 fname = e + 1;
377 } while (*e == '.');
378 return NULL;
379 }
380
381
382
383
384
385
386
387
388
389
390 #define bufflen(B) ((B)->p - (B)->buffer)
391 #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
392
393 #define LIMIT (LUA_MINSTACK/2)
394
395
396 static int emptybuffer (luaL_Buffer *B) {
397 size_t l = bufflen(B);
398 if (l == 0) return 0;
399 else {
400 lua_pushlstring(B->L, B->buffer, l);
401 B->p = B->buffer;
402 B->lvl++;
403 return 1;
404 }
405 }
406
407
408 static void adjuststack (luaL_Buffer *B) {
409 if (B->lvl > 1) {
410 lua_State *L = B->L;
411 int toget = 1;
412 size_t toplen = lua_strlen(L, -1);
413 do {
414 size_t l = lua_strlen(L, -(toget+1));
415 if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
416 toplen += l;
417 toget++;
418 }
419 else break;
420 } while (toget < B->lvl);
421 lua_concat(L, toget);
422 B->lvl = B->lvl - toget + 1;
423 }
424 }
425
426
427 LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
428 if (emptybuffer(B))
429 adjuststack(B);
430 return B->buffer;
431 }
432
433
434 LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
435 while (l--)
436 luaL_addchar(B, *s++);
437 }
438
439
440 LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
441 luaL_addlstring(B, s, strlen(s));
442 }
443
444
445 LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
446 emptybuffer(B);
447 lua_concat(B->L, B->lvl);
448 B->lvl = 1;
449 }
450
451
452 LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
453 lua_State *L = B->L;
454 size_t vl;
455 const char *s = lua_tolstring(L, -1, &vl);
456 if (vl <= bufffree(B)) {
457 memcpy(B->p, s, vl);
458 B->p += vl;
459 lua_pop(L, 1);
460 }
461 else {
462 if (emptybuffer(B))
463 lua_insert(L, -2);
464 B->lvl++;
465 adjuststack(B);
466 }
467 }
468
469
470 LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
471 B->L = L;
472 B->p = B->buffer;
473 B->lvl = 0;
474 }
475
476
477
478
479 LUALIB_API int luaL_ref (lua_State *L, int t) {
480 int ref;
481 t = abs_index(L, t);
482 if (lua_isnil(L, -1)) {
483 lua_pop(L, 1);
484 return LUA_REFNIL;
485 }
486 lua_rawgeti(L, t, FREELIST_REF);
487 ref = (int)lua_tointeger(L, -1);
488 lua_pop(L, 1);
489 if (ref != 0) {
490 lua_rawgeti(L, t, ref);
491 lua_rawseti(L, t, FREELIST_REF);
492 }
493 else {
494 ref = (int)lua_objlen(L, t);
495 ref++;
496 }
497 lua_rawseti(L, t, ref);
498 return ref;
499 }
500
501
502 LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
503 if (ref >= 0) {
504 t = abs_index(L, t);
505 lua_rawgeti(L, t, FREELIST_REF);
506 lua_rawseti(L, t, ref);
507 lua_pushinteger(L, ref);
508 lua_rawseti(L, t, FREELIST_REF);
509 }
510 }
511
512
513
514
515
516
517
518
519 #if 0
520 typedef struct LoadF {
521 int extraline;
522 FILE *f;
523 char buff[LUAL_BUFFERSIZE];
524 } LoadF;
525
526
527 static const char *getF (lua_State *L, void *ud, size_t *size) {
528 LoadF *lf = (LoadF *)ud;
529 (void)L;
530 if (lf->extraline) {
531 lf->extraline = 0;
532 *size = 1;
533 return "\n";
534 }
535 if (feof(lf->f)) return NULL;
536 *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
537 return (*size > 0) ? lf->buff : NULL;
538 }
539 #else
540 typedef struct LoadF {
541 FILE *f;
542 char buff[LUAL_BUFFERSIZE];
543 } LoadF;
544
545 static const char *getF (lua_State *L, void *ud, size_t *size) {
546 LoadF *lf = (LoadF *)ud;
547 (void)L;
548 if (feof(lf->f)) return NULL;
549 *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
550 return (*size > 0) ? lf->buff : NULL;
551 }
552 #endif
553
554 static int errfile (lua_State *L, const char *what, int fnameindex) {
555 #if 0
556 const char *serr = strerror(errno);
557 const char *filename = lua_tostring(L, fnameindex) + 1;
558 lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
559 #else
560 const char *filename = lua_tostring(L, fnameindex) + 1;
561 lua_pushfstring(L, "cannot %s %s", what, filename);
562 #endif
563 lua_remove(L, fnameindex);
564 return LUA_ERRFILE;
565 }
566
567 #if 0
568 LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
569 LoadF lf;
570 int status, readstatus;
571 int c;
572 int fnameindex = lua_gettop(L) + 1;
573 lf.extraline = 0;
574 if (filename == NULL) {
575 lua_pushliteral(L, "=stdin");
576 lf.f = stdin;
577 }
578 else {
579 lua_pushfstring(L, "@%s", filename);
580 lf.f = fopen(filename, "r");
581 if (lf.f == NULL) return errfile(L, "open", fnameindex);
582 }
583 c = getc(lf.f);
584 if (c == '#') {
585 lf.extraline = 1;
586 while ((c = getc(lf.f)) != EOF && c != '\n') ;
587 if (c == '\n') c = getc(lf.f);
588 }
589 if (c == LUA_SIGNATURE[0] && filename) {
590 lf.f = freopen(filename, "rb", lf.f);
591 if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
592
593 while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
594 lf.extraline = 0;
595 }
596 ungetc(c, lf.f);
597 status = lua_load(L, getF, &lf, lua_tostring(L, -1));
598 readstatus = ferror(lf.f);
599 if (filename) fclose(lf.f);
600 if (readstatus) {
601 lua_settop(L, fnameindex);
602 return errfile(L, "read", fnameindex);
603 }
604 lua_remove(L, fnameindex);
605 return status;
606 }
607 #else
608 LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
609 LoadF lf;
610 int status, readerror;
611 char c;
612 int fnameindex = lua_gettop(L) + 1;
613 lua_pushfstring(L, "@%s", filename);
614 lf.f = fopen(filename, "rb");
615 if (lf.f == NULL) return errfile(L, "fopen", fnameindex);
616 status = lua_load(L, getF, &lf, lua_tostring(L, -1));
617
618 readerror = ((fread(&c, 1, 1, lf.f) < 1) && !feof(lf.f));
619
620 fclose(lf.f);
621 if (readerror) {
622 lua_settop(L, fnameindex);
623 return errfile(L, "read", fnameindex);
624 }
625 lua_remove(L, fnameindex);
626 return status;
627 }
628 #endif
629
630 typedef struct LoadS {
631 const char *s;
632 size_t size;
633 } LoadS;
634
635
636 static const char *getS (lua_State *L, void *ud, size_t *size) {
637 LoadS *ls = (LoadS *)ud;
638 (void)L;
639 if (ls->size == 0) return NULL;
640 *size = ls->size;
641 ls->size = 0;
642 return ls->s;
643 }
644
645
646 LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
647 const char *name) {
648 LoadS ls;
649 ls.s = buff;
650 ls.size = size;
651 return lua_load(L, getS, &ls, name);
652 }
653
654
655 LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) {
656 return luaL_loadbuffer(L, s, strlen(s), s);
657 }
658
659
660
661
662
663
664 static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
665 (void)ud;
666 (void)osize;
667 if (nsize == 0) {
668 free(ptr);
669 return NULL;
670 }
671 else {
672 if( nsize <= osize ) {
673 return ptr;
674 }
675 void* res = malloc( nsize );
676 if( !res )
677 return NULL;
678 memcpy( res, ptr, osize );
679 free( ptr );
680 return res;
681 }
682 }
683
684
685 static int panic (lua_State *L) {
686 (void)L;
687 #if 0
688 printf( "PANIC: unprotected error in call to Lua API (%s)\n",
689 lua_tostring(L, -1));
690 #endif
691 return 0;
692 }
693
694
695 LUALIB_API lua_State *luaL_newstate (void) {
696 lua_State *L = lua_newstate(l_alloc, NULL);
697 if (L) lua_atpanic(L, &panic);
698 return L;
699 }
700