summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2016-06-17 11:26:25 +0800
committerruki <[email protected]>2016-06-17 11:26:25 +0800
commit72b64ee532c8de65d177e387087fb14ab9ee478f (patch)
tree2693f4506e7567e968f0ae1995c742298da78dd2
parente58accaa27a4e8a9631c56e7f11279f3e437e967 (diff)
parse package arguments and fix output bug
-rw-r--r--xmake/core/base/option.lua236
-rw-r--r--xmake/core/sandbox/modules/import/core/base/option.lua48
-rwxr-xr-xxmake/plugins/macro/macros/package.lua34
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