~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/lua/src/lbaselib.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
** $Id: lbaselib.c,v 1.276 2013/02/21 13:44:53 roberto Exp $
 
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
#define lbaselib_c
 
15
#define LUA_LIB
 
16
 
 
17
#include "lua.h"
 
18
 
 
19
#include "lauxlib.h"
 
20
#include "lualib.h"
 
21
 
 
22
 
 
23
static int luaB_print (lua_State *L) {
 
24
  int n = lua_gettop(L);  /* number of arguments */
 
25
  int i;
 
26
  lua_getglobal(L, "tostring");
 
27
  for (i=1; i<=n; i++) {
 
28
    const char *s;
 
29
    size_t l;
 
30
    lua_pushvalue(L, -1);  /* function to be called */
 
31
    lua_pushvalue(L, i);   /* value to print */
 
32
    lua_call(L, 1, 1);
 
33
    s = lua_tolstring(L, -1, &l);  /* get result */
 
34
    if (s == NULL)
 
35
      return luaL_error(L,
 
36
         LUA_QL("tostring") " must return a string to " LUA_QL("print"));
 
37
    if (i>1) luai_writestring("\t", 1);
 
38
    luai_writestring(s, l);
 
39
    lua_pop(L, 1);  /* pop result */
 
40
  }
 
41
  luai_writeline();
 
42
  return 0;
 
43
}
 
44
 
 
45
 
 
46
#define SPACECHARS      " \f\n\r\t\v"
 
47
 
 
48
static int luaB_tonumber (lua_State *L) {
 
49
  if (lua_isnoneornil(L, 2)) {  /* standard conversion */
 
50
    int isnum;
 
51
    lua_Number n = lua_tonumberx(L, 1, &isnum);
 
52
    if (isnum) {
 
53
      lua_pushnumber(L, n);
 
54
      return 1;
 
55
    }  /* else not a number; must be something */
 
56
    luaL_checkany(L, 1);
 
57
  }
 
58
  else {
 
59
    size_t l;
 
60
    const char *s = luaL_checklstring(L, 1, &l);
 
61
    const char *e = s + l;  /* end point for 's' */
 
62
    int base = luaL_checkint(L, 2);
 
63
    int neg = 0;
 
64
    luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
 
65
    s += strspn(s, SPACECHARS);  /* skip initial spaces */
 
66
    if (*s == '-') { s++; neg = 1; }  /* handle signal */
 
67
    else if (*s == '+') s++;
 
68
    if (isalnum((unsigned char)*s)) {
 
69
      lua_Number n = 0;
 
70
      do {
 
71
        int digit = (isdigit((unsigned char)*s)) ? *s - '0'
 
72
                       : toupper((unsigned char)*s) - 'A' + 10;
 
73
        if (digit >= base) break;  /* invalid numeral; force a fail */
 
74
        n = n * (lua_Number)base + (lua_Number)digit;
 
75
        s++;
 
76
      } while (isalnum((unsigned char)*s));
 
77
      s += strspn(s, SPACECHARS);  /* skip trailing spaces */
 
78
      if (s == e) {  /* no invalid trailing characters? */
 
79
        lua_pushnumber(L, (neg) ? -n : n);
 
80
        return 1;
 
81
      }  /* else not a number */
 
82
    }  /* else not a number */
 
83
  }
 
84
  lua_pushnil(L);  /* not a number */
 
85
  return 1;
 
86
}
 
87
 
 
88
 
 
89
static int luaB_error (lua_State *L) {
 
90
  int level = luaL_optint(L, 2, 1);
 
91
  lua_settop(L, 1);
 
92
  if (lua_isstring(L, 1) && level > 0) {  /* add extra information? */
 
93
    luaL_where(L, level);
 
94
    lua_pushvalue(L, 1);
 
95
    lua_concat(L, 2);
 
96
  }
 
97
  return lua_error(L);
 
98
}
 
99
 
 
100
 
 
101
static int luaB_getmetatable (lua_State *L) {
 
102
  luaL_checkany(L, 1);
 
103
  if (!lua_getmetatable(L, 1)) {
 
104
    lua_pushnil(L);
 
105
    return 1;  /* no metatable */
 
106
  }
 
107
  luaL_getmetafield(L, 1, "__metatable");
 
108
  return 1;  /* returns either __metatable field (if present) or metatable */
 
109
}
 
110
 
 
111
 
 
112
static int luaB_setmetatable (lua_State *L) {
 
113
  int t = lua_type(L, 2);
 
114
  luaL_checktype(L, 1, LUA_TTABLE);
 
115
  luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
 
116
                    "nil or table expected");
 
117
  if (luaL_getmetafield(L, 1, "__metatable"))
 
118
    return luaL_error(L, "cannot change a protected metatable");
 
