diff options
| author | ruki <[email protected]> | 2016-06-17 11:26:25 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2016-06-17 11:26:25 +0800 |
| commit | 72b64ee532c8de65d177e387087fb14ab9ee478f (patch) | |
| tree | 2693f4506e7567e968f0ae1995c742298da78dd2 | |
| parent | e58accaa27a4e8a9631c56e7f11279f3e437e967 (diff) | |
parse package arguments and fix output bug
| -rw-r--r-- | xmake/core/base/option.lua | 236 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/base/option.lua | 48 | ||||
| -rwxr-xr-x | xmake/plugins/macro/macros/package.lua | 34 |
3 files changed, 306 insertions, 12 deletions
diff --git a/xmake/core/base/option.lua b/xmake/core/base/option.lua index eb779b097..353d1e837 100644 --- a/xmake/core/base/option.lua +++ b/xmake/core/base/option.lua @@ -501,6 +501,242 @@ function option.find(argv, name, shortname) end end +-- parse arguments with the given options +function option.parse(argv, options) + + -- check + assert(argv and options) + + -- parse arguments + local results = {} + local argkv_end = false + local _iter, _s, _k = ipairs(argv) + while true do + + -- the idx and arg + local idx, arg = _iter(_s, _k) + + -- end? + _k = idx + if idx == nil then break end + + -- parse key and value + local key, value + local i = arg:find("=", 1, true) + + -- key=value? + if i and not argkv_end then + key = arg:sub(1, i - 1) + value = arg:sub(i + 1) + -- only key? + else + key = arg + value = true + end + + -- --key? + local prefix = 0 + if not argkv_end and key:startswith("--") then + key = key:sub(3) + prefix = 2 + -- -k? + elseif not argkv_end and key:startswith("-") then + key = key:sub(2) + prefix = 1 + end + + -- check key + if prefix and #key == 0 then + + -- failed + return nil, "invalid option: " .. arg + end + + -- --key=value or -k value or -k? + if prefix ~= 0 then + + -- find this option + local opt = nil + local longname = nil + for _, o in ipairs(options) do + + -- check + assert(o) + + -- the short name + local shortname = o[1] + + -- the long name and bindings + -- + -- .e.g test:xxx1,xxx2,xxx3 + -- + -- longname: test + -- bindings: xxx1 xxx2 xxx3 + -- + longname = option._longname(o[2]) + + -- --key? + if prefix == 2 and key == longname then + opt = o + break + -- k? + elseif prefix == 1 and key == shortname then + opt = o + break + end + end + + -- not found? + if not opt then + + -- failed + return nil, "invalid option: " .. arg + end + + -- -k value? continue to get the value + if prefix == 1 and opt[3] == "kv" then + + -- get the next idx and arg + idx, arg = _iter(_s, _k) + + -- exists value? + _k = idx + if idx == nil or arg:startswith("-") then + + -- failed + return nil, "invalid option: " .. option._ifelse(idx, arg, key) + end + + -- get value + value = arg + end + + -- check mode + if (opt[3] == "k" and type(value) ~= "boolean") or (opt[3] == "kv" and type(value) ~= "string") then + + -- failed + return nil, "invalid option: " .. arg + end + + -- value is "true" or "false", translate it + if type(value) == "string" then + if value == "true" or value == "yes" or value == "y" then value = true + elseif value == "false" or value == "no" or value == "n" then value = false + end + end + + -- save option + results[longname] = value + + -- save bindings + local bindings = option._bindings(opt[2]) + if bindings then + for _, bindname in ipairs(bindings) do + if bindname:startswith("!") then + if type(value) == "boolean" then + results[bindname:sub(2, -1)] = not value + end + else + results[bindname] = value + end + end + end + + -- value? + else + + -- stop to parse key-value arguments + argkv_end = true + + -- find a value option with name + local opt = nil + for _, o in ipairs(options) do + + -- the mode + local mode = o[3] + + -- the name + local name = option._longname(o[2]) + + -- check + assert(o and ((mode ~= "v" and mode ~= "vs") or name)) + + -- is value and with name? + if mode == "v" and name and not results[name] then + opt = o + break + -- is values and with name? + elseif mode == "vs" and name then + opt = o + break + end + end + + -- ok? save this value with name opt[2] + if opt then + + -- the mode + local mode = opt[3] + + -- the name + local name = option._longname(opt[2]) + + -- save value + if mode == "v" then + results[name] = key + elseif mode == "vs" then + -- the option + local o = results[name] + if not o then + results[name] = {} + o = results[name] + end + + -- append value + table.insert(o, key) + end + else + + -- failed + return nil, "invalid option: " .. arg + end + + end + end + + -- init the default value + for _, o in ipairs(options) do + + -- the long name + local longname = option._longname(o[2]) + + -- key=value? + if o[3] == "kv" then + + -- the key + local key = longname or o[1] + assert(key) + + -- save the default value + if results[key] == nil then + results[key] = o[4] + end + + -- value with name? + elseif o[3] == "v" and longname then + + -- save the default value + if results[longname] == nil then + results[longname] = o[4] + end + end + end + + -- ok + return results +end + + -- get the current task name function option.taskname() diff --git a/xmake/core/sandbox/modules/import/core/base/option.lua b/xmake/core/sandbox/modules/import/core/base/option.lua index 21066ce32..a98ebc113 100644 --- a/xmake/core/sandbox/modules/import/core/base/option.lua +++ b/xmake/core/sandbox/modules/import/core/base/option.lua @@ -24,7 +24,9 @@ local sandbox_core_base_option = sandbox_core_base_option or {} -- load modules +local table = require("base/table") local option = require("base/option") +local raise = require("sandbox/modules/raise") -- get the option value function sandbox_core_base_option.get(name) @@ -54,5 +56,51 @@ function sandbox_core_base_option.defaults() return option.defaults() or {} end +-- parse arguments with the given options +function sandbox_core_base_option.parse(argv, options, ...) + + -- check + assert(argv and options) + + -- add common options + table.insert(options, 1, {}) + table.insert(options, 2, {'h', "help", "k", nil, "Print this help message and exit." }) + table.insert(options, 3, {}) + + -- parse it + local results, errors = option.parse(argv, options) + if not results then + + -- show descriptions + for _, description in ipairs({...}) do + print(description) + end + + -- show options + option.show_options(options) + + -- raise errors + raise(errors) + end + + -- help? + if results.help then + + -- show descriptions + for _, description in ipairs({...}) do + print(description) + end + + -- show options + option.show_options(options) + + -- exit + raise() + end + + -- ok + return results +end + -- return module return sandbox_core_base_option diff --git a/xmake/plugins/macro/macros/package.lua b/xmake/plugins/macro/macros/package.lua index b96e11e91..f5d27e5bd 100755 --- a/xmake/plugins/macro/macros/package.lua +++ b/xmake/plugins/macro/macros/package.lua @@ -21,10 +21,19 @@ -- -- imports +import("core.base.option") import("core.project.config") import("core.project.project") import("core.platform.platform") +-- the options +local options = +{ + {'p', "plat", "kv", os.host(), "Set the platform." } +, {'f', "config", "kv", nil, "Pass the config arguments to \"xmake config\" .." } +, {'o', "outputdir", "kv", nil, "Set the output directory of the package." } +} + -- package all -- -- .e.g @@ -35,25 +44,26 @@ import("core.platform.platform") -- function main(argv) - -- get plat - local plat = argv[1] or os.host() - if plat == "." then - plat = os.host() - end - - -- get args - local args = argv[2] or "" + -- parse arguments + local args = option.parse(argv, options, "Package all architectures for the given the platform." + , "" + , "Usage: xmake macro package [options]") -- package all archs + local plat = args.plat for _, arch in ipairs(platform.archs(plat)) do -- package it - os.exec("xmake f -p %s -a %s %s", plat, arch, args) - os.exec("xmake p") + os.exec("xmake f -p %s -a %s %s", plat, arch, args.config or "") + if args.outputdir then + os.exec("xmake p -o %s", args.outputdir) + else + os.exec("xmake p") + end end -- package universal for iphoneos, watchos ... - if plat:startswith("iphone") or plat:startswith("watch") then + if plat == "iphoneos" or plat == "watchos" then -- load configure config.load() @@ -62,7 +72,7 @@ function main(argv) project.load() -- the outputdir directory - local outputdir = config.get("buildir") + local outputdir = args.outputdir or config.get("buildir") -- package all targets for _, target in pairs(project.targets()) do |
