Exemple #1
0
    def get_short_option_with_angle_bracket(self, current, token):
        lt_index = current.find('<')
        prepended = False
        arg_token = None
        if self.stdopt and self.attachopt:
            # -a<sth> -> -a <sth>; -abc<sth> -> -a -bc<sth>
            if not self.attachvalue:
                raise DocpieError(
                    "You can't write %s while attachvalue=False" %
                    current)

            flag = current[:2]
            # -abc<sth>
            if lt_index > 2:
                token.insert(0, '-' + current[2:])
                prepended = True
            # -a<sth>
            else:
                arg_token = Token([current[lt_index:]])
                # rest = atom[lt_index:]
        # -a<sth> -> -a <sth>; -abc<sth> -> -abc <sth>
        else:
            flag = current[:lt_index]
            arg_token = Token([current[lt_index:]])

        return flag, arg_token, prepended
Exemple #2
0
    def get_short_option_arg(self, current, token, arg_token, rest):
        prepended = False

        opt_2_ins = {}
        # TODO: Better solution, maybe cache one
        for options in self.titled_opt_to_ins.values():
            opt_2_ins.update(options)

        if current in opt_2_ins:
            ins = opt_2_ins[current][0]
            # In Options it requires no argument
            if ins.ref is None:
                # sth stacked with it
                if rest:
                    if Atom.get_class(rest)[0] is Argument:
                        raise DocpieError(
                            ('%s announced difference in '
                             'Options(%s) and Usage(%s)') %
                            (current, ins, current))
                    if not (self.stdopt and self.attachopt):
                        raise DocpieError(
                            ("You can't write %s while it requires "
                             "argument and attachopt=False") % current)

                    token.insert(0, '-' + rest)
                    prepended = True
            # In Options it requires argument
            else:
                if rest:
                    arg_token = Token([rest])
                elif arg_token:
                    pass
                else:
                    _current = token.current()
                    if _current in '([':
                        tk = [token.next()]
                        tk.extend(token.till_end_bracket(tk[0]))
                        tk.append(')' if tk[0] == '(' else ']')
                        arg_token = Token(tk)
                    elif _current in ('...', '|'):
                        raise DocpieError(
                            ('%s requires argument in Options(%s) '
                             'but hit "%s" in Usage') %
                            current, ins, _current)
                    else:
                        arg_token = Token([token.next()])

                if token.current() == '...':
                    arg_token.append(token.next())
        elif rest:
            if not (self.stdopt and self.attachopt):
                raise DocpieError(
                    "You can't write %s while it requires argument "
                    "and attachopt=False" % current)
            # -asth -> -a -sth
            token.insert(0, '-' + rest)
            prepended = True

        return arg_token, prepended
Exemple #3
0
    def parse_other_element(self, current, token):
        atom_class, title = Atom.get_class(current)
        if atom_class is OptionsShortcut:
            return self.parse_options_shortcut(title, token)

        args = set([current])

        if atom_class is Option:
            for options in self.titled_opt_to_ins.values():
                if current in options:
                    ins_in_opt = options[current][0]

                    args.update(ins_in_opt.names)
                    if ins_in_opt.ref is not None:
                        ref_current = token.next()
                        ref_token = Token()
                        if ref_current in '([':
                            ref_token.append(ref_current)
                            ref_token.extend(
                                token.till_end_bracket(ref_current)
                            )
                            ref_token.append(
                                ')' if ref_current == '(' else ']'
                            )
                        else:
                            ref_token.extend(('(', ref_current, ')'))

                        ref_ins = self.parse_pattern(ref_token)

                        logger.debug(ins_in_opt.ref)
                        logger.debug(ref_ins[0])

                        if len(ref_ins) != 1:
                            raise DocpieError(
                                ('%s announced difference in '
                                 'Options(%s) and Usage(%s)') %
                                (current, ins_in_opt, ref_ins))

                        if ins_in_opt.ref != ref_ins[0]:
                            raise DocpieError(
                                ('%s announced difference in '
                                 'Options(%s) and Usage(%s)') %
                                (current, ins_in_opt, ref_ins))

                        ins = atom_class(*args, **{'ref': ins_in_opt.ref})
                        return (ins,)

        ins = atom_class(*args)

        repeat = token.check_ellipsis_and_drop()
        if repeat:
            ins = Required(ins, repeat=True)
        logger.debug('%s -> %s', current, ins)
        return (ins,)
