summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@samsung.com>2014-12-12 13:39:57 +0000
committerDaniel Kolesa <d.kolesa@samsung.com>2014-12-12 13:39:57 +0000
commit09869589c9528afef7544753b7229d2cd944cbec (patch)
treea8b656ed25561ded5102a437ced93e046fef1ff3 /src/bin
parent4a1bfdeb4d771f39c49f9d8fc65aa0cde2700de0 (diff)
elua: move caching into the library
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/elua/cache.c215
-rw-r--r--src/bin/elua/main.c12
-rw-r--r--src/bin/elua/main.h3
3 files changed, 6 insertions, 224 deletions
diff --git a/src/bin/elua/cache.c b/src/bin/elua/cache.c
deleted file mode 100644
index c71fd04e7b..0000000000
--- a/src/bin/elua/cache.c
+++ /dev/null
@@ -1,215 +0,0 @@
1#include "config.h"
2
3/* elua bytecode caching */
4
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/mman.h>
8#include <fcntl.h>
9#include <unistd.h>
10
11#include "main.h"
12
13/* bytecode caching */
14
15static Eina_File *
16check_bc(Eina_File *of, const char *fname, Eina_Bool *bc)
17{
18 if (of)
19 {
20 struct stat bc_stat, sc_stat;
21 /* original file doesn't exist, only bytecode does, use bytecode */
22 if (stat(fname, &sc_stat) < 0)
23 return of;
24 if (stat(eina_file_filename_get(of), &bc_stat) < 0)
25 {
26 /* what? */
27 eina_file_close(of);
28 goto generate;
29 }
30 /* bytecode is newer than original file, use bytecode */
31 if (bc_stat.st_mtime > sc_stat.st_mtime)
32 return of;
33 /* bytecode is not new enough; trigger regeneration */
34 eina_file_close(of);
35 }
36generate:
37 *bc = EINA_TRUE;
38 return eina_file_open(fname, EINA_FALSE);
39}
40
41static Eina_File *
42open_src(const char *fname, Eina_Bool *bc)
43{
44 Eina_File *f = NULL;
45 const char *ext = strstr(fname, ".lua");
46 if (ext && !ext[4])
47 {
48 char buf[PATH_MAX];
49 snprintf(buf, sizeof(buf), "%sc", fname);
50 f = check_bc(eina_file_open(buf, EINA_FALSE), fname, bc);
51 }
52 if (!f) f = eina_file_open(fname, EINA_FALSE);
53 return f;
54}
55
56static int
57writef(lua_State *L EINA_UNUSED, const void *p, size_t size, void *ud)
58{
59 FILE *f = ud;
60 return ferror(f) || (fwrite(p, 1, size, f) != size);
61}
62
63static FILE *
64bc_tmp_open(const char *fname, char *buf, size_t buflen)
65{
66 int fd;
67#ifndef _WIN32
68 mode_t old_umask;
69#endif
70 char *fs = strrchr(fname, '/'), *bs = strrchr(fname, '\\');
71 if (!fs && !bs)
72 snprintf(buf, buflen, "./XXXXXX");
73 else
74 {
75 char *ss = (fs > bs) ? fs : bs;
76 snprintf(buf, buflen, "%.*sXXXXXX", (int)(ss - fname + 1), fname);
77 }
78#ifndef _WIN32
79 old_umask = umask(S_IRWXG|S_IRWXO);
80#endif
81 fd = mkstemp(buf);
82#ifndef _WIN32
83 umask(old_umask);
84#endif
85 if (fd < 0)
86 return NULL;
87 return fdopen(fd, "w");
88}
89
90static void
91write_bc(lua_State *L, const char *fname)
92{
93 FILE *f;
94 char buf[PATH_MAX];
95 if ((f = bc_tmp_open(fname, buf, sizeof(buf))))
96 {
97 char buf2[PATH_MAX];
98 if (lua_dump(L, writef, f))
99 {
100 fclose(f);
101 /* there really is nothing to handle here */
102 (void)!!remove(buf);
103 }
104 else fclose(f);
105 snprintf(buf2, sizeof(buf2), "%sc", fname);
106 if (rename(buf, buf2))
107 {
108 /* a futile attempt at cleanup */
109 (void)!!remove(buf);
110 (void)!!remove(buf2);
111 }
112 }
113}
114
115static const char *
116getf(lua_State *L EINA_UNUSED, void *ud, size_t *size)
117{
118 char *buff = *((char**)ud);
119 if (feof(stdin)) return NULL;
120 *size = fread(buff, 1, LUAL_BUFFERSIZE, stdin);
121 return (*size > 0) ? buff : NULL;
122}
123
124static int
125elua_loadstdin(lua_State *L)
126{
127 char buff[LUAL_BUFFERSIZE];
128 int status = lua_load(L, getf, &buff, "=stdin");
129 if (ferror(stdin))
130 {
131 lua_pop(L, 1);
132 lua_pushfstring(L, "cannot read stdin: %s", strerror(errno));
133 return LUA_ERRFILE;
134 }
135 return status;
136}
137
138typedef struct Map_Stream
139{
140 char *fmap;
141 size_t flen;
142} Map_Stream;
143
144static const char *
145getf_map(lua_State *L EINA_UNUSED, void *ud, size_t *size)
146{
147 Map_Stream *s = ud;
148 const char *fmap = s->fmap;
149 *size = s->flen;
150 /* gotta null it - tell luajit to terminate reading */
151 s->fmap = NULL;
152 return fmap;
153}
154
155int
156elua_loadfile(lua_State *L, const char *fname)
157{
158 Map_Stream s;
159 int status;
160 Eina_File *f;
161 const char *chname;
162 Eina_Bool bcache = EINA_FALSE;
163 if (!fname)
164 {
165 return elua_loadstdin(L);
166 }
167 if (!(f = open_src(fname, &bcache)))
168 {
169 lua_pushfstring(L, "cannot open %s: %s", fname, strerror(errno));
170 return LUA_ERRFILE;
171 }
172 chname = lua_pushfstring(L, "@%s", fname);
173 s.flen = eina_file_size_get(f);
174 if (!(s.fmap = eina_file_map_all(f, EINA_FILE_RANDOM)))
175 {
176 lua_pushfstring(L, "cannot read %s: %s", chname + 1, strerror(errno));
177 lua_remove(L, -2);
178 return LUA_ERRFILE;
179 }
180 status = lua_load(L, getf_map, &s, chname);
181 eina_file_map_free(f, s.fmap);
182 eina_file_close(f);
183 if (!status && bcache) write_bc(L, fname);
184 lua_remove(L, -2);
185 return status;
186}
187
188/* lua function */
189
190static int
191loadfile(lua_State *L)
192{
193 const char *fname = luaL_optstring(L, 1, NULL);
194 int status = elua_loadfile(L, fname),
195 hasenv = (lua_gettop(L) >= 3);
196 if (!status)
197 {
198 if (hasenv)
199 {
200 lua_pushvalue(L, 3);
201 lua_setfenv(L, -2);
202 }
203 return 1;
204 }
205 lua_pushnil(L);
206 lua_insert(L, -2);
207 return 2;
208}
209
210void
211elua_register_cache(lua_State *L)
212{
213 lua_pushcfunction(L, loadfile);
214 lua_setglobal(L, "loadfile");
215}
diff --git a/src/bin/elua/main.c b/src/bin/elua/main.c
index 5ff7487bef..1eb2a7508a 100644
--- a/src/bin/elua/main.c
+++ b/src/bin/elua/main.c
@@ -195,7 +195,7 @@ elua_dolib(lua_State *L, const char *libname)
195static int 195static int
196elua_dofile(lua_State *L, const char *fname) 196elua_dofile(lua_State *L, const char *fname)
197{ 197{
198 return elua_report(L, elua_loadfile(L, fname) || elua_docall(L, 0, 1)); 198 return elua_report(L, elua_io_loadfile(L, fname) || elua_docall(L, 0, 1));
199} 199}
200 200
201static int 201static int
@@ -238,14 +238,14 @@ elua_doscript(lua_State *L, int argc, char **argv, int n, int *quit)
238 if (f) 238 if (f)
239 { 239 {
240 fclose(f); 240 fclose(f);
241 status = elua_loadfile(L, fname); 241 status = elua_io_loadfile(L, fname);
242 } 242 }
243 else 243 else
244 status = !elua_loadapp(L, fname); 244 status = !elua_loadapp(L, fname);
245 } 245 }
246 else 246 else
247 { 247 {
248 status = elua_loadfile(L, fname); 248 status = elua_io_loadfile(L, fname);
249 } 249 }
250 lua_insert(L, -(narg + 1)); 250 lua_insert(L, -(narg + 1));
251 if (!status) 251 if (!status)
@@ -444,7 +444,7 @@ elua_main(lua_State *L)
444 } 444 }
445 } 445 }
446 snprintf(modfile, sizeof(modfile), "%s/module.lua", coref); 446 snprintf(modfile, sizeof(modfile), "%s/module.lua", coref);
447 if (elua_report(L, elua_loadfile(L, modfile))) 447 if (elua_report(L, elua_io_loadfile(L, modfile)))
448 { 448 {
449 m->status = 1; 449 m->status = 1;
450 return 0; 450 return 0;
@@ -460,7 +460,7 @@ elua_main(lua_State *L)
460 lua_call(L, 2, 0); 460 lua_call(L, 2, 0);
461 461
462 snprintf(modfile, sizeof(modfile), "%s/gettext.lua", coref); 462 snprintf(modfile, sizeof(modfile), "%s/gettext.lua", coref);
463 if (elua_report(L, elua_loadfile(L, modfile))) 463 if (elua_report(L, elua_io_loadfile(L, modfile)))
464 { 464 {
465 m->status = 1; 465 m->status = 1;
466 return 0; 466 return 0;
@@ -468,7 +468,7 @@ elua_main(lua_State *L)
468 elua_state_setup_i18n(L); 468 elua_state_setup_i18n(L);
469 lua_call(L, 1, 0); 469 lua_call(L, 1, 0);
470 470
471 elua_register_cache(L); 471 elua_io_register(L);
472 lua_gc(L, LUA_GCRESTART, 0); 472 lua_gc(L, LUA_GCRESTART, 0);
473 473
474 INF("elua lua state initialized"); 474 INF("elua lua state initialized");
diff --git a/src/bin/elua/main.h b/src/bin/elua/main.h
index c66b3d6d7d..29f7a4249d 100644
--- a/src/bin/elua/main.h
+++ b/src/bin/elua/main.h
@@ -37,7 +37,4 @@ extern int el_log_domain;
37#define ERR(...) EINA_LOG_DOM_ERR(el_log_domain, __VA_ARGS__) 37#define ERR(...) EINA_LOG_DOM_ERR(el_log_domain, __VA_ARGS__)
38#define CRT(...) EINA_LOG_DOM_CRITICAL(el_log_domain, __VA_ARGS__) 38#define CRT(...) EINA_LOG_DOM_CRITICAL(el_log_domain, __VA_ARGS__)
39 39
40int elua_loadfile(lua_State *L, const char *fname);
41void elua_register_cache(lua_State *L);
42
43#endif 40#endif