This source file includes following definitions.
- ll_unloadlib
- ll_load
- ll_sym
- setprogdir
- pusherror
- ll_unloadlib
- ll_load
- ll_sym
- pusherror
- errorfromcode
- ll_unloadlib
- ll_load
- ll_sym
- ll_unloadlib
- ll_load
- ll_sym
- ll_register
- gctm
- ll_loadfunc
- ll_loadlib
- readable
- pushnexttemplate
- findfile
- loaderror
- loader_Lua
- mkfuncname
- loader_C
- loader_Croot
- loader_preload
- ll_require
- setfenv
- dooptions
- modinit
- ll_module
- ll_seeall
- setpath
- luaopen_package
1
2
3
4
5
6
7
8
9
10
11
12 #include <stdlib.h>
13 #include <string.h>
14
15
16 #define loadlib_c
17 #define LUA_LIB
18
19 #include "lua.h"
20
21 #include "lauxlib.h"
22 #include "lualib.h"
23
24
25
26 #define LUA_POF "luaopen_"
27
28
29 #define LUA_OFSEP "_"
30
31
32 #define LIBPREFIX "LOADLIB: "
33
34 #define POF LUA_POF
35 #define LIB_FAIL "open"
36
37
38
39 #define ERRLIB 1
40 #define ERRFUNC 2
41
42 #define setprogdir(L) ((void)0)
43
44
45 #if 0
46 static void ll_unloadlib (void *lib);
47 static void *ll_load (lua_State *L, const char *path);
48 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
49 #endif
50
51
52 #if defined(LUA_DL_DLOPEN)
53
54
55
56
57
58
59
60
61
62 #include <dlfcn.h>
63
64 static void ll_unloadlib (void *lib) {
65 dlclose(lib);
66 }
67
68
69 static void *ll_load (lua_State *L, const char *path) {
70 void *lib = dlopen(path, RTLD_NOW);
71 if (lib == NULL) lua_pushstring(L, dlerror());
72 return lib;
73 }
74
75
76 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
77 lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
78 if (f == NULL) lua_pushstring(L, dlerror());
79 return f;
80 }
81
82
83
84
85
86 #elif defined(LUA_DL_DLL)
87
88
89
90
91
92
93 #include <windows.h>
94
95
96 #undef setprogdir
97
98 static void setprogdir (lua_State *L) {
99 char buff[MAX_PATH + 1];
100 char *lb;
101 DWORD nsize = sizeof(buff)/sizeof(char);
102 DWORD n = GetModuleFileNameA(NULL, buff, nsize);
103 if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
104 luaL_error(L, "unable to get ModuleFileName");
105 else {
106 *lb = '\0';
107 luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
108 lua_remove(L, -2);
109 }
110 }
111
112
113 static void pusherror (lua_State *L) {
114 int error = GetLastError();
115 char buffer[128];
116 if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
117 NULL, error, 0, buffer, sizeof(buffer), NULL))
118 lua_pushstring(L, buffer);
119 else
120 lua_pushfstring(L, "system error %d\n", error);
121 }
122
123 static void ll_unloadlib (void *lib) {
124 FreeLibrary((HINSTANCE)lib);
125 }
126
127
128 static void *ll_load (lua_State *L, const char *path) {
129 HINSTANCE lib = LoadLibraryA(path);
130 if (lib == NULL) pusherror(L);
131 return lib;
132 }
133
134
135 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
136 lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
137 if (f == NULL) pusherror(L);
138 return f;
139 }
140
141
142
143
144
145 #elif defined(LUA_DL_DYLD)
146
147
148
149
150
151
152 #include <mach-o/dyld.h>
153
154
155
156 #undef POF
157 #define POF "_" LUA_POF
158
159
160 static void pusherror (lua_State *L) {
161 const char *err_str;
162 const char *err_file;
163 NSLinkEditErrors err;
164 int err_num;
165 NSLinkEditError(&err, &err_num, &err_file, &err_str);
166 lua_pushstring(L, err_str);
167 }
168
169
170 static const char *errorfromcode (NSObjectFileImageReturnCode ret) {
171 switch (ret) {
172 case NSObjectFileImageInappropriateFile:
173 return "file is not a bundle";
174 case NSObjectFileImageArch:
175 return "library is for wrong CPU type";
176 case NSObjectFileImageFormat:
177 return "bad format";
178 case NSObjectFileImageAccess:
179 return "cannot access file";
180 case NSObjectFileImageFailure:
181 default:
182 return "unable to load library";
183 }
184 }
185
186
187 static void ll_unloadlib (void *lib) {
188 NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
189 }
190
191
192 static void *ll_load (lua_State *L, const char *path) {
193 NSObjectFileImage img;
194 NSObjectFileImageReturnCode ret;
195
196 if(!_dyld_present()) {
197 lua_pushliteral(L, "dyld not present");
198 return NULL;
199 }
200 ret = NSCreateObjectFileImageFromFile(path, &img);
201 if (ret == NSObjectFileImageSuccess) {
202 NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE |
203 NSLINKMODULE_OPTION_RETURN_ON_ERROR);
204 NSDestroyObjectFileImage(img);
205 if (mod == NULL) pusherror(L);
206 return mod;
207 }
208 lua_pushstring(L, errorfromcode(ret));
209 return NULL;
210 }
211
212
213 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
214 NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym);
215 if (nss == NULL) {
216 lua_pushfstring(L, "symbol " LUA_QS " not found", sym);
217 return NULL;
218 }
219 return (lua_CFunction)NSAddressOfSymbol(nss);
220 }
221
222
223
224
225
226 #else
227
228
229
230
231
232
233 #if 0
234 #undef LIB_FAIL
235 #define LIB_FAIL "absent"
236
237
238 #define DLMSG "dynamic libraries not enabled; check your Lua installation"
239
240
241 static void ll_unloadlib (void *lib) {
242 (void)lib;
243 }
244
245
246 static void *ll_load (lua_State *L, const char *path) {
247 (void)path;
248 lua_pushliteral(L, DLMSG);
249 return NULL;
250 }
251
252
253 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
254 (void)lib; (void)sym;
255 lua_pushliteral(L, DLMSG);
256 return NULL;
257 }
258 #endif
259
260
261 #endif
262
263
264 #if 0
265 static void **ll_register (lua_State *L, const char *path) {
266 void **plib;
267 lua_pushfstring(L, "%s%s", LIBPREFIX, path);
268 lua_gettable(L, LUA_REGISTRYINDEX);
269 if (!lua_isnil(L, -1))
270 plib = (void **)lua_touserdata(L, -1);
271 else {
272 lua_pop(L, 1);
273 plib = (void **)lua_newuserdata(L, sizeof(const void *));
274 *plib = NULL;
275 luaL_getmetatable(L, "_LOADLIB");
276 lua_setmetatable(L, -2);
277 lua_pushfstring(L, "%s%s", LIBPREFIX, path);
278 lua_pushvalue(L, -2);
279 lua_settable(L, LUA_REGISTRYINDEX);
280 }
281 return plib;
282 }
283
284
285
286
287
288
289 static int gctm (lua_State *L) {
290 void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
291 if (*lib) ll_unloadlib(*lib);
292 *lib = NULL;
293 return 0;
294 }
295
296
297 static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
298 void **reg = ll_register(L, path);
299 if (*reg == NULL) *reg = ll_load(L, path);
300 if (*reg == NULL)
301 return ERRLIB;
302 else {
303 lua_CFunction f = ll_sym(L, *reg, sym);
304 if (f == NULL)
305 return ERRFUNC;
306 lua_pushcfunction(L, f);
307 return 0;
308 }
309 }
310
311
312 static int ll_loadlib (lua_State *L) {
313 const char *path = luaL_checkstring(L, 1);
314 const char *init = luaL_checkstring(L, 2);
315 int stat = ll_loadfunc(L, path, init);
316 if (stat == 0)
317 return 1;
318 else {
319 lua_pushnil(L);
320 lua_insert(L, -2);
321 lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
322 return 3;
323 }
324 }
325 #endif
326
327
328
329
330
331
332
333
334
335 static int readable (const char *filename) {
336 #ifdef HOST_LUA
337 FILE *f = fopen(filename, "r");
338 if (f == NULL) return 0;
339 fclose(f);
340 #else
341 int f = open(filename,O_RDONLY,0777);
342 if (f == -1) return 0;
343 close(f);
344 #endif
345 return 1;
346 }
347
348 static const char *pushnexttemplate (lua_State *L, const char *path) {
349 const char *l;
350 while (*path == *LUA_PATHSEP) path++;
351 if (*path == '\0') return NULL;
352 l = strchr(path, *LUA_PATHSEP);
353 if (l == NULL) l = path + strlen(path);
354 lua_pushlstring(L, path, l - path);
355 return l;
356 }
357
358
359 static const char *findfile (lua_State *L, const char *name,
360 const char *pname) {
361 const char *path;
362 name = luaL_gsub(L, name, ".", LUA_DIRSEP);
363 lua_getfield(L, LUA_ENVIRONINDEX, pname);
364 path = lua_tostring(L, -1);
365 if (path == NULL)
366 luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
367 lua_pushliteral(L, "");
368 while ((path = pushnexttemplate(L, path)) != NULL) {
369 const char *filename;
370 filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
371 lua_remove(L, -2);
372 if (readable(filename))
373 return filename;
374 lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
375 lua_remove(L, -2);
376 lua_concat(L, 2);
377 }
378 return NULL;
379 }
380
381 static void loaderror (lua_State *L, const char *filename) {
382 luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
383 lua_tostring(L, 1), filename, lua_tostring(L, -1));
384 }
385
386
387 static int loader_Lua (lua_State *L) {
388 const char *filename;
389 const char *name = luaL_checkstring(L, 1);
390 filename = findfile(L, name, "path");
391 if (filename == NULL) return 1;
392 if (luaL_loadfile(L, filename) != 0)
393 loaderror(L, filename);
394 return 1;
395 }
396
397 #if 0
398 static const char *mkfuncname (lua_State *L, const char *modname) {
399 const char *funcname;
400 const char *mark = strchr(modname, *LUA_IGMARK);
401 if (mark) modname = mark + 1;
402 funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
403 funcname = lua_pushfstring(L, POF"%s", funcname);
404 lua_remove(L, -2);
405 return funcname;
406 }
407
408
409 static int loader_C (lua_State *L) {
410 const char *funcname;
411 const char *name = luaL_checkstring(L, 1);
412 const char *filename = findfile(L, name, "cpath");
413 if (filename == NULL) return 1;
414 funcname = mkfuncname(L, name);
415 if (ll_loadfunc(L, filename, funcname) != 0)
416 loaderror(L, filename);
417 return 1;
418 }
419
420
421 static int loader_Croot (lua_State *L) {
422 const char *funcname;
423 const char *filename;
424 const char *name = luaL_checkstring(L, 1);
425 const char *p = strchr(name, '.');
426 int stat;
427 if (p == NULL) return 0;
428 lua_pushlstring(L, name, p - name);
429 filename = findfile(L, lua_tostring(L, -1), "cpath");
430 if (filename == NULL) return 1;
431 funcname = mkfuncname(L, name);
432 if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
433 if (stat != ERRFUNC) loaderror(L, filename);
434 lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
435 name, filename);
436 return 1;
437 }
438 return 1;
439 }
440 #endif
441
442 static int loader_preload (lua_State *L) {
443 const char *name = luaL_checkstring(L, 1);
444 lua_getfield(L, LUA_ENVIRONINDEX, "preload");
445 if (!lua_istable(L, -1))
446 luaL_error(L, LUA_QL("package.preload") " must be a table");
447 lua_getfield(L, -1, name);
448 if (lua_isnil(L, -1))
449 lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
450 return 1;
451 }
452
453
454 static const int sentinel_ = 0;
455 #define sentinel ((void *)&sentinel_)
456
457
458 static int ll_require (lua_State *L) {
459 const char *name = luaL_checkstring(L, 1);
460 int i;
461 lua_settop(L, 1);
462 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
463 lua_getfield(L, 2, name);
464 if (lua_toboolean(L, -1)) {
465 if (lua_touserdata(L, -1) == sentinel)
466 luaL_error(L, "loop or previous error loading module " LUA_QS, name);
467 return 1;
468 }
469
470 lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
471 if (!lua_istable(L, -1))
472 luaL_error(L, LUA_QL("package.loaders") " must be a table");
473 lua_pushliteral(L, "");
474 for (i=1; ; i++) {
475 lua_rawgeti(L, -2, i);
476 if (lua_isnil(L, -1))
477 luaL_error(L, "module " LUA_QS " not found:%s",
478 name, lua_tostring(L, -2));
479 lua_pushstring(L, name);
480 lua_call(L, 1, 1);
481 if (lua_isfunction(L, -1))
482 break;
483 else if (lua_isstring(L, -1))
484 lua_concat(L, 2);
485 else
486 lua_pop(L, 1);
487 }
488 lua_pushlightuserdata(L, sentinel);
489 lua_setfield(L, 2, name);
490 lua_pushstring(L, name);
491 lua_call(L, 1, 1);
492 if (!lua_isnil(L, -1))
493 lua_setfield(L, 2, name);
494 lua_getfield(L, 2, name);
495 if (lua_touserdata(L, -1) == sentinel) {
496 lua_pushboolean(L, 1);
497 lua_pushvalue(L, -1);
498 lua_setfield(L, 2, name);
499 }
500 return 1;
501 }
502
503
504
505
506 #if 0
507
508
509
510
511
512
513
514 static void setfenv (lua_State *L) {
515 lua_Debug ar;
516 if (lua_getstack(L, 1, &ar) == 0 ||
517 lua_getinfo(L, "f", &ar) == 0 ||
518 lua_iscfunction(L, -1))
519 luaL_error(L, LUA_QL("module") " not called from a Lua function");
520 lua_pushvalue(L, -2);
521 lua_setfenv(L, -2);
522 lua_pop(L, 1);
523 }
524
525
526 static void dooptions (lua_State *L, int n) {
527 int i;
528 for (i = 2; i <= n; i++) {
529 lua_pushvalue(L, i);
530 lua_pushvalue(L, -2);
531 lua_call(L, 1, 0);
532 }
533 }
534
535
536 static void modinit (lua_State *L, const char *modname) {
537 const char *dot;
538 lua_pushvalue(L, -1);
539 lua_setfield(L, -2, "_M");
540 lua_pushstring(L, modname);
541 lua_setfield(L, -2, "_NAME");
542 dot = strrchr(modname, '.');
543 if (dot == NULL) dot = modname;
544 else dot++;
545
546 lua_pushlstring(L, modname, dot - modname);
547 lua_setfield(L, -2, "_PACKAGE");
548 }
549
550
551 static int ll_module (lua_State *L) {
552 const char *modname = luaL_checkstring(L, 1);
553 int loaded = lua_gettop(L) + 1;
554 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
555 lua_getfield(L, loaded, modname);
556 if (!lua_istable(L, -1)) {
557 lua_pop(L, 1);
558
559 if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
560 return luaL_error(L, "name conflict for module " LUA_QS, modname);
561 lua_pushvalue(L, -1);
562 lua_setfield(L, loaded, modname);
563 }
564
565 lua_getfield(L, -1, "_NAME");
566 if (!lua_isnil(L, -1))
567 lua_pop(L, 1);
568 else {
569 lua_pop(L, 1);
570 modinit(L, modname);
571 }
572 lua_pushvalue(L, -1);
573 setfenv(L);
574 dooptions(L, loaded - 1);
575 return 0;
576 }
577
578
579 static int ll_seeall (lua_State *L) {
580 luaL_checktype(L, 1, LUA_TTABLE);
581 if (!lua_getmetatable(L, 1)) {
582 lua_createtable(L, 0, 1);
583 lua_pushvalue(L, -1);
584 lua_setmetatable(L, 1);
585 }
586 lua_pushvalue(L, LUA_GLOBALSINDEX);
587 lua_setfield(L, -2, "__index");
588 return 0;
589 }
590 #endif
591
592
593
594
595
596 #define AUXMARK "\1"
597
598 static void setpath (lua_State *L, const char *fieldname, __attribute__ ((unused))const char *envname,
599 const char *def) {
600
601 #if defined(HDK_VERSION)
602 lua_pushstring(L, def);
603 #else
604 const char *path = getenv(envname);
605 if (path == NULL)
606 lua_pushstring(L, def);
607 else {
608
609 path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
610 LUA_PATHSEP AUXMARK LUA_PATHSEP);
611 luaL_gsub(L, path, AUXMARK, def);
612 lua_remove(L, -2);
613 }
614 #endif
615 setprogdir(L);
616 lua_setfield(L, -2, fieldname);
617 }
618
619 static const luaL_Reg pk_funcs[] = {
620
621
622 {NULL, NULL}
623 };
624
625
626 static const luaL_Reg ll_funcs[] = {
627
628 {"require", ll_require},
629 {NULL, NULL}
630 };
631
632
633 static const lua_CFunction loaders[] =
634 {loader_preload, loader_Lua, NULL};
635
636
637 LUALIB_API int luaopen_package (lua_State *L) {
638 int i;
639 #if 0
640
641 luaL_newmetatable(L, "_LOADLIB");
642 lua_pushcfunction(L, gctm);
643 lua_setfield(L, -2, "__gc");
644 #endif
645
646 luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
647 #if 0
648 #if defined(LUA_COMPAT_LOADLIB)
649 lua_getfield(L, -1, "loadlib");
650 lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
651 #endif
652 #endif
653 lua_pushvalue(L, -1);
654 lua_replace(L, LUA_ENVIRONINDEX);
655
656 lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0);
657
658 for (i=0; loaders[i] != NULL; i++) {
659 lua_pushcfunction(L, loaders[i]);
660 lua_rawseti(L, -2, i+1);
661 }
662 lua_setfield(L, -2, "loaders");
663 setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT);
664 setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT);
665
666 lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n"
667 LUA_EXECDIR "\n" LUA_IGMARK);
668 lua_setfield(L, -2, "config");
669
670 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2);
671 lua_setfield(L, -2, "loaded");
672
673 lua_newtable(L);
674 lua_setfield(L, -2, "preload");
675 lua_pushvalue(L, LUA_GLOBALSINDEX);
676 luaL_register(L, NULL, ll_funcs);
677 lua_pop(L, 1);
678 return 1;
679 }
680