Tamar 0.7.5 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/.gitmodules +3 -0
  2. data/HISTORY +22 -5
  3. data/Tamar.gemspec +114 -1
  4. data/VERSION +1 -1
  5. data/src/lua/CMakeLists.txt +176 -0
  6. data/src/lua/COPYRIGHT +34 -0
  7. data/src/lua/FindReadline.cmake +25 -0
  8. data/src/lua/HISTORY +183 -0
  9. data/src/lua/INSTALL +99 -0
  10. data/src/lua/Makefile +128 -0
  11. data/src/lua/README +46 -0
  12. data/src/lua/dist.cmake +450 -0
  13. data/src/lua/dist.info +10 -0
  14. data/src/lua/doc/amazon.gif +0 -0
  15. data/src/lua/doc/contents.html +499 -0
  16. data/src/lua/doc/cover.png +0 -0
  17. data/src/lua/doc/logo.gif +0 -0
  18. data/src/lua/doc/lua.1 +163 -0
  19. data/src/lua/doc/lua.css +41 -0
  20. data/src/lua/doc/lua.html +172 -0
  21. data/src/lua/doc/luac.1 +136 -0
  22. data/src/lua/doc/luac.html +145 -0
  23. data/src/lua/doc/manual.css +13 -0
  24. data/src/lua/doc/manual.html +8801 -0
  25. data/src/lua/doc/readme.html +40 -0
  26. data/src/lua/etc/Makefile +44 -0
  27. data/src/lua/etc/README +37 -0
  28. data/src/lua/etc/all.c +38 -0
  29. data/src/lua/etc/lua.hpp +9 -0
  30. data/src/lua/etc/lua.ico +0 -0
  31. data/src/lua/etc/lua.pc +31 -0
  32. data/src/lua/etc/luavs.bat +28 -0
  33. data/src/lua/etc/min.c +39 -0
  34. data/src/lua/etc/noparser.c +50 -0
  35. data/src/lua/etc/strict.lua +41 -0
  36. data/src/lua/src/Makefile +182 -0
  37. data/src/lua/src/lapi.c +1087 -0
  38. data/src/lua/src/lapi.h +16 -0
  39. data/src/lua/src/lauxlib.c +652 -0
  40. data/src/lua/src/lauxlib.h +174 -0
  41. data/src/lua/src/lbaselib.c +653 -0
  42. data/src/lua/src/lcode.c +831 -0
  43. data/src/lua/src/lcode.h +76 -0
  44. data/src/lua/src/ldblib.c +398 -0
  45. data/src/lua/src/ldebug.c +638 -0
  46. data/src/lua/src/ldebug.h +33 -0
  47. data/src/lua/src/ldo.c +518 -0
  48. data/src/lua/src/ldo.h +57 -0
  49. data/src/lua/src/ldump.c +164 -0
  50. data/src/lua/src/lfunc.c +174 -0
  51. data/src/lua/src/lfunc.h +34 -0
  52. data/src/lua/src/lgc.c +711 -0
  53. data/src/lua/src/lgc.h +110 -0
  54. data/src/lua/src/linit.c +38 -0
  55. data/src/lua/src/liolib.c +556 -0
  56. data/src/lua/src/llex.c +463 -0
  57. data/src/lua/src/llex.h +81 -0
  58. data/src/lua/src/llimits.h +128 -0
  59. data/src/lua/src/lmathlib.c +263 -0
  60. data/src/lua/src/lmem.c +86 -0
  61. data/src/lua/src/lmem.h +49 -0
  62. data/src/lua/src/loadlib.c +666 -0
  63. data/src/lua/src/loadlib_rel.c +719 -0
  64. data/src/lua/src/lobject.c +214 -0
  65. data/src/lua/src/lobject.h +381 -0
  66. data/src/lua/src/lopcodes.c +102 -0
  67. data/src/lua/src/lopcodes.h +268 -0
  68. data/src/lua/src/loslib.c +243 -0
  69. data/src/lua/src/lparser.c +1339 -0
  70. data/src/lua/src/lparser.h +82 -0
  71. data/src/lua/src/lstate.c +214 -0
  72. data/src/lua/src/lstate.h +169 -0
  73. data/src/lua/src/lstring.c +111 -0
  74. data/src/lua/src/lstring.h +31 -0
  75. data/src/lua/src/lstrlib.c +871 -0
  76. data/src/lua/src/ltable.c +588 -0
  77. data/src/lua/src/ltable.h +40 -0
  78. data/src/lua/src/ltablib.c +287 -0
  79. data/src/lua/src/ltm.c +75 -0
  80. data/src/lua/src/ltm.h +54 -0
  81. data/src/lua/src/lua.c +392 -0
  82. data/src/lua/src/lua.def +131 -0
  83. data/src/lua/src/lua.h +388 -0
  84. data/src/lua/src/lua.rc +28 -0
  85. data/src/lua/src/lua_dll.rc +26 -0
  86. data/src/lua/src/luac.c +200 -0
  87. data/src/lua/src/luac.rc +1 -0
  88. data/src/lua/src/luaconf.h.in +724 -0
  89. data/src/lua/src/luaconf.h.orig +763 -0
  90. data/src/lua/src/lualib.h +53 -0
  91. data/src/lua/src/lundump.c +227 -0
  92. data/src/lua/src/lundump.h +36 -0
  93. data/src/lua/src/lvm.c +766 -0
  94. data/src/lua/src/lvm.h +36 -0
  95. data/src/lua/src/lzio.c +82 -0
  96. data/src/lua/src/lzio.h +67 -0
  97. data/src/lua/src/print.c +227 -0
  98. data/src/lua/test/README +26 -0
  99. data/src/lua/test/bisect.lua +27 -0
  100. data/src/lua/test/cf.lua +16 -0
  101. data/src/lua/test/echo.lua +5 -0
  102. data/src/lua/test/env.lua +7 -0
  103. data/src/lua/test/factorial.lua +32 -0
  104. data/src/lua/test/fib.lua +40 -0
  105. data/src/lua/test/fibfor.lua +13 -0
  106. data/src/lua/test/globals.lua +13 -0
  107. data/src/lua/test/hello.lua +3 -0
  108. data/src/lua/test/life.lua +111 -0
  109. data/src/lua/test/luac.lua +7 -0
  110. data/src/lua/test/printf.lua +7 -0
  111. data/src/lua/test/readonly.lua +12 -0
  112. data/src/lua/test/sieve.lua +29 -0
  113. data/src/lua/test/sort.lua +66 -0
  114. data/src/lua/test/table.lua +12 -0
  115. data/src/lua/test/trace-calls.lua +32 -0
  116. data/src/lua/test/trace-globals.lua +38 -0
  117. data/src/lua/test/xd.lua +14 -0
  118. metadata +115 -2
