xref: /freebsd/stand/liblua/lutils.c (revision a07d59d1daafdaae0d1b1ad1f977f9eda92dc83b)
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 void
214 lregister(lua_State *L, const char *tableName, const char *funcName, int (*funcPointer)(lua_State *))
215 {
216 	lua_getglobal(L, tableName);
217 	if (!lua_istable(L, -1)) {
218 		lua_pop(L, 1);
219 		lua_newtable(L);
220 		lua_setglobal(L, tableName);
221 		lua_getglobal(L, tableName);
222 	}
223 
224 	lua_pushcfunction(L, funcPointer);
225 	lua_setfield(L, -2, funcName);
226 	lua_pop(L, 1);
227 }
228 
229 
230 typedef struct utils_func
231 {
232 	int (*func)(lua_State *);
233 	const char *table;
234 	const char *name;
235 } utils_func;
236 
237 static utils_func reg_funcs[] = {
238 			{lua_delay, "loader", "delay"},
239 			{lua_getenv, "loader", "getenv"},
240 			{lua_perform, "loader", "perform"},
241 			{lua_printc, "loader", "printc"},
242 			{lua_setenv, "loader", "setenv"},
243 			{lua_time, "loader", "time"},
244 			{lua_unsetenv, "loader", "unsetenv"},
245 
246 			{lua_closefile, "io", "close"},
247 			{lua_getchar, "io", "getchar"},
248 			{lua_gets, "io", "gets"},
249 			{lua_ischar, "io", "ischar"},
250 			{lua_openfile, "io", "open"},
251 			{lua_readfile, "io", "read"},
252 
253 			{NULL, NULL, NULL},
254 			};
255 
256 void
257 register_utils(lua_State *L)
258 {
259 	utils_func	*f = reg_funcs;
260 
261 	while (f->func != NULL && f->name != NULL) {
262 		if (f->table != NULL)
263 			lregister(L, f->table, f->name, f->func);
264 		else
265 			lua_register(L, f->name, f->func);
266 		++f;
267 	}
268 }
269