Lua 5.1.4: liolib.c
L0001    
L0006    
L0007    
L0008    #include <errno.h>
L0009    #include <stdio.h>
L0010    #include <stdlib.h>
L0011    #include <string.h>
L0012    
L0013    #define liolib_c
L0014    #define LUA_LIB
L0015    
L0016    #include "lua.h"
L0017    
L0018    #include "lauxlib.h"
L0019    #include "lualib.h"
L0020    
L0021    
L0022    
L0023    #define IO_INPUT	1
L0024    #define IO_OUTPUT	2
L0025    
L0026    
L0027    static const char *const fnames[] = {"input", "output"};
L0028    
L0029    
L0030    static int pushresult (lua_State *L, int i, const char *filename) {
L0031      int en = errno;  
L0032      if (i) {
L0033        lua_pushboolean(L, 1);
L0034        return 1;
L0035      }
L0036      else {
L0037        lua_pushnil(L);
L0038        if (filename)
L0039          lua_pushfstring(L, "%s: %s", filename, strerror(en));
L0040        else
L0041          lua_pushfstring(L, "%s", strerror(en));
L0042        lua_pushinteger(L, en);
L0043        return 3;
L0044      }
L0045    }
L0046    
L0047    
L0048    static void fileerror (lua_State *L, int arg, const char *filename) {
L0049      lua_pushfstring(L, "%s: %s", filename, strerror(errno));
L0050      luaL_argerror(L, arg, lua_tostring(L, -1));
L0051    }
L0052    
L0053    
L0054    #define tofilep(L)	((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
L0055    
L0056    
L0057    static int io_type (lua_State *L) {
L0058      void *ud;
L0059      luaL_checkany(L, 1);
L0060      ud = lua_touserdata(L, 1);
L0061      lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
L0062      if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
L0063        lua_pushnil(L);  
L0064      else if (*((FILE **)ud) == NULL)
L0065        lua_pushliteral(L, "closed file");
L0066      else
L0067        lua_pushliteral(L, "file");
L0068      return 1;
L0069    }
L0070    
L0071    
L0072    static FILE *tofile (lua_State *L) {
L0073      FILE **f = tofilep(L);
L0074      if (*f == NULL)
L0075        luaL_error(L, "attempt to use a closed file");
L0076      return *f;
L0077    }
L0078    
L0079    
L0080    
L0081    
L0086    static FILE **newfile (lua_State *L) {
L0087      FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
L0088      *pf = NULL;  
L0089      luaL_getmetatable(L, LUA_FILEHANDLE);
L0090      lua_setmetatable(L, -2);
L0091      return pf;
L0092    }
L0093    
L0094    
L0095    
L0098    static int io_noclose (lua_State *L) {
L0099      lua_pushnil(L);
L0100      lua_pushliteral(L, "cannot close standard file");
L0101      return 2;
L0102    }
L0103    
L0104    
L0105    
L0108    static int io_pclose (lua_State *L) {
L0109      FILE **p = tofilep(L);
L0110      int ok = lua_pclose(L, *p);
L0111      *p = NULL;
L0112      return pushresult(L, ok, NULL);
L0113    }
L0114    
L0115    
L0116    
L0119    static int io_fclose (lua_State *L) {
L0120      FILE **p = tofilep(L);
L0121      int ok = (fclose(*p) == 0);
L0122      *p = NULL;
L0123      return pushresult(L, ok, NULL);
L0124    }
L0125    
L0126    
L0127    static int aux_close (lua_State *L) {
L0128      lua_getfenv(L, 1);
L0129      lua_getfield(L, -1, "__close");
L0130      return (lua_tocfunction(L, -1))(L);
L0131    }
L0132    
L0133    
L0134    static int io_close (lua_State *L) {
L0135      if (lua_isnone(L, 1))
L0136        lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
L0137      tofile(L);  
L0138      return aux_close(L);
L0139    }
L0140    
L0141    
L0142    static int io_gc (lua_State *L) {
L0143      FILE *f = *tofilep(L);
L0144      
L0145      if (f != NULL)
L0146        aux_close(L);
L0147      return 0;
L0148    }
L0149    
L0150    
L0151    static int io_tostring (lua_State *L) {
L0152      FILE *f = *tofilep(L);
L0153      if (f == NULL)
L0154        lua_pushliteral(L, "file (closed)");
L0155      else
L0156        lua_pushfstring(L, "file (%p)", f);
L0157      return 1;
L0158    }
L0159    
L0160    
L0161    static int io_open (lua_State *L) {
L0162      const char *filename = luaL_checkstring(L, 1);
L0163      const char *mode = luaL_optstring(L, 2, "r");
L0164      FILE **pf = newfile(L);
L0165      *pf = fopen(filename, mode);
L0166      return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
L0167    }
L0168    
L0169    
L0170    
L0174    static int io_popen (lua_State *L) {
L0175      const char *filename = luaL_checkstring(L, 1);
L0176      const char *mode = luaL_optstring(L, 2, "r");
L0177      FILE **pf = newfile(L);
L0178      *pf = lua_popen(L, filename, mode);
L0179      return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
L0180    }
L0181    
L0182    
L0183    static int io_tmpfile (lua_State *L) {
L0184      FILE **pf = newfile(L);
L0185      *pf = tmpfile();
L0186      return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
L0187    }
L0188    
L0189    
L0190    static FILE *getiofile (lua_State *L, int findex) {
L0191      FILE *f;
L0192      lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
L0193      f = *(FILE **)lua_touserdata(L, -1);
L0194      if (f == NULL)
L0195        luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
L0196      return f;
L0197    }
L0198    
L0199    
L0200    static int g_iofile (lua_State *L, int f, const char *mode) {
L0201      if (!lua_isnoneornil(L, 1)) {
L0202        const char *filename = lua_tostring(L, 1);
L0203        if (filename) {
L0204          FILE **pf = newfile(L);
L0205          *pf = fopen(filename, mode);
L0206          if (*pf == NULL)
L0207            fileerror(L, 1, filename);
L0208        }
L0209        else {
L0210          tofile(L);  
L0211          lua_pushvalue(L, 1);
L0212        }
L0213        lua_rawseti(L, LUA_ENVIRONINDEX, f);
L0214      }
L0215      
L0216      lua_rawgeti(L, LUA_ENVIRONINDEX, f);
L0217      return 1;
L0218    }
L0219    
L0220    
L0221    static int io_input (lua_State *L) {
L0222      return g_iofile(L, IO_INPUT, "r");
L0223    }
L0224    
L0225    
L0226    static int io_output (lua_State *L) {
L0227      return g_iofile(L, IO_OUTPUT, "w");
L0228    }
L0229    
L0230    
L0231    static int io_readline (lua_State *L);
L0232    
L0233    
L0234    static void aux_lines (lua_State *L, int idx, int toclose) {
L0235      lua_pushvalue(L, idx);
L0236      lua_pushboolean(L, toclose);  
L0237      lua_pushcclosure(L, io_readline, 2);
L0238    }
L0239    
L0240    
L0241    static int f_lines (lua_State *L) {
L0242      tofile(L);  
L0243      aux_lines(L, 1, 0);
L0244      return 1;
L0245    }
L0246    
L0247    
L0248    static int io_lines (lua_State *L) {
L0249      if (lua_isnoneornil(L, 1)) {  
L0250        
L0251        lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
L0252        return f_lines(L);
L0253      }
L0254      else {
L0255        const char *filename = luaL_checkstring(L, 1);
L0256        FILE **pf = newfile(L);
L0257        *pf = fopen(filename, "r");
L0258        if (*pf == NULL)
L0259          fileerror(L, 1, filename);
L0260        aux_lines(L, lua_gettop(L), 1);
L0261        return 1;
L0262      }
L0263    }
L0264    
L0265    
L0266    
L0271    
L0272    
L0273    static int read_number (lua_State *L, FILE *f) {
L0274      lua_Number d;
L0275      if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
L0276        lua_pushnumber(L, d);
L0277        return 1;
L0278      }
L0279      else return 0;  
L0280    }
L0281    
L0282    
L0283    static int test_eof (lua_State *L, FILE *f) {
L0284      int c = getc(f);
L0285      ungetc(c, f);
L0286      lua_pushlstring(L, NULL, 0);
L0287      return (c != EOF);
L0288    }
L0289    
L0290    
L0291    static int read_line (lua_State *L, FILE *f) {
L0292      luaL_Buffer b;
L0293      luaL_buffinit(L, &b);
L0294      for (;;) {
L0295        size_t l;
L0296        char *p = luaL_prepbuffer(&b);
L0297        if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) {  
L0298          luaL_pushresult(&b);  
L0299          return (lua_objlen(L, -1) > 0);  
L0300        }
L0301        l = strlen(p);
L0302        if (l == 0 || p[l-1] != '\n')
L0303          luaL_addsize(&b, l);
L0304        else {
L0305          luaL_addsize(&b, l - 1);  
L0306          luaL_pushresult(&b);  
L0307          return 1;  
L0308        }
L0309      }
L0310    }
L0311    
L0312    
L0313    static int read_chars (lua_State *L, FILE *f, size_t n) {
L0314      size_t rlen;  
L0315      size_t nr;  
L0316      luaL_Buffer b;
L0317      luaL_buffinit(L, &b);
L0318      rlen = LUAL_BUFFERSIZE;  
L0319      do {
L0320        char *p = luaL_prepbuffer(&b);
L0321        if (rlen > n) rlen = n;  
L0322        nr = fread(p, sizeof(char), rlen, f);
L0323        luaL_addsize(&b, nr);
L0324        n -= nr;  
L0325      } while (n > 0 && nr == rlen);  
L0326      luaL_pushresult(&b);  
L0327      return (n == 0 || lua_objlen(L, -1) > 0);
L0328    }
L0329    
L0330    
L0331    static int g_read (lua_State *L, FILE *f, int first) {
L0332      int nargs = lua_gettop(L) - 1;
L0333      int success;
L0334      int n;
L0335      clearerr(f);
L0336      if (nargs == 0) {  
L0337        success = read_line(L, f);
L0338        n = first+1;  
L0339      }
L0340      else {  
L0341        luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
L0342        success = 1;
L0343        for (n = first; nargs-- && success; n++) {
L0344          if (lua_type(L, n) == LUA_TNUMBER) {
L0345            size_t l = (size_t)lua_tointeger(L, n);
L0346            success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
L0347          }
L0348          else {
L0349            const char *p = lua_tostring(L, n);
L0350            luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
L0351            switch (p[1]) {
L0352              case 'n':  
L0353                success = read_number(L, f);
L0354                break;
L0355              case 'l':  
L0356                success = read_line(L, f);
L0357                break;
L0358              case 'a':  
L0359                read_chars(L, f, ~((size_t)0));  
L0360                success = 1; 
L0361                break;
L0362              default:
L0363                return luaL_argerror(L, n, "invalid format");
L0364            }
L0365          }
L0366        }
L0367      }
L0368      if (ferror(f))
L0369        return pushresult(L, 0, NULL);
L0370      if (!success) {
L0371        lua_pop(L, 1);  
L0372        lua_pushnil(L);  
L0373      }
L0374      return n - first;
L0375    }
L0376    
L0377    
L0378    static int io_read (lua_State *L) {
L0379      return g_read(L, getiofile(L, IO_INPUT), 1);
L0380    }
L0381    
L0382    
L0383    static int f_read (lua_State *L) {
L0384      return g_read(L, tofile(L), 2);
L0385    }
L0386    
L0387    
L0388    static int io_readline (lua_State *L) {
L0389      FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
L0390      int sucess;
L0391      if (f == NULL)  
L0392        luaL_error(L, "file is already closed");
L0393      sucess = read_line(L, f);
L0394      if (ferror(f))
L0395        return luaL_error(L, "%s", strerror(errno));
L0396      if (sucess) return 1;
L0397      else {  
L0398        if (lua_toboolean(L, lua_upvalueindex(2))) {  
L0399          lua_settop(L, 0);
L0400          lua_pushvalue(L, lua_upvalueindex(1));
L0401          aux_close(L);  
L0402        }
L0403        return 0;
L0404      }
L0405    }
L0406    
L0407    
L0408    
L0409    
L0410    static int g_write (lua_State *L, FILE *f, int arg) {
L0411      int nargs = lua_gettop(L) - 1;
L0412      int status = 1;
L0413      for (; nargs--; arg++) {
L0414        if (lua_type(L, arg) == LUA_TNUMBER) {
L0415          
L0416          status = status &&
L0417              fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
L0418        }
L0419        else {
L0420          size_t l;
L0421          const char *s = luaL_checklstring(L, arg, &l);
L0422          status = status && (fwrite(s, sizeof(char), l, f) == l);
L0423        }
L0424      }
L0425      return pushresult(L, status, NULL);
L0426    }
L0427    
L0428    
L0429    static int io_write (lua_State *L) {
L0430      return g_write(L, getiofile(L, IO_OUTPUT), 1);
L0431    }
L0432    
L0433    
L0434    static int f_write (lua_State *L) {
L0435      return g_write(L, tofile(L), 2);
L0436    }
L0437    
L0438    
L0439    static int f_seek (lua_State *L) {
L0440      static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
L0441      static const char *const modenames[] = {"set", "cur", "end", NULL};
L0442      FILE *f = tofile(L);
L0443      int op = luaL_checkoption(L, 2, "cur", modenames);
L0444      long offset = luaL_optlong(L, 3, 0);
L0445      op = fseek(f, offset, mode[op]);
L0446      if (op)
L0447        return pushresult(L, 0, NULL);  
L0448      else {
L0449        lua_pushinteger(L, ftell(f));
L0450        return 1;
L0451      }
L0452    }
L0453    
L0454    
L0455    static int f_setvbuf (lua_State *L) {
L0456      static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
L0457      static const char *const modenames[] = {"no", "full", "line", NULL};
L0458      FILE *f = tofile(L);
L0459      int op = luaL_checkoption(L, 2, NULL, modenames);
L0460      lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
L0461      int res = setvbuf(f, NULL, mode[op], sz);
L0462      return pushresult(L, res == 0, NULL);
L0463    }
L0464    
L0465    
L0466    
L0467    static int io_flush (lua_State *L) {
L0468      return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
L0469    }
L0470    
L0471    
L0472    static int f_flush (lua_State *L) {
L0473      return pushresult(L, fflush(tofile(L)) == 0, NULL);
L0474    }
L0475    
L0476    
L0477    static const luaL_Reg iolib[] = {
L0478      {"close", io_close},
L0479      {"flush", io_flush},
L0480      {"input", io_input},
L0481      {"lines", io_lines},
L0482      {"open", io_open},
L0483      {"output", io_output},
L0484      {"popen", io_popen},
L0485      {"read", io_read},
L0486      {"tmpfile", io_tmpfile},
L0487      {"type", io_type},
L0488      {"write", io_write},
L0489      {NULL, NULL}
L0490    };
L0491    
L0492    
L0493    static const luaL_Reg flib[] = {
L0494      {"close", io_close},
L0495      {"flush", f_flush},
L0496      {"lines", f_lines},
L0497      {"read", f_read},
L0498      {"seek", f_seek},
L0499      {"setvbuf", f_setvbuf},
L0500      {"write", f_write},
L0501      {"__gc", io_gc},
L0502      {"__tostring", io_tostring},
L0503      {NULL, NULL}
L0504    };
L0505    
L0506    
L0507    static void createmeta (lua_State *L) {
L0508      luaL_newmetatable(L, LUA_FILEHANDLE);  
L0509      lua_pushvalue(L, -1);  
L0510      lua_setfield(L, -2, "__index");  
L0511      luaL_register(L, NULL, flib);  
L0512    }
L0513    
L0514    
L0515    static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
L0516      *newfile(L) = f;
L0517      if (k > 0) {
L0518        lua_pushvalue(L, -1);
L0519        lua_rawseti(L, LUA_ENVIRONINDEX, k);
L0520      }
L0521      lua_pushvalue(L, -2);  
L0522      lua_setfenv(L, -2);  
L0523      lua_setfield(L, -3, fname);
L0524    }
L0525    
L0526    
L0527    static void newfenv (lua_State *L, lua_CFunction cls) {
L0528      lua_createtable(L, 0, 1);
L0529      lua_pushcfunction(L, cls);
L0530      lua_setfield(L, -2, "__close");
L0531    }
L0532    
L0533    
L0534    LUALIB_API int luaopen_io (lua_State *L) {
L0535      createmeta(L);
L0536      
L0537      newfenv(L, io_fclose);
L0538      lua_replace(L, LUA_ENVIRONINDEX);
L0539      
L0540      luaL_register(L, LUA_IOLIBNAME, iolib);
L0541      
L0542      newfenv(L, io_noclose);  
L0543      createstdfile(L, stdin, IO_INPUT, "stdin");
L0544      createstdfile(L, stdout, IO_OUTPUT, "stdout");
L0545      createstdfile(L, stderr, 0, "stderr");
L0546      lua_pop(L, 1);  
L0547      lua_getfield(L, -1, "popen");
L0548      newfenv(L, io_pclose);  
L0549      lua_setfenv(L, -2);  
L0550      lua_pop(L, 1);  
L0551      return 1;
L0552    }
L0553    
Generated by pretty.lua