119
  lua_settop(L, 2);
 
120
  lua_setmetatable(L, 1);
 
121
  return 1;
 
122
}
 
123
 
 
124
 
 
125
static int luaB_rawequal (lua_State *L) {
 
126
  luaL_checkany(L, 1);
 
127
  luaL_checkany(L, 2);
 
128
  lua_pushboolean(L, lua_rawequal(L, 1, 2));
 
129
  return 1;
 
130
}
 
131
 
 
132
 
 
133
static int luaB_rawlen (lua_State *L) {
 
134
  int t = lua_type(L, 1);
 
135
  luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
 
136
                   "table or string expected");
 
137
  lua_pushinteger(L, lua_rawlen(L, 1));
 
138
  return 1;
 
139
}
 
140
 
 
141
 
 
142
static int luaB_rawget (lua_State *L) {
 
143
  luaL_checktype(L, 1, LUA_TTABLE);
 
144
  luaL_checkany(L, 2);
 
145
  lua_settop(L, 2);
 
146
  lua_rawget(L, 1);
 
147
  return 1;
 
148
}
 
149
 
 
150
static int luaB_rawset (lua_State *L) {
 
151
  luaL_checktype(L, 1, LUA_TTABLE);
 
152
  luaL_checkany(L, 2);
 
153
  luaL_checkany(L, 3);
 
154
  lua_settop(L, 3);
 
155
  lua_rawset(L, 1);
 
156
  return 1;
 
157
}
 
158
 
 
159
 
 
160
static int luaB_collectgarbage (lua_State *L) {
 
161
  static const char *const opts[] = {"stop", "restart", "collect",
 
162
    "count", "step", "setpause", "setstepmul",
 
163
    "setmajorinc", "isrunning", "generational", "incremental", NULL};
 
164
  static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
 
165
    LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
 
166
    LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
 
167
  int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
 
168
  int ex = luaL_optint(L, 2, 0);
 
169
  int res = lua_gc(L, o, ex);
 
170
  switch (o) {
 
171
    case LUA_GCCOUNT: {
 
172
      int b = lua_gc(L, LUA_GCCOUNTB, 0);
 
173
      lua_pushnumber(L, res + ((lua_Number)b/1024));
 
174
      lua_pushinteger(L, b);
 
175
      return 2;
 
176
    }
 
177
    case LUA_GCSTEP: case LUA_GCISRUNNING: {
 
178
      lua_pushboolean(L, res);
 
179
      return 1;
 
180
    }
 
181
    default: {
 
182
      lua_pushinteger(L, res);
 
183
      return 1;
 
184
    }
 
185
  }
 
186
}
 
187
 
 
188
 
 
189
static int luaB_type (lua_State *L) {
 
190
  luaL_checkany(L, 1);
 
191
  lua_pushstring(L, luaL_typename(L, 1));
 
192
  return 1;
 
193
}
 
194
 
 
195
 
 
196
static int pairsmeta (lua_State *L, const char *method, int iszero,
 
197
                      lua_CFunction iter) {
 
198
  if (!luaL_getmetafield(L, 1, method)) {  /* no metamethod? */
 
199
    luaL_checktype(L, 1, LUA_TTABLE);  /* argument must be a table */
 
200
    lua_pushcfunction(L, iter);  /* will return generator, */
 
201
    lua_pushvalue(L, 1);  /* state, */
 
202
    if (iszero) lua_pushinteger(L, 0);  /* and initial value */
 
203
    else lua_pushnil(L);
 
204
  }
 
205
  else {
 
206
    lua_pushvalue(L, 1);  /* argument 'self' to metamethod */
 
207
    lua_call(L, 1, 3);  /* get 3 values from metamethod */
 
208
  }
 
209
  return 3;
 
210
}
 
211
 
 
212
 
 
213
static int luaB_next (lua_State *L) {
 
214
  luaL_checktype(L, 1, LUA_TTABLE);
 
215
  lua_settop(L, 2);  /* create a 2nd argument if there isn't one */
 
216
  if (lua_next(L, 1))
 
217
    return 2;
 
218
  else {
 
219
    lua_pushnil(L);
 
220
    return 1;
 
221
  }
 
222
}
 
223
 
 
224
 
 
225
static int luaB_pairs (lua_State *L) {
 
226
  return pairsmeta(L, "__pairs", 0, luaB_next);
 
227
}
 
228
 
 
229
 
 
230
static int ipairsaux (lua_State *L) {
 
231
  int i = luaL_checkint(L, 2);
 
232
  luaL_checktype(L, 1, LUA_TTABLE);
 
233
  i++;  /* next value */
 
234
  lua_pushinteger(L, i);
 
235
  lua_rawgeti(L, 1, i);
 
236
  return (lua_isnil(L, -1)) ? 1 : 2;
 
237
}
 
