📄 liolib.c
字号:
static int read_chars (lua_State *L, FILE *f, size_t n) { char *buffer; size_t n1; char statbuff[BUFSIZ]; if (n <= BUFSIZ) buffer = statbuff; else { buffer = (char *)malloc(n); if (buffer == NULL) lua_error(L, "not enough memory to read a file"); } n1 = fread(buffer, sizeof(char), n, f); lua_pushlstring(L, buffer, n1); if (buffer != statbuff) free(buffer); return (n1 > 0 || n == 0);}static int io_read (lua_State *L) { IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); int lastarg = lua_gettop(L) - 1; int firstarg = 1; FILE *f = gethandle(L, ctrl, firstarg); int n; if (f) firstarg++; else f = getfilebyref(L, ctrl, INFILE); /* get _INPUT */ lua_pop(L, 1); if (firstarg > lastarg) { /* no arguments? */ lua_settop(L, 0); /* erase upvalue and other eventual garbage */ firstarg = lastarg = 1; /* correct indices */ lua_pushstring(L, "*l"); /* push default argument */ } else /* ensure stack space for all results and for auxlib's buffer */ luaL_checkstack(L, lastarg-firstarg+1+LUA_MINSTACK, "too many arguments"); for (n = firstarg; n<=lastarg; n++) { int success; if (lua_isnumber(L, n)) success = read_chars(L, f, (size_t)lua_tonumber(L, n)); else { const char *p = luaL_check_string(L, n); if (p[0] != '*') success = read_pattern(L, f, p); /* deprecated! */ else { switch (p[1]) { case 'n': /* number */ if (!read_number(L, f)) goto endloop; /* read fails */ continue; /* number is already pushed; avoid the "pushstring" */ case 'l': /* line */ success = read_line(L, f); break; case 'a': /* file */ read_file(L, f); success = 1; /* always success */ break; case 'w': /* word */ success = read_word(L, f); break; default: luaL_argerror(L, n, "invalid format"); success = 0; /* to avoid warnings */ } } } if (!success) { lua_pop(L, 1); /* remove last result */ break; /* read fails */ } } endloop: return n - firstarg;}/* }====================================================== */static int io_write (lua_State *L) { int lastarg = lua_gettop(L) - 1; IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); int arg = 1; int status = 1; FILE *f = gethandle(L, ctrl, arg); if (f) arg++; else f = getfilebyref(L, ctrl, OUTFILE); /* get _OUTPUT */ for (; arg <= lastarg; arg++) { if (lua_type(L, arg) == LUA_TNUMBER) { /* LUA_NUMBER */ /* optimization: could be done exactly as for strings */ status = status && fprintf(f, "%.16g", lua_tonumber(L, arg)) > 0; } else { size_t l; const char *s = luaL_check_lstr(L, arg, &l); status = status && (fwrite(s, sizeof(char), l, f) == l); } } pushresult(L, status); return 1;}static int io_seek (lua_State *L) { static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; static const char *const modenames[] = {"set", "cur", "end", NULL}; IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); FILE *f; int op; long offset; lua_pop(L, 1); /* remove upvalue */ f = getnonullfile(L, ctrl, 1); op = luaL_findstring(luaL_opt_string(L, 2, "cur"), modenames); offset = luaL_opt_long(L, 3, 0); luaL_arg_check(L, op != -1, 2, "invalid mode"); op = fseek(f, offset, mode[op]); if (op) return pushresult(L, 0); /* error */ else { lua_pushnumber(L, ftell(f)); return 1; }}static int io_flush (lua_State *L) { IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); FILE *f; lua_pop(L, 1); /* remove upvalue */ f = gethandle(L, ctrl, 1); luaL_arg_check(L, f || lua_isnull(L, 1), 1, "invalid file handle"); return pushresult(L, fflush(f) == 0);}/* }====================================================== *//*** {======================================================** Other O.S. Operations** =======================================================*/static int io_execute (lua_State *L) { lua_pushnumber(L, system(luaL_check_string(L, 1))); return 1;}static int io_remove (lua_State *L) { return pushresult(L, remove(luaL_check_string(L, 1)) == 0);}static int io_rename (lua_State *L) { return pushresult(L, rename(luaL_check_string(L, 1), luaL_check_string(L, 2)) == 0);}static int io_tmpname (lua_State *L) {/* #ifdef macintosh */#if 1 /* mkstemp unavailable on Mac OS 9 */ assert (0); #else static char tmpfname[16]; int fid; strcpy(tmpfname,"/tmp/lua.XXXXXX"); if((fid=mkstemp(tmpfname))) close(fid); lua_pushstring(L, tmpfname);#endif return 1;}static int io_getenv (lua_State *L) { lua_pushstring(L, getenv(luaL_check_string(L, 1))); /* if NULL push nil */ return 1;}static int io_clock (lua_State *L) { lua_pushnumber(L, ((double)clock())/CLOCKS_PER_SEC); return 1;}static int io_date (lua_State *L) { char b[256]; const char *s = luaL_opt_string(L, 1, "%c"); struct tm *stm; time_t t; time(&t); stm = localtime(&t); if (strftime(b, sizeof(b), s, stm)) lua_pushstring(L, b); else lua_error(L, "invalid `date' format"); return 1;}static int setloc (lua_State *L) { static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME}; static const char *const catnames[] = {"all", "collate", "ctype", "monetary", "numeric", "time", NULL}; int op = luaL_findstring(luaL_opt_string(L, 2, "all"), catnames); luaL_arg_check(L, op != -1, 2, "invalid option"); lua_pushstring(L, setlocale(cat[op], luaL_check_string(L, 1))); return 1;}static int io_exit (lua_State *L) { exit(luaL_opt_int(L, 1, EXIT_SUCCESS)); return 0; /* to avoid warnings */}/* }====================================================== */static int io_debug (lua_State *L) { for (;;) { char buffer[250]; fprintf(stderr, "lua_debug> "); if (fgets(buffer, sizeof(buffer), stdin) == 0 || strcmp(buffer, "cont\n") == 0) return 0; lua_dostring(L, buffer); lua_settop(L, 0); /* remove eventual returns */ }}#define LEVELS1 12 /* size of the first part of the stack */#define LEVELS2 10 /* size of the second part of the stack */static int errorfb (lua_State *L) { int level = 1; /* skip level 0 (it's this function) */ int firstpart = 1; /* still before eventual `...' */ lua_Debug ar; luaL_Buffer b; luaL_buffinit(L, &b); luaL_addstring(&b, "error: "); luaL_addstring(&b, luaL_check_string(L, 1)); luaL_addstring(&b, "\n"); while (lua_getstack(L, level++, &ar)) { char buff[120]; /* enough to fit following `sprintf's */ if (level == 2) luaL_addstring(&b, "stack traceback:\n"); else if (level > LEVELS1 && firstpart) { /* no more than `LEVELS2' more levels? */ if (!lua_getstack(L, level+LEVELS2, &ar)) level--; /* keep going */ else { luaL_addstring(&b, " ...\n"); /* too many levels */ while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */ level++; } firstpart = 0; continue; } sprintf(buff, "%4d: ", level-1); luaL_addstring(&b, buff); lua_getinfo(L, "Snl", &ar); switch (*ar.namewhat) { case 'g': case 'l': /* global, local */ sprintf(buff, "function `%.50s'", ar.name); break; case 'f': /* field */ sprintf(buff, "method `%.50s'", ar.name); break; case 't': /* tag method */ sprintf(buff, "`%.50s' tag method", ar.name); break; default: { if (*ar.what == 'm') /* main? */ sprintf(buff, "main of %.70s", ar.short_src); else if (*ar.what == 'C') /* C function? */ sprintf(buff, "%.70s", ar.short_src); else sprintf(buff, "function <%d:%.70s>", ar.linedefined, ar.short_src); ar.source = NULL; /* do not print source again */ } } luaL_addstring(&b, buff); if (ar.currentline > 0) { sprintf(buff, " at line %d", ar.currentline); luaL_addstring(&b, buff); } if (ar.source) { sprintf(buff, " [%.70s]", ar.short_src); luaL_addstring(&b, buff); } luaL_addstring(&b, "\n"); } luaL_pushresult(&b); lua_getglobal(L, LUA_ALERT); if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */ lua_pushvalue(L, -2); /* error message */ lua_rawcall(L, 1, 0); } return 0;}static const struct luaL_reg iolib[] = { {LUA_ERRORMESSAGE, errorfb}, {"clock", io_clock}, {"date", io_date}, {"debug", io_debug}, {"execute", io_execute}, {"exit", io_exit}, {"getenv", io_getenv}, {"remove", io_remove}, {"rename", io_rename}, {"setlocale", setloc}, {"tmpname", io_tmpname}};static const struct luaL_reg iolibtag[] = { {"appendto", io_appendto}, {"closefile", io_close}, {"flush", io_flush}, {"openfile", io_open}, {"read", io_read}, {"readfrom", io_readfrom}, {"seek", io_seek}, {"write", io_write}, {"writeto", io_writeto}};static void openwithcontrol (lua_State *L) { IOCtrl *ctrl = (IOCtrl *)lua_newuserdata(L, sizeof(IOCtrl)); unsigned int i; ctrl->iotag = lua_newtag(L); ctrl->closedtag = lua_newtag(L); for (i=0; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) { /* put `ctrl' as upvalue for these functions */ lua_pushvalue(L, -1); lua_pushcclosure(L, iolibtag[i].func, 1); lua_setglobal(L, iolibtag[i].name); } /* create references to variable names */ lua_pushstring(L, filenames[INFILE]); ctrl->ref[INFILE] = lua_ref(L, 1); lua_pushstring(L, filenames[OUTFILE]); ctrl->ref[OUTFILE] = lua_ref(L, 1); /* predefined file handles */ setfile(L, ctrl, stdin, INFILE); setfile(L, ctrl, stdout, OUTFILE); setfilebyname(L, ctrl, stdin, "_STDIN"); setfilebyname(L, ctrl, stdout, "_STDOUT"); setfilebyname(L, ctrl, stderr, "_STDERR"); /* close files when collected */ lua_pushcclosure(L, file_collect, 1); /* pops `ctrl' from stack */ lua_settagmethod(L, ctrl->iotag, "gc");}LUALIB_API void lua_iolibopen (lua_State *L) { luaL_openl(L, iolib); openwithcontrol(L);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -