aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-06-26 17:39:10 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-06-26 17:39:10 -0300
commitda585783e33f92f8dff6fd47a89671494adc11e0 (patch)
treeaa1a0f59eea602c6622427b573e9b85e94f79b66
parente81f1841644405845e7de6bd70a0f074cced3d81 (diff)
downloadlua-da585783e33f92f8dff6fd47a89671494adc11e0.tar.gz
lua-da585783e33f92f8dff6fd47a89671494adc11e0.tar.bz2
lua-da585783e33f92f8dff6fd47a89671494adc11e0.zip
new method to handle current files, with global variables
_INPUT and _OUTPUT.
-rw-r--r--iolib.c89
-rw-r--r--manual.tex91
2 files changed, 105 insertions, 75 deletions
diff --git a/iolib.c b/iolib.c
index 3a532c8a..d367097e 100644
--- a/iolib.c
+++ b/iolib.c
@@ -10,8 +10,6 @@
10#include "lualib.h" 10#include "lualib.h"
11 11
12 12
13FILE *lua_infile, *lua_outfile;
14
15int lua_tagio; 13int lua_tagio;
16 14
17 15
@@ -39,59 +37,80 @@ static void pushresult (int i)
39} 37}
40 38
41 39
42static void closefile (FILE *f) 40
41static FILE *getfile (char *name)
43{ 42{
44 if (f == stdin || f == stdout) 43 lua_Object f = lua_getglobal(name);
45 return; 44 if (lua_tag(f) != lua_tagio)
46 if (f == lua_infile) 45 luaL_verror("global variable %s is not a file handle", name);
47 lua_infile = stdin; 46 return lua_getuserdata(f);
48 if (f == lua_outfile) 47}
49 lua_outfile = stdout; 48
49
50static void closefile (char *name)
51{
52 FILE *f = getfile(name);
53 if (f == stdin || f == stdout) return;
50 if (pclose(f) == -1) 54 if (pclose(f) == -1)
51 fclose(f); 55 fclose(f);
52} 56}
53 57
54 58
59static void setfile (FILE *f, char *name)
60{
61 lua_pushusertag(f, lua_tagio);
62 lua_setglobal(name);
63}
64
65
66static void setreturn (FILE *f, char *name)
67{
68 setfile(f, name);
69 lua_pushusertag(f, lua_tagio);
70}
71
55 72
56static void io_readfrom (void) 73static void io_readfrom (void)
57{ 74{
75 FILE *current;
58 lua_Object f = lua_getparam(1); 76 lua_Object f = lua_getparam(1);
59 if (f == LUA_NOOBJECT) 77 if (f == LUA_NOOBJECT) {
60 closefile(lua_infile); /* restore standart input */ 78 closefile("_INPUT");
79 current = stdin;
80 }
61 else if (lua_tag(f) == lua_tagio) 81 else if (lua_tag(f) == lua_tagio)
62 lua_infile = lua_getuserdata(f); 82 current = lua_getuserdata(f);
63 else { 83 else {
64 char *s = luaL_check_string(1); 84 char *s = luaL_check_string(1);
65 FILE *fp = (*s == '|') ? popen(s+1, "r") : fopen(s, "r"); 85 current = (*s == '|') ? popen(s+1, "r") : fopen(s, "r");
66 if (fp) 86 if (current == NULL) {
67 lua_infile = fp;
68 else {
69 pushresult(0); 87 pushresult(0);
70 return; 88 return;
71 } 89 }
72 } 90 }
73 lua_pushusertag(lua_infile, lua_tagio); 91 setreturn(current, "_INPUT");
74} 92}
75 93
76 94
77static void io_writeto (void) 95static void io_writeto (void)
78{ 96{
97 FILE *current;
79 lua_Object f = lua_getparam(1); 98 lua_Object f = lua_getparam(1);
80 if (f == LUA_NOOBJECT) 99 if (f == LUA_NOOBJECT) {
81 closefile(lua_outfile); /* restore standart output */ 100 closefile("_OUTPUT");
101 current = stdout;
102 }
82 else if (lua_tag(f) == lua_tagio) 103 else if (lua_tag(f) == lua_tagio)
83 lua_outfile = lua_getuserdata(f); 104 current = lua_getuserdata(f);
84 else { 105 else {
85 char *s = luaL_check_string(1); 106 char *s = luaL_check_string(1);
86 FILE *fp = (*s == '|') ? popen(s+1,"w") : fopen(s,"w"); 107 current = (*s == '|') ? popen(s+1,"w") : fopen(s,"w");
87 if (fp) 108 if (current == NULL) {
88 lua_outfile = fp;
89 else {
90 pushresult(0); 109 pushresult(0);
91 return; 110 return;
92 } 111 }
93 } 112 }
94 lua_pushusertag(lua_outfile, lua_tagio); 113 setreturn(current, "_OUTPUT");
95} 114}
96 115
97 116
@@ -99,10 +118,8 @@ static void io_appendto (void)
99{ 118{
100 char *s = luaL_check_string(1); 119 char *s = luaL_check_string(1);
101 FILE *fp = fopen (s, "a"); 120 FILE *fp = fopen (s, "a");
102 if (fp != NULL) { 121 if (fp != NULL)
103 lua_outfile = fp; 122 setreturn(fp, "_OUTPUT");
104 lua_pushusertag(lua_outfile, lua_tagio);
105 }
106 else 123 else
107 pushresult(0); 124 pushresult(0);
108} 125}
@@ -112,6 +129,7 @@ static void io_appendto (void)
112 129
113static void io_read (void) 130static void io_read (void)
114{ 131{
132 FILE *f = getfile("_INPUT");
115 char *buff; 133 char *buff;
116 char *p = luaL_opt_string(1, "[^\n]*{\n}"); 134 char *p = luaL_opt_string(1, "[^\n]*{\n}");
117 int inskip = 0; /* to control {skips} */ 135 int inskip = 0; /* to control {skips} */
@@ -131,7 +149,7 @@ static void io_read (void)
131 else { 149 else {
132 char *ep = luaL_item_end(p); /* get what is next */ 150 char *ep = luaL_item_end(p); /* get what is next */
133 int m; /* match result */ 151 int m; /* match result */
134 if (c == NEED_OTHER) c = getc(lua_infile); 152 if (c == NEED_OTHER) c = getc(f);
135 m = (c == EOF) ? 0 : luaL_singlematch((char)c, p); 153 m = (c == EOF) ? 0 : luaL_singlematch((char)c, p);
136 if (m) { 154 if (m) {
137 if (inskip == 0) luaI_addchar(c); 155 if (inskip == 0) luaI_addchar(c);
@@ -152,7 +170,7 @@ static void io_read (void)
152 } 170 }
153 } break_while: 171 } break_while:
154 if (c >= 0) /* not EOF nor NEED_OTHER? */ 172 if (c >= 0) /* not EOF nor NEED_OTHER? */
155 ungetc(c, lua_infile); 173 ungetc(c, f);
156 buff = luaI_addchar(0); 174 buff = luaI_addchar(0);
157 if (*buff != 0 || *p == 0) /* read something or did not fail? */ 175 if (*buff != 0 || *p == 0) /* read something or did not fail? */
158 lua_pushstring(buff); 176 lua_pushstring(buff);
@@ -161,11 +179,12 @@ static void io_read (void)
161 179
162static void io_write (void) 180static void io_write (void)
163{ 181{
182 FILE *f = getfile("_OUTPUT");
164 int arg = 1; 183 int arg = 1;
165 int status = 1; 184 int status = 1;
166 char *s; 185 char *s;
167 while ((s = luaL_opt_string(arg++, NULL)) != NULL) 186 while ((s = luaL_opt_string(arg++, NULL)) != NULL)
168 status = status && (fputs(s, lua_outfile) != EOF); 187 status = status && (fputs(s, f) != EOF);
169 pushresult(status); 188 pushresult(status);
170} 189}
171 190
@@ -300,7 +319,11 @@ static struct luaL_reg iolib[] = {
300void iolib_open (void) 319void iolib_open (void)
301{ 320{
302 lua_tagio = lua_newtag(); 321 lua_tagio = lua_newtag();
303 lua_infile=stdin; lua_outfile=stdout; 322 setfile(stdin, "_INPUT");
323 setfile(stdout, "_OUTPUT");
324 setfile(stdin, "_STDIN");
325 setfile(stdout, "_STDOUT");
326 setfile(stderr, "_STDERR");
304 luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0]))); 327 luaL_openlib(iolib, (sizeof(iolib)/sizeof(iolib[0])));
305 lua_pushcfunction(errorfb); 328 lua_pushcfunction(errorfb);
306 lua_seterrormethod(); 329 lua_seterrormethod();
diff --git a/manual.tex b/manual.tex
index 210721b2..1bab89c1 100644
--- a/manual.tex
+++ b/manual.tex
@@ -1,4 +1,4 @@
1% $Id: manual.tex,v 2.4 1997/06/19 18:49:40 roberto Exp roberto $ 1% $Id: manual.tex,v 2.5 1997/06/20 19:28:16 roberto Exp roberto $
2 2
3\documentstyle[fullpage,11pt,bnf]{article} 3\documentstyle[fullpage,11pt,bnf]{article}
4 4
@@ -38,7 +38,7 @@ Waldemar Celes
38\tecgraf\ --- Computer Science Department --- PUC-Rio 38\tecgraf\ --- Computer Science Department --- PUC-Rio
39} 39}
40 40
41\date{\small \verb$Date: 1997/06/19 18:49:40 $} 41\date{\small \verb$Date: 1997/06/20 19:28:16 $}
42 42
43\maketitle 43\maketitle
44 44
@@ -1034,7 +1034,7 @@ This method cannot be set for tables with default tag.
1034 function settable_event (table, index, value) 1034 function settable_event (table, index, value)
1035 local tm = gettagmethod(tag(table), "settable") 1035 local tm = gettagmethod(tag(table), "settable")
1036 if tm then 1036 if tm then
1037 return tm(table, index, value) 1037 tm(table, index, value)
1038 elseif type(table) ~= "table" then 1038 elseif type(table) ~= "table" then
1039 error("indexed expression not a table") 1039 error("indexed expression not a table")
1040 else 1040 else
@@ -1598,11 +1598,10 @@ If \verb|retmode| is absent,
1598all results from \verb|func| are just returned by the call. 1598all results from \verb|func| are just returned by the call.
1599If \verb|retmode| is equal to \verb|"pack"|, 1599If \verb|retmode| is equal to \verb|"pack"|,
1600the results are {\em packed\/} in a single table.\index{packed results} 1600the results are {\em packed\/} in a single table.\index{packed results}
1601That is, \verb|call| returns just one table. 1601That is, \verb|call| returns just one table;
1602At index \verb|n|, the table has the total number of results 1602at index \verb|n|, the table has the total number of results
1603from the call; 1603from the call;
1604the first result is at index 1, etc. 1604the first result is at index 1, etc.
1605
1606For instance, the following calls produce the following results: 1605For instance, the following calls produce the following results:
1607\begin{verbatim} 1606\begin{verbatim}
1608a = call(sin, {5}) --> a = 0.0871557 = sin(5) 1607a = call(sin, {5}) --> a = 0.0871557 = sin(5)
@@ -1666,7 +1665,9 @@ semantically, there is no difference between a
1666field not present in a table or a field with value \nil. 1665field not present in a table or a field with value \nil.
1667Therefore, the function only considers fields with non \nil\ values. 1666Therefore, the function only considers fields with non \nil\ values.
1668The order in which the indices are enumerated is not specified, 1667The order in which the indices are enumerated is not specified,
1669{\em not even for numeric indices}. 1668{\em not even for numeric indices}
1669(to traverse a table in numeric order,
1670use a counter).
1670If the table is modified in any way during a traversal, 1671If the table is modified in any way during a traversal,
1671the semantics of \verb|next| is undefined. 1672the semantics of \verb|next| is undefined.
1672 1673
@@ -1904,7 +1905,7 @@ stands for the value of the n-th captured substring.
1904 1905
1905If \verb|repl| is a function, then this function is called every time a 1906If \verb|repl| is a function, then this function is called every time a
1906match occurs, with the following arguments: 1907match occurs, with the following arguments:
1907If \verb|table| is present, the the first argument is this table 1908If \verb|table| is present, then the first argument is this table
1908and the second one is a match counter (1 for the first call). 1909and the second one is a match counter (1 for the first call).
1909Independently of these two optional arguments, 1910Independently of these two optional arguments,
1910all captured substrings are passed as arguments, 1911all captured substrings are passed as arguments,
@@ -2072,10 +2073,21 @@ range \Math{[0,1)}.
2072 2073
2073\subsection{I/O Facilities} \label{libio} 2074\subsection{I/O Facilities} \label{libio}
2074 2075
2075All input and output operations in Lua are done over two {\em current\/} files: 2076All input and output operations in Lua are done over two
2076one for reading and one for writing. 2077\Def{file handles}, one for reading and one for writing.
2077Initially, the current input file is \verb|stdin|, 2078These handles are stored in two Lua global variables,
2078and the current output file is \verb|stdout|. 2079called \verb|_INPUT| and \verb|_OUTPUT|.
2080The global variables
2081\verb|_STDIN|, \verb|_STDOUT| and \verb|_STDERR|
2082are initialized with file descriptors for
2083\verb|stdin|, \verb|stdout| and \verb|stderr|.
2084Initially, \verb|_INPUT=_STDIN| and \verb|_OUTPUT=_STDOUT|.
2085\Deffunc{_INPUT}\Deffunc{_OUTPUT}
2086\Deffunc{_STDIN}\Deffunc{_STDOUT}\Deffunc{_STDERR}
2087
2088A file handle is a userdata containing the file stream \verb|FILE*|,
2089and with a distinctive tag created by the I/O library.
2090
2079 2091
2080Unless otherwise stated, 2092Unless otherwise stated,
2081all I/O functions return \nil\ on failure and 2093all I/O functions return \nil\ on failure and
@@ -2083,18 +2095,16 @@ some value different from \nil\ on success.
2083 2095
2084\subsubsection*{\ff {\tt readfrom (filename)}}\Deffunc{readfrom} 2096\subsubsection*{\ff {\tt readfrom (filename)}}\Deffunc{readfrom}
2085 2097
2086This function may be called in three ways. 2098This function may be called in two ways.
2087When called with a file name, 2099When called with a file name, it opens the named file,
2088it opens the named file, 2100sets its handle as the value of \verb|_INPUT|,
2089sets it as the {\em current\/} input file, 2101and returns this value.
2090and returns a {\em handle\/} to the file
2091(this handle is a userdata containing the file stream \verb|FILE*|).
2092It does not close the current input file. 2102It does not close the current input file.
2093When called with a file handle returned by a previous call, 2103%When called with a file handle returned by a previous call,
2094it restores the file as the current input. 2104%it simply assigns it to \verb|_INPUT|.
2095When called without parameters, 2105When called without parameters,
2096it closes the current input file, 2106it closes the \verb|_INPUT| file,
2097and restores \verb|stdin| as the current input file. 2107and restores \verb|stdin| as the value of \verb|_INPUT|.
2098 2108
2099If this function fails, it returns \nil, 2109If this function fails, it returns \nil,
2100plus a string describing the error. 2110plus a string describing the error.
@@ -2105,28 +2115,26 @@ plus a string describing the error.
2105then a \Index{piped input} is open, via function \IndexVerb{popen}. 2115then a \Index{piped input} is open, via function \IndexVerb{popen}.
2106Not all systems implement pipes. 2116Not all systems implement pipes.
2107Moreover, 2117Moreover,
2108the number of files that can be open at the same time is usually limited and 2118the number of files that can be open at the same time is
2109depends on the system. 2119usually limited and depends on the system.
2110\end{quotation} 2120\end{quotation}
2111 2121
2112\subsubsection*{\ff {\tt writeto (filename)}}\Deffunc{writeto} 2122\subsubsection*{\ff {\tt writeto (filename)}}\Deffunc{writeto}
2113 2123
2114This function may be called in three ways. 2124This function may be called in two ways.
2115When called with a file name, 2125When called with a file name,
2116it opens the named file, 2126it opens the named file,
2117sets it as the {\em current\/} output file, 2127sets its handle as the value of \verb|_OUTPUT|,
2118and returns a {\em handle\/} to the file 2128and returns this value.
2119(this handle is a user data containing the file stream \verb|FILE*|).
2120It does not close the current output file. 2129It does not close the current output file.
2121Notice that, if the file already exists, 2130Notice that, if the file already exists,
2122then it will be {\em completely erased\/} with this operation. 2131then it will be {\em completely erased\/} with this operation.
2123When called with a file handle returned by a previous call, 2132%When called with a file handle returned by a previous call,
2124it restores the file as the current output. 2133%it restores the file as the current output.
2125When called without parameters, 2134When called without parameters,
2126this function closes the current output file, 2135this function closes the \verb|_OUTPUT| file,
2127and restores \verb|stdout| as the current output file. 2136and restores \verb|stdout| as the value of \verb|_OUTPUT|.
2128\index{closing a file} 2137\index{closing a file}
2129%%LHF: nao tem como escrever em stderr, tem?
2130 2138
2131If this function fails, it returns \nil, 2139If this function fails, it returns \nil,
2132plus a string describing the error. 2140plus a string describing the error.
@@ -2137,16 +2145,14 @@ plus a string describing the error.
2137then a \Index{piped output} is open, via function \IndexVerb{popen}. 2145then a \Index{piped output} is open, via function \IndexVerb{popen}.
2138Not all systems implement pipes. 2146Not all systems implement pipes.
2139Moreover, 2147Moreover,
2140the number of files that can be open at the same time is usually limited and 2148the number of files that can be open at the same time is
2141depends on the system. 2149usually limited and depends on the system.
2142\end{quotation} 2150\end{quotation}
2143 2151
2144\subsubsection*{\ff {\tt appendto (filename)}}\Deffunc{appendto} 2152\subsubsection*{\ff {\tt appendto (filename)}}\Deffunc{appendto}
2145 2153
2146This function opens a file named \verb|filename| and sets it as the 2154This function opens a file named \verb|filename| and sets it as the
2147{\em current\/} output file. 2155value of \verb|_OUTPUT|.
2148It returns the file handle,
2149or \nil\ in case of error.
2150Unlike the \verb|writeto| operation, 2156Unlike the \verb|writeto| operation,
2151this function does not erase any previous content of the file. 2157this function does not erase any previous content of the file.
2152If this function fails, it returns \nil, 2158If this function fails, it returns \nil,
@@ -2174,7 +2180,7 @@ The file must be explicitly removed when no longer needed.
2174 2180
2175\subsubsection*{\ff {\tt read ([readpattern])}}\Deffunc{read} 2181\subsubsection*{\ff {\tt read ([readpattern])}}\Deffunc{read}
2176 2182
2177This function reads the current input 2183This function reads the file \verb|_INPUT|
2178according to a read pattern, that specifies how much to read; 2184according to a read pattern, that specifies how much to read;
2179characters are read from the current input file until 2185characters are read from the current input file until
2180the read pattern fails or ends. 2186the read pattern fails or ends.
@@ -2196,7 +2202,7 @@ from the input if it belongs to the class;
2196it never fails. 2202it never fails.
2197A character class followed by \verb|*| reads until a character that 2203A character class followed by \verb|*| reads until a character that
2198does not belong to the class, or end of file; 2204does not belong to the class, or end of file;
2199since it can match a sequence of zero characteres, it never fails.% 2205since it can match a sequence of zero characters, it never fails.%
2200\footnote{ 2206\footnote{
2201Notice that the behavior of read patterns is different from 2207Notice that the behavior of read patterns is different from
2202the regular pattern matching behavior, 2208the regular pattern matching behavior,
@@ -2220,6 +2226,7 @@ Following are some examples of read patterns and their meanings:
2220This is the default pattern. 2226This is the default pattern.
2221\item \verb|"{%s*}%S%S*"| returns the next word 2227\item \verb|"{%s*}%S%S*"| returns the next word
2222(maximal sequence of non white-space characters), 2228(maximal sequence of non white-space characters),
2229skipping spaces if necessary,
2223or \nil\ on end of file. 2230or \nil\ on end of file.
2224\item \verb|"{%s*}[+-]?%d%d*"| returns the next integer 2231\item \verb|"{%s*}[+-]?%d%d*"| returns the next integer
2225or \nil\ if the next characters do not conform to an integer format. 2232or \nil\ if the next characters do not conform to an integer format.
@@ -2228,10 +2235,10 @@ or \nil\ if the next characters do not conform to an integer format.
2228\subsubsection*{\ff {\tt write (value1, ...)}}\Deffunc{write} 2235\subsubsection*{\ff {\tt write (value1, ...)}}\Deffunc{write}
2229 2236
2230This function writes the value of each of its arguments to the 2237This function writes the value of each of its arguments to the
2231current output file. 2238file \verb|_OUTPUT|.
2232The arguments must be strings or numbers. 2239The arguments must be strings or numbers.
2233To write other values, 2240To write other values,
2234use \verb|tostring| before \verb|write|. 2241use \verb|tostring| or \verb|format| before \verb|write|.
2235If this function fails, it returns \nil, 2242If this function fails, it returns \nil,
2236plus a string describing the error. 2243plus a string describing the error.
2237 2244