static int g_read (lua_State *L, FILE *f, int first) { int nargs = lua_gettop(L) - 1; int success; int n; clearerr(f); if (nargs == 0) { /* no arguments? */ success = read_line(L, f, 1); n = first+1; /* to return 1 result */ } else { /* ensure stack space for all results and for auxlib's buffer */ luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); success = 1; for (n = first; nargs-- && success; n++) { if (lua_type(L, n) == LUA_TNUMBER) { size_t l = (size_t)luaL_checkinteger(L, n); success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); } else { const char *p = luaL_checkstring(L, n); if (*p == '*') p++; /* skip optional '*' (for compatibility) */ switch (*p) { case 'n': /* number */ success = read_number(L, f); break; case 'l': /* line */ success = read_line(L, f, 1); break; case 'L': /* line with end-of-line */ success = read_line(L, f, 0); break; case 'a': /* file */ read_all(L, f); /* read entire file */ success = 1; /* always success */ break; default: return luaL_argerror(L, n, "invalid format"); } } } } if (ferror(f)) return luaL_fileresult(L, 0, NULL); if (!success) { lua_pop(L, 1); /* remove last result */ lua_pushnil(L); /* push nil instead */ } return n - first; }
static int f_seek(lua_State *L) { static const int mode[] = { SEEK_SET, SEEK_CUR, SEEK_END }; static const char *const modenames[] = { "set", "cur", "end", NULL }; FILE *f = tofile(L); int op = luaL_checkoption(L, 2, "cur", modenames); lua_Number p3 = luaL_optnumber(L, 3, 0); l_seeknum offset = (l_seeknum)p3; luaL_argcheck(L, (lua_Number)offset == p3, 3, "not an integer in proper range"); op = l_fseek(f, offset, mode[op]); if (op) return luaL_fileresult(L, 0, NULL); /* error */ else { lua_pushnumber(L, (lua_Number)l_ftell(f)); return 1; } }
LUALIB_API int luaL_execresult (lua_State *L, int stat) { const char *what = "exit"; /* type of termination */ if (stat == -1) /* error? */ return luaL_fileresult(L, 0, NULL); else { inspectstat(stat, what); /* interpret result */ if (*what == 'e' && stat == 0) /* successful termination? */ lua_pushboolean(L, 1); else lua_pushnil(L); lua_pushstring(L, what); lua_pushinteger(L, stat); return 3; /* return true/nil,what,code */ } }
static int g_write(lua_State *L, FILE *f, int arg) { int nargs = lua_gettop(L) - arg; int status = 1; for (; nargs--; arg++) { if (lua_type(L, arg) == LUA_TNUMBER) { /* optimization: could be done exactly as for strings */ status = status && fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; } else { size_t l; const char *s = luaL_checklstring(L, arg, &l); status = status && (fwrite(s, sizeof(char), l, f) == l); } } if (status) return 1; /* file handle already on stack top */ else return luaL_fileresult(L, status, NULL); }
int luaL_execresult (LuaThread *L, int stat) { THREAD_CHECK(L); const char *what = "exit"; /* type of termination */ if (stat == -1) /* error? */ return luaL_fileresult(L, 0, NULL); else { if (*what == 'e' && stat == 0) { // successful termination? lua_pushboolean(L, 1); } else { L->stack_.push(LuaValue::Nil()); } lua_pushstring(L, what); lua_pushinteger(L, stat); return 3; /* return true/nil,what,code */ } }
static int io_file_write(lua_State *L, FILE *fp, int start) { cTValue *tv; int status = 1; for (tv = L->base+start; tv < L->top; tv++) { char buf[STRFMT_MAXBUF_NUM]; MSize len; const char *p = lj_strfmt_wstrnum(buf, tv, &len); if (!p) lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING); status = status && (fwrite(p, 1, len, fp) == len); } if (LJ_52 && status) { L->top = L->base+1; if (start == 0) setudataV(L, L->base, IOSTDF_UD(L, GCROOT_IO_OUTPUT)); return 1; } return luaL_fileresult(L, status, NULL); }
static int io_open (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *md = luaL_optstring(L, 2, "r"); LStream *p = newfile(L); #if defined(USE_FATFS) BYTE mode; if (strchr(md, 'w') || strchr(md, 'a')) mode = FA_WRITE; else mode = FA_READ; FRESULT result = f_open(&p->f, filename, mode); if (result == FR_OK && strchr(md, 'a')) result = f_lseek(&p->f, f_size(&p->f)); return result == FR_OK ? 1 : 0; #else const char *mode = md; /* to traverse/check mode */ luaL_argcheck(L, lua_checkmode(mode), 2, "invalid mode"); p->f = fopen(filename, md); return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; #endif }
// File Write Operatings int LuaIOLib::g_write (lua_State *L, FileHandle *file, int arg) { int nargs = lua_gettop(L) - arg; int status = 1; for (; nargs--; arg++) { size_t l; const char *s = luaL_checklstring(L, arg, &l); if (status != 1) { continue; } auto result = file->write(l, (const uint8_t *)s); if (result.status() != ReturnCode::SUCCESS) { status = (int)result.status(); break; } } if (status) return 1; /* file handle already on stack top */ else return luaL_fileresult(L, status, NULL); }
static int io_file_read(lua_State *L, FILE *fp, int start) { int ok, n, nargs = (int)(L->top - L->base) - start; clearerr(fp); if (nargs == 0) { ok = io_file_readline(L, fp, 1); n = start+1; /* Return 1 result. */ } else { /* The results plus the buffers go on top of the args. */ luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); ok = 1; for (n = start; nargs-- && ok; n++) { if (tvisstr(L->base+n)) { const char *p = strVdata(L->base+n); if (p[0] != '*') lj_err_arg(L, n+1, LJ_ERR_INVOPT); if (p[1] == 'n') ok = io_file_readnum(L, fp); else if ((p[1] & ~0x20) == 'L') ok = io_file_readline(L, fp, (p[1] == 'l')); else if (p[1] == 'a') io_file_readall(L, fp); else lj_err_arg(L, n+1, LJ_ERR_INVFMT); } else if (tvisnumber(L->base+n)) { ok = io_file_readlen(L, fp, (MSize)lj_lib_checkint(L, n+1)); } else { lj_err_arg(L, n+1, LJ_ERR_INVOPT); } } } if (ferror(fp)) return luaL_fileresult(L, 0, NULL); if (!ok) setnilV(L->top-1); /* Replace last result with nil. */ return n - start; }
static int io_flush(lua_State *L) { return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); }
static int f_flush(lua_State *L) { return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL); }
int luaFileresult(lua_State* plua_state, bool stat, const std::string& fname) { return fname.empty() ? luaL_fileresult(plua_state, stat, NULL) : luaL_fileresult(plua_state, stat, fname.c_str()); }
int LuaIOLib::io_open(lua_State *lua) { const char *filename = luaL_checkstring(lua, 1); const char *mode = luaL_optstring(lua, 2, "r"); int i = 0; /* check whether 'mode' matches '[rwa]%+?b?' */ auto file_mode = FileHandle::NONE; while (mode[i] != '\0') { auto m = mode[i++]; if (m == 'r') { file_mode |= FileHandle::READ; } else if (m == 'w') { file_mode |= FileHandle::WRITE; } else if (m == 'a') { file_mode |= FileHandle::APPEND; } else if (m == '+') { file_mode |= FileHandle::READ | FileHandle::WRITE; } else { return luaL_error(lua, "invalid mode " LUA_QS " (should match " LUA_QL("[rwa]%%+?b?") ")", mode); } } auto process = proc(lua); auto &info = process->info(); auto &vfs = info.vfs(); FileHandle *handle = nullptr; vfs.open(info.id(), filename, file_mode, handle); if (handle == nullptr) { if ((file_mode & (FileHandle::WRITE | FileHandle::APPEND)) > 0) { if (vfs.create_file(filename) != ReturnCode::SUCCESS) { return luaL_fileresult(lua, 0, filename); } vfs.open(info.id(), filename, file_mode, handle); if (handle == nullptr) { return luaL_fileresult(lua, 0, filename); } } else { return luaL_fileresult(lua, 0, filename); } } auto result = new LuaFile(); result->file(handle); wrap_object(lua, result); return 1; }
static int io_tmpfile(lua_State *L) { LStream *p = newfile(L); p->f = tmpfile(); return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1; }
/* ** function to close regular files */ static int io_fclose(lua_State *L) { LStream *p = tolstream(L); int res = fclose(p->f); return luaL_fileresult(L, (res == 0), NULL); }
/* From http://www.lua.org/source/5.2/liolib.c.html#io_fclose */ static int io_fclose (lua_State *L) { luaL_Stream *p = (luaL_Stream *)luaL_checkudata(L, 1, LUA_FILEHANDLE); FILE *pf = p->f; int res = fclose(pf); return luaL_fileresult(L, (res == 0), NULL); }
static int os_remove (LuaThread *L) { THREAD_CHECK(L); const char *filename = luaL_checkstring(L, 1); return luaL_fileresult(L, remove(filename) == 0, filename); }
static int os_remove (lua_State *L) { const char *filename = luaL_checkstring(L, 1); return luaL_fileresult(L, remove(filename) == 0, filename); }
static int os_rename (lua_State *L) { const char *fromname = luaL_checkstring(L, 1); const char *toname = luaL_checkstring(L, 2); return luaL_fileresult(L, rename(fromname, toname) == 0, fromname); }
static int os_rename (LuaThread *L) { THREAD_CHECK(L); const char *fromname = luaL_checkstring(L, 1); const char *toname = luaL_checkstring(L, 2); return luaL_fileresult(L, rename(fromname, toname) == 0, fromname); }