238
 
 
239
 
 
240
static int luaB_ipairs (lua_State *L) {
 
241
  return pairsmeta(L, "__ipairs", 1, ipairsaux);
 
242
}
 
243
 
 
244
 
 
245
static int load_aux (lua_State *L, int status, int envidx) {
 
246
  if (status == LUA_OK) {
 
247
    if (envidx != 0) {  /* 'env' parameter? */
 
248
      lua_pushvalue(L, envidx);  /* environment for loaded function */
 
249
      if (!lua_setupvalue(L, -2, 1))  /* set it as 1st upvalue */
 
250
        lua_pop(L, 1);  /* remove 'env' if not used by previous call */
 
251
    }
 
252
    return 1;
 
253
  }
 
254
  else {  /* error (message is on top of the stack) */
 
255
    lua_pushnil(L);
 
256
    lua_insert(L, -2);  /* put before error message */
 
257
    return 2;  /* return nil plus error message */
 
258
  }
 
259
}
 
260
 
 
261
 
 
262
static int luaB_loadfile (lua_State *L) {
 
263
  const char *fname = luaL_optstring(L, 1, NULL);
 
264
  const char *mode = luaL_optstring(L, 2, NULL);
 
265
  int env = (!lua_isnone(L, 3) ? 3 : 0);  /* 'env' index or 0 if no 'env' */
 
266
  int status = luaL_loadfilex(L, fname, mode);
 
267
  return load_aux(L, status, env);
 
268
}
 
269
 
 
270
 
 
271
/*
 
272
** {======================================================
 
273
** Generic Read function
 
274
** =======================================================
 
275
*/
 
276
 
 
277
 
 
278
/*
 
279
** reserved slot, above all arguments, to hold a copy of the returned
 
280
** string to avoid it being collected while parsed. 'load' has four
 
281
** optional arguments (chunk, source name, mode, and environment).
 
282
*/
 
283
#define RESERVEDSLOT    5
 
284
 
 
285
 
 
286
/*
 
287
** Reader for generic `load' function: `lua_load' uses the
 
288
** stack for internal stuff, so the reader cannot change the
 
289
** stack top. Instead, it keeps its resulting string in a
 
290
** reserved slot inside the stack.
 
291
*/
 
292
static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
 
293
  (void)(ud);  /* not used */
 
294
  luaL_checkstack(L, 2, "too many nested functions");
 
295
  lua_pushvalue(L, 1);  /* get function */
 
296
  lua_call(L, 0, 1);  /* call it */
 
297
  if (lua_isnil(L, -1)) {
 
298
    lua_pop(L, 1);  /* pop result */
 
299
    *size = 0;
 
300
    return NULL;
 
301
  }
 
302
  else if (!lua_isstring(L, -1))
 
303
    luaL_error(L, "reader function must return a string");
 
304
  lua_replace(L, RESERVEDSLOT);  /* save string in reserved slot */
 
305
  return lua_tolstring(L, RESERVEDSLOT, size);
 
306
}
 
307
 
 
308
 
 
309
static int luaB_load (lua_State *L) {
 
310
  int status;
 
311
  size_t l;
 
312
  const char *s = lua_tolstring(L, 1, &l);
 
313
  const char *mode = luaL_optstring(L, 3, "bt");
 
314
  int env = (!lua_isnone(L, 4) ? 4 : 0);  /* 'env' index or 0 if no 'env' */
 
315
  if (s != NULL) {  /* loading a string? */
 
316
    const char *chunkname = luaL_optstring(L, 2, s);
 
317
    status = luaL_loadbufferx(L, s, l, chunkname, mode);
 
318
  }
 
319
  else {  /* loading from a reader function */
 
320
    const char *chunkname = luaL_optstring(L, 2, "=(load)");
 
321
    luaL_checktype(L, 1, LUA_TFUNCTION);
 
322
    lua_settop(L, RESERVEDSLOT);  /* create reserved slot */
 
323
    status = lua_load(L, generic_reader, NULL, chunkname, mode);
 
324
  }
 
325
  return load_aux(L, status, env);
 
326
}
 
327
 
 
328
/* }====================================================== */
 
329
 
 
330
 
 
331
static int dofilecont (lua_State *L) {
 
332
  return lua_gettop(L) - 1;
 
333
}
 
334
 
 
335
 
 
336
static int luaB_dofile (lua_State *L) {
 
337
  const char *fname = luaL_optstring(L, 1, NULL);
 
338
  lua_settop(L, 1);
 
339
  if (luaL_loadfile(L, fname) != LUA_OK)
 
340
    return lua_error(L);
 
341
  lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
 
342
  return dofilecont(L);
 
343
}
 
