annotate lib/lua/lua-5.2.2/loadlib.c @ 1866:41cc4dd3c122

Lua 5.2.2 added.
author Nomad
date Wed, 16 Oct 2013 13:34:26 +0200
parents
children
rev   line source
1866
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
1 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
2 ** $Id: loadlib.c,v 1.111 2012/05/30 12:33:44 roberto Exp $
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
3 ** Dynamic library loader for Lua
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
4 ** See Copyright Notice in lua.h
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
5 **
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
6 ** This module contains an implementation of loadlib for Unix systems
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
7 ** that have dlfcn, an implementation for Windows, and a stub for other
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
8 ** systems.
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
9 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
10
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
11
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
12 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
13 ** if needed, includes windows header before everything else
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
14 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
15 #if defined(_WIN32)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
16 #include <windows.h>
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
17 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
18
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
19
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
20 #include <stdlib.h>
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
21 #include <string.h>
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
22
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
23
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
24 #define loadlib_c
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
25 #define LUA_LIB
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
26
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
27 #include "lua.h"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
28
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
29 #include "lauxlib.h"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
30 #include "lualib.h"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
31
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
32
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
33 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
34 ** LUA_PATH and LUA_CPATH are the names of the environment
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
35 ** variables that Lua check to set its paths.
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
36 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
37 #if !defined(LUA_PATH)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
38 #define LUA_PATH "LUA_PATH"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
39 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
40
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
41 #if !defined(LUA_CPATH)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
42 #define LUA_CPATH "LUA_CPATH"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
43 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
44
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
45 #define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
46
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
47 #define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
48 #define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
49
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
50 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
51 ** LUA_PATH_SEP is the character that separates templates in a path.
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
52 ** LUA_PATH_MARK is the string that marks the substitution points in a
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
53 ** template.
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
54 ** LUA_EXEC_DIR in a Windows path is replaced by the executable's
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
55 ** directory.
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
56 ** LUA_IGMARK is a mark to ignore all before it when building the
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
57 ** luaopen_ function name.
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
58 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
59 #if !defined (LUA_PATH_SEP)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
60 #define LUA_PATH_SEP ";"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
61 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
62 #if !defined (LUA_PATH_MARK)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
63 #define LUA_PATH_MARK "?"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
64 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
65 #if !defined (LUA_EXEC_DIR)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
66 #define LUA_EXEC_DIR "!"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
67 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
68 #if !defined (LUA_IGMARK)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
69 #define LUA_IGMARK "-"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
70 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
71
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
72
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
73 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
74 ** LUA_CSUBSEP is the character that replaces dots in submodule names
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
75 ** when searching for a C loader.
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
76 ** LUA_LSUBSEP is the character that replaces dots in submodule names
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
77 ** when searching for a Lua loader.
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
78 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
79 #if !defined(LUA_CSUBSEP)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
80 #define LUA_CSUBSEP LUA_DIRSEP
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
81 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
82
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
83 #if !defined(LUA_LSUBSEP)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
84 #define LUA_LSUBSEP LUA_DIRSEP
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
85 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
86
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
87
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
88 /* prefix for open functions in C libraries */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
89 #define LUA_POF "luaopen_"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
90
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
91 /* separator for open functions in C libraries */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
92 #define LUA_OFSEP "_"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
93
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
94
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
95 /* table (in the registry) that keeps handles for all loaded C libraries */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
96 #define CLIBS "_CLIBS"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
97
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
98 #define LIB_FAIL "open"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
99
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
100
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
101 /* error codes for ll_loadfunc */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
102 #define ERRLIB 1
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
103 #define ERRFUNC 2
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
104
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
105 #define setprogdir(L) ((void)0)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
106
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
107
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
108 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
109 ** system-dependent functions
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
110 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
111 static void ll_unloadlib (void *lib);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
112 static void *ll_load (lua_State *L, const char *path, int seeglb);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
113 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
114
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
115
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
116
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
117 #if defined(LUA_USE_DLOPEN)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
118 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
119 ** {========================================================================
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
120 ** This is an implementation of loadlib based on the dlfcn interface.
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
121 ** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
122 ** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
123 ** as an emulation layer on top of native functions.
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
124 ** =========================================================================
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
125 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
126
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
127 #include <dlfcn.h>
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
128
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
129 static void ll_unloadlib (void *lib) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
130 dlclose(lib);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
131 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
132
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
133
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
134 static void *ll_load (lua_State *L, const char *path, int seeglb) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
135 void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
136 if (lib == NULL) lua_pushstring(L, dlerror());
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
137 return lib;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
138 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
139
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
140
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
141 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
142 lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
143 if (f == NULL) lua_pushstring(L, dlerror());
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
144 return f;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
145 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
146
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
147 /* }====================================================== */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
148
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
149
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
150
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
151 #elif defined(LUA_DL_DLL)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
152 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
153 ** {======================================================================
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
154 ** This is an implementation of loadlib for Windows using native functions.
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
155 ** =======================================================================
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
156 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
157
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
158 #undef setprogdir
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
159
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
160 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
161 ** optional flags for LoadLibraryEx
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
162 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
163 #if !defined(LUA_LLE_FLAGS)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
164 #define LUA_LLE_FLAGS 0
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
165 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
166
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
167
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
168 static void setprogdir (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
169 char buff[MAX_PATH + 1];
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
170 char *lb;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
171 DWORD nsize = sizeof(buff)/sizeof(char);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
172 DWORD n = GetModuleFileNameA(NULL, buff, nsize);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
173 if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
174 luaL_error(L, "unable to get ModuleFileName");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
175 else {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
176 *lb = '\0';
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
177 luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
178 lua_remove(L, -2); /* remove original string */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
179 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
180 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
181
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
182
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
183 static void pusherror (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
184 int error = GetLastError();
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
185 char buffer[128];
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
186 if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
187 NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL))
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
188 lua_pushstring(L, buffer);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
189 else
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
190 lua_pushfstring(L, "system error %d\n", error);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
191 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
192
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
193 static void ll_unloadlib (void *lib) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
194 FreeLibrary((HMODULE)lib);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
195 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
196
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
197
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
198 static void *ll_load (lua_State *L, const char *path, int seeglb) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
199 HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
200 (void)(seeglb); /* not used: symbols are 'global' by default */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
201 if (lib == NULL) pusherror(L);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
202 return lib;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
203 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
204
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
205
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
206 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
207 lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
208 if (f == NULL) pusherror(L);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
209 return f;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
210 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
211
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
212 /* }====================================================== */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
213
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
214
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
215 #else
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
216 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
217 ** {======================================================
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
218 ** Fallback for other systems
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
219 ** =======================================================
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
220 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
221
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
222 #undef LIB_FAIL
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
223 #define LIB_FAIL "absent"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
224
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
225
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
226 #define DLMSG "dynamic libraries not enabled; check your Lua installation"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
227
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
228
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
229 static void ll_unloadlib (void *lib) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
230 (void)(lib); /* not used */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
231 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
232
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
233
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
234 static void *ll_load (lua_State *L, const char *path, int seeglb) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
235 (void)(path); (void)(seeglb); /* not used */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
236 lua_pushliteral(L, DLMSG);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
237 return NULL;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
238 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
239
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
240
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
241 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
242 (void)(lib); (void)(sym); /* not used */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
243 lua_pushliteral(L, DLMSG);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
244 return NULL;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
245 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
246
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
247 /* }====================================================== */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
248 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
249
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
250
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
251 static void *ll_checkclib (lua_State *L, const char *path) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
252 void *plib;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
253 lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
254 lua_getfield(L, -1, path);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
255 plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
256 lua_pop(L, 2); /* pop CLIBS table and 'plib' */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
257 return plib;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
258 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
259
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
260
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
261 static void ll_addtoclib (lua_State *L, const char *path, void *plib) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
262 lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
263 lua_pushlightuserdata(L, plib);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
264 lua_pushvalue(L, -1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
265 lua_setfield(L, -3, path); /* CLIBS[path] = plib */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
266 lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
267 lua_pop(L, 1); /* pop CLIBS table */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
268 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
269
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
270
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
271 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
272 ** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
273 ** handles in list CLIBS
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
274 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
275 static int gctm (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
276 int n = luaL_len(L, 1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
277 for (; n >= 1; n--) { /* for each handle, in reverse order */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
278 lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
279 ll_unloadlib(lua_touserdata(L, -1));
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
280 lua_pop(L, 1); /* pop handle */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
281 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
282 return 0;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
283 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
284
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
285
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
286 static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
287 void *reg = ll_checkclib(L, path); /* check loaded C libraries */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
288 if (reg == NULL) { /* must load library? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
289 reg = ll_load(L, path, *sym == '*');
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
290 if (reg == NULL) return ERRLIB; /* unable to load library */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
291 ll_addtoclib(L, path, reg);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
292 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
293 if (*sym == '*') { /* loading only library (no function)? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
294 lua_pushboolean(L, 1); /* return 'true' */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
295 return 0; /* no errors */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
296 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
297 else {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
298 lua_CFunction f = ll_sym(L, reg, sym);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
299 if (f == NULL)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
300 return ERRFUNC; /* unable to find function */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
301 lua_pushcfunction(L, f); /* else create new function */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
302 return 0; /* no errors */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
303 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
304 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
305
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
306
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
307 static int ll_loadlib (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
308 const char *path = luaL_checkstring(L, 1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
309 const char *init = luaL_checkstring(L, 2);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
310 int stat = ll_loadfunc(L, path, init);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
311 if (stat == 0) /* no errors? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
312 return 1; /* return the loaded function */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
313 else { /* error; error message is on stack top */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
314 lua_pushnil(L);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
315 lua_insert(L, -2);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
316 lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
317 return 3; /* return nil, error message, and where */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
318 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
319 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
320
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
321
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
322
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
323 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
324 ** {======================================================
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
325 ** 'require' function
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
326 ** =======================================================
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
327 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
328
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
329
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
330 static int readable (const char *filename) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
331 FILE *f = fopen(filename, "r"); /* try to open file */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
332 if (f == NULL) return 0; /* open failed */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
333 fclose(f);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
334 return 1;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
335 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
336
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
337
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
338 static const char *pushnexttemplate (lua_State *L, const char *path) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
339 const char *l;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
340 while (*path == *LUA_PATH_SEP) path++; /* skip separators */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
341 if (*path == '\0') return NULL; /* no more templates */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
342 l = strchr(path, *LUA_PATH_SEP); /* find next separator */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
343 if (l == NULL) l = path + strlen(path);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
344 lua_pushlstring(L, path, l - path); /* template */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
345 return l;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
346 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
347
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
348
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
349 static const char *searchpath (lua_State *L, const char *name,
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
350 const char *path,
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
351 const char *sep,
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
352 const char *dirsep) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
353 luaL_Buffer msg; /* to build error message */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
354 luaL_buffinit(L, &msg);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
355 if (*sep != '\0') /* non-empty separator? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
356 name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
357 while ((path = pushnexttemplate(L, path)) != NULL) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
358 const char *filename = luaL_gsub(L, lua_tostring(L, -1),
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
359 LUA_PATH_MARK, name);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
360 lua_remove(L, -2); /* remove path template */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
361 if (readable(filename)) /* does file exist and is readable? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
362 return filename; /* return that file name */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
363 lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
364 lua_remove(L, -2); /* remove file name */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
365 luaL_addvalue(&msg); /* concatenate error msg. entry */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
366 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
367 luaL_pushresult(&msg); /* create error message */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
368 return NULL; /* not found */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
369 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
370
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
371
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
372 static int ll_searchpath (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
373 const char *f = searchpath(L, luaL_checkstring(L, 1),
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
374 luaL_checkstring(L, 2),
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
375 luaL_optstring(L, 3, "."),
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
376 luaL_optstring(L, 4, LUA_DIRSEP));
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
377 if (f != NULL) return 1;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
378 else { /* error message is on top of the stack */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
379 lua_pushnil(L);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
380 lua_insert(L, -2);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
381 return 2; /* return nil + error message */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
382 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
383 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
384
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
385
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
386 static const char *findfile (lua_State *L, const char *name,
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
387 const char *pname,
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
388 const char *dirsep) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
389 const char *path;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
390 lua_getfield(L, lua_upvalueindex(1), pname);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
391 path = lua_tostring(L, -1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
392 if (path == NULL)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
393 luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
394 return searchpath(L, name, path, ".", dirsep);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
395 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
396
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
397
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
398 static int checkload (lua_State *L, int stat, const char *filename) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
399 if (stat) { /* module loaded successfully? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
400 lua_pushstring(L, filename); /* will be 2nd argument to module */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
401 return 2; /* return open function and file name */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
402 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
403 else
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
404 return luaL_error(L, "error loading module " LUA_QS
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
405 " from file " LUA_QS ":\n\t%s",
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
406 lua_tostring(L, 1), filename, lua_tostring(L, -1));
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
407 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
408
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
409
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
410 static int searcher_Lua (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
411 const char *filename;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
412 const char *name = luaL_checkstring(L, 1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
413 filename = findfile(L, name, "path", LUA_LSUBSEP);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
414 if (filename == NULL) return 1; /* module not found in this path */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
415 return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
416 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
417
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
418
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
419 static int loadfunc (lua_State *L, const char *filename, const char *modname) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
420 const char *funcname;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
421 const char *mark;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
422 modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
423 mark = strchr(modname, *LUA_IGMARK);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
424 if (mark) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
425 int stat;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
426 funcname = lua_pushlstring(L, modname, mark - modname);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
427 funcname = lua_pushfstring(L, LUA_POF"%s", funcname);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
428 stat = ll_loadfunc(L, filename, funcname);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
429 if (stat != ERRFUNC) return stat;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
430 modname = mark + 1; /* else go ahead and try old-style name */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
431 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
432 funcname = lua_pushfstring(L, LUA_POF"%s", modname);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
433 return ll_loadfunc(L, filename, funcname);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
434 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
435
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
436
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
437 static int searcher_C (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
438 const char *name = luaL_checkstring(L, 1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
439 const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
440 if (filename == NULL) return 1; /* module not found in this path */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
441 return checkload(L, (loadfunc(L, filename, name) == 0), filename);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
442 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
443
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
444
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
445 static int searcher_Croot (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
446 const char *filename;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
447 const char *name = luaL_checkstring(L, 1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
448 const char *p = strchr(name, '.');
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
449 int stat;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
450 if (p == NULL) return 0; /* is root */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
451 lua_pushlstring(L, name, p - name);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
452 filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
453 if (filename == NULL) return 1; /* root not found */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
454 if ((stat = loadfunc(L, filename, name)) != 0) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
455 if (stat != ERRFUNC)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
456 return checkload(L, 0, filename); /* real error */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
457 else { /* open function not found */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
458 lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
459 name, filename);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
460 return 1;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
461 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
462 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
463 lua_pushstring(L, filename); /* will be 2nd argument to module */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
464 return 2;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
465 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
466
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
467
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
468 static int searcher_preload (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
469 const char *name = luaL_checkstring(L, 1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
470 lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
471 lua_getfield(L, -1, name);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
472 if (lua_isnil(L, -1)) /* not found? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
473 lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
474 return 1;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
475 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
476
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
477
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
478 static void findloader (lua_State *L, const char *name) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
479 int i;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
480 luaL_Buffer msg; /* to build error message */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
481 luaL_buffinit(L, &msg);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
482 lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
483 if (!lua_istable(L, 3))
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
484 luaL_error(L, LUA_QL("package.searchers") " must be a table");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
485 /* iterate over available searchers to find a loader */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
486 for (i = 1; ; i++) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
487 lua_rawgeti(L, 3, i); /* get a searcher */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
488 if (lua_isnil(L, -1)) { /* no more searchers? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
489 lua_pop(L, 1); /* remove nil */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
490 luaL_pushresult(&msg); /* create error message */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
491 luaL_error(L, "module " LUA_QS " not found:%s",
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
492 name, lua_tostring(L, -1));
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
493 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
494 lua_pushstring(L, name);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
495 lua_call(L, 1, 2); /* call it */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
496 if (lua_isfunction(L, -2)) /* did it find a loader? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
497 return; /* module loader found */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
498 else if (lua_isstring(L, -2)) { /* searcher returned error message? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
499 lua_pop(L, 1); /* remove extra return */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
500 luaL_addvalue(&msg); /* concatenate error message */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
501 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
502 else
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
503 lua_pop(L, 2); /* remove both returns */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
504 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
505 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
506
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
507
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
508 static int ll_require (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
509 const char *name = luaL_checkstring(L, 1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
510 lua_settop(L, 1); /* _LOADED table will be at index 2 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
511 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
512 lua_getfield(L, 2, name); /* _LOADED[name] */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
513 if (lua_toboolean(L, -1)) /* is it there? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
514 return 1; /* package is already loaded */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
515 /* else must load package */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
516 lua_pop(L, 1); /* remove 'getfield' result */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
517 findloader(L, name);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
518 lua_pushstring(L, name); /* pass name as argument to module loader */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
519 lua_insert(L, -2); /* name is 1st argument (before search data) */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
520 lua_call(L, 2, 1); /* run loader to load module */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
521 if (!lua_isnil(L, -1)) /* non-nil return? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
522 lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
523 lua_getfield(L, 2, name);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
524 if (lua_isnil(L, -1)) { /* module did not set a value? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
525 lua_pushboolean(L, 1); /* use true as result */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
526 lua_pushvalue(L, -1); /* extra copy to be returned */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
527 lua_setfield(L, 2, name); /* _LOADED[name] = true */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
528 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
529 return 1;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
530 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
531
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
532 /* }====================================================== */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
533
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
534
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
535
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
536 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
537 ** {======================================================
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
538 ** 'module' function
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
539 ** =======================================================
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
540 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
541 #if defined(LUA_COMPAT_MODULE)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
542
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
543 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
544 ** changes the environment variable of calling function
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
545 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
546 static void set_env (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
547 lua_Debug ar;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
548 if (lua_getstack(L, 1, &ar) == 0 ||
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
549 lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
550 lua_iscfunction(L, -1))
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
551 luaL_error(L, LUA_QL("module") " not called from a Lua function");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
552 lua_pushvalue(L, -2); /* copy new environment table to top */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
553 lua_setupvalue(L, -2, 1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
554 lua_pop(L, 1); /* remove function */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
555 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
556
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
557
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
558 static void dooptions (lua_State *L, int n) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
559 int i;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
560 for (i = 2; i <= n; i++) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
561 if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
562 lua_pushvalue(L, i); /* get option (a function) */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
563 lua_pushvalue(L, -2); /* module */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
564 lua_call(L, 1, 0);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
565 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
566 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
567 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
568
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
569
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
570 static void modinit (lua_State *L, const char *modname) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
571 const char *dot;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
572 lua_pushvalue(L, -1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
573 lua_setfield(L, -2, "_M"); /* module._M = module */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
574 lua_pushstring(L, modname);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
575 lua_setfield(L, -2, "_NAME");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
576 dot = strrchr(modname, '.'); /* look for last dot in module name */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
577 if (dot == NULL) dot = modname;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
578 else dot++;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
579 /* set _PACKAGE as package name (full module name minus last part) */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
580 lua_pushlstring(L, modname, dot - modname);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
581 lua_setfield(L, -2, "_PACKAGE");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
582 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
583
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
584
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
585 static int ll_module (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
586 const char *modname = luaL_checkstring(L, 1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
587 int lastarg = lua_gettop(L); /* last parameter */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
588 luaL_pushmodule(L, modname, 1); /* get/create module table */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
589 /* check whether table already has a _NAME field */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
590 lua_getfield(L, -1, "_NAME");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
591 if (!lua_isnil(L, -1)) /* is table an initialized module? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
592 lua_pop(L, 1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
593 else { /* no; initialize it */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
594 lua_pop(L, 1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
595 modinit(L, modname);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
596 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
597 lua_pushvalue(L, -1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
598 set_env(L);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
599 dooptions(L, lastarg);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
600 return 1;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
601 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
602
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
603
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
604 static int ll_seeall (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
605 luaL_checktype(L, 1, LUA_TTABLE);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
606 if (!lua_getmetatable(L, 1)) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
607 lua_createtable(L, 0, 1); /* create new metatable */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
608 lua_pushvalue(L, -1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
609 lua_setmetatable(L, 1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
610 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
611 lua_pushglobaltable(L);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
612 lua_setfield(L, -2, "__index"); /* mt.__index = _G */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
613 return 0;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
614 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
615
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
616 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
617 /* }====================================================== */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
618
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
619
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
620
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
621 /* auxiliary mark (for internal use) */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
622 #define AUXMARK "\1"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
623
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
624
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
625 /*
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
626 ** return registry.LUA_NOENV as a boolean
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
627 */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
628 static int noenv (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
629 int b;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
630 lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
631 b = lua_toboolean(L, -1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
632 lua_pop(L, 1); /* remove value */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
633 return b;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
634 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
635
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
636
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
637 static void setpath (lua_State *L, const char *fieldname, const char *envname1,
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
638 const char *envname2, const char *def) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
639 const char *path = getenv(envname1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
640 if (path == NULL) /* no environment variable? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
641 path = getenv(envname2); /* try alternative name */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
642 if (path == NULL || noenv(L)) /* no environment variable? */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
643 lua_pushstring(L, def); /* use default */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
644 else {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
645 /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
646 path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
647 LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
648 luaL_gsub(L, path, AUXMARK, def);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
649 lua_remove(L, -2);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
650 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
651 setprogdir(L);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
652 lua_setfield(L, -2, fieldname);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
653 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
654
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
655
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
656 static const luaL_Reg pk_funcs[] = {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
657 {"loadlib", ll_loadlib},
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
658 {"searchpath", ll_searchpath},
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
659 #if defined(LUA_COMPAT_MODULE)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
660 {"seeall", ll_seeall},
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
661 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
662 {NULL, NULL}
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
663 };
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
664
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
665
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
666 static const luaL_Reg ll_funcs[] = {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
667 #if defined(LUA_COMPAT_MODULE)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
668 {"module", ll_module},
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
669 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
670 {"require", ll_require},
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
671 {NULL, NULL}
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
672 };
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
673
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
674
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
675 static void createsearcherstable (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
676 static const lua_CFunction searchers[] =
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
677 {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
678 int i;
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
679 /* create 'searchers' table */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
680 lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
681 /* fill it with pre-defined searchers */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
682 for (i=0; searchers[i] != NULL; i++) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
683 lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
684 lua_pushcclosure(L, searchers[i], 1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
685 lua_rawseti(L, -2, i+1);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
686 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
687 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
688
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
689
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
690 LUAMOD_API int luaopen_package (lua_State *L) {
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
691 /* create table CLIBS to keep track of loaded C libraries */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
692 luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
693 lua_createtable(L, 0, 1); /* metatable for CLIBS */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
694 lua_pushcfunction(L, gctm);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
695 lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
696 lua_setmetatable(L, -2);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
697 /* create `package' table */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
698 luaL_newlib(L, pk_funcs);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
699 createsearcherstable(L);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
700 #if defined(LUA_COMPAT_LOADERS)
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
701 lua_pushvalue(L, -1); /* make a copy of 'searchers' table */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
702 lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
703 #endif
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
704 lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
705 /* set field 'path' */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
706 setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
707 /* set field 'cpath' */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
708 setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
709 /* store config information */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
710 lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
711 LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
712 lua_setfield(L, -2, "config");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
713 /* set field `loaded' */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
714 luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
715 lua_setfield(L, -2, "loaded");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
716 /* set field `preload' */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
717 luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
718 lua_setfield(L, -2, "preload");
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
719 lua_pushglobaltable(L);
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
720 lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
721 luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
722 lua_pop(L, 1); /* pop global table */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
723 return 1; /* return 'package' table */
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
724 }
41cc4dd3c122 Lua 5.2.2 added.
Nomad
parents:
diff changeset
725