public Option parse()

in gogo/shell/src/main/java/org/apache/felix/gogo/options/Options.java [469:629]


    public Option parse(List<?> argv, boolean skipArg0)
    {
        reset();
        List<Object> args = new ArrayList<Object>(Arrays.asList(defArgs));
        for (Object arg : argv)
        {
            if (skipArg0)
            {
                skipArg0 = false;
                usageName = arg.toString();
            }
            else
            {
                args.add(arg);
            }
        }

        String needArg = null;
        String needOpt = null;
        boolean endOpt = false;

        for (Object oarg : args)
        {
            String arg = oarg == null ? "null" : oarg.toString();

            if (endOpt)
            {
                xargs.add(oarg);
            }
            else if (needArg != null)
            {
                addArg(needArg, oarg);
                needArg = null;
                needOpt = null;
            }
            else if (!arg.startsWith("-") || "-".equals(oarg))
            {
                if (optionsFirst)
                {
                    endOpt = true;
                }
                xargs.add(oarg);
            }
            else
            {
                if (arg.equals("--"))
                {
                    endOpt = true;
                }
                else if (arg.startsWith("--"))
                {
                    int eq = arg.indexOf("=");
                    String value = (eq == -1) ? null : arg.substring(eq + 1);
                    String name = arg.substring(2, ((eq == -1) ? arg.length() : eq));
                    List<String> names = new ArrayList<>();

                    if (optSet.containsKey(name))
                    {
                        names.add(name);
                    }
                    else
                    {
                        for (String k : optSet.keySet())
                        {
                            if (k.startsWith(name))
                                names.add(k);
                        }
                    }

                    switch (names.size())
                    {
                        case 1:
                            name = names.get(0);
                            optSet.put(name, true);
                            if (optArg.containsKey(name))
                            {
                                if (value != null)
                                    addArg(name, value);
                                else
                                    needArg = name;
                            }
                            else if (value != null)
                            {
                                throw usageError("option '--" + name + "' doesn't allow an argument");
                            }
                            break;

                        case 0:
                            if (stopOnBadOption)
                            {
                                endOpt = true;
                                xargs.add(oarg);
                                break;
                            }
                            else
                                throw usageError("invalid option '--" + name + "'");

                        default:
                            throw usageError("option '--" + name + "' is ambiguous: " + names);
                    }
                }
                else
                {
                    for (int i = 1; i < arg.length(); i++)
                    {
                        String c = String.valueOf(arg.charAt(i));
                        if (optName.containsKey(c))
                        {
                            String name = optName.get(c);
                            optSet.put(name, true);
                            if (optArg.containsKey(name))
                            {
                                int k = i + 1;
                                if (k < arg.length())
                                {
                                    addArg(name, arg.substring(k));
                                }
                                else
                                {
                                    needOpt = c;
                                    needArg = name;
                                }
                                break;
                            }
                        }
                        else
                        {
                            if (stopOnBadOption)
                            {
                                xargs.add("-" + c);
                                endOpt = true;
                            }
                            else
                                throw usageError("invalid option '" + c + "'");
                        }
                    }
                }
            }
        }

        if (needArg != null)
        {
            String name = (needOpt != null) ? needOpt : "--" + needArg;
            throw usageError("option '" + name + "' requires an argument");
        }

        // remove long option aliases
        for (Entry<String, String> alias : optAlias.entrySet())
        {
            if (optSet.get(alias.getKey()))
            {
                optSet.put(alias.getValue(), true);
                if (optArg.containsKey(alias.getKey()))
                    optArg.put(alias.getValue(), optArg.get(alias.getKey()));
            }
            optSet.remove(alias.getKey());
            optArg.remove(alias.getKey());
        }

        return this;
    }