diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-09-05 16:33:56 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-09-05 16:33:56 -0300 |
commit | 2018380e9f47e8e59c3f84964591c4fb7727f8c0 (patch) | |
tree | 647ef7e266ad8003503657946e01b296cb1667f3 | |
parent | 6e80c1cde193b767d63d2cc30ebd71d65512e061 (diff) | |
download | lua-2018380e9f47e8e59c3f84964591c4fb7727f8c0.tar.gz lua-2018380e9f47e8e59c3f84964591c4fb7727f8c0.tar.bz2 lua-2018380e9f47e8e59c3f84964591c4fb7727f8c0.zip |
late `lbuiltin.c', now implemented through the official API (and
therefore distributed as a regular library).
-rw-r--r-- | lbaselib.c | 599 |
1 files changed, 599 insertions, 0 deletions
diff --git a/lbaselib.c b/lbaselib.c new file mode 100644 index 00000000..708ce4ff --- /dev/null +++ b/lbaselib.c | |||
@@ -0,0 +1,599 @@ | |||
1 | /* | ||
2 | ** $Id: $ | ||
3 | ** Basic library | ||
4 | ** See Copyright Notice in lua.h | ||
5 | */ | ||
6 | |||
7 | |||
8 | |||
9 | #include <ctype.h> | ||
10 | #include <stdio.h> | ||
11 | #include <stdlib.h> | ||
12 | #include <string.h> | ||
13 | |||
14 | #include "lua.h" | ||
15 | |||
16 | #include "lauxlib.h" | ||
17 | #include "lualib.h" | ||
18 | |||
19 | |||
20 | |||
21 | /* | ||
22 | ** If your system does not support `stderr', redefine this function, or | ||
23 | ** redefine _ERRORMESSAGE so that it won't need _ALERT. | ||
24 | */ | ||
25 | static int luaB__ALERT (lua_State *L) { | ||
26 | fputs(luaL_check_string(L, 1), stderr); | ||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | |||
31 | /* | ||
32 | ** Basic implementation of _ERRORMESSAGE. | ||
33 | ** The library `liolib' redefines _ERRORMESSAGE for better error information. | ||
34 | */ | ||
35 | static int luaB__ERRORMESSAGE (lua_State *L) { | ||
36 | lua_settop(L, 1); | ||
37 | lua_getglobals(L); | ||
38 | lua_pushstring(L, LUA_ALERT); | ||
39 | lua_rawget(L, -2); | ||
40 | if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */ | ||
41 | luaL_checktype(L, 1, "string"); | ||
42 | lua_pushvalue(L, -1); /* function to be called */ | ||
43 | lua_pushstring(L, "error: "); | ||
44 | lua_pushvalue(L, 1); | ||
45 | lua_pushstring(L, "\n"); | ||
46 | lua_concat(L, 3); | ||
47 | lua_call(L, 1, 0); | ||
48 | } | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | |||
53 | /* | ||
54 | ** If your system does not support `stdout', you can just remove this function. | ||
55 | ** If you need, you can define your own `print' function, following this | ||
56 | ** model but changing `fputs' to put the strings at a proper place | ||
57 | ** (a console window or a log file, for instance). | ||
58 | */ | ||
59 | static int luaB_print (lua_State *L) { | ||
60 | int n = lua_gettop(L); /* number of arguments */ | ||
61 | int i; | ||
62 | lua_getglobal(L, "tostring"); | ||
63 | for (i=1; i<=n; i++) { | ||
64 | const char *s; | ||
65 | lua_pushvalue(L, -1); /* function to be called */ | ||
66 | lua_pushvalue(L, i); /* value to print */ | ||
67 | if (lua_call(L, 1, 1) != 0) | ||
68 | lua_error(L, NULL); | ||
69 | s = lua_tostring(L, -1); /* get result */ | ||
70 | if (s == NULL) | ||
71 | lua_error(L, "`tostring' must return a string to `print'"); | ||
72 | if (i>1) fputs("\t", stdout); | ||
73 | fputs(s, stdout); | ||
74 | lua_pop(L, 1); /* pop result */ | ||
75 | } | ||
76 | fputs("\n", stdout); | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | |||
81 | static int luaB_tonumber (lua_State *L) { | ||
82 | int base = luaL_opt_int(L, 2, 10); | ||
83 | if (base == 10) { /* standard conversion */ | ||
84 | luaL_checktype(L, 1, "any"); | ||
85 | if (lua_isnumber(L, 1)) { | ||
86 | lua_pushnumber(L, lua_tonumber(L, 1)); | ||
87 | return 1; | ||
88 | } | ||
89 | } | ||
90 | else { | ||
91 | const char *s1 = luaL_check_string(L, 1); | ||
92 | char *s2; | ||
93 | unsigned long n; | ||
94 | luaL_arg_check(L, 2 <= base && base <= 36, 2, "base out of range"); | ||
95 | n = strtoul(s1, &s2, base); | ||
96 | if (s1 != s2) { /* at least one valid digit? */ | ||
97 | while (isspace((unsigned char)*s2)) s2++; /* skip trailing spaces */ | ||
98 | if (*s2 == '\0') { /* no invalid trailing characters? */ | ||
99 | lua_pushnumber(L, n); | ||
100 | return 1; | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | lua_pushnil(L); /* else not a number */ | ||
105 | return 1; | ||
106 | } | ||
107 | |||
108 | |||
109 | static int luaB_error (lua_State *L) { | ||
110 | lua_error(L, luaL_opt_string(L, 1, NULL)); | ||
111 | return 0; /* to avoid warnings */ | ||
112 | } | ||
113 | |||
114 | static int luaB_setglobal (lua_State *L) { | ||
115 | luaL_checktype(L, 2, "any"); | ||
116 | lua_setglobal(L, luaL_check_string(L, 1)); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static int luaB_getglobal (lua_State *L) { | ||
121 | lua_getglobal(L, luaL_check_string(L, 1)); | ||
122 | return 1; | ||
123 | } | ||
124 | |||
125 | static int luaB_tag (lua_State *L) { | ||
126 | luaL_checktype(L, 1, "any"); | ||
127 | lua_pushnumber(L, lua_tag(L, 1)); | ||
128 | return 1; | ||
129 | } | ||
130 | |||
131 | static int luaB_settag (lua_State *L) { | ||
132 | luaL_checktype(L, 1, "table"); | ||
133 | lua_pushvalue(L, 1); /* push table */ | ||
134 | lua_settag(L, luaL_check_int(L, 2)); | ||
135 | lua_pop(L, 1); /* remove second argument */ | ||
136 | return 1; /* return first argument */ | ||
137 | } | ||
138 | |||
139 | static int luaB_newtag (lua_State *L) { | ||
140 | lua_pushnumber(L, lua_newtag(L)); | ||
141 | return 1; | ||
142 | } | ||
143 | |||
144 | static int luaB_copytagmethods (lua_State *L) { | ||
145 | lua_pushnumber(L, lua_copytagmethods(L, luaL_check_int(L, 1), | ||
146 | luaL_check_int(L, 2))); | ||
147 | return 1; | ||
148 | } | ||
149 | |||
150 | static int luaB_globals (lua_State *L) { | ||
151 | lua_getglobals(L); /* value to be returned */ | ||
152 | if (!lua_isnull(L, 1)) { | ||
153 | luaL_checktype(L, 1, "table"); | ||
154 | lua_pushvalue(L, 1); /* new table of globals */ | ||
155 | lua_setglobals(L); | ||
156 | } | ||
157 | return 1; | ||
158 | } | ||
159 | |||
160 | static int luaB_rawget (lua_State *L) { | ||
161 | luaL_checktype(L, 1, "table"); | ||
162 | luaL_checktype(L, 2, "any"); | ||
163 | lua_rawget(L, -2); | ||
164 | return 1; | ||
165 | } | ||
166 | |||
167 | static int luaB_rawset (lua_State *L) { | ||
168 | luaL_checktype(L, 1, "table"); | ||
169 | luaL_checktype(L, 2, "any"); | ||
170 | luaL_checktype(L, 3, "any"); | ||
171 | lua_rawset(L, -3); | ||
172 | return 1; | ||
173 | } | ||
174 | |||
175 | static int luaB_settagmethod (lua_State *L) { | ||
176 | int tag = (int)luaL_check_int(L, 1); | ||
177 | const char *event = luaL_check_string(L, 2); | ||
178 | luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3, | ||
179 | "function or nil expected"); | ||
180 | lua_pushnil(L); /* to get its tag */ | ||
181 | if (strcmp(event, "gc") == 0 && tag != lua_tag(L, -1)) | ||
182 | lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua"); | ||
183 | lua_pop(L, 1); /* remove the nil */ | ||
184 | lua_settagmethod(L, tag, event); | ||
185 | return 1; | ||
186 | } | ||
187 | |||
188 | static int luaB_gettagmethod (lua_State *L) { | ||
189 | lua_gettagmethod(L, luaL_check_int(L, 1), luaL_check_string(L, 2)); | ||
190 | return 1; | ||
191 | } | ||
192 | |||
193 | |||
194 | static int luaB_collectgarbage (lua_State *L) { | ||
195 | lua_pushnumber(L, lua_collectgarbage(L, luaL_opt_int(L, 1, 0))); | ||
196 | return 1; | ||
197 | } | ||
198 | |||
199 | |||
200 | static int luaB_type (lua_State *L) { | ||
201 | luaL_checktype(L, 1, "any"); | ||
202 | lua_pushstring(L, lua_type(L, 1)); | ||
203 | return 1; | ||
204 | } | ||
205 | |||
206 | |||
207 | static int luaB_next (lua_State *L) { | ||
208 | luaL_checktype(L, 1, "table"); | ||
209 | lua_settop(L, 2); /* create a 2nd argument if there isn't one */ | ||
210 | if (lua_next(L, 1)) | ||
211 | return 2; | ||
212 | else { | ||
213 | lua_pushnil(L); | ||
214 | return 1; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | |||
219 | static int passresults (lua_State *L, int status, int oldtop) { | ||
220 | if (status == 0) { | ||
221 | int nresults = lua_gettop(L) - oldtop; | ||
222 | if (nresults > 0) | ||
223 | return nresults; /* results are already on the stack */ | ||
224 | else { | ||
225 | lua_pushuserdata(L, NULL); /* at least one result to signal no errors */ | ||
226 | return 1; | ||
227 | } | ||
228 | } | ||
229 | else { /* error */ | ||
230 | lua_pushnil(L); | ||
231 | lua_pushnumber(L, status); /* error code */ | ||
232 | return 2; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | static int luaB_dostring (lua_State *L) { | ||
237 | int oldtop = lua_gettop(L); | ||
238 | size_t l; | ||
239 | const char *s = luaL_check_lstr(L, 1, &l); | ||
240 | if (*s == '\27') /* binary files start with ESC... */ | ||
241 | lua_error(L, "`dostring' cannot run pre-compiled code"); | ||
242 | return passresults(L, lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)), oldtop); | ||
243 | } | ||
244 | |||
245 | |||
246 | static int luaB_dofile (lua_State *L) { | ||
247 | int oldtop = lua_gettop(L); | ||
248 | const char *fname = luaL_opt_string(L, 1, NULL); | ||
249 | return passresults(L, lua_dofile(L, fname), oldtop); | ||
250 | } | ||
251 | |||
252 | |||
253 | static int luaB_call (lua_State *L) { | ||
254 | int oldtop; | ||
255 | const char *options = luaL_opt_string(L, 3, ""); | ||
256 | int err = 0; /* index of old error method */ | ||
257 | int i, status; | ||
258 | int n; | ||
259 | luaL_checktype(L, 2, "table"); | ||
260 | n = lua_getn(L, 2); | ||
261 | if (!lua_isnull(L, 4)) { /* set new error method */ | ||
262 | lua_getglobal(L, LUA_ERRORMESSAGE); | ||
263 | err = lua_gettop(L); /* get index */ | ||
264 | lua_pushvalue(L, 4); | ||
265 | lua_setglobal(L, LUA_ERRORMESSAGE); | ||
266 | } | ||
267 | oldtop = lua_gettop(L); /* top before function-call preparation */ | ||
268 | /* push function */ | ||
269 | lua_pushvalue(L, 1); | ||
270 | luaL_checkstack(L, n, "too many arguments"); | ||
271 | for (i=0; i<n; i++) /* push arg[1...n] */ | ||
272 | lua_rawgeti(L, 2, i+1); | ||
273 | status = lua_call(L, n, LUA_MULTRET); | ||
274 | if (err != 0) { /* restore old error method */ | ||
275 | lua_pushvalue(L, err); | ||
276 | lua_setglobal(L, LUA_ERRORMESSAGE); | ||
277 | } | ||
278 | if (status != 0) { /* error in call? */ | ||
279 | if (strchr(options, 'x')) | ||
280 | lua_pushnil(L); /* return nil to signal the error */ | ||
281 | else | ||
282 | lua_error(L, NULL); /* propagate error without additional messages */ | ||
283 | return 1; | ||
284 | } | ||
285 | if (strchr(options, 'p')) /* pack results? */ | ||
286 | lua_error(L, "deprecated option `p' in `call'"); | ||
287 | return lua_gettop(L) - oldtop; /* results are already on the stack */ | ||
288 | } | ||
289 | |||
290 | |||
291 | static int luaB_tostring (lua_State *L) { | ||
292 | char buff[64]; | ||
293 | switch (lua_type(L, 1)[2]) { | ||
294 | case 'm': /* nuMber */ | ||
295 | lua_pushstring(L, lua_tostring(L, 1)); | ||
296 | return 1; | ||
297 | case 'r': /* stRing */ | ||
298 | lua_pushvalue(L, 1); | ||
299 | return 1; | ||
300 | case 'b': /* taBle */ | ||
301 | sprintf(buff, "table: %p", lua_topointer(L, 1)); | ||
302 | break; | ||
303 | case 'n': /* fuNction */ | ||
304 | sprintf(buff, "function: %p", lua_topointer(L, 1)); | ||
305 | break; | ||
306 | case 'e': /* usErdata */ | ||
307 | sprintf(buff, "userdata(%d): %p", lua_tag(L, 1), lua_touserdata(L, 1)); | ||
308 | break; | ||
309 | case 'l': /* niL */ | ||
310 | lua_pushstring(L, "nil"); | ||
311 | return 1; | ||
312 | default: | ||
313 | luaL_argerror(L, 1, "value expected"); | ||
314 | } | ||
315 | lua_pushstring(L, buff); | ||
316 | return 1; | ||
317 | } | ||
318 | |||
319 | |||
320 | static int luaB_foreachi (lua_State *L) { | ||
321 | int n, i; | ||
322 | luaL_checktype(L, 1, "table"); | ||
323 | luaL_checktype(L, 2, "function"); | ||
324 | n = lua_getn(L, 1); | ||
325 | for (i=1; i<=n; i++) { | ||
326 | lua_pushvalue(L, 2); /* function */ | ||
327 | lua_pushnumber(L, i); /* 1st argument */ | ||
328 | lua_rawgeti(L, 1, i); /* 2nd argument */ | ||
329 | if (lua_call(L, 2, 1) != 0) | ||
330 | lua_error(L, NULL); | ||
331 | if (!lua_isnil(L, -1)) | ||
332 | return 1; | ||
333 | lua_pop(L, 1); /* remove nil result */ | ||
334 | } | ||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | |||
339 | static int luaB_foreach (lua_State *L) { | ||
340 | luaL_checktype(L, 1, "table"); | ||
341 | luaL_checktype(L, 2, "function"); | ||
342 | lua_pushnil(L); /* first index */ | ||
343 | for (;;) { | ||
344 | if (lua_next(L, 1) == 0) | ||
345 | return 0; | ||
346 | lua_pushvalue(L, 2); /* function */ | ||
347 | lua_pushvalue(L, -3); /* key */ | ||
348 | lua_pushvalue(L, -3); /* value */ | ||
349 | if (lua_call(L, 2, 1) != 0) lua_error(L, NULL); | ||
350 | if (!lua_isnil(L, -1)) | ||
351 | return 1; | ||
352 | lua_pop(L, 2); /* remove value and result */ | ||
353 | } | ||
354 | } | ||
355 | |||
356 | |||
357 | static int luaB_assert (lua_State *L) { | ||
358 | luaL_checktype(L, 1, "any"); | ||
359 | if (lua_isnil(L, 1)) | ||
360 | luaL_verror(L, "assertion failed! %.90s", luaL_opt_string(L, 2, "")); | ||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | |||
365 | static int luaB_getn (lua_State *L) { | ||
366 | luaL_checktype(L, 1, "table"); | ||
367 | lua_pushnumber(L, lua_getn(L, 1)); | ||
368 | return 1; | ||
369 | } | ||
370 | |||
371 | |||
372 | static int luaB_tinsert (lua_State *L) { | ||
373 | int v = lua_gettop(L); /* last argument: to be inserted */ | ||
374 | int n, pos; | ||
375 | luaL_checktype(L, 1, "table"); | ||
376 | n = lua_getn(L, 1); | ||
377 | if (v == 2) /* called with only 2 arguments */ | ||
378 | pos = n+1; | ||
379 | else | ||
380 | pos = luaL_check_int(L, 2); /* 2nd argument is the position */ | ||
381 | lua_pushstring(L, "n"); | ||
382 | lua_pushnumber(L, n+1); | ||
383 | lua_rawset(L, 1); /* t.n = n+1 */ | ||
384 | for (; n>=pos; n--) { | ||
385 | lua_rawgeti(L, 1, n); | ||
386 | lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ | ||
387 | } | ||
388 | lua_pushvalue(L, v); | ||
389 | lua_rawseti(L, 1, pos); /* t[pos] = v */ | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | |||
394 | static int luaB_tremove (lua_State *L) { | ||
395 | int pos, n; | ||
396 | luaL_checktype(L, 1, "table"); | ||
397 | n = lua_getn(L, 1); | ||
398 | pos = luaL_opt_int(L, 2, n); | ||
399 | if (n <= 0) return 0; /* table is "empty" */ | ||
400 | lua_rawgeti(L, 1, pos); /* result = t[pos] */ | ||
401 | for ( ;pos<n; pos++) { | ||
402 | lua_rawgeti(L, 1, pos+1); | ||
403 | lua_rawseti(L, 1, pos); /* a[pos] = a[pos+1] */ | ||
404 | } | ||
405 | lua_pushstring(L, "n"); | ||
406 | lua_pushnumber(L, n-1); | ||
407 | lua_rawset(L, 1); /* t.n = n-1 */ | ||
408 | lua_pushnil(L); | ||
409 | lua_rawseti(L, 1, n); /* t[n] = nil */ | ||
410 | return 1; | ||
411 | } | ||
412 | |||
413 | |||
414 | |||
415 | |||
416 | /* | ||
417 | ** {====================================================== | ||
418 | ** Quicksort | ||
419 | ** (based on `Algorithms in MODULA-3', Robert Sedgewick; | ||
420 | ** Addison-Wesley, 1993.) | ||
421 | */ | ||
422 | |||
423 | |||
424 | static void swap (lua_State *L, int i, int j) { | ||
425 | lua_rawgeti(L, 1, i); | ||
426 | lua_rawgeti(L, 1, j); | ||
427 | lua_rawseti(L, 1, i); | ||
428 | lua_rawseti(L, 1, j); | ||
429 | } | ||
430 | |||
431 | static int sort_comp (lua_State *L, int n, int r) { | ||
432 | /* WARNING: the caller (auxsort) must ensure stack space */ | ||
433 | int res; | ||
434 | if (!lua_isnil(L, 2)) { /* function? */ | ||
435 | lua_pushvalue(L, 2); | ||
436 | if (r) { | ||
437 | lua_rawgeti(L, 1, n); /* a[n] */ | ||
438 | lua_pushvalue(L, -3); /* pivot */ | ||
439 | } | ||
440 | else { | ||
441 | lua_pushvalue(L, -2); /* pivot */ | ||
442 | lua_rawgeti(L, 1, n); /* a[n] */ | ||
443 | } | ||
444 | if (lua_call(L, 2, 1) != 0) lua_error(L, NULL); | ||
445 | res = !lua_isnil(L, -1); | ||
446 | } | ||
447 | else { /* a < b? */ | ||
448 | lua_rawgeti(L, 1, n); /* a[n] */ | ||
449 | if (r) | ||
450 | res = lua_lessthan(L, -1, -2); | ||
451 | else | ||
452 | res = lua_lessthan(L, -2, -1); | ||
453 | } | ||
454 | lua_pop(L, 1); | ||
455 | return res; | ||
456 | } | ||
457 | |||
458 | static void auxsort (lua_State *L, int l, int u) { | ||
459 | while (l < u) { /* for tail recursion */ | ||
460 | int i, j; | ||
461 | luaL_checkstack(L, 4, "array too large"); | ||
462 | /* sort elements a[l], a[(l+u)/2] and a[u] */ | ||
463 | lua_rawgeti(L, 1, u); | ||
464 | if (sort_comp(L, l, 0)) /* a[u] < a[l]? */ | ||
465 | swap(L, l, u); | ||
466 | lua_pop(L, 1); | ||
467 | if (u-l == 1) break; /* only 2 elements */ | ||
468 | i = (l+u)/2; | ||
469 | lua_rawgeti(L, 1, i); /* Pivot = a[i] */ | ||
470 | if (sort_comp(L, l, 0)) /* a[i]<a[l]? */ | ||
471 | swap(L, l, i); | ||
472 | else { | ||
473 | if (sort_comp(L, u, 1)) /* a[u]<a[i]? */ | ||
474 | swap(L, i, u); | ||
475 | } | ||
476 | lua_pop(L, 1); /* pop old a[i] */ | ||
477 | if (u-l == 2) break; /* only 3 elements */ | ||
478 | lua_rawgeti(L, 1, i); /* Pivot */ | ||
479 | swap(L, i, u-1); /* put median element as pivot (a[u-1]) */ | ||
480 | /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */ | ||
481 | i = l; j = u-1; | ||
482 | for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ | ||
483 | /* repeat i++ until a[i] >= P */ | ||
484 | while (sort_comp(L, ++i, 1)) | ||
485 | if (i>u) lua_error(L, "invalid order function for sorting"); | ||
486 | /* repeat j-- until a[j] <= P */ | ||
487 | while (sort_comp(L, --j, 0)) | ||
488 | if (j<l) lua_error(L, "invalid order function for sorting"); | ||
489 | if (j<i) break; | ||
490 | swap(L, i, j); | ||
491 | } | ||
492 | swap(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */ | ||
493 | /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ | ||
494 | /* adjust so that smaller "half" is in [j..i] and larger one in [l..u] */ | ||
495 | if (i-l < u-i) { | ||
496 | j=l; i=i-1; l=i+2; | ||
497 | } | ||
498 | else { | ||
499 | j=i+1; i=u; u=j-2; | ||
500 | } | ||
501 | lua_pop(L, 1); /* remove pivot from stack */ | ||
502 | auxsort(L, j, i); /* call recursively the smaller one */ | ||
503 | } /* repeat the routine for the larger one */ | ||
504 | } | ||
505 | |||
506 | static int luaB_sort (lua_State *L) { | ||
507 | int n; | ||
508 | luaL_checktype(L, 1, "table"); | ||
509 | n = lua_getn(L, 1); | ||
510 | if (!lua_isnull(L, 2)) /* is there a 2nd argument? */ | ||
511 | luaL_checktype(L, 2, "function"); | ||
512 | lua_settop(L, 2); /* make sure there is two arguments */ | ||
513 | auxsort(L, 1, n); | ||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | /* }====================================================== */ | ||
518 | |||
519 | |||
520 | |||
521 | /* | ||
522 | ** {====================================================== | ||
523 | ** Deprecated functions to manipulate global environment. | ||
524 | ** ======================================================= | ||
525 | */ | ||
526 | |||
527 | |||
528 | /* | ||
529 | ** gives an explicit error in any attempt to call a deprecated function | ||
530 | */ | ||
531 | static int deprecated_func (lua_State *L) { | ||
532 | luaL_verror(L, "function `%.20s' is deprecated", luaL_check_string(L, -1)); | ||
533 | return 0; /* to avoid warnings */ | ||
534 | } | ||
535 | |||
536 | |||
537 | #define num_deprecated 4 | ||
538 | |||
539 | static const char *const deprecated_names [num_deprecated] = { | ||
540 | "foreachvar", "nextvar", "rawgetglobal", "rawsetglobal" | ||
541 | }; | ||
542 | |||
543 | |||
544 | static void deprecated_funcs (lua_State *L) { | ||
545 | int i; | ||
546 | for (i=0; i<num_deprecated; i++) { | ||
547 | lua_pushstring(L, deprecated_names[i]); | ||
548 | lua_pushcclosure(L, deprecated_func, 1); | ||
549 | lua_setglobal(L, deprecated_names[i]); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | |||
554 | /* }====================================================== */ | ||
555 | |||
556 | static const struct luaL_reg base_funcs[] = { | ||
557 | {LUA_ALERT, luaB__ALERT}, | ||
558 | {LUA_ERRORMESSAGE, luaB__ERRORMESSAGE}, | ||
559 | {"call", luaB_call}, | ||
560 | {"collectgarbage", luaB_collectgarbage}, | ||
561 | {"copytagmethods", luaB_copytagmethods}, | ||
562 | {"dofile", luaB_dofile}, | ||
563 | {"dostring", luaB_dostring}, | ||
564 | {"error", luaB_error}, | ||
565 | {"foreach", luaB_foreach}, | ||
566 | {"foreachi", luaB_foreachi}, | ||
567 | {"getglobal", luaB_getglobal}, | ||
568 | {"gettagmethod", luaB_gettagmethod}, | ||
569 | {"globals", luaB_globals}, | ||
570 | {"newtag", luaB_newtag}, | ||
571 | {"next", luaB_next}, | ||
572 | {"print", luaB_print}, | ||
573 | {"rawget", luaB_rawget}, | ||
574 | {"rawset", luaB_rawset}, | ||
575 | {"rawgettable", luaB_rawget}, /* for compatibility */ | ||
576 | {"rawsettable", luaB_rawset}, /* for compatibility */ | ||
577 | {"setglobal", luaB_setglobal}, | ||
578 | {"settag", luaB_settag}, | ||
579 | {"settagmethod", luaB_settagmethod}, | ||
580 | {"tag", luaB_tag}, | ||
581 | {"tonumber", luaB_tonumber}, | ||
582 | {"tostring", luaB_tostring}, | ||
583 | {"type", luaB_type}, | ||
584 | {"assert", luaB_assert}, | ||
585 | {"getn", luaB_getn}, | ||
586 | {"sort", luaB_sort}, | ||
587 | {"tinsert", luaB_tinsert}, | ||
588 | {"tremove", luaB_tremove} | ||
589 | }; | ||
590 | |||
591 | |||
592 | |||
593 | void lua_baselibopen (lua_State *L) { | ||
594 | luaL_openl(L, base_funcs); | ||
595 | lua_pushstring(L, LUA_VERSION); | ||
596 | lua_setglobal(L, "_VERSION"); | ||
597 | deprecated_funcs(L); | ||
598 | } | ||
599 | |||