344
 
 
345
 
 
346
static int luaB_assert (lua_State *L) {
 
347
  if (!lua_toboolean(L, 1))
 
348
    return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
 
349
  return lua_gettop(L);
 
350
}
 
351
 
 
352
 
 
353
static int luaB_select (lua_State *L) {
 
354
  int n = lua_gettop(L);
 
355
  if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
 
356
    lua_pushinteger(L, n-1);
 
357
    return 1;
 
358
  }
 
359
  else {
 
360
    int i = luaL_checkint(L, 1);
 
361
    if (i < 0) i = n + i;
 
362
    else if (i > n) i = n;
 
363
    luaL_argcheck(L, 1 <= i, 1, "index out of range");
 
364
    return n - i;
 
365
  }
 
366
}
 
367
 
 
368
 
 
369
static int finishpcall (lua_State *L, int status) {
 
370
  if (!lua_checkstack(L, 1)) {  /* no space for extra boolean? */
 
371
    lua_settop(L, 0);  /* create space for return values */
 
372
    lua_pushboolean(L, 0);
 
373
    lua_pushstring(L, "stack overflow");
 
374
    return 2;  /* return false, msg */
 
375
  }
 
376
  lua_pushboolean(L, status);  /* first result (status) */
 
377
  lua_replace(L, 1);  /* put first result in first slot */
 
378
  return lua_gettop(L);
 
379
}
 
380
 
 
381
 
 
382
static int pcallcont (lua_State *L) {
 
383
  int status = lua_getctx(L, NULL);
 
384
  return finishpcall(L, (status == LUA_YIELD));
 
385
}
 
386
 
 
387
 
 
388
static int luaB_pcall (lua_State *L) {
 
389
  int status;
 
390
  luaL_checkany(L, 1);
 
391
  lua_pushnil(L);
 
392
  lua_insert(L, 1);  /* create space for status result */
 
393
  status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont);
 
394
  return finishpcall(L, (status == LUA_OK));
 
395
}
 
396
 
 
397
 
 
398
static int luaB_xpcall (lua_State *L) {
 
399
  int status;
 
400
  int n = lua_gettop(L);
 
401
  luaL_argcheck(L, n >= 2, 2, "value expected");
 
402
  lua_pushvalue(L, 1);  /* exchange function... */
 
403
  lua_copy(L, 2, 1);  /* ...and error handler */
 
404
  lua_replace(L, 2);
 
405
  status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont);
 
406
  return finishpcall(L, (status == LUA_OK));
 
407
}
 
408
 
 
409
 
 
410
static int luaB_tostring (lua_State *L) {
 
411
  luaL_checkany(L, 1);
 
412
  luaL_tolstring(L, 1, NULL);
 
413
  return 1;
 
414
}
 
415
 
 
416
 
 
417
static const luaL_Reg base_funcs[] = {
 
418
  {"assert", luaB_assert},
 
419
  {"collectgarbage", luaB_collectgarbage},
 
420
  {"dofile", luaB_dofile},
 
421
  {"error", luaB_error},
 
422
  {"getmetatable", luaB_getmetatable},
 
423
  {"ipairs", luaB_ipairs},
 
424
  {"loadfile", luaB_loadfile},
 
425
  {"load", luaB_load},
 
426
#if defined(LUA_COMPAT_LOADSTRING)
 
427
  {"loadstring", luaB_load},
 
428
#endif
 
429
  {"next", luaB_next},
 
430
  {"pairs", luaB_pairs},
 
431
  {"pcall", luaB_pcall},
 
432
  {"print", luaB_print},
 
433
  {"rawequal", luaB_rawequal},
 
434
  {"rawlen", luaB_rawlen},
 
435
  {"rawget", luaB_rawget},
 
436
  {"rawset", luaB_rawset},
 
437
  {"select", luaB_select},
 
438
  {"setmetatable", luaB_setmetatable},
 
439
  {"tonumber", luaB_tonumber},
 
440
  {"tostring", luaB_tostring},
 
441
  {"type", luaB_type},
 
442
  {"xpcall", luaB_xpcall},
 
443
  {NULL, NULL}
 
444
};
 
445
 
 
446
 
 
447
LUAMOD_API int luaopen_base (lua_State *L) {
 
448
  /* set global _G */
 
449
  lua_pushglobaltable(L);
 
450
  lua_pushglobaltable(L);
 
451
  lua_setfield(L, -2, "_G");
 
452
  /* open lib into global table */
 
453
  luaL_setfuncs(L, base_funcs, 0);
 
454
  lua_pushliteral(L, LUA_VERSION);
 
455
  lua_setfield(L, -2, "_VERSION");  /* set global _VERSION */
 
456
  return 1;
 
457
}
 
458