]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - stand/liblua/lutils.c
MFV r307315:
[FreeBSD/FreeBSD.git] / stand / liblua / lutils.c
1 /*-
2  * Copyright (c) 2014 Pedro Souza <pedrosouza@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include "lua.h"
32 #include "lauxlib.h"
33 #include "lstd.h"
34 #include "lutils.h"
35 #include "bootstrap.h"
36
37 static int
38 lua_perform(lua_State *L)
39 {
40         int     argc;
41         char    **argv;
42         int     res = 1;
43
44         if (parse(&argc, &argv, luaL_checkstring(L, 1)) == 0) {
45                 res = interp_builtin_cmd(argc, argv);
46                 free(argv);
47         }
48         lua_pushinteger(L, res);
49
50         return 1;
51 }
52
53 static int
54 lua_getchar(lua_State *L)
55 {
56
57         lua_pushinteger(L, getchar());
58         return 1;
59 }
60
61 static int
62 lua_ischar(lua_State *L)
63 {
64
65         lua_pushboolean(L, ischar());
66         return 1;
67 }
68
69 static int
70 lua_gets(lua_State *L)
71 {
72         char    buf[129];
73
74         ngets(buf, 128);
75         lua_pushstring(L, buf);
76         return 1;
77 }
78
79 static int
80 lua_time(lua_State *L)
81 {
82
83         lua_pushinteger(L, time(NULL));
84         return 1;
85 }
86
87 static int
88 lua_delay(lua_State *L)
89 {
90
91         delay((int)luaL_checknumber(L, 1));
92         return 0;
93 }
94
95 static int
96 lua_getenv(lua_State *L)
97 {
98         lua_pushstring(L, getenv(luaL_checkstring(L, 1)));
99
100         return 1;
101 }
102
103 static int
104 lua_setenv(lua_State *L)
105 {
106         const char *key, *val;
107
108         key = luaL_checkstring(L, 1);
109         val = luaL_checkstring(L, 2);
110         lua_pushinteger(L, setenv(key, val, 1));
111
112         return 1;
113 }
114
115 static int
116 lua_unsetenv(lua_State *L)
117 {
118         const char      *ev;
119
120         ev = luaL_checkstring(L, 1);
121         lua_pushinteger(L, unsetenv(ev));
122
123         return 1;
124 }
125
126 static int
127 lua_printc(lua_State *L)
128 {
129         int status;
130         ssize_t l;
131         const char *s = luaL_checklstring(L, 1, &l);
132
133         status = (printf("%s", s) == l);
134
135         return status;
136 }
137
138 static int
139 lua_openfile(lua_State *L)
140 {
141         const char      *str;
142
143         if (lua_gettop(L) != 1) {
144                 lua_pushnil(L);
145                 return 1;
146         }
147         str = lua_tostring(L, 1);
148
149         FILE * f = fopen(str, "r");
150         if (f != NULL) {
151                 FILE ** ptr = (FILE**)lua_newuserdata(L, sizeof(FILE**));
152                 *ptr = f;
153         } else
154                 lua_pushnil(L);
155         return 1;
156 }
157
158 static int
159 lua_closefile(lua_State *L)
160 {
161         FILE ** f;
162         if (lua_gettop(L) != 1) {
163                 lua_pushboolean(L, 0);
164                 return 1;
165         }
166
167         f = (FILE**)lua_touserdata(L, 1);
168         if (f != NULL && *f != NULL) {
169                 lua_pushboolean(L, fclose(*f) == 0 ? 1 : 0);
170                 *f = NULL;
171         } else
172                 lua_pushboolean(L, 0);
173
174         return 1;
175 }
176
177 static int
178 lua_readfile(lua_State *L)
179 {
180         FILE    **f;
181         size_t  size, r;
182         char * buf;
183
184         if (lua_gettop(L) < 1 || lua_gettop(L) > 2) {
185                 lua_pushnil(L);
186                 lua_pushinteger(L, 0);
187                 return 2;
188         }
189
190         f = (FILE**)lua_touserdata(L, 1);
191
192         if (f == NULL || *f == NULL) {
193                 lua_pushnil(L);
194                 lua_pushinteger(L, 0);
195                 return 2;
196         }
197
198         if (lua_gettop(L) == 2)
199                 size = (size_t)lua_tonumber(L, 2);
200         else
201                 size = (*f)->size;
202
203
204         buf = (char*)malloc(size);
205         r = fread(buf, 1, size, *f);
206         lua_pushlstring(L, buf, r);
207         free(buf);
208         lua_pushinteger(L, r);
209
210         return 2;
211 }
212
213 #define REG_SIMPLE(n)   { #n, lua_ ## n }
214 static const struct luaL_Reg loaderlib[] = {
215         REG_SIMPLE(delay),
216         REG_SIMPLE(getenv),
217         REG_SIMPLE(perform),
218         REG_SIMPLE(printc),
219         REG_SIMPLE(setenv),
220         REG_SIMPLE(time),
221         REG_SIMPLE(unsetenv),
222         { NULL, NULL },
223 };
224
225 static const struct luaL_Reg iolib[] = {
226         { "close", lua_closefile },
227         REG_SIMPLE(getchar),
228         REG_SIMPLE(gets),
229         REG_SIMPLE(ischar),
230         { "open", lua_openfile },
231         { "read", lua_readfile },
232         { NULL, NULL },
233 };
234 #undef REG_SIMPLE
235
236 int
237 luaopen_loader(lua_State *L)
238 {
239         luaL_newlib(L, loaderlib);
240         return 1;
241 }
242
243 int
244 luaopen_io(lua_State *L)
245 {
246         luaL_newlib(L, iolib);
247         return 1;
248 }