summaryrefslogtreecommitdiff
path: root/src/lib/elua
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@samsung.com>2015-04-10 16:36:26 +0100
committerDaniel Kolesa <d.kolesa@osg.samsung.com>2015-05-06 15:05:20 +0100
commit5aca5e13a18ef06a8fcb1f4e6f93624e309a93f2 (patch)
tree9ecf622cc984acee90cb2fbc2de057d61cd998cd /src/lib/elua
parentf80999ae605911a757e0f4a53f124e048d1b4914 (diff)
elua lib: add elua_util_ APIs
Diffstat (limited to 'src/lib/elua')
-rw-r--r--src/lib/elua/Elua.h8
-rw-r--r--src/lib/elua/elua.c148
2 files changed, 156 insertions, 0 deletions
diff --git a/src/lib/elua/Elua.h b/src/lib/elua/Elua.h
index 6d49303012..cb1edc13ee 100644
--- a/src/lib/elua/Elua.h
+++ b/src/lib/elua/Elua.h
@@ -98,6 +98,14 @@ EAPI int elua_io_popen(lua_State *L);
98EAPI int elua_module_init(lua_State *L); 98EAPI int elua_module_init(lua_State *L);
99EAPI int elua_module_system_init(lua_State *L); 99EAPI int elua_module_system_init(lua_State *L);
100 100
101EAPI int elua_util_require(Elua_State *es, const char *libname);
102EAPI int elua_util_file_run(Elua_State *es, const char *fname);
103EAPI int elua_util_string_run(Elua_State *es, const char *chunk,
104 const char *chname);
105EAPI Eina_Bool elua_util_app_load(Elua_State *es, const char *appname);
106EAPI int elua_util_script_run(Elua_State *es, int argc, char **argv, int n,
107 int *quit);
108
101#endif 109#endif
102 110
103#ifdef __cplusplus 111#ifdef __cplusplus
diff --git a/src/lib/elua/elua.c b/src/lib/elua/elua.c
index 1827e1e878..df96e1d00c 100644
--- a/src/lib/elua/elua.c
+++ b/src/lib/elua/elua.c
@@ -350,3 +350,151 @@ elua_module_system_init(lua_State *L)
350 lua_concat(L, 2); 350 lua_concat(L, 2);
351 return 2; 351 return 2;
352} 352}
353
354/* Utility functions - these could be written using the other APIs */
355
356static int
357_elua_traceback(lua_State *L)
358{
359 lua_getglobal(L, "debug");
360 if (!lua_istable(L, -1))
361 {
362 lua_pop(L, 1);
363 return 1;
364 }
365 lua_getfield(L, -1, "traceback");
366 if (!lua_isfunction(L, -1))
367 {
368 lua_pop(L, 2);
369 return 1;
370 }
371 lua_pushvalue(L, 1);
372 lua_pushinteger(L, 2);
373 lua_call(L, 2, 1);
374 return 1;
375}
376
377static int
378_elua_docall(Elua_State *es, int narg, int nret)
379{
380 int status;
381 EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
382 EINA_SAFETY_ON_NULL_RETURN_VAL(es->luastate, -1);
383 int bs = lua_gettop(es->luastate) - narg;
384 lua_pushcfunction(es->luastate, _elua_traceback);
385 lua_insert(es->luastate, bs);
386 status = lua_pcall(es->luastate, narg, nret, bs);
387 lua_remove(es->luastate, bs);
388 if (status)
389 lua_gc(es->luastate, LUA_GCCOLLECT, 0);
390 return status;
391}
392
393static int
394_elua_getargs(Elua_State *es, int argc, char **argv, int n)
395{
396 int i;
397 int narg = argc - (n + 1);
398 EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
399 EINA_SAFETY_ON_NULL_RETURN_VAL(es->luastate, -1);
400 luaL_checkstack(es->luastate, narg + 3, "too many arguments to script");
401 for (i = n + 1; i < argc; ++i)
402 {
403 lua_pushstring(es->luastate, argv[i]);
404 }
405 lua_createtable(es->luastate, narg, n + 1);
406 for (i = 0; i < argc; ++i)
407 {
408 lua_pushstring(es->luastate, argv[i]);
409 lua_rawseti(es->luastate, -2, i - n);
410 }
411 return narg;
412}
413
414EAPI int
415elua_util_require(Elua_State *es, const char *libname)
416{
417 EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
418 EINA_SAFETY_ON_NULL_RETURN_VAL(es->luastate, -1);
419 EINA_SAFETY_ON_FALSE_RETURN_VAL(es->requireref, -1);
420 lua_pushstring(es->luastate, libname);
421 return elua_report_error(es, es->progname,
422 lua_pcall(es->luastate, 1, 0, 0));
423}
424
425EAPI int
426elua_util_file_run(Elua_State *es, const char *fname)
427{
428 EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
429 EINA_SAFETY_ON_NULL_RETURN_VAL(es->luastate, -1);
430 return elua_report_error(es, es->progname,
431 elua_io_loadfile(es, fname)
432 || _elua_docall(es, 0, 1));
433}
434
435EAPI int
436elua_util_string_run(Elua_State *es, const char *chunk, const char *chname)
437{
438 EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
439 EINA_SAFETY_ON_NULL_RETURN_VAL(es->luastate, -1);
440 return elua_report_error(es, es->progname,
441 luaL_loadbuffer(es->luastate, chunk, strlen(chunk),
442 chname)
443 || _elua_docall(es, 0, 0));
444}
445
446EAPI Eina_Bool
447elua_util_app_load(Elua_State *es, const char *appname)
448{
449 EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
450 EINA_SAFETY_ON_NULL_RETURN_VAL(es->luastate, EINA_FALSE);
451 EINA_SAFETY_ON_FALSE_RETURN_VAL(es->apploadref, EINA_FALSE);
452 lua_pushstring(es->luastate, appname);
453 lua_call(es->luastate, 1, 2);
454 if (lua_isnil(es->luastate, -2))
455 {
456 lua_remove(es->luastate, -2);
457 return EINA_FALSE;
458 }
459 lua_pop(es->luastate, 1);
460 return EINA_TRUE;
461}
462
463EAPI int
464elua_util_script_run(Elua_State *es, int argc, char **argv, int n, int *quit)
465{
466 int status, narg;
467 const char *fname;
468 EINA_SAFETY_ON_FALSE_RETURN_VAL(n < argc, -1);
469 EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
470 EINA_SAFETY_ON_NULL_RETURN_VAL(es->luastate, -1);
471 fname = argv[n];
472 narg = _elua_getargs(es, argc, argv, n);
473 lua_setglobal(es->luastate, "arg");
474 if (fname[0] == '-' && !fname[1]) fname = NULL;
475 if (fname)
476 {
477 /* check if there is a file of that name */
478 FILE *f = fopen(fname, "r");
479 if (f)
480 {
481 fclose(f);
482 status = elua_io_loadfile(es, fname);
483 }
484 else
485 status = !elua_util_app_load(es, fname);
486 }
487 else
488 status = elua_io_loadfile(es, fname);
489 lua_insert(es->luastate, -(narg + 1));
490 if (!status)
491 status = _elua_docall(es, narg, 1);
492 else
493 lua_pop(es->luastate, narg);
494 if (!status)
495 {
496 *quit = lua_toboolean(es->luastate, -1);
497 lua_pop(es->luastate, 1);
498 }
499 return elua_report_error(es, es->progname, status);
500}