--- /dev/null
+-- Lualian application
+-- for use with Elua
+
+local lualian = require("lualian")
+local getopt = require("getopt")
+local file = require("eina.file")
+
+local arg_parser = {
+ usage = "Usage: %prog [OPTIONS] file1.eo file2.eo ... fileN.eo",
+ args = arg, descs = {
+ { "h", "help" , false, help = "Show this message." },
+ { "l", "license", false, help = "Show a license message." },
+ { "v", "verbose", false, help = "Be verbose." },
+ { "I", "include", true, help = "Include a directory.",
+ metavar = "DIR"
+ },
+ { "L", "library", true, help = "Specify a C library name." },
+ { "M", "module" , true, help = "Specify a module name." },
+ { "P", "prefix" , true, help = "Specify a class name prefix "
+ .. "to strip out for public interfaces."
+ },
+ { "o", "output" , true, help = "Specify output file name(s), by "
+ .. "default goes to stdout."
+ }
+ }
+}
+
+local opts, args = getopt.parse_desc(arg_parser)
+
+if not opts then
+ io.stderr:write(args, "\n")
+ getopt.help(arg_parser, io.stderr)
+ return
+end
+
+local include_dirs = {}
+local output_files = {}
+local libname, modname, cprefix = nil, nil, ""
+
+local printv = function() end
+
+for i, opt in ipairs(opts) do
+ local on = opt[1]
+ if on == "-h" or on == "--help" then
+ getopt.help(arg_parser, io.stdout)
+ return
+ end
+ if on == "-l" or on == "--license" then
+ print("Copyright (C) 2014 Daniel \"q66\" Kolesa, available under the "
+ .. "terms of the MIT license.")
+ return
+ end
+ if on == "-v" or on == "--verbose" then
+ printv = print
+ elseif on == "-I" or on == "--include" then
+ include_dirs[#include_dirs + 1] = opt[2]
+ elseif on == "-L" or on == "--library" then
+ libname = opt[2]
+ elseif on == "-M" or on == "--module" then
+ modname = opt[2]
+ elseif on == "-P" or on == "--prefix" then
+ cprefix = opt[2]
+ elseif on == "-o" or on == "--output" then
+ output_files[#output_files + 1] = opt[2]
+ end
+end
+
+if not libname then
+ io.stderr:write("library name not specified\n")
+ getopt.help(arg_parser, io.stderr)
+end
+
+local include_files = {}
+for i, v in ipairs(include_dirs) do
+ for f in file.ls(v) do
+ if f:match(".*%.eo$") then
+ printv("Including:", f)
+ include_files[#include_files + 1] = f
+ end
+ end
+end
+
+lualian.include_files(include_files)
+
+for i, fname in ipairs(args) do
+ printv("Generating for file: " .. fname)
+ local fstream = io.stdout
+ if output_files[i] then
+ printv(" Output file: " .. output_files[i])
+ fstream = io.open(output_files[i], "w")
+ if not fstream then
+ error("Cannot open output file: " .. output_files)
+ end
+ else
+ printv(" Output file: printing to stdout...")
+ end
+ lualian.generate(fname, modname, libname, cprefix, fstream)
+end
\ No newline at end of file
/* The Lua runtime component of the EFL */
-#include "main.h"
-
-static Eina_List *modlist = NULL;
-static int require_ref = LUA_REFNIL;
-
-int el_log_domain = -1;
+#include <getopt.h>
-enum {
- ARG_CODE = 0, ARG_LIBRARY, ARG_LIBDIR
-};
+#include "main.h"
typedef struct Arg_Data {
int type;
const char *value;
} Arg_Data;
-static Eina_Bool append_cb(const Ecore_Getopt *parser EINA_UNUSED,
- const Ecore_Getopt_Desc *desc EINA_UNUSED,
- const char *str,
- void *data,
- Ecore_Getopt_Value *val)
-{
- Eina_List **l = val->listp;
- Arg_Data *v = malloc(sizeof(Arg_Data));
- v->type = (size_t)data;
- v->value = str;
- *l = eina_list_append(*l, v);
- return EINA_TRUE;
-}
-
-static Ecore_Getopt opt = {
- "elua", "%prog [options] [script [args]]", "0.0.1", "See COPYING",
- "See COPYING", "A main entry for all EFL/LuaJIT powered applications.",
- 0, {
- ECORE_GETOPT_LICENSE('L', "license"),
- ECORE_GETOPT_COPYRIGHT('c', "copyright"),
- ECORE_GETOPT_VERSION('v', "version"),
- ECORE_GETOPT_HELP('h', "help"),
-
- ECORE_GETOPT_STORE_STR('C', "core-dir", "Elua core directory path."),
- ECORE_GETOPT_STORE_STR('M', "modules-dir", "Elua modules directory path."),
-
- ECORE_GETOPT_CALLBACK_ARGS('e', "execute", "Execute string "
- "'code'.", "CODE", append_cb, (void*)ARG_CODE),
- ECORE_GETOPT_CALLBACK_ARGS('l', "library", "Require library 'library'.",
- "LIBRARY", append_cb, (void*)ARG_LIBRARY),
- ECORE_GETOPT_CALLBACK_ARGS('I', "lib-dir", "Append an additional "
- "require path 'LIBDIR'.", "LIBDIR", append_cb, (void*)ARG_LIBDIR),
- ECORE_GETOPT_STORE_TRUE('E', "noenv", "Ignore environment vars."),
-
- ECORE_GETOPT_SENTINEL
- }
+enum {
+ ARG_CODE = 0, ARG_LIBRARY, ARG_LIBDIR
};
+static Eina_List *modlist = NULL;
+static int require_ref = LUA_REFNIL;
+static const char *progname = NULL;
+
+int el_log_domain = -1;
+
static void errmsg(const char *pname, const char *msg) {
ERR("%s%s%s", pname ? pname : "", pname ? ": " : "", msg);
}
static int report(lua_State *L, int status) {
if (status && !lua_isnil(L, -1)) {
const char *msg = lua_tostring(L, -1);
- errmsg(opt.prog, msg ? msg : "(non-string error)");
+ errmsg(progname, msg ? msg : "(non-string error)");
lua_pop(L, 1);
}
return status;
{ NULL, NULL }
};
+static void print_help(const char *progname, FILE *stream) {
+ fprintf(stream, "Usage: %s [OPTIONS] [SCRIPT [ARGS]]\n\n"
+ "A main entry for all EFL/LuaJIT powered applications.\n\n"
+ "The following options are supported:\n\n"
+ ""
+ " -h, --help Show this message.\n"
+ " -l, --license Show a license message.\n"
+ " -C[COREDIR], --core-dir=[COREDIR] Elua core directory path.\n"
+ " -M[MODDIR], --modules-dir=[MODDIR] Elua modules directory path.\n"
+ " -e[CODE], --execute=[CODE] Execute string 'code'.\n"
+ " -l[LIBRARY], --library=[LIBRARY] Require library 'library'.\n"
+ " -I[DIR], --lib-dir=[DIR] Append an additional require path.\n"
+ " -E, --noenv Ignore environment variables.\n", progname);
+}
+
+static void print_license(FILE *stream) {
+ fprintf(stream, "Copyright (C) 2014 Daniel \"q66\" Kolesa, available under"
+ " the terms of the MIT license.\n");
+}
+
+static struct option lopt[] = {
+ { "license" , no_argument , NULL, 'L' },
+ { "help" , no_argument , NULL, 'h' },
+
+ { "core-dir" , required_argument, NULL, 'C' },
+ { "modules-dir", required_argument, NULL, 'M' },
+
+ { "execute" , required_argument, NULL, 'e' },
+ { "library" , required_argument, NULL, 'l' },
+ { "lib-dir" , required_argument, NULL, 'I' },
+ { "noenv" , no_argument , NULL, 'E' },
+ { NULL , 0 , NULL, 0 }
+};
+
/* protected main */
static int lua_main(lua_State *L) {
- Eina_Bool quit = EINA_FALSE,
- noenv = EINA_FALSE,
- hasexec = EINA_FALSE;
- Eina_List *largs = NULL, *l = NULL;
- Arg_Data *data = NULL;
- const char *coref = NULL;
- char *coredir = NULL, *moddir = NULL;
+ Eina_Bool noenv = EINA_FALSE,
+ hasexec = EINA_FALSE;
+ Eina_List *largs = NULL, *l = NULL;
+ Arg_Data *data = NULL;
+ const char *coref = NULL;
+ char *coredir = NULL, *moddir = NULL;
char modfile[1024];
- int nonopt;
+ int ch;
struct Main_Data *m = (struct Main_Data*)lua_touserdata(L, 1);
int argc = m->argc;
char **argv = m->argv;
- if (argv[0] && argv[0][0]) opt.prog = argv[0];
-
- nonopt = ecore_getopt_parse(&opt, (Ecore_Getopt_Value[]){
- ECORE_GETOPT_VALUE_BOOL(quit), /* license */
- ECORE_GETOPT_VALUE_BOOL(quit), /* copyright */
- ECORE_GETOPT_VALUE_BOOL(quit), /* version */
- ECORE_GETOPT_VALUE_BOOL(quit), /* help */
-
- ECORE_GETOPT_VALUE_STR(coredir),
- ECORE_GETOPT_VALUE_STR( moddir),
-
- ECORE_GETOPT_VALUE_LIST(largs),
- ECORE_GETOPT_VALUE_LIST(largs),
- ECORE_GETOPT_VALUE_LIST(largs),
- ECORE_GETOPT_VALUE_LIST(largs),
- ECORE_GETOPT_VALUE_BOOL(noenv)
- }, argc, argv);
-
- if (quit) return 0;
+ progname = (argv[0] && argv[0][0]) ? argv[0] : "elua";
+
+ while ((ch = getopt_long(argc, argv, "LhC:M:e:l:I:E", lopt, NULL)) != -1) {
+ switch (ch) {
+ case 'L':
+ print_license(stdout);
+ return 0;
+ case 'h':
+ print_help(progname, stdout);
+ return 0;
+ case 'C':
+ coredir = optarg;
+ break;
+ case 'M':
+ moddir = optarg;
+ break;
+ case 'e':
+ case 'l':
+ case 'I': {
+ Arg_Data *v = malloc(sizeof(Arg_Data));
+ v->type = (ch == 'e') ? ARG_CODE : ((ch == 'l')
+ ? ARG_LIBRARY : ARG_LIBDIR);
+ v->value = optarg;
+ largs = eina_list_append(largs, v);
+ break;
+ }
+ }
+ }
INF("arguments parsed");
EINA_LIST_FREE(largs, data) free(data);
/* run script or execute sdin as file */
- if (nonopt >= 0 && nonopt < argc) {
- if ((m->status = doscript(L, argc, argv, nonopt))) return 0;
+ if (optind < argc) {
+ if ((m->status = doscript(L, argc, argv, optind))) return 0;
} else if (!hasexec) {
dofile(L, NULL);
}
return Class(classn, parent, mixins, gen_contents(classn))
end
-M.generate = function(files, include_files, fstream)
+M.include_files = function(include_files)
for i, file in ipairs(include_files) do
if not eolian.eo_file_parse(file) then
error("Failed parsing include file: " .. file)
end
end
- for i, file in ipairs(files) do
- if not eolian.eo_file_parse(file[1]) then
- error("Failed parsing file: " .. file[1])
- end
+end
+
+M.generate = function(fname, modname, libname, cprefix, fstream)
+ if not eolian.eo_file_parse(fname) then
+ error("Failed parsing file: " .. fname)
end
- for i, file in ipairs(files) do
- local fname = file[1]
- local classn = eolian.class_find_by_file(fname)
- local tp = eolian.class_type_get(classn)
- local ct = eolian.class_type
- local cl
- if tp == ct.MIXIN or tp == ct.INTERFACE then
- cl = gen_mixin(classn)
- elseif tp == ct.REGULAR or tp == ct.ABSTRACT then
- cl = gen_class(classn)
- else
- error(classn .. ": unknown type")
- end
- File(fname, classn, file[2], file[3], file[4], { cl }):generate(fstream)
+ local classn = eolian.class_find_by_file(fname)
+ local tp = eolian.class_type_get(classn)
+ local ct = eolian.class_type
+ local cl
+ if tp == ct.MIXIN or tp == ct.INTERFACE then
+ cl = gen_mixin(classn)
+ elseif tp == ct.REGULAR or tp == ct.ABSTRACT then
+ cl = gen_class(classn)
+ else
+ error(classn .. ": unknown type")
end
+ File(fname, classn, modname, libname, cprefix, { cl })
+ :generate(fstream or io.stdout)
end
return M
\ No newline at end of file