misc/liblua/liolib.c
author koda
Mon, 02 May 2011 02:07:28 +0200
changeset 5196 04ce9666a692
parent 2812 0a24853de796
child 10017 de822cd3df3a
permissions -rw-r--r--
update hgtags
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2812
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     1
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     2
** $Id: liolib.c,v 2.73.1.3 2008/01/18 17:47:43 roberto Exp $
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     3
** Standard I/O (and system) library
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     4
** See Copyright Notice in lua.h
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     5
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     6
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     7
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     8
#include <errno.h>
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
     9
#include <stdio.h>
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    10
#include <stdlib.h>
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    11
#include <string.h>
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    12
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    13
#define liolib_c
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    14
#define LUA_LIB
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    15
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    16
#include "lua.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    17
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    18
#include "lauxlib.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    19
#include "lualib.h"
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    20
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    21
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    22
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    23
#define IO_INPUT	1
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    24
#define IO_OUTPUT	2
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    25
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    26
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    27
static const char *const fnames[] = {"input", "output"};
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    28
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    29
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    30
static int pushresult (lua_State *L, int i, const char *filename) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    31
  int en = errno;  /* calls to Lua API may change this value */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    32
  if (i) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    33
    lua_pushboolean(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    34
    return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    35
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    36
  else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    37
    lua_pushnil(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    38
    if (filename)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    39
      lua_pushfstring(L, "%s: %s", filename, strerror(en));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    40
    else
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    41
      lua_pushfstring(L, "%s", strerror(en));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    42
    lua_pushinteger(L, en);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    43
    return 3;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    44
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    45
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    46
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    47
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    48
static void fileerror (lua_State *L, int arg, const char *filename) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    49
  lua_pushfstring(L, "%s: %s", filename, strerror(errno));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    50
  luaL_argerror(L, arg, lua_tostring(L, -1));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    51
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    52
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    53
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    54
#define tofilep(L)	((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    55
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    56
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    57
static int io_type (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    58
  void *ud;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    59
  luaL_checkany(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    60
  ud = lua_touserdata(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    61
  lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    62
  if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    63
    lua_pushnil(L);  /* not a file */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    64
  else if (*((FILE **)ud) == NULL)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    65
    lua_pushliteral(L, "closed file");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    66
  else
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    67
    lua_pushliteral(L, "file");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    68
  return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    69
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    70
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    71
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    72
static FILE *tofile (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    73
  FILE **f = tofilep(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    74
  if (*f == NULL)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    75
    luaL_error(L, "attempt to use a closed file");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    76
  return *f;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    77
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    78
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    79
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    80
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    81
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    82
** When creating file handles, always creates a `closed' file handle
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    83
** before opening the actual file; so, if there is a memory error, the
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    84
** file is not left opened.
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    85
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    86
static FILE **newfile (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    87
  FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    88
  *pf = NULL;  /* file handle is currently `closed' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    89
  luaL_getmetatable(L, LUA_FILEHANDLE);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    90
  lua_setmetatable(L, -2);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    91
  return pf;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    92
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    93
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    94
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    95
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    96
** function to (not) close the standard files stdin, stdout, and stderr
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    97
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    98
static int io_noclose (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
    99
  lua_pushnil(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   100
  lua_pushliteral(L, "cannot close standard file");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   101
  return 2;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   102
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   103
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   104
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   105
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   106
** function to close 'popen' files
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   107
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   108
static int io_pclose (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   109
  FILE **p = tofilep(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   110
  int ok = lua_pclose(L, *p);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   111
  *p = NULL;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   112
  return pushresult(L, ok, NULL);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   113
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   114
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   115
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   116
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   117
** function to close regular files
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   118
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   119
static int io_fclose (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   120
  FILE **p = tofilep(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   121
  int ok = (fclose(*p) == 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   122
  *p = NULL;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   123
  return pushresult(L, ok, NULL);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   124
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   125
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   126
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   127
static int aux_close (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   128
  lua_getfenv(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   129
  lua_getfield(L, -1, "__close");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   130
  return (lua_tocfunction(L, -1))(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   131
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   132
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   133
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   134
static int io_close (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   135
  if (lua_isnone(L, 1))
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   136
    lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   137
  tofile(L);  /* make sure argument is a file */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   138
  return aux_close(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   139
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   140
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   141
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   142
static int io_gc (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   143
  FILE *f = *tofilep(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   144
  /* ignore closed files */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   145
  if (f != NULL)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   146
    aux_close(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   147
  return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   148
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   149
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   150
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   151
static int io_tostring (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   152
  FILE *f = *tofilep(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   153
  if (f == NULL)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   154
    lua_pushliteral(L, "file (closed)");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   155
  else
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   156
    lua_pushfstring(L, "file (%p)", f);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   157
  return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   158
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   159
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   160
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   161
static int io_open (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   162
  const char *filename = luaL_checkstring(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   163
  const char *mode = luaL_optstring(L, 2, "r");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   164
  FILE **pf = newfile(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   165
  *pf = fopen(filename, mode);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   166
  return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   167
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   168
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   169
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   170
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   171
** this function has a separated environment, which defines the
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   172
** correct __close for 'popen' files
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   173
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   174
static int io_popen (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   175
  const char *filename = luaL_checkstring(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   176
  const char *mode = luaL_optstring(L, 2, "r");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   177
  FILE **pf = newfile(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   178
  *pf = lua_popen(L, filename, mode);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   179
  return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   180
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   181
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   182
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   183
static int io_tmpfile (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   184
  FILE **pf = newfile(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   185
  *pf = tmpfile();
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   186
  return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   187
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   188
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   189
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   190
static FILE *getiofile (lua_State *L, int findex) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   191
  FILE *f;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   192
  lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   193
  f = *(FILE **)lua_touserdata(L, -1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   194
  if (f == NULL)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   195
    luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   196
  return f;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   197
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   198
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   199
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   200
static int g_iofile (lua_State *L, int f, const char *mode) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   201
  if (!lua_isnoneornil(L, 1)) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   202
    const char *filename = lua_tostring(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   203
    if (filename) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   204
      FILE **pf = newfile(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   205
      *pf = fopen(filename, mode);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   206
      if (*pf == NULL)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   207
        fileerror(L, 1, filename);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   208
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   209
    else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   210
      tofile(L);  /* check that it's a valid file handle */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   211
      lua_pushvalue(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   212
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   213
    lua_rawseti(L, LUA_ENVIRONINDEX, f);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   214
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   215
  /* return current value */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   216
  lua_rawgeti(L, LUA_ENVIRONINDEX, f);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   217
  return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   218
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   219
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   220
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   221
static int io_input (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   222
  return g_iofile(L, IO_INPUT, "r");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   223
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   224
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   225
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   226
static int io_output (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   227
  return g_iofile(L, IO_OUTPUT, "w");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   228
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   229
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   230
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   231
static int io_readline (lua_State *L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   232
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   233
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   234
static void aux_lines (lua_State *L, int idx, int toclose) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   235
  lua_pushvalue(L, idx);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   236
  lua_pushboolean(L, toclose);  /* close/not close file when finished */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   237
  lua_pushcclosure(L, io_readline, 2);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   238
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   239
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   240
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   241
static int f_lines (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   242
  tofile(L);  /* check that it's a valid file handle */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   243
  aux_lines(L, 1, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   244
  return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   245
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   246
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   247
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   248
static int io_lines (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   249
  if (lua_isnoneornil(L, 1)) {  /* no arguments? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   250
    /* will iterate over default input */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   251
    lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   252
    return f_lines(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   253
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   254
  else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   255
    const char *filename = luaL_checkstring(L, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   256
    FILE **pf = newfile(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   257
    *pf = fopen(filename, "r");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   258
    if (*pf == NULL)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   259
      fileerror(L, 1, filename);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   260
    aux_lines(L, lua_gettop(L), 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   261
    return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   262
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   263
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   264
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   265
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   266
/*
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   267
** {======================================================
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   268
** READ
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   269
** =======================================================
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   270
*/
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   271
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   272
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   273
static int read_number (lua_State *L, FILE *f) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   274
  lua_Number d;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   275
  if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   276
    lua_pushnumber(L, d);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   277
    return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   278
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   279
  else return 0;  /* read fails */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   280
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   281
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   282
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   283
static int test_eof (lua_State *L, FILE *f) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   284
  int c = getc(f);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   285
  ungetc(c, f);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   286
  lua_pushlstring(L, NULL, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   287
  return (c != EOF);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   288
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   289
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   290
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   291
static int read_line (lua_State *L, FILE *f) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   292
  luaL_Buffer b;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   293
  luaL_buffinit(L, &b);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   294
  for (;;) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   295
    size_t l;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   296
    char *p = luaL_prepbuffer(&b);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   297
    if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) {  /* eof? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   298
      luaL_pushresult(&b);  /* close buffer */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   299
      return (lua_objlen(L, -1) > 0);  /* check whether read something */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   300
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   301
    l = strlen(p);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   302
    if (l == 0 || p[l-1] != '\n')
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   303
      luaL_addsize(&b, l);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   304
    else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   305
      luaL_addsize(&b, l - 1);  /* do not include `eol' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   306
      luaL_pushresult(&b);  /* close buffer */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   307
      return 1;  /* read at least an `eol' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   308
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   309
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   310
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   311
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   312
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   313
static int read_chars (lua_State *L, FILE *f, size_t n) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   314
  size_t rlen;  /* how much to read */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   315
  size_t nr;  /* number of chars actually read */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   316
  luaL_Buffer b;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   317
  luaL_buffinit(L, &b);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   318
  rlen = LUAL_BUFFERSIZE;  /* try to read that much each time */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   319
  do {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   320
    char *p = luaL_prepbuffer(&b);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   321
    if (rlen > n) rlen = n;  /* cannot read more than asked */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   322
    nr = fread(p, sizeof(char), rlen, f);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   323
    luaL_addsize(&b, nr);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   324
    n -= nr;  /* still have to read `n' chars */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   325
  } while (n > 0 && nr == rlen);  /* until end of count or eof */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   326
  luaL_pushresult(&b);  /* close buffer */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   327
  return (n == 0 || lua_objlen(L, -1) > 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   328
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   329
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   330
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   331
static int g_read (lua_State *L, FILE *f, int first) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   332
  int nargs = lua_gettop(L) - 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   333
  int success;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   334
  int n;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   335
  clearerr(f);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   336
  if (nargs == 0) {  /* no arguments? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   337
    success = read_line(L, f);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   338
    n = first+1;  /* to return 1 result */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   339
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   340
  else {  /* ensure stack space for all results and for auxlib's buffer */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   341
    luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   342
    success = 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   343
    for (n = first; nargs-- && success; n++) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   344
      if (lua_type(L, n) == LUA_TNUMBER) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   345
        size_t l = (size_t)lua_tointeger(L, n);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   346
        success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   347
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   348
      else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   349
        const char *p = lua_tostring(L, n);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   350
        luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   351
        switch (p[1]) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   352
          case 'n':  /* number */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   353
            success = read_number(L, f);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   354
            break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   355
          case 'l':  /* line */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   356
            success = read_line(L, f);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   357
            break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   358
          case 'a':  /* file */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   359
            read_chars(L, f, ~((size_t)0));  /* read MAX_SIZE_T chars */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   360
            success = 1; /* always success */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   361
            break;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   362
          default:
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   363
            return luaL_argerror(L, n, "invalid format");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   364
        }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   365
      }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   366
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   367
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   368
  if (ferror(f))
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   369
    return pushresult(L, 0, NULL);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   370
  if (!success) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   371
    lua_pop(L, 1);  /* remove last result */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   372
    lua_pushnil(L);  /* push nil instead */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   373
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   374
  return n - first;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   375
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   376
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   377
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   378
static int io_read (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   379
  return g_read(L, getiofile(L, IO_INPUT), 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   380
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   381
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   382
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   383
static int f_read (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   384
  return g_read(L, tofile(L), 2);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   385
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   386
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   387
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   388
static int io_readline (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   389
  FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   390
  int sucess;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   391
  if (f == NULL)  /* file is already closed? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   392
    luaL_error(L, "file is already closed");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   393
  sucess = read_line(L, f);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   394
  if (ferror(f))
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   395
    return luaL_error(L, "%s", strerror(errno));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   396
  if (sucess) return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   397
  else {  /* EOF */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   398
    if (lua_toboolean(L, lua_upvalueindex(2))) {  /* generator created file? */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   399
      lua_settop(L, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   400
      lua_pushvalue(L, lua_upvalueindex(1));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   401
      aux_close(L);  /* close it */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   402
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   403
    return 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   404
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   405
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   406
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   407
/* }====================================================== */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   408
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   409
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   410
static int g_write (lua_State *L, FILE *f, int arg) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   411
  int nargs = lua_gettop(L) - 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   412
  int status = 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   413
  for (; nargs--; arg++) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   414
    if (lua_type(L, arg) == LUA_TNUMBER) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   415
      /* optimization: could be done exactly as for strings */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   416
      status = status &&
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   417
          fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   418
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   419
    else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   420
      size_t l;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   421
      const char *s = luaL_checklstring(L, arg, &l);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   422
      status = status && (fwrite(s, sizeof(char), l, f) == l);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   423
    }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   424
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   425
  return pushresult(L, status, NULL);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   426
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   427
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   428
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   429
static int io_write (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   430
  return g_write(L, getiofile(L, IO_OUTPUT), 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   431
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   432
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   433
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   434
static int f_write (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   435
  return g_write(L, tofile(L), 2);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   436
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   437
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   438
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   439
static int f_seek (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   440
  static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   441
  static const char *const modenames[] = {"set", "cur", "end", NULL};
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   442
  FILE *f = tofile(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   443
  int op = luaL_checkoption(L, 2, "cur", modenames);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   444
  long offset = luaL_optlong(L, 3, 0);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   445
  op = fseek(f, offset, mode[op]);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   446
  if (op)
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   447
    return pushresult(L, 0, NULL);  /* error */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   448
  else {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   449
    lua_pushinteger(L, ftell(f));
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   450
    return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   451
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   452
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   453
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   454
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   455
static int f_setvbuf (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   456
  static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   457
  static const char *const modenames[] = {"no", "full", "line", NULL};
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   458
  FILE *f = tofile(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   459
  int op = luaL_checkoption(L, 2, NULL, modenames);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   460
  lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   461
  int res = setvbuf(f, NULL, mode[op], sz);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   462
  return pushresult(L, res == 0, NULL);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   463
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   464
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   465
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   466
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   467
static int io_flush (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   468
  return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   469
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   470
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   471
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   472
static int f_flush (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   473
  return pushresult(L, fflush(tofile(L)) == 0, NULL);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   474
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   475
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   476
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   477
static const luaL_Reg iolib[] = {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   478
  {"close", io_close},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   479
  {"flush", io_flush},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   480
  {"input", io_input},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   481
  {"lines", io_lines},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   482
  {"open", io_open},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   483
  {"output", io_output},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   484
  {"popen", io_popen},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   485
  {"read", io_read},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   486
  {"tmpfile", io_tmpfile},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   487
  {"type", io_type},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   488
  {"write", io_write},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   489
  {NULL, NULL}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   490
};
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   491
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   492
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   493
static const luaL_Reg flib[] = {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   494
  {"close", io_close},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   495
  {"flush", f_flush},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   496
  {"lines", f_lines},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   497
  {"read", f_read},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   498
  {"seek", f_seek},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   499
  {"setvbuf", f_setvbuf},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   500
  {"write", f_write},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   501
  {"__gc", io_gc},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   502
  {"__tostring", io_tostring},
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   503
  {NULL, NULL}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   504
};
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   505
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   506
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   507
static void createmeta (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   508
  luaL_newmetatable(L, LUA_FILEHANDLE);  /* create metatable for file handles */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   509
  lua_pushvalue(L, -1);  /* push metatable */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   510
  lua_setfield(L, -2, "__index");  /* metatable.__index = metatable */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   511
  luaL_register(L, NULL, flib);  /* file methods */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   512
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   513
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   514
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   515
static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   516
  *newfile(L) = f;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   517
  if (k > 0) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   518
    lua_pushvalue(L, -1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   519
    lua_rawseti(L, LUA_ENVIRONINDEX, k);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   520
  }
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   521
  lua_pushvalue(L, -2);  /* copy environment */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   522
  lua_setfenv(L, -2);  /* set it */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   523
  lua_setfield(L, -3, fname);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   524
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   525
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   526
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   527
static void newfenv (lua_State *L, lua_CFunction cls) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   528
  lua_createtable(L, 0, 1);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   529
  lua_pushcfunction(L, cls);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   530
  lua_setfield(L, -2, "__close");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   531
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   532
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   533
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   534
LUALIB_API int luaopen_io (lua_State *L) {
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   535
  createmeta(L);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   536
  /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   537
  newfenv(L, io_fclose);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   538
  lua_replace(L, LUA_ENVIRONINDEX);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   539
  /* open library */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   540
  luaL_register(L, LUA_IOLIBNAME, iolib);
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   541
  /* create (and set) default files */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   542
  newfenv(L, io_noclose);  /* close function for default files */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   543
  createstdfile(L, stdin, IO_INPUT, "stdin");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   544
  createstdfile(L, stdout, IO_OUTPUT, "stdout");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   545
  createstdfile(L, stderr, 0, "stderr");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   546
  lua_pop(L, 1);  /* pop environment for default files */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   547
  lua_getfield(L, -1, "popen");
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   548
  newfenv(L, io_pclose);  /* create environment for 'popen' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   549
  lua_setfenv(L, -2);  /* set fenv for 'popen' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   550
  lua_pop(L, 1);  /* pop 'popen' */
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   551
  return 1;
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   552
}
0a24853de796 add liblua to sources for macosx
koda
parents:
diff changeset
   553