@@ -0,0 +1,719 @@
1
+ /*
2
+ ** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $
3
+ ** Dynamic library loader for Lua
4
+ ** See Copyright Notice in lua.h
5
+ **
6
+ ** This module contains an implementation of loadlib for Unix systems
7
+ ** that have dlfcn, an implementation for Darwin (Mac OS X), an
8
+ ** implementation for Windows, and a stub for other systems.
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
+ /* prefix for open functions in C libraries */
26
+ #define LUA_POF "luaopen_"
27
+
28
+ /* separator for open functions in C libraries */
29
+ #define LUA_OFSEP "_"
30
+
31
+
32
+ #define LIBPREFIX "LOADLIB: "
33
+
34
+ #define POF LUA_POF
35
+ #define LIB_FAIL "open"
36
+
37
+
38
+ /* error codes for ll_loadfunc */
39
+ #define ERRLIB 1
40
+ #define ERRFUNC 2
41
+
42
+ static void ll_unloadlib (void *lib);
43
+ static void *ll_load (lua_State *L, const char *path);
44
+ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
45
+ static void setprogdir (lua_State *L);
46
+
47
+ /*
48
+ ** {=========================================================================
49
+ ** This determines the location of the executable for relative module loading
50
+ ** ==========================================================================
51
+ */
52
+ #if defined(_WIN32) || defined(__CYGWIN__)
53
+ #include <windows.h>
54
+ #define _PATH_MAX MAX_PATH
55
+ #else
56
+ #define _PATH_MAX PATH_MAX
57
+ #endif
58
+
59
+ #if defined(__linux__)
60
+ #include <unistd.h> /* readlink */
61
+ #endif
62
+
63
+ #if defined(__APPLE__)
64
+ #include <sys/param.h>
65
+ #include <mach-o/dyld.h>
66
+ #endif
67
+
68
+ static void setprogdir (lua_State *L) {
69
+ char progdir[_PATH_MAX + 1];
70
+ char *lb;
71
+ int nsize = sizeof(progdir)/sizeof(char);
72
+ int n;
73
+ #if defined(__CYGWIN__)
74
+ char win_buff[_PATH_MAX + 1];
75
+ GetModuleFileNameA(NULL, win_buff, nsize);
76
+ cygwin_conv_to_posix_path(win_buff, progdir);
77
+ n = strlen(progdir);
78
+ #elif defined(_WIN32)
79
+ n = GetModuleFileNameA(NULL, progdir, nsize);
80
+ #elif defined(__linux__)
81
+ n = readlink("/proc/self/exe", progdir, nsize);
82
+ if (n > 0) progdir[n] = 0;
83
+ #elif defined(__FreeBSD__)
84
+ n = readlink("/proc/curproc/file", progdir, nsize);
85
+ if (n > 0) progdir[n] = 0;
86
+ #elif defined(__APPLE__)
87
+ uint32_t nsize_apple = nsize;
88
+ if (_NSGetExecutablePath(progdir, &nsize_apple) == 0)
89
+ n = strlen(progdir);
90
+ #else
91
+ // FALLBACK
92
+ // Use 'lsof' ... should work on most UNIX systems (incl. OSX)
93
+ // lsof will list open files, this captures the 1st file listed (usually the executable)
94
+ int pid;
95
+ FILE* fd;
96
+ char cmd[80];
97
+ pid = getpid();
98
+
99
+ sprintf(cmd, "lsof -p %d | awk '{if ($5==\"REG\") { print $9 ; exit}}' 2> /dev/null", pid);
100
+ fd = popen(cmd, "r");
101
+ n = fread(progdir, 1, nsize, fd);
102
+
103
+ // remove newline
104
+ if (n > 1) progdir[--n] = '\0';
105
+ #endif
106
+ if (n == 0 || n == nsize || (lb = strrchr(progdir, (int)LUA_DIRSEP[0])) == NULL)
107
+ luaL_error(L, "unable to get process executable path");
108
+ else {
109
+ *lb = '\0';
110
+ // Set progdir global
111
+ lua_pushstring(L, progdir);
112
+ lua_setglobal(L, "_PROGDIR");
113
+
114
+ // Replace the relative path placeholder
115
+ luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, progdir);
116
+ lua_remove(L, -2);
117
+ }
118
+ }
119
+
120
+ /* }====================================================== */
121
+
122
+ #if defined(LUA_DL_DLOPEN)
123
+ /*
124
+ ** {========================================================================
125
+ ** This is an implementation of loadlib based on the dlfcn interface.
126
+ ** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
127
+ ** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
128
+ ** as an emulation layer on top of native functions.
129
+ ** =========================================================================
130
+ */
131
+
132
+ #include <dlfcn.h>
133
+ #include <sys/stat.h>
134
+
135
+ static void ll_unloadlib (void *lib) {
136
+ dlclose(lib);
137
+ }
138
+
139
+ static void *ll_load (lua_State *L, const char *path) {
140
+ void *lib = dlopen(path, RTLD_NOW);
141
+ if (lib == NULL) lua_pushstring(L, dlerror());
142
+ return lib;
143
+ }
144
+
145
+
146
+ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
147
+ lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
148
+ if (f == NULL) lua_pushstring(L, dlerror());
149
+ return f;
150
+ }
151
+
152
+ /* }====================================================== */
153
+
154
+
155
+
156
+ #elif defined(LUA_DL_DLL)
157
+ /*
158
+ ** {======================================================================
159
+ ** This is an implementation of loadlib for Windows using native functions.
160
+ ** =======================================================================
161
+ */
162
+
163
+ #include <windows.h>
164
+
165
+ static void pusherror (lua_State *L) {
166
+ int error = GetLastError();
167
+ char buffer[128];
168
+ if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
169
+ NULL, error, 0, buffer, sizeof(buffer), NULL))
170
+ lua_pushstring(L, buffer);
171
+ else
172
+ lua_pushfstring(L, "system error %d\n", error);
173
+ }
174
+
175
+ static void ll_unloadlib (void *lib) {
176
+ FreeLibrary((HINSTANCE)lib);
177
+ }
178
+
179
+
180
+ static void *ll_load (lua_State *L, const char *path) {
181
+ HINSTANCE lib = LoadLibraryA(path);
182
+ if (lib == NULL) pusherror(L);
183
+ return lib;
184
+ }
185
+
186
+
187
+ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
188
+ lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
189
+ if (f == NULL) pusherror(L);
190
+ return f;
191
+ }
192
+
193
+ /* }====================================================== */
194
+
195
+
196
+
197
+ #elif defined(LUA_DL_DYLD)
198
+ /*
199
+ ** {======================================================================
200
+ ** Native Mac OS X / Darwin Implementation
201
+ ** =======================================================================
202
+ */
203
+
204
+ #include <mach-o/dyld.h>
205
+
206
+
207
+ /* Mac appends a `_' before C function names */
208
+ #undef POF
209
+ #define POF "_" LUA_POF
210
+
211
+
212
+ static void pusherror (lua_State *L) {
213
+ const char *err_str;
214
+ const char *err_file;
215
+ NSLinkEditErrors err;
216
+ int err_num;
217
+ NSLinkEditError(&err, &err_num, &err_file, &err_str);
218
+ lua_pushstring(L, err_str);
219
+ }
220
+
221
+
222
+ static const char *errorfromcode (NSObjectFileImageReturnCode ret) {
223
+ switch (ret) {
224
+ case NSObjectFileImageInappropriateFile:
225
+ return "file is not a bundle";
226
+ case NSObjectFileImageArch:
227
+ return "library is for wrong CPU type";
228
+ case NSObjectFileImageFormat:
229
+ return "bad format";
230
+ case NSObjectFileImageAccess:
231
+ return "cannot access file";
232
+ case NSObjectFileImageFailure:
233
+ default:
234
+ return "unable to load library";
235
+ }
236
+ }
237
+
238
+
239
+ static void ll_unloadlib (void *lib) {
240
+ NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
241
+ }
242
+
243
+
244
+ static void *ll_load (lua_State *L, const char *path) {
245
+ NSObjectFileImage img;
246
+ NSObjectFileImageReturnCode ret;
247
+ /* this would be a rare case, but prevents crashing if it happens */
248
+ if(!_dyld_present()) {
249
+ lua_pushliteral(L, "dyld not present");
250
+ return NULL;
251
+ }
252
+ ret = NSCreateObjectFileImageFromFile(path, &img);
253
+ if (ret == NSObjectFileImageSuccess) {
254
+ NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE |
255
+ NSLINKMODULE_OPTION_RETURN_ON_ERROR);
256
+ NSDestroyObjectFileImage(img);
257
+ if (mod == NULL) pusherror(L);
258
+ return mod;
259
+ }
260
+ lua_pushstring(L, errorfromcode(ret));
261
+ return NULL;
262
+ }
263
+
264
+
265
+ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
266
+ NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym);
267
+ if (nss == NULL) {
268
+ lua_pushfstring(L, "symbol " LUA_QS " not found", sym);
269
+ return NULL;
270
+ }
271
+ return (lua_CFunction)NSAddressOfSymbol(nss);
272
+ }
273
+
274
+ /* }====================================================== */
275
+
276
+
277
+
278
+ #else
279
+ /*
280
+ ** {======================================================
281
+ ** Fallback for other systems
282
+ ** =======================================================
283
+ */
284
+
285
+ #undef LIB_FAIL
286
+ #define LIB_FAIL "absent"
287
+
288
+
289
+ #define DLMSG "dynamic libraries not enabled; check your Lua installation"
290
+
291
+
292
+ static void ll_unloadlib (void *lib) {
293
+ (void)lib; /* to avoid warnings */
294
+ }
295
+
296
+
297
+ static void *ll_load (lua_State *L, const char *path) {
298
+ (void)path; /* to avoid warnings */
299
+ lua_pushliteral(L, DLMSG);
300
+ return NULL;
301
+ }
302
+
303
+
304
+ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
305
+ (void)lib; (void)sym; /* to avoid warnings */
306
+ lua_pushliteral(L, DLMSG);
307
+ return NULL;
308
+ }
309
+
310
+ /* }====================================================== */
311
+ #endif
312
+
313
+
314
+
315
+ static void **ll_register (lua_State *L, const char *path) {
316
+ void **plib;
317
+ lua_pushfstring(L, "%s%s", LIBPREFIX, path);
318
+ lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */
319
+ if (!lua_isnil(L, -1)) /* is there an entry? */
320
+ plib = (void **)lua_touserdata(L, -1);
321
+ else { /* no entry yet; create one */
322
+ lua_pop(L, 1);
323
+ plib = (void **)lua_newuserdata(L, sizeof(const void *));
324
+ *plib = NULL;
325
+ luaL_getmetatable(L, "_LOADLIB");
326
+ lua_setmetatable(L, -2);
327
+ lua_pushfstring(L, "%s%s", LIBPREFIX, path);
328
+ lua_pushvalue(L, -2);
329
+ lua_settable(L, LUA_REGISTRYINDEX);
330
+ }
331
+ return plib;
332
+ }
333
+
334
+
335
+ /*
336
+ ** __gc tag method: calls library's `ll_unloadlib' function with the lib
337
+ ** handle
338
+ */
339
+ static int gctm (lua_State *L) {
340
+ void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
341
+ if (*lib) ll_unloadlib(*lib);
342
+ *lib = NULL; /* mark library as closed */
343
+ return 0;
344
+ }
345
+
346
+
347
+ static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
348
+ void **reg = ll_register(L, path);
349
+ if (*reg == NULL) *reg = ll_load(L, path);
350
+ if (*reg == NULL)
351
+ return ERRLIB; /* unable to load library */
352
+ else {
353
+ lua_CFunction f = ll_sym(L, *reg, sym);
354
+ if (f == NULL)
355
+ return ERRFUNC; /* unable to find function */
356
+ lua_pushcfunction(L, f);
357
+ return 0; /* return function */
358
+ }
359
+ }
360
+
361
+
362
+ static int ll_loadlib (lua_State *L) {
363
+ const char *path = luaL_checkstring(L, 1);
364
+ const char *init = luaL_checkstring(L, 2);
365
+ int stat = ll_loadfunc(L, path, init);
366
+ if (stat == 0) /* no errors? */
367
+ return 1; /* return the loaded function */
368
+ else { /* error; error message is on stack top */
369
+ lua_pushnil(L);
370
+ lua_insert(L, -2);
371
+ lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
372
+ return 3; /* return nil, error message, and where */
373
+ }
374
+ }
375
+
376
+
377
+
378
+ /*
379
+ ** {======================================================
380
+ ** 'require' function
381
+ ** =======================================================
382
+ */
383
+
384
+
385
+ static int readable (const char *filename) {
386
+ FILE *f = fopen(filename, "r"); /* try to open file */
387
+ if (f == NULL) return 0; /* open failed */
388
+ fclose(f);
389
+ return 1;
390
+ }
391
+
392
+
393
+ static const char *pushnexttemplate (lua_State *L, const char *path) {
394
+ const char *l;
395
+ while (*path == *LUA_PATHSEP) path++; /* skip separators */
396
+ if (*path == '\0') return NULL; /* no more templates */
397
+ l = strchr(path, *LUA_PATHSEP); /* find next separator */
398
+ if (l == NULL) l = path + strlen(path);
399
+ lua_pushlstring(L, path, l - path); /* template */
400
+ return l;
401
+ }
402
+
403
+
404
+ static const char *findfile (lua_State *L, const char *name,
405
+ const char *pname) {
406
+ const char *path;
407
+ name = luaL_gsub(L, name, ".", LUA_DIRSEP);
408
+ lua_getfield(L, LUA_ENVIRONINDEX, pname);
409
+ path = lua_tostring(L, -1);
410
+ if (path == NULL)
411
+ luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
412
+ lua_pushliteral(L, ""); /* error accumulator */
413
+ while ((path = pushnexttemplate(L, path)) != NULL) {
414
+ const char *filename;
415
+ filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
416
+ lua_remove(L, -2); /* remove path template */
417
+ if (readable(filename)) /* does file exist and is readable? */
418
+ return filename; /* return that file name */
419
+ lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
420
+ lua_remove(L, -2); /* remove file name */
421
+ lua_concat(L, 2); /* add entry to possible error message */
422
+ }
423
+ return NULL; /* not found */
424
+ }
425
+
426
+
427
+ static void loaderror (lua_State *L, const char *filename) {
428
+ luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
429
+ lua_tostring(L, 1), filename, lua_tostring(L, -1));
430
+ }
431
+
432
+
433
+ static int loader_Lua (lua_State *L) {
434
+ const char *filename;
435
+ const char *name = luaL_checkstring(L, 1);
436
+ filename = findfile(L, name, "path");
437
+ if (filename == NULL) return 1; /* library not found in this path */
438
+ if (luaL_loadfile(L, filename) != 0)
439
+ loaderror(L, filename);
440
+ return 1; /* library loaded successfully */
441
+ }
442
+
443
+
444
+ static const char *mkfuncname (lua_State *L, const char *modname) {
445
+ const char *funcname;
446
+ const char *mark = strchr(modname, *LUA_IGMARK);
447
+ if (mark) modname = mark + 1;
448
+ funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
449
+ funcname = lua_pushfstring(L, POF"%s", funcname);
450
+ lua_remove(L, -2); /* remove 'gsub' result */
451
+ return funcname;
452
+ }
453
+
454
+
455
+ static int loader_C (lua_State *L) {
456
+ const char *funcname;
457
+ const char *name = luaL_checkstring(L, 1);
458
+ const char *filename = findfile(L, name, "cpath");
459
+ if (filename == NULL) return 1; /* library not found in this path */
460
+ funcname = mkfuncname(L, name);
461
+ if (ll_loadfunc(L, filename, funcname) != 0)
462
+ loaderror(L, filename);
463
+ return 1; /* library loaded successfully */
464
+ }
465
+
466
+
467
+ static int loader_Croot (lua_State *L) {
468
+ const char *funcname;
469
+ const char *filename;
470
+ const char *name = luaL_checkstring(L, 1);
471
+ const char *p = strchr(name, '.');
472
+ int stat;
473
+ if (p == NULL) return 0; /* is root */
474
+ lua_pushlstring(L, name, p - name);
475
+ filename = findfile(L, lua_tostring(L, -1), "cpath");
476
+ if (filename == NULL) return 1; /* root not found */
477
+ funcname = mkfuncname(L, name);
478
+ if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
479
+ if (stat != ERRFUNC) loaderror(L, filename); /* real error */
480
+ lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
481
+ name, filename);
482
+ return 1; /* function not found */
483
+ }
484
+ return 1;
485
+ }
486
+
487
+
488
+ static int loader_preload (lua_State *L) {
489
+ const char *name = luaL_checkstring(L, 1);
490
+ lua_getfield(L, LUA_ENVIRONINDEX, "preload");
491
+ if (!lua_istable(L, -1))
492
+ luaL_error(L, LUA_QL("package.preload") " must be a table");
493
+ lua_getfield(L, -1, name);
494
+ if (lua_isnil(L, -1)) /* not found? */
495
+ lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
496
+ return 1;
497
+ }
498
+
499
+
500
+ static const int sentinel_ = 0;
501
+ #define sentinel ((void *)&sentinel_)
502
+
503
+
504
+ static int ll_require (lua_State *L) {
505
+ const char *name = luaL_checkstring(L, 1);
506
+ int i;
507
+ lua_settop(L, 1); /* _LOADED table will be at index 2 */
508
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
509
+ lua_getfield(L, 2, name);
510
+ if (lua_toboolean(L, -1)) { /* is it there? */
511
+ if (lua_touserdata(L, -1) == sentinel) /* check loops */
512
+ luaL_error(L, "loop or previous error loading module " LUA_QS, name);
513
+ return 1; /* package is already loaded */
514
+ }
515
+ /* else must load it; iterate over available loaders */
516
+ lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
517
+ if (!lua_istable(L, -1))
518
+ luaL_error(L, LUA_QL("package.loaders") " must be a table");
519
+ lua_pushliteral(L, ""); /* error message accumulator */
520
+ for (i=1; ; i++) {
521
+ lua_rawgeti(L, -2, i); /* get a loader */
522
+ if (lua_isnil(L, -1))
523
+ luaL_error(L, "module " LUA_QS " not found:%s",
524
+ name, lua_tostring(L, -2));
525
+ lua_pushstring(L, name);
526
+ lua_call(L, 1, 1); /* call it */
527
+ if (lua_isfunction(L, -1)) /* did it find module? */
528
+ break; /* module loaded successfully */
529
+ else if (lua_isstring(L, -1)) /* loader returned error message? */
530
+ lua_concat(L, 2); /* accumulate it */
531
+ else
532
+ lua_pop(L, 1);
533
+ }
534
+ lua_pushlightuserdata(L, sentinel);
535
+ lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
536
+ lua_pushstring(L, name); /* pass name as argument to module */
537
+ lua_call(L, 1, 1); /* run loaded module */
538
+ if (!lua_isnil(L, -1)) /* non-nil return? */
539
+ lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
540
+ lua_getfield(L, 2, name);
541
+ if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */
542
+ lua_pushboolean(L, 1); /* use true as result */
543
+ lua_pushvalue(L, -1); /* extra copy to be returned */
544
+ lua_setfield(L, 2, name); /* _LOADED[name] = true */
545
+ }
546
+ return 1;
547
+ }
548
+
549
+ /* }====================================================== */
550
+
551
+
552
+
553
+ /*
554
+ ** {======================================================
555
+ ** 'module' function
556
+ ** =======================================================
557
+ */
558
+
559
+
560
+ static void setfenv (lua_State *L) {
561
+ lua_Debug ar;
562
+ if (lua_getstack(L, 1, &ar) == 0 ||
563
+ lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
564
+ lua_iscfunction(L, -1))
565
+ luaL_error(L, LUA_QL("module") " not called from a Lua function");
566
+ lua_pushvalue(L, -2);
567
+ lua_setfenv(L, -2);
568
+ lua_pop(L, 1);
569
+ }
570
+
571
+
572
+ static void dooptions (lua_State *L, int n) {
573
+ int i;
574
+ for (i = 2; i <= n; i++) {
575
+ lua_pushvalue(L, i); /* get option (a function) */
576
+ lua_pushvalue(L, -2); /* module */
577
+ lua_call(L, 1, 0);
578
+ }
579
+ }
580
+
581
+
582
+ static void modinit (lua_State *L, const char *modname) {
583
+ const char *dot;
584
+ lua_pushvalue(L, -1);
585
+ lua_setfield(L, -2, "_M"); /* module._M = module */
586
+ lua_pushstring(L, modname);
587
+ lua_setfield(L, -2, "_NAME");
588
+ dot = strrchr(modname, '.'); /* look for last dot in module name */
589
+ if (dot == NULL) dot = modname;
590
+ else dot++;
591
+ /* set _PACKAGE as package name (full module name minus last part) */
592
+ lua_pushlstring(L, modname, dot - modname);
593
+ lua_setfield(L, -2, "_PACKAGE");
594
+ }
595
+
596
+
597
+ static int ll_module (lua_State *L) {
598
+ const char *modname = luaL_checkstring(L, 1);
599
+ int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
600
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
601
+ lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
602
+ if (!lua_istable(L, -1)) { /* not found? */
603
+ lua_pop(L, 1); /* remove previous result */
604
+ /* try global variable (and create one if it does not exist) */
605
+ if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
606
+ return luaL_error(L, "name conflict for module " LUA_QS, modname);
607
+ lua_pushvalue(L, -1);
608
+ lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
609
+ }
610
+ /* check whether table already has a _NAME field */
611
+ lua_getfield(L, -1, "_NAME");
612
+ if (!lua_isnil(L, -1)) /* is table an initialized module? */
613
+ lua_pop(L, 1);
614
+ else { /* no; initialize it */
615
+ lua_pop(L, 1);
616
+ modinit(L, modname);
617
+ }
618
+ lua_pushvalue(L, -1);
619
+ setfenv(L);
620
+ dooptions(L, loaded - 1);
621
+ return 0;
622
+ }
623
+
624
+
625
+ static int ll_seeall (lua_State *L) {
626
+ luaL_checktype(L, 1, LUA_TTABLE);
627
+ if (!lua_getmetatable(L, 1)) {
628
+ lua_createtable(L, 0, 1); /* create new metatable */
629
+ lua_pushvalue(L, -1);
630
+ lua_setmetatable(L, 1);
631
+ }
632
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
633
+ lua_setfield(L, -2, "__index"); /* mt.__index = _G */
634
+ return 0;
635
+ }
636
+
637
+
638
+ /* }====================================================== */
639
+
640
+
641
+
642
+ /* auxiliary mark (for internal use) */
643
+ #define AUXMARK "\1"
644
+
645
+ static void setpath (lua_State *L, const char *fieldname, const char *envname,
646
+ const char *def) {
647
+ const char *path = getenv(envname);
648
+ if (path == NULL) /* no environment variable? */
649
+ lua_pushstring(L, def); /* use default */
650
+ else {
651
+ /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
652
+ path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
653
+ LUA_PATHSEP AUXMARK LUA_PATHSEP);
654
+ luaL_gsub(L, path, AUXMARK, def);
655
+ lua_remove(L, -2);
656
+ }
657
+ setprogdir(L);
658
+ lua_setfield(L, -2, fieldname);
659
+ }
660
+
661
+
662
+ static const luaL_Reg pk_funcs[] = {
663
+ {"loadlib", ll_loadlib},
664
+ {"seeall", ll_seeall},
665
+ {NULL, NULL}
666
+ };
667
+
668
+
669
+ static const luaL_Reg ll_funcs[] = {
670
+ {"module", ll_module},
671
+ {"require", ll_require},
672
+ {NULL, NULL}
673
+ };
674
+
675
+
676
+ static const lua_CFunction loaders[] =
677
+ {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
678
+
679
+
680
+ LUALIB_API int luaopen_package (lua_State *L) {
681
+ int i;
682
+ /* create new type _LOADLIB */
683
+ luaL_newmetatable(L, "_LOADLIB");
684
+ lua_pushcfunction(L, gctm);
685
+ lua_setfield(L, -2, "__gc");
686
+ /* create `package' table */
687
+ luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
688
+ #if defined(LUA_COMPAT_LOADLIB)
689
+ lua_getfield(L, -1, "loadlib");
690
+ lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
691
+ #endif
692
+ lua_pushvalue(L, -1);
693
+ lua_replace(L, LUA_ENVIRONINDEX);
694
+ /* create `loaders' table */
695
+ lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0);
696
+ /* fill it with pre-defined loaders */
697
+ for (i=0; loaders[i] != NULL; i++) {
698
+ lua_pushcfunction(L, loaders[i]);
699
+ lua_rawseti(L, -2, i+1);
700
+ }
701
+ lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */
702
+ setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */
703
+ setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */
704
+ /* store config information */
705
+ lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n"
706
+ LUA_EXECDIR "\n" LUA_IGMARK);
707
+ lua_setfield(L, -2, "config");
708
+ /* set field `loaded' */
709
+ luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2);
710
+ lua_setfield(L, -2, "loaded");
711
+ /* set field `preload' */
712
+ lua_newtable(L);
713
+ lua_setfield(L, -2, "preload");
714
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
715
+ luaL_register(L, NULL, ll_funcs); /* open lib into global table */
716
+ lua_pop(L, 1);
717
+ return 1; /* return 'package' table */
718
+ }
719
+