Exemple #4
0
    def get_short_option_arg(self, current, token, arg_token, rest):
        prepended = False

        opt_2_ins = {}
        # TODO: Better solution, maybe cache one
        for options in self.titled_opt_to_ins.values():
            opt_2_ins.update(options)

        if current in opt_2_ins:
            ins = opt_2_ins[current][0]
            # In Options it requires no argument
            if ins.ref is None:
                # sth stacked with it
                if rest:
                    if Atom.get_class(rest)[0] is Argument:
                        raise DocpieError(
                            ('%s announced difference in '
                             'Options(%s) and Usage(%s)') %
                            (current, ins, current))
                    if not (self.stdopt and self.attachopt):
                        raise DocpieError(
                            ("You can't write %s while it requires "
                             "argument and attachopt=False") % current)

                    token.insert(0, '-' + rest)
                    prepended = True
            # In Options it requires argument
            else:
                if rest:
                    arg_token = Token([rest])
                elif arg_token:
                    pass
                else:
                    _current = token.current()
                    if _current in '([':
                        tk = [token.next()]
                        tk.extend(token.till_end_bracket(tk[0]))
                        tk.append(')' if tk[0] == '(' else ']')
                        arg_token = Token(tk)
                    elif _current in ('...', '|'):
                        raise DocpieError(
                            ('%s requires argument in Options(%s) '
                             'but hit "%s" in Usage') %
                            current, ins, _current)
                    else:
                        arg_token = Token([token.next()])

                if token.current() == '...':
                    arg_token.append(token.next())
        elif rest:
            if not (self.stdopt and self.attachopt):
                raise DocpieError(
                    "You can't write %s while it requires argument "
                    "and attachopt=False" % current)
            # -asth -> -a -sth
            token.insert(0, '-' + rest)
            prepended = True

        return arg_token, prepended
Exemple #5
0
 def parse_2_instance(self, name):
     result = []
     for each_line in self.split_line_by_indent(self.formal_content):
         raw_str_lis = self.parse_line_to_lis(each_line, name)
         chain = self.parse_pattern(Token(raw_str_lis))
         result.append(chain)
     self.instances = result
Exemple #6
0
    def get_long_option_with_arg(self, current, token):
        flag, arg = current.split('=', 1)
        if Atom.get_class(flag)[0] is Option:
            if arg:
                arg_token = Token([arg])
            else:
                next_arg = token.next()
                if next_arg not in '([':
                    raise DocpieError('format error: %s' % current)
                tk = [next_arg]
                tk.extend(token.till_end_bracket(next_arg))
                tk.append(')' if next_arg == '(' else ']')
                arg_token = Token(tk)

            if token.current() == '...':
                arg_token.append(token.next())

            return flag, arg_token
Exemple #7
0
    def parse_other_element(self, current, token):
        atom_class, title = Atom.get_class(current)
        if atom_class is OptionsShortcut:
            return self.parse_options_shortcut(title, token)

        args = set([current])

        if atom_class is Option:
            for options in self.titled_opt_to_ins.values():
                if current in options:
                    ins_in_opt = options[current][0]

                    args.update(ins_in_opt.names)
                    if ins_in_opt.ref is not None:
                        ref_current = token.next()
                        ref_token = Token()
                        if ref_current in '([':
                            ref_token.append(ref_current)
                            ref_token.extend(token.till_end_bracket(ref_current))
                            ref_token.append(')' if ref_current == '(' else ']')
                        else:
                            ref_token.extend(('(', ref_current, ')'))

                        ref_ins = self.parse_pattern(ref_token)

                        logger.debug(ins_in_opt.ref)
                        logger.debug(ref_ins[0])

                        if len(ref_ins) != 1:
                            raise DocpieError(
                                '%s announced difference in Options(%s) and Usage(%s)' %
                                (current, ins_in_opt, ref_ins))

                        if ins_in_opt.ref != ref_ins[0]:
                            raise DocpieError(
                                '%s announced difference in Options(%s) and Usage(%s)' %
                                (current, ins_in_opt, ref_ins))

                        ins = atom_class(*args, **{'ref': ins_in_opt.ref})
                        return (ins,)

        ins = atom_class(*args)

        repeat = token.check_ellipsis_and_drop()
        if repeat:
            ins = Required(ins, repeat=True)
        logger.debug('%s -> %s', current, ins)
        return (ins,)
Exemple #8
0
    def parse_bracket(self, token):
        start = token.next()
        instance_type = Required if start == '(' else Optional

        lis = token.till_end_bracket(start)

        repeat = token.check_ellipsis_and_drop()

        bracket_token = Token(lis)

        instances = self.parse_pattern(bracket_token)

        return instance_type(*instances, **{'repeat': repeat})
Exemple #9
0
    def get_long_option_with_arg(self, current, token):
        flag, arg = current.split('=', 1)
        if Atom.get_class(flag)[0] is Option:
            if arg:
                arg_token = Token([arg])
            else:
                next_arg = token.next()
                if next_arg not in '([':
                    raise DocpieError('format error: %s' % current)
                tk = [next_arg]
                tk.extend(token.till_end_bracket(next_arg))
                tk.append(')' if next_arg == '(' else ']')
                arg_token = Token(tk)

            if token.current() == '...':
                arg_token.append(token.next())

            return flag, arg_token
Exemple #10
0
    def parse_opt_str(self, opt):

        repeat = False

        # -sth=<goes> ON -> -sth, <goes>, ON
        opt_lis = self.opt_str_to_list(opt)
        logger.debug('%r -> %s' % (opt, opt_lis))

        first = opt_lis.pop(0)
        if not first.startswith('-'):
            raise DocpieError('option %s does not start with "-"' % first)

        # if self.stdopt:
        # -sth -> name=-s, value=th
        # else:
        # -sth -> name=-sth, value=''
        name, value = self.split_short_by_cfg(first)
        opt_ins = Option(name)
        if value == '...':
            repeat = True
            # -f... <sth>
            if opt_lis and not opt_lis[0].startswith('-'):
                raise DocpieError(
                    'option "%s" has argument following "..."', opt)
        elif value:
            args_ins = [Required(Argument(value))]
        else:
            args_ins = []

        if opt_lis and opt_lis[0] == '...':
            repeat = True
            opt_lis.pop(0)
            if opt_lis and not opt_lis[0].startswith('-'):
                raise DocpieError(
                    'option "%s" has argument following "..."', opt)

        args = []    # store the current args after option
        for each in opt_lis:
            if each.startswith('-'):    # alias
                name, value = self.split_short_by_cfg(each)
                opt_ins.names.add(name)
                if value:
                    args_ins.append(Required(Argument(value)))
                if args:    # trun it into instance
                    if args[0] == '...':
                        if len(args) != 1:
                            raise DocpieError(
                                'Error in %s: "..." followed by non option',
                                opt)
                        repeat = True
                    else:
                        this_arg = Required(
                                            *self.parse_pattern(Token(args))
                                           ).fix()
                        if this_arg is not None:
                            args_ins.append(this_arg)
                del args[:]
            else:
                args.append(each)
        else:
            if args:    # trun it into instance
                if args[0] == '...':
                    if len(args) != 1:
                        raise DocpieError(
                            'Error in %s: "..." followed by non option',
                            opt)
                    repeat = True
                else:
                    this_arg = Required(
                        *self.parse_pattern(Token(args))).fix()
                    if this_arg is not None:
                        args_ins.append(this_arg)

        # option without any args
        if not args_ins:
            return opt_ins, repeat

        # in Option, there should only have one arg list
        # e.g.: -f <file> --file=FILE -> -f/--file (<file>|FILE)
        # because the arg name will now be shown, it parsed as:
        # -f <file> --file=FILE -> -f/--file (<file>)
        current_ins = args_ins.pop(0)
        current_range = current_ins.arg_range()

        # avoid e.g.: -f <a> <b> --file <c>
        for other_ins in args_ins:
            this_range = other_ins.arg_range()
            if this_range != current_range:
                raise DocpieError("%s announced differently (%s, %s)" % (
                                  opt_ins, this_range, current_range))

        if len(current_range) > 1:
            logger.debug('too many possibilities: '
                         'option %s expect %s arguments',
                         name, '/'.join(map(str, current_range)))

        # TODO: check if current_ins contain Command(not allowed in fact)
        opt_ins.ref = current_ins
        return opt_ins, repeat