#include #include #include #include "options.h" #include "bindings.h" #include "logging.h" #include "lua-script/script.h" struct settings { const char *template_dir; }; #define CHECK_LUA_ERROR() \ do { \ if (error != 0) { \ argent_log(FATAL, "lua_error: %s", lua_tostring(L, -1)); \ lua_close(L); \ return error; \ } \ } while(0) int hs_call(lua_State *L, int nargs, int nret); int main(int argc, char **argv) { argent_log(DEBUG, "parse command-line options"); struct argent_options opts; int error = parse_options(&opts, argc, argv); if (error) // error of '2' indicates -h was passed return error == 2 ? 0 : 1; argent_log(INFO, "log level: %s", level_string(argent_log_level)); argent_log(INFO, "configuration file: %s", opts.conf_filename); if (opts.script_filename != NULL) { argent_log(INFO, "script override: %s", opts.script_filename); } argent_log(DEBUG, "create lua state"); lua_State *L = luaL_newstate(); luaL_openlibs(L); argent_log(DEBUG, "create argent table"); luaL_Reg tbl[] = { {"markdown", markdown}, {"currentWorkingDirectory", current_working_directory}, {"scanDirectory", scan_directory}, {"createDirectory", create_directory}, {"copyFile", copy_file}, {"log", argent_log_lua}, {NULL, NULL}, }; luaL_register(L, "argent", tbl); // load argent lua script argent_log(DEBUG, "load main lua script"); if (opts.script_filename == NULL) { error = luaL_dostring(L, argent_script); CHECK_LUA_ERROR(); } else { error = luaL_dofile(L, opts.script_filename); CHECK_LUA_ERROR(); if (!lua_isfunction(L, -1)) { argent_log(FATAL, "override script '%s' did not return a function!", opts.script_filename); return 1; } } // load configuration file argent_log(DEBUG, "load configuration file"); error = luaL_loadfile(L, opts.conf_filename); CHECK_LUA_ERROR(); // push config table to stack argent_log(DEBUG, "run configuration file"); error = hs_call(L, 0, 1); CHECK_LUA_ERROR(); // run argent script argent_log(DEBUG, "run main lua script"); error = hs_call(L, 1, 0); CHECK_LUA_ERROR(); argent_log(DEBUG, "close lua state"); lua_close(L); return 0; } int hs_traceback(lua_State *L) { if (!lua_isstring(L, 1)) /* 'message' is not a string, keep intact */ return 1; lua_getglobal(L, "debug"); if (!lua_istable(L, -1)) { lua_pop(L, 1); return 1; } lua_getfield(L, -1, "traceback"); if (!lua_isfunction(L, -1)) { lua_pop(L, 2); return 1; } lua_pushvalue(L, 1); lua_pushinteger(L, 2); lua_call(L, 2, 1); return 1; } int hs_call(lua_State *L, int nargs, int nret) { int traceback_pos = lua_gettop(L) - nargs; lua_pushcfunction(L, hs_traceback); lua_insert(L, traceback_pos); int result = lua_pcall(L, nargs, nret, traceback_pos); lua_remove(L, traceback_pos); return result; }