⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 liolib.c

📁 Lua 语言解释器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** $Id: liolib.c,v 2.39a 2003/03/19 21:16:12 roberto Exp $** Standard I/O (and system) library** See Copyright Notice in lua.h*/#include <errno.h>#include <locale.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#define liolib_c#include "lua.h"#include "lauxlib.h"#include "lualib.h"/*** by default, gcc does not get `tmpname'*/#ifndef USE_TMPNAME#ifdef __GNUC__#define USE_TMPNAME	0#else#define USE_TMPNAME	1#endif#endif/*** by default, posix systems get `popen'*/#ifndef USE_POPEN#ifdef _POSIX_C_SOURCE#if _POSIX_C_SOURCE >= 2#define USE_POPEN	1#endif#endif#endif#ifndef USE_POPEN#define USE_POPEN	0#endif/*** {======================================================** FILE Operations** =======================================================*/#if !USE_POPEN#define pclose(f)    (-1)#endif#define FILEHANDLE		"FILE*"#define IO_INPUT		"_input"#define IO_OUTPUT		"_output"static int pushresult (lua_State *L, int i, const char *filename) {  if (i) {    lua_pushboolean(L, 1);    return 1;  }  else {    lua_pushnil(L);    if (filename)      lua_pushfstring(L, "%s: %s", filename, strerror(errno));    else      lua_pushfstring(L, "%s", strerror(errno));    lua_pushnumber(L, errno);    return 3;  }}static FILE **topfile (lua_State *L, int findex) {  FILE **f = (FILE **)luaL_checkudata(L, findex, FILEHANDLE);  if (f == NULL) luaL_argerror(L, findex, "bad file");  return f;}static int io_type (lua_State *L) {  FILE **f = (FILE **)luaL_checkudata(L, 1, FILEHANDLE);  if (f == NULL) lua_pushnil(L);  else if (*f == NULL)    lua_pushliteral(L, "closed file");  else    lua_pushliteral(L, "file");  return 1;}static FILE *tofile (lua_State *L, int findex) {  FILE **f = topfile(L, findex);  if (*f == NULL)    luaL_error(L, "attempt to use a closed file");  return *f;}/*** When creating file handles, always creates a `closed' file handle** before opening the actual file; so, if there is a memory error, the** file is not left opened.*/static FILE **newfile (lua_State *L) {  FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));  *pf = NULL;  /* file handle is currently `closed' */  luaL_getmetatable(L, FILEHANDLE);  lua_setmetatable(L, -2);  return pf;}/*** assumes that top of the stack is the `io' library, and next is** the `io' metatable*/static void registerfile (lua_State *L, FILE *f, const char *name,                                                 const char *impname) {  lua_pushstring(L, name);  *newfile(L) = f;  if (impname) {    lua_pushstring(L, impname);    lua_pushvalue(L, -2);    lua_settable(L, -6);  /* metatable[impname] = file */  }  lua_settable(L, -3);  /* io[name] = file */}static int aux_close (lua_State *L) {  FILE *f = tofile(L, 1);  if (f == stdin || f == stdout || f == stderr)    return 0;  /* file cannot be closed */  else {    int ok = (pclose(f) != -1) || (fclose(f) == 0);    if (ok)      *(FILE **)lua_touserdata(L, 1) = NULL;  /* mark file as closed */    return ok;  }}static int io_close (lua_State *L) {  if (lua_isnone(L, 1) && lua_type(L, lua_upvalueindex(1)) == LUA_TTABLE) {    lua_pushstring(L, IO_OUTPUT);    lua_rawget(L, lua_upvalueindex(1));  }  return pushresult(L, aux_close(L), NULL);}static int io_gc (lua_State *L) {  FILE **f = topfile(L, 1);  if (*f != NULL)  /* ignore closed files */    aux_close(L);  return 0;}static int io_tostring (lua_State *L) {  char buff[128];  FILE **f = topfile(L, 1);  if (*f == NULL)    strcpy(buff, "closed");  else    sprintf(buff, "%p", lua_touserdata(L, 1));  lua_pushfstring(L, "file (%s)", buff);  return 1;}static int io_open (lua_State *L) {  const char *filename = luaL_checkstring(L, 1);  const char *mode = luaL_optstring(L, 2, "r");  FILE **pf = newfile(L);  *pf = fopen(filename, mode);  return (*pf == NULL) ? pushresult(L, 0, filename) : 1;}static int io_popen (lua_State *L) {#if !USE_POPEN  luaL_error(L, "`popen' not supported");  return 0;#else  const char *filename = luaL_checkstring(L, 1);  const char *mode = luaL_optstring(L, 2, "r");  FILE **pf = newfile(L);  *pf = popen(filename, mode);  return (*pf == NULL) ? pushresult(L, 0, filename) : 1;#endif}static int io_tmpfile (lua_State *L) {  FILE **pf = newfile(L);  *pf = tmpfile();  return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;}static FILE *getiofile (lua_State *L, const char *name) {  lua_pushstring(L, name);  lua_rawget(L, lua_upvalueindex(1));  return tofile(L, -1);}static int g_iofile (lua_State *L, const char *name, const char *mode) {  if (!lua_isnoneornil(L, 1)) {    const char *filename = lua_tostring(L, 1);    lua_pushstring(L, name);    if (filename) {      FILE **pf = newfile(L);      *pf = fopen(filename, mode);      if (*pf == NULL) {        lua_pushfstring(L, "%s: %s", filename, strerror(errno));        luaL_argerror(L, 1, lua_tostring(L, -1));      }    }    else {      tofile(L, 1);  /* check that it's a valid file handle */      lua_pushvalue(L, 1);    }    lua_rawset(L, lua_upvalueindex(1));  }  /* return current value */  lua_pushstring(L, name);  lua_rawget(L, lua_upvalueindex(1));  return 1;}static int io_input (lua_State *L) {  return g_iofile(L, IO_INPUT, "r");}static int io_output (lua_State *L) {  return g_iofile(L, IO_OUTPUT, "w");}static int io_readline (lua_State *L);static void aux_lines (lua_State *L, int idx, int close) {  lua_pushliteral(L, FILEHANDLE);  lua_rawget(L, LUA_REGISTRYINDEX);  lua_pushvalue(L, idx);  lua_pushboolean(L, close);  /* close/not close file when finished */  lua_pushcclosure(L, io_readline, 3);}static int f_lines (lua_State *L) {  tofile(L, 1);  /* check that it's a valid file handle */  aux_lines(L, 1, 0);  return 1;}static int io_lines (lua_State *L) {  if (lua_isnoneornil(L, 1)) {  /* no arguments? */    lua_pushstring(L, IO_INPUT);    lua_rawget(L, lua_upvalueindex(1));  /* will iterate over default input */    return f_lines(L);  }  else {    const char *filename = luaL_checkstring(L, 1);    FILE **pf = newfile(L);    *pf = fopen(filename, "r");    luaL_argcheck(L, *pf, 1,  strerror(errno));    aux_lines(L, lua_gettop(L), 1);    return 1;  }}/*** {======================================================** READ** =======================================================*/static int read_number (lua_State *L, FILE *f) {  lua_Number d;  if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {    lua_pushnumber(L, d);    return 1;  }  else return 0;  /* read fails */}static int test_eof (lua_State *L, FILE *f) {  int c = getc(f);  ungetc(c, f);  lua_pushlstring(L, NULL, 0);  return (c != EOF);}static int read_line (lua_State *L, FILE *f) {  luaL_Buffer b;  luaL_buffinit(L, &b);  for (;;) {    size_t l;    char *p = luaL_prepbuffer(&b);    if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) {  /* eof? */      luaL_pushresult(&b);  /* close buffer */      return (lua_strlen(L, -1) > 0);  /* check whether read something */    }    l = strlen(p);    if (p[l-1] != '\n')      luaL_addsize(&b, l);    else {      luaL_addsize(&b, l - 1);  /* do not include `eol' */      luaL_pushresult(&b);  /* close buffer */      return 1;  /* read at least an `eol' */    }  }}static int read_chars (lua_State *L, FILE *f, size_t n) {  size_t rlen;  /* how much to read */  size_t nr;  /* number of chars actually read */  luaL_Buffer b;  luaL_buffinit(L, &b);  rlen = LUAL_BUFFERSIZE;  /* try to read that much each time */  do {    char *p = luaL_prepbuffer(&b);    if (rlen > n) rlen = n;  /* cannot read more than asked */    nr = fread(p, sizeof(char), rlen, f);    luaL_addsize(&b, nr);    n -= nr;  /* still have to read `n' chars */  } while (n > 0 && nr == rlen);  /* until end of count or eof */  luaL_pushresult(&b);  /* close buffer */  return (n == 0 || lua_strlen(L, -1) > 0);}static int g_read (lua_State *L, FILE *f, int first) {  int nargs = lua_gettop(L) - 1;  int success;  int n;  if (nargs == 0) {  /* no arguments? */    success = read_line(L, f);    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)lua_tonumber(L, n);        success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -