xref: /freebsd/stand/liblua/lutils.c (revision f276951a4de9fa5d1cd1d40ed51145c9fb196fcd)
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 void
237 register_utils(lua_State *L)
238 {
239 	luaL_newlib(L, loaderlib);
240 	lua_setglobal(L, "loader");
241 	luaL_newlib(L, iolib);
242 	lua_setglobal(L, "io");
243 }
244