LCOV - code coverage report
Current view: top level - src - lauxlib.c Coverage Total Hit
Test: Lua 5.1.5 Lines: 84.5 % 309 261
Test Date: 2024-04-28 10:23:09
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              : ** $Id: lauxlib.c,v 1.159.1.3 2008/01/21 13:20:51 roberto Exp $
       3              : ** Auxiliary functions for building Lua libraries
       4              : ** See Copyright Notice in lua.h
       5              : */
       6              : 
       7              : 
       8              : #include <ctype.h>
       9              : #include <errno.h>
      10              : #include <stdarg.h>
      11              : #include <stdio.h>
      12              : #include <stdlib.h>
      13              : #include <string.h>
      14              : 
      15              : 
      16              : /* This file uses only the official API of Lua.
      17              : ** Any function declared here could be written as an application function.
      18              : */
      19              : 
      20              : #define lauxlib_c
      21              : #define LUA_LIB
      22              : 
      23              : #include "lua.h"
      24              : 
      25              : #include "lauxlib.h"
      26              : 
      27              : 
      28              : #define FREELIST_REF    0       /* free list of references */
      29              : 
      30              : 
      31              : /* convert a stack index to positive */
      32              : #define abs_index(L, i)         ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
      33              :                                         lua_gettop(L) + (i) + 1)
      34              : 
      35              : 
      36              : /*
      37              : ** {======================================================
      38              : ** Error-report functions
      39              : ** =======================================================
      40              : */
      41              : 
      42              : 
      43           44 : LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
      44              :   lua_Debug ar;
      45           44 :   if (!lua_getstack(L, 0, &ar))  /* no stack frame? */
      46            0 :     return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
      47           44 :   lua_getinfo(L, "n", &ar);
      48           44 :   if (strcmp(ar.namewhat, "method") == 0) {
      49            2 :     narg--;  /* do not count `self' */
      50            2 :     if (narg == 0)  /* error is in the self argument itself? */
      51            0 :       return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
      52              :                            ar.name, extramsg);
      53              :   }
      54           44 :   if (ar.name == NULL)
      55            2 :     ar.name = "?";
      56           44 :   return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
      57              :                         narg, ar.name, extramsg);
      58              : }
      59              : 
      60              : 
      61            9 : LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
      62            9 :   const char *msg = lua_pushfstring(L, "%s expected, got %s",
      63              :                                     tname, luaL_typename(L, narg));
      64            9 :   return luaL_argerror(L, narg, msg);
      65              : }
      66              : 
      67              : 
      68            9 : static void tag_error (lua_State *L, int narg, int tag) {
      69            9 :   luaL_typerror(L, narg, lua_typename(L, tag));
      70            0 : }
      71              : 
      72              : 
      73          138 : LUALIB_API void luaL_where (lua_State *L, int level) {
      74              :   lua_Debug ar;
      75          138 :   if (lua_getstack(L, level, &ar)) {  /* check function at level */
      76          138 :     lua_getinfo(L, "Sl", &ar);  /* get info about it */
      77          138 :     if (ar.currentline > 0) {  /* is there info? */
      78           90 :       lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
      79           90 :       return;
      80              :     }
      81              :   }
      82           48 :   lua_pushliteral(L, "");  /* else, no information available... */
      83              : }
      84              : 
      85              : 
      86          131 : LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
      87              :   va_list argp;
      88          131 :   va_start(argp, fmt);
      89          131 :   luaL_where(L, 1);
      90          131 :   lua_pushvfstring(L, fmt, argp);
      91          131 :   va_end(argp);
      92          131 :   lua_concat(L, 2);
      93          131 :   return lua_error(L);
      94              : }
      95              : 
      96              : /* }====================================================== */
      97              : 
      98              : 
      99           15 : LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
     100              :                                  const char *const lst[]) {
     101           15 :   const char *name = (def) ? luaL_optstring(L, narg, def) :
     102            3 :                              luaL_checkstring(L, narg);
     103              :   int i;
     104           42 :   for (i=0; lst[i]; i++)
     105           40 :     if (strcmp(lst[i], name) == 0)
     106           13 :       return i;
     107            2 :   return luaL_argerror(L, narg,
     108              :                        lua_pushfstring(L, "invalid option " LUA_QS, name));
     109              : }
     110              : 
     111              : 
     112          166 : LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
     113          166 :   lua_getfield(L, LUA_REGISTRYINDEX, tname);  /* get registry.name */
     114          166 :   if (!lua_isnil(L, -1))  /* name already in use? */
     115            0 :     return 0;  /* leave previous value on top, but return 0 */
     116          166 :   lua_pop(L, 1);
     117          166 :   lua_newtable(L);  /* create metatable */
     118          166 :   lua_pushvalue(L, -1);
     119          166 :   lua_setfield(L, LUA_REGISTRYINDEX, tname);  /* registry.name = metatable */
     120          166 :   return 1;
     121              : }
     122              : 
     123              : 
     124          684 : LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
     125          684 :   void *p = lua_touserdata(L, ud);
     126          684 :   if (p != NULL) {  /* value is a userdata? */
     127          684 :     if (lua_getmetatable(L, ud)) {  /* does it have a metatable? */
     128          684 :       lua_getfield(L, LUA_REGISTRYINDEX, tname);  /* get correct metatable */
     129          684 :       if (lua_rawequal(L, -1, -2)) {  /* does it have the correct mt? */
     130          684 :         lua_pop(L, 2);  /* remove both metatables */
     131          684 :         return p;
     132              :       }
     133              :     }
     134              :   }
     135            0 :   luaL_typerror(L, ud, tname);  /* else error */
     136            0 :   return NULL;  /* to avoid warnings */
     137              : }
     138              : 
     139              : 
     140         6584 : LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
     141         6584 :   if (!lua_checkstack(L, space))
     142            0 :     luaL_error(L, "stack overflow (%s)", mes);
     143         6584 : }
     144              : 
     145              : 
     146        70375 : LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
     147        70375 :   if (lua_type(L, narg) != t)
     148            2 :     tag_error(L, narg, t);
     149        70373 : }
     150              : 
     151              : 
     152        11017 : LUALIB_API void luaL_checkany (lua_State *L, int narg) {
     153        11017 :   if (lua_type(L, narg) == LUA_TNONE)
     154            6 :     luaL_argerror(L, narg, "value expected");
     155        11011 : }
     156              : 
     157              : 
     158        20756 : LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
     159        20756 :   const char *s = lua_tolstring(L, narg, len);
     160        20756 :   if (!s) tag_error(L, narg, LUA_TSTRING);
     161        20754 :   return s;
     162              : }
     163              : 
     164              : 
     165        12327 : LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
     166              :                                         const char *def, size_t *len) {
     167        12327 :   if (lua_isnoneornil(L, narg)) {
     168          284 :     if (len)
     169            1 :       *len = (def ? strlen(def) : 0);
     170          284 :     return def;
     171              :   }
     172        12043 :   else return luaL_checklstring(L, narg, len);
     173              : }
     174              : 
     175              : 
     176          132 : LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
     177          132 :   lua_Number d = lua_tonumber(L, narg);
     178          132 :   if (d == 0 && !lua_isnumber(L, narg))  /* avoid extra test when d is not 0 */
     179            3 :     tag_error(L, narg, LUA_TNUMBER);
     180          129 :   return d;
     181              : }
     182              : 
     183              : 
     184            1 : LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
     185            1 :   return luaL_opt(L, luaL_checknumber, narg, def);
     186              : }
     187              : 
     188              : 
     189        59092 : LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
     190        59092 :   lua_Integer d = lua_tointeger(L, narg);
     191        59092 :   if (d == 0 && !lua_isnumber(L, narg))  /* avoid extra test when d is not 0 */
     192            2 :     tag_error(L, narg, LUA_TNUMBER);
     193        59090 :   return d;
     194              : }
     195              : 
     196              : 
     197        19112 : LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
     198              :                                                       lua_Integer def) {
     199        19112 :   return luaL_opt(L, luaL_checkinteger, narg, def);
     200              : }
     201              : 
     202              : 
     203         4314 : LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
     204         4314 :   if (!lua_getmetatable(L, obj))  /* no metatable? */
     205         1864 :     return 0;
     206         2450 :   lua_pushstring(L, event);
     207         2450 :   lua_rawget(L, -2);
     208         2450 :   if (lua_isnil(L, -1)) {
     209         2403 :     lua_pop(L, 2);  /* remove metatable and metafield */
     210         2403 :     return 0;
     211              :   }
     212              :   else {
     213           47 :     lua_remove(L, -2);  /* remove only metatable */
     214           47 :     return 1;
     215              :   }
     216              : }
     217              : 
     218              : 
     219         4215 : LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
     220         4215 :   obj = abs_index(L, obj);
     221         4215 :   if (!luaL_getmetafield(L, obj, event))  /* no metafield? */
     222         4170 :     return 0;
     223           45 :   lua_pushvalue(L, obj);
     224           45 :   lua_call(L, 1, 1);
     225           44 :   return 1;
     226              : }
     227              : 
     228              : 
     229          913 : LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
     230              :                                 const luaL_Reg *l) {
     231          913 :   luaI_openlib(L, libname, l, 0);
     232          913 : }
     233              : 
     234              : 
     235          747 : static int libsize (const luaL_Reg *l) {
     236          747 :   int size = 0;
     237        10707 :   for (; l->name; l++) size++;
     238          747 :   return size;
     239              : }
     240              : 
     241              : 
     242          913 : LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
     243              :                               const luaL_Reg *l, int nup) {
     244          913 :   if (libname) {
     245          747 :     int size = libsize(l);
     246              :     /* check whether lib already exists */
     247          747 :     luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);
     248          747 :     lua_getfield(L, -1, libname);  /* get _LOADED[libname] */
     249          747 :     if (!lua_istable(L, -1)) {  /* not found? */
     250          747 :       lua_pop(L, 1);  /* remove previous result */
     251              :       /* try global variable (and create one if it does not exist) */
     252          747 :       if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
     253            0 :         luaL_error(L, "name conflict for module " LUA_QS, libname);
     254          747 :       lua_pushvalue(L, -1);
     255          747 :       lua_setfield(L, -3, libname);  /* _LOADED[libname] = new table */
     256              :     }
     257          747 :     lua_remove(L, -2);  /* remove _LOADED table */
     258          747 :     lua_insert(L, -(nup+1));  /* move library table to below upvalues */
     259              :   }
     260        11786 :   for (; l->name; l++) {
     261              :     int i;
     262        10873 :     for (i=0; i<nup; i++)  /* copy upvalues to the top */
     263            0 :       lua_pushvalue(L, -nup);
     264        10873 :     lua_pushcclosure(L, l->func, nup);
     265        10873 :     lua_setfield(L, -(nup+2), l->name);
     266              :   }
     267          913 :   lua_pop(L, nup);  /* remove upvalues */
     268          913 : }
     269              : 
     270              : 
     271              : 
     272              : /*
     273              : ** {======================================================
     274              : ** getn-setn: size for arrays
     275              : ** =======================================================
     276              : */
     277              : 
     278              : #if defined(LUA_COMPAT_GETN)
     279              : 
     280              : static int checkint (lua_State *L, int topop) {
     281              :   int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
     282              :   lua_pop(L, topop);
     283              :   return n;
     284              : }
     285              : 
     286              : 
     287              : static void getsizes (lua_State *L) {
     288              :   lua_getfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");
     289              :   if (lua_isnil(L, -1)) {  /* no `size' table? */
     290              :     lua_pop(L, 1);  /* remove nil */
     291              :     lua_newtable(L);  /* create it */
     292              :     lua_pushvalue(L, -1);  /* `size' will be its own metatable */
     293              :     lua_setmetatable(L, -2);
     294              :     lua_pushliteral(L, "kv");
     295              :     lua_setfield(L, -2, "__mode");  /* metatable(N).__mode = "kv" */
     296              :     lua_pushvalue(L, -1);
     297              :     lua_setfield(L, LUA_REGISTRYINDEX, "LUA_SIZES");  /* store in register */
     298              :   }
     299              : }
     300              : 
     301              : 
     302              : LUALIB_API void luaL_setn (lua_State *L, int t, int n) {
     303              :   t = abs_index(L, t);
     304              :   lua_pushliteral(L, "n");
     305              :   lua_rawget(L, t);
     306              :   if (checkint(L, 1) >= 0) {  /* is there a numeric field `n'? */
     307              :     lua_pushliteral(L, "n");  /* use it */
     308              :     lua_pushinteger(L, n);
     309              :     lua_rawset(L, t);
     310              :   }
     311              :   else {  /* use `sizes' */
     312              :     getsizes(L);
     313              :     lua_pushvalue(L, t);
     314              :     lua_pushinteger(L, n);
     315              :     lua_rawset(L, -3);  /* sizes[t] = n */
     316              :     lua_pop(L, 1);  /* remove `sizes' */
     317              :   }
     318              : }
     319              : 
     320              : 
     321              : LUALIB_API int luaL_getn (lua_State *L, int t) {
     322              :   int n;
     323              :   t = abs_index(L, t);
     324              :   lua_pushliteral(L, "n");  /* try t.n */
     325              :   lua_rawget(L, t);
     326              :   if ((n = checkint(L, 1)) >= 0) return n;
     327              :   getsizes(L);  /* else try sizes[t] */
     328              :   lua_pushvalue(L, t);
     329              :   lua_rawget(L, -2);
     330              :   if ((n = checkint(L, 2)) >= 0) return n;
     331              :   return (int)lua_objlen(L, t);
     332              : }
     333              : 
     334              : #endif
     335              : 
     336              : /* }====================================================== */
     337              : 
     338              : 
     339              : 
     340         1389 : LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
     341              :                                                                const char *r) {
     342              :   const char *wild;
     343         1389 :   size_t l = strlen(p);
     344              :   luaL_Buffer b;
     345         1389 :   luaL_buffinit(L, &b);
     346         2544 :   while ((wild = strstr(s, p)) != NULL) {
     347         1155 :     luaL_addlstring(&b, s, wild - s);  /* push prefix */
     348         1155 :     luaL_addstring(&b, r);  /* push replacement in place of pattern */
     349         1155 :     s = wild + l;  /* continue after `p' */
     350              :   }
     351         1389 :   luaL_addstring(&b, s);  /* push last suffix */
     352         1389 :   luaL_pushresult(&b);
     353         1389 :   return lua_tostring(L, -1);
     354              : }
     355              : 
     356              : 
     357         1579 : LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
     358              :                                        const char *fname, int szhint) {
     359              :   const char *e;
     360         1579 :   lua_pushvalue(L, idx);
     361              :   do {
     362         1579 :     e = strchr(fname, '.');
     363         1579 :     if (e == NULL) e = fname + strlen(fname);
     364         1579 :     lua_pushlstring(L, fname, e - fname);
     365         1579 :     lua_rawget(L, -2);
     366         1579 :     if (lua_isnil(L, -1)) {  /* no such field? */
     367          749 :       lua_pop(L, 1);  /* remove this nil */
     368          749 :       lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
     369          749 :       lua_pushlstring(L, fname, e - fname);
     370          749 :       lua_pushvalue(L, -2);
     371          749 :       lua_settable(L, -4);  /* set new table into field */
     372              :     }
     373          830 :     else if (!lua_istable(L, -1)) {  /* field has a non-table value? */
     374            0 :       lua_pop(L, 2);  /* remove table and value */
     375            0 :       return fname;  /* return problematic part of the name */
     376              :     }
     377         1579 :     lua_remove(L, -2);  /* remove previous table */
     378         1579 :     fname = e + 1;
     379         1579 :   } while (*e == '.');
     380         1579 :   return NULL;
     381              : }
     382              : 
     383              : 
     384              : 
     385              : /*
     386              : ** {======================================================
     387              : ** Generic Buffer manipulation
     388              : ** =======================================================
     389              : */
     390              : 
     391              : 
     392              : #define bufflen(B)      ((B)->p - (B)->buffer)
     393              : #define bufffree(B)     ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
     394              : 
     395              : #define LIMIT   (LUA_MINSTACK/2)
     396              : 
     397              : 
     398        13952 : static int emptybuffer (luaL_Buffer *B) {
     399        13952 :   size_t l = bufflen(B);
     400        13952 :   if (l == 0) return 0;  /* put nothing on stack */
     401              :   else {
     402        13665 :     lua_pushlstring(B->L, B->buffer, l);
     403        13665 :     B->p = B->buffer;
     404        13665 :     B->lvl++;
     405        13665 :     return 1;
     406              :   }
     407              : }
     408              : 
     409              : 
     410           12 : static void adjuststack (luaL_Buffer *B) {
     411           12 :   if (B->lvl > 1) {
     412            9 :     lua_State *L = B->L;
     413            9 :     int toget = 1;  /* number of levels to concat */
     414            9 :     size_t toplen = lua_strlen(L, -1);
     415              :     do {
     416            9 :       size_t l = lua_strlen(L, -(toget+1));
     417            9 :       if (B->lvl - toget + 1 >= LIMIT || toplen > l) {
     418            0 :         toplen += l;
     419            0 :         toget++;
     420              :       }
     421              :       else break;
     422            0 :     } while (toget < B->lvl);
     423            9 :     lua_concat(L, toget);
     424            9 :     B->lvl = B->lvl - toget + 1;
     425              :   }
     426           12 : }
     427              : 
     428              : 
     429          265 : LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
     430          265 :   if (emptybuffer(B))
     431           12 :     adjuststack(B);
     432          265 :   return B->buffer;
     433              : }
     434              : 
     435              : 
     436        92920 : LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
     437       296101 :   while (l--)
     438       203181 :     luaL_addchar(B, *s++);
     439        92920 : }
     440              : 
     441              : 
     442         2544 : LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
     443         2544 :   luaL_addlstring(B, s, strlen(s));
     444         2544 : }
     445              : 
     446              : 
     447        13687 : LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
     448        13687 :   emptybuffer(B);
     449        13687 :   lua_concat(B->L, B->lvl);
     450        13687 :   B->lvl = 1;
     451        13687 : }
     452              : 
     453              : 
     454        80925 : LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
     455        80925 :   lua_State *L = B->L;
     456              :   size_t vl;
     457        80925 :   const char *s = lua_tolstring(L, -1, &vl);
     458        80925 :   if (vl <= bufffree(B)) {  /* fit into buffer? */
     459        80925 :     memcpy(B->p, s, vl);  /* put it there */
     460        80925 :     B->p += vl;
     461        80925 :     lua_pop(L, 1);  /* remove from stack */
     462              :   }
     463              :   else {
     464            0 :     if (emptybuffer(B))
     465            0 :       lua_insert(L, -2);  /* put buffer before new value */
     466            0 :     B->lvl++;  /* add new value into B stack */
     467            0 :     adjuststack(B);
     468              :   }
     469        80925 : }
     470              : 
     471              : 
     472        13704 : LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
     473        13704 :   B->L = L;
     474        13704 :   B->p = B->buffer;
     475        13704 :   B->lvl = 0;
     476        13704 : }
     477              : 
     478              : /* }====================================================== */
     479              : 
     480              : 
     481            0 : LUALIB_API int luaL_ref (lua_State *L, int t) {
     482              :   int ref;
     483            0 :   t = abs_index(L, t);
     484            0 :   if (lua_isnil(L, -1)) {
     485            0 :     lua_pop(L, 1);  /* remove from stack */
     486            0 :     return LUA_REFNIL;  /* `nil' has a unique fixed reference */
     487              :   }
     488            0 :   lua_rawgeti(L, t, FREELIST_REF);  /* get first free element */
     489            0 :   ref = (int)lua_tointeger(L, -1);  /* ref = t[FREELIST_REF] */
     490            0 :   lua_pop(L, 1);  /* remove it from stack */
     491            0 :   if (ref != 0) {  /* any free element? */
     492            0 :     lua_rawgeti(L, t, ref);  /* remove it from list */
     493            0 :     lua_rawseti(L, t, FREELIST_REF);  /* (t[FREELIST_REF] = t[ref]) */
     494              :   }
     495              :   else {  /* no free elements */
     496            0 :     ref = (int)lua_objlen(L, t);
     497            0 :     ref++;  /* create new reference */
     498              :   }
     499            0 :   lua_rawseti(L, t, ref);
     500            0 :   return ref;
     501              : }
     502              : 
     503              : 
     504            0 : LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
     505            0 :   if (ref >= 0) {
     506            0 :     t = abs_index(L, t);
     507            0 :     lua_rawgeti(L, t, FREELIST_REF);
     508            0 :     lua_rawseti(L, t, ref);  /* t[ref] = t[FREELIST_REF] */
     509            0 :     lua_pushinteger(L, ref);
     510            0 :     lua_rawseti(L, t, FREELIST_REF);  /* t[FREELIST_REF] = ref */
     511              :   }
     512            0 : }
     513              : 
     514              : 
     515              : 
     516              : /*
     517              : ** {======================================================
     518              : ** Load functions
     519              : ** =======================================================
     520              : */
     521              : 
     522              : typedef struct LoadF {
     523              :   int extraline;
     524              :   FILE *f;
     525              :   char buff[LUAL_BUFFERSIZE];
     526              : } LoadF;
     527              : 
     528              : 
     529          401 : static const char *getF (lua_State *L, void *ud, size_t *size) {
     530          401 :   LoadF *lf = (LoadF *)ud;
     531              :   (void)L;
     532          401 :   if (lf->extraline) {
     533           50 :     lf->extraline = 0;
     534           50 :     *size = 1;
     535           50 :     return "\n";
     536              :   }
     537          351 :   if (feof(lf->f)) return NULL;
     538          186 :   *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
     539          186 :   return (*size > 0) ? lf->buff : NULL;
     540              : }
     541              : 
     542              : 
     543            4 : static int errfile (lua_State *L, const char *what, int fnameindex) {
     544            4 :   const char *serr = strerror(errno);
     545            4 :   const char *filename = lua_tostring(L, fnameindex) + 1;
     546            4 :   lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
     547            4 :   lua_remove(L, fnameindex);
     548            4 :   return LUA_ERRFILE;
     549              : }
     550              : 
     551              : 
     552          179 : LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
     553              :   LoadF lf;
     554              :   int status, readstatus;
     555              :   int c;
     556          179 :   int fnameindex = lua_gettop(L) + 1;  /* index of filename on the stack */
     557          179 :   lf.extraline = 0;
     558          179 :   if (filename == NULL) {
     559            6 :     lua_pushliteral(L, "=stdin");
     560            6 :     lf.f = stdin;
     561              :   }
     562              :   else {
     563          173 :     lua_pushfstring(L, "@%s", filename);
     564          173 :     lf.f = fopen(filename, "r");
     565          173 :     if (lf.f == NULL) return errfile(L, "open", fnameindex);
     566              :   }
     567          175 :   c = getc(lf.f);
     568          175 :   if (c == '#') {  /* Unix exec. file? */
     569           50 :     lf.extraline = 1;
     570          750 :     while ((c = getc(lf.f)) != EOF && c != '\n') ;  /* skip first line */
     571           50 :     if (c == '\n') c = getc(lf.f);
     572              :   }
     573          175 :   if (c == LUA_SIGNATURE[0] && filename) {  /* binary file? */
     574            6 :     lf.f = freopen(filename, "rb", lf.f);  /* reopen in binary mode */
     575            6 :     if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
     576              :     /* skip eventual `#!...' */
     577            6 :    while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
     578            6 :     lf.extraline = 0;
     579              :   }
     580          175 :   ungetc(c, lf.f);
     581          175 :   status = lua_load(L, getF, &lf, lua_tostring(L, -1));
     582          175 :   readstatus = ferror(lf.f);
     583          175 :   if (filename) fclose(lf.f);  /* close file (even in case of errors) */
     584          175 :   if (readstatus) {
     585            0 :     lua_settop(L, fnameindex);  /* ignore results from `lua_load' */
     586            0 :     return errfile(L, "read", fnameindex);
     587              :   }
     588          175 :   lua_remove(L, fnameindex);
     589          175 :   return status;
     590              : }
     591              : 
     592              : 
     593              : typedef struct LoadS {
     594              :   const char *s;
     595              :   size_t size;
     596              : } LoadS;
     597              : 
     598              : 
     599          598 : static const char *getS (lua_State *L, void *ud, size_t *size) {
     600          598 :   LoadS *ls = (LoadS *)ud;
     601              :   (void)L;
     602          598 :   if (ls->size == 0) return NULL;
     603          308 :   *size = ls->size;
     604          308 :   ls->size = 0;
     605          308 :   return ls->s;
     606              : }
     607              : 
     608              : 
     609          308 : LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
     610              :                                 const char *name) {
     611              :   LoadS ls;
     612          308 :   ls.s = buff;
     613          308 :   ls.size = size;
     614          308 :   return lua_load(L, getS, &ls, name);
     615              : }
     616              : 
     617              : 
     618            0 : LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) {
     619            0 :   return luaL_loadbuffer(L, s, strlen(s), s);
     620              : }
     621              : 
     622              : 
     623              : 
     624              : /* }====================================================== */
     625              : 
     626              : 
     627       269505 : static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
     628              :   (void)ud;
     629              :   (void)osize;
     630       269505 :   if (nsize == 0) {
     631       123415 :     free(ptr);
     632       123415 :     return NULL;
     633              :   }
     634              :   else
     635       146090 :     return realloc(ptr, nsize);
     636              : }
     637              : 
     638              : 
     639            0 : static int panic (lua_State *L) {
     640              :   (void)L;  /* to avoid warnings */
     641            0 :   fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
     642              :                    lua_tostring(L, -1));
     643            0 :   return 0;
     644              : }
     645              : 
     646              : 
     647           95 : LUALIB_API lua_State *luaL_newstate (void) {
     648           95 :   lua_State *L = lua_newstate(l_alloc, NULL);
     649           95 :   if (L) lua_atpanic(L, &panic);
     650           95 :   return L;
     651              : }
     652              : 
        

Generated by: LCOV version 2.0-1