elua: do not use ecore_getopt, getopt.lua improvements and fixes, initial lualian...
authorDaniel Kolesa <quaker66@gmail.com>
Thu, 24 Apr 2014 14:27:33 +0000 (15:27 +0100)
committerDaniel Kolesa <d.kolesa@samsung.com>
Tue, 10 Jun 2014 14:48:48 +0000 (15:48 +0100)
src/bin/elua/lualian.lua [new file with mode: 0644]
src/bin/elua/main.c
src/bin/elua/main.h
src/bin/elua/modules/getopt.lua
src/bin/elua/modules/lualian.lua

diff --git a/src/bin/elua/lualian.lua b/src/bin/elua/lualian.lua
new file mode 100644 (file)
index 0000000..5ec07a1
--- /dev/null
@@ -0,0 +1,98 @@
+-- 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
index a44d638..d323d66 100644 (file)
@@ -1,59 +1,24 @@
 /* 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);
 }
@@ -61,7 +26,7 @@ static void errmsg(const char *pname, const char *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;
@@ -230,43 +195,85 @@ const luaL_reg cutillib[] = {
     { 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");
 
@@ -324,8 +331,8 @@ static int lua_main(lua_State *L) {
     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);
     }
index 9f0a1e4..e5b5fb1 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <Eina.h>
 #include <Ecore.h>
-#include <Ecore_Getopt.h>
 
 #include <lua.h>
 #include <lualib.h>
index 9f79639..a479cb4 100644 (file)
@@ -86,16 +86,16 @@ local getopt_u = function(args, short, long)
     return opts, args
 end
 
-local getopt = function(args, short, long)
+M.parse = function(args, short, long)
     local ret, opts, args = pcall(getopt_u, args, short, long)
     if not ret then
         return nil, opts
     end
     return opts, args
 end
-M.getopt = getopt
+local parse = M.parse
 
-M.getopt_desc = function(parser)
+M.parse_desc = function(parser)
     local args = parser.args
     local short, long = {}, {}
     for i, desc in ipairs(parser.descs) do
@@ -109,7 +109,7 @@ M.getopt_desc = function(parser)
         if buf then long[#long + 1] = buf end
     end
     short = table.concat(short)
-    return getopt(args, short, long)
+    return parse(args, short, long)
 end
 
 M.help = function(parser, f)
index 58ca2ad..32a0727 100644 (file)
@@ -625,32 +625,31 @@ local gen_class = function(classn)
     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