Пример #1
0
def test_parse_section():
    assert parse_section('usage:', 'foo bar fizz buzz') == []
    assert parse_section('usage:', 'usage: prog') == ['usage: prog']
    assert parse_section('usage:', 'usage: -x\n -y') == ['usage: -x\n -y']
    assert parse_section('usage:', usage) == [
        'usage: this',
        'usage:hai',
        'usage: this that',
        'usage: foo\n       bar',
        'PROGRAM USAGE:\n foo\n bar',
        'usage:\n\ttoo\n\ttar',
        'Usage: eggs spam',
        'usage: pit stop',
    ]
Пример #2
0
def test_parse_section():
    assert parse_section("usage:", "foo bar fizz buzz") == []
    assert parse_section("usage:", "usage: prog") == ["usage: prog"]
    assert parse_section("usage:", "usage: -x\n -y") == ["usage: -x\n -y"]
    assert parse_section("usage:", usage) == [
        "usage: this",
        "usage:hai",
        "usage: this that",
        "usage: foo\n       bar",
        "PROGRAM USAGE:\n foo\n bar",
        "usage:\n\ttoo\n\ttar",
        "Usage: eggs spam",
        "usage: pit stop",
    ]
Пример #3
0
def test_parse_section():
    assert parse_section('usage:', 'foo bar fizz buzz') == []
    assert parse_section('usage:', 'usage: prog') == ['usage: prog']
    assert parse_section('usage:',
                         'usage: -x\n -y') == ['usage: -x\n -y']
    assert parse_section('usage:', usage) == [
            'usage: this',
            'usage:hai',
            'usage: this that',
            'usage: foo\n       bar',
            'PROGRAM USAGE:\n foo\n bar',
            'usage:\n\ttoo\n\ttar',
            'Usage: eggs spam',
            'usage: pit stop',
    ]
Пример #4
0
    def create_console(self, script):
        usage_sections = parse_section('usage:', script.__doc__)
        if len(usage_sections) == 0:
            raise DocoptLanguageError('"usage:" (case-insensitive) not found.')
        if len(usage_sections) > 1:
            raise DocoptLanguageError('More than one "usage:" (case-insensitive).')
        DocoptExit.usage = usage_sections[0]
        pattern = parse_pattern(formal_usage(DocoptExit.usage), parse_defaults(script.__doc__))

        paths = []

        paths.append({
            "flags": [opt for opt in parse_defaults(script.__doc__) if not opt.argcount and opt.name not in ["--help", "--version"]],
            "extras": [opt for opt in parse_defaults(script.__doc__) if not opt.argcount and opt.name in ["--help", "--version"]],
            "options": [opt for opt in parse_defaults(script.__doc__) if opt.argcount and not opt.value],
            "default_options": [opt for opt in parse_defaults(script.__doc__) if opt.value],
            "arguments": [arg.name for arg in pattern.flat(Argument)],
        })

        return {
            "name": script.__name__,
            "file": script.__file__,
            "doc": script.__doc__,
            "paths": paths,
        }
Пример #5
0
def test_formal_usage():
    doc = """
    Usage: prog [-hv] ARG
           prog N M

    prog is a program."""
    usage, = parse_section('usage:', doc)
    assert usage == "Usage: prog [-hv] ARG\n           prog N M"
    assert formal_usage(usage) == "( [-hv] ARG ) | ( N M )"
Пример #6
0
def test_formal_usage():
    doc = """
    Usage: prog [-hv] ARG
           prog N M

    prog is a program."""
    usage, = parse_section('usage:', doc)
    assert usage == "Usage: prog [-hv] ARG\n           prog N M"
    assert formal_usage(usage) == "( [-hv] ARG ) | ( N M )"
Пример #7
0
def parseDocoptOptions(usage):
    defaults = []

    for s in docopt.parse_section('options:', usage):
        # FIXME corner case "bla: options: --foo"
        _, _, s = s.partition(':')  # get rid of "options:"
        split = re.split('\n[ \t]*(-\S+?)', '\n' + s)[1:]
        split = [s1 + s2 for s1, s2 in zip(split[::2], split[1::2])]

        # Modified from docopt {
        #options = [Option.parse(s) for s in split if s.startswith('-')]
        #defaults += options
        for line in split:
            if not line.startswith('-'):
                continue
            option = docopt.Option.parse(line)
            option.description = extractOptionDescription(line)  # Monkeypatch.
            defaults.append(option)
        # } End of modified from docopt.

    return defaults
Пример #8
0
        else:
            args['<docopt>'] = sys.stdin.read()
        if args['--template'] is None:
            args['--template'] = os.path.join(
                os.path.dirname(os.path.realpath(__file__)), "template.c")
        template_h_path = re.sub(r'\.c$', '.h', args['--template'])
        with open(args['--template'], 'r') as f:
            args['--template'] = f.read()
        if args['--header']:
            with open(template_h_path, 'r') as f:
                template_h = f.read()
    except IOError as e:
        sys.exit(e)

    doc = args['<docopt>']
    usage = docopt.parse_section('usage:', doc)
    s = ['More than one ', '"usage:" (case-insensitive)', ' not found.']
    usage = {0: s[1:], 1: usage[0] if usage else None}.get(len(usage), s[:2])
    if isinstance(usage, list):
        raise docopt.DocoptLanguageError(''.join(usage))

    all_options = docopt.parse_defaults(doc)
    pattern = docopt.parse_pattern(docopt.formal_usage(usage), all_options)
    leafs, commands, arguments, flags, options = parse_leafs(
        pattern, all_options)

    t_commands = ';\n    '.join('int %s' % c_name(cmd.name)
                                for cmd in commands)
    t_commands = (('\n    /* commands */\n    ' + t_commands +
                   ';') if t_commands != '' else '')
    t_arguments = ';\n    '.join('char *%s' % c_name(arg.name)
Пример #9
0
            with open(args["<docopt>"], "r") as f:
                args["<docopt>"] = f.read()
        elif args["<docopt>"] is None and sys.stdin.isatty():
            print(__doc__.strip("\n"))
            sys.exit("")
        else:
            args["<docopt>"] = sys.stdin.read()
        if args["--template"] is None:
            args["--template"] = os.path.join(os.path.dirname(os.path.realpath(__file__)), "template.c")
        with open(args["--template"], "r") as f:
            args["--template"] = f.read()
    except IOError as e:
        sys.exit(e)

    doc = args["<docopt>"]
    usage = docopt.parse_section("usage:", doc)
    s = ["More than one ", '"usage:" (case-insensitive)', " not found."]
    usage = {0: s[1:], 1: usage[0] if usage else None}.get(len(usage), s[:2])
    if isinstance(usage, list):
        raise docopt.DocoptLanguageError("".join(usage))

    all_options = docopt.parse_defaults(doc)
    pattern = docopt.parse_pattern(docopt.formal_usage(usage), all_options)
    leafs, commands, arguments, flags, options = parse_leafs(pattern, all_options)

    t_commands = ";\n    ".join("int %s" % c_name(cmd.name) for cmd in commands)
    t_commands = ("\n    /* commands */\n    " + t_commands + ";") if t_commands != "" else ""
    t_arguments = ";\n    ".join("char *%s" % c_name(arg.name) for arg in arguments)
    t_arguments = ("\n    /* arguments */\n    " + t_arguments + ";") if t_arguments != "" else ""
    t_flags = ";\n    ".join("int %s" % c_name(flag.long or flag.short) for flag in flags)
    t_flags = ("\n    /* options without arguments */\n    " + t_flags + ";") if t_flags != "" else ""
Пример #10
0
            args['--output-name']='docoptout'
        if args['--templatec'] is None:
            args['--templatec'] = os.path.join(
                    os.path.dirname(os.path.realpath(__file__)), "template.c")
        with open(args['--templatec'], 'r') as f:
                args['--templatec'] = f.read()
        if args['--templateh'] is None:
            args['--templateh'] = os.path.join(
                    os.path.dirname(os.path.realpath(__file__)), "template.h")
        with open(args['--templateh'], 'r') as f:
                args['--templateh'] = f.read()
    except IOError as e:
        sys.exit(e)

    doc = args['<docopt>']
    usage = docopt.parse_section('usage:', doc)
    s = ['More than one ', '"usage:" (case-insensitive)', ' not found.']
    usage = {0: s[1:], 1: usage[0] if usage else None}.get(len(usage), s[:2])
    if isinstance(usage, list):
        raise docopt.DocoptLanguageError(''.join(usage))

    options = docopt.parse_defaults(doc)
    pattern = docopt.parse_pattern(docopt.formal_usage(usage), options)
    leafs, commands, arguments, flags, options = parse_leafs(pattern)

    t_commands = ';\n    '.join('int %s' % c_name(cmd.name)
                                for cmd in commands)
    t_commands = (('\n    /* commands */\n    ' + t_commands + ';')
                  if t_commands != '' else '')
    t_arguments = ';\n    '.join('char *%s' % c_name(arg.name)
                                 for arg in arguments)
Пример #11
0
                args['<docopt>'] = f.read()
        elif args['<docopt>'] is None and sys.stdin.isatty():
            print(__doc__.strip("\n"))
            sys.exit("")
        else:
            args['<docopt>'] = sys.stdin.read()
        if args['--module'] is None:
            args['--module'] = os.path.join(
                    os.path.dirname(os.path.realpath(__file__)), "template.c")
        #with open(args['--module'], 'r') as f:
        #        args['--module'] = f.read()
    except IOError as e:
        sys.exit(e)

    doc = args['<docopt>']
    usage = docopt.parse_section('usage:', doc)
    s = ['More than one ', '"usage:" (case-insensitive)', ' not found.']
    usage = {0: s[1:], 1: usage[0] if usage else None}.get(len(usage), s[:2])
    if isinstance(usage, list):
        raise docopt.DocoptLanguageError(''.join(usage))

    all_options = docopt.parse_defaults(doc)
    pattern = docopt.parse_pattern(docopt.formal_usage(usage), all_options)
    leafs, commands, arguments, flags, options = parse_leafs(pattern, all_options)

    t_commands = ';\n    '.join('int %s' % c_name(cmd.name)
                                for cmd in commands)
    t_commands = (('\n    /* commands */\n    ' + t_commands + ';')
                  if t_commands != '' else '')
    t_arguments = ';\n    '.join('char *%s' % c_name(arg.name)
                                 for arg in arguments)
Пример #12
0
def main():
    assert __doc__ is not None
    args = docopt.docopt(__doc__)

    try:
        if args['<docopt>'] is not None:
            with open(args['<docopt>'], 'r') as f:
                args['<docopt>'] = f.read()
        elif args['<docopt>'] is None and sys.stdin.isatty():
            print(__doc__.strip("\n"))
            sys.exit("")
        else:
            args['<docopt>'] = sys.stdin.read()
        if args['--template'] is None:
            args['--template'] = template_c
        else:
            with open(args['--template'], 'rt') as f:
                args['--template'] = f.read()
        if args['--template-header'] is None:
            args['--template-header'] = template_h
        else:
            with open(args['--template-header'], 'rt') as f:
                args['--template-header'] = f.read()
    except IOError as e:
        sys.exit(e)

    doc = args['<docopt>']
    usage = docopt.parse_section('usage:', doc)
    error_str_l = 'More than one ', '"usage:" (case-insensitive)', ' not found.'
    usage = {0: error_str_l[1:], 1: usage[0] if usage else None}.get(len(usage), error_str_l[:2])
    if isinstance(usage, list):
        raise docopt.DocoptLanguageError(''.join(usage))

    all_options = docopt.parse_defaults(doc)
    pattern = docopt.parse_pattern(docopt.formal_usage(usage), all_options)
    leafs, commands, arguments, flags, options = parse_leafs(pattern, all_options)

    _indent = ' ' * 4

    t_commands = ';\n{indent}'.format(indent=_indent).join('size_t {!s}'.format(c_name(cmd.name))
                                                           for cmd in commands)
    t_commands = '\n{indent}/* commands */\n{indent}{t_commands};'.format(indent=_indent, t_commands=t_commands) \
        if t_commands != '' else ''
    t_arguments = ';\n{indent}'.join('char *{!s}'.format(c_name(arg.name))
                                     for arg in arguments)
    t_arguments = '\n{indent}/* arguments */\n{indent}{t_arguments};'.format(indent=_indent, t_arguments=t_arguments) \
        if t_arguments != '' else ''
    t_flags = ';\n{indent}'.format(indent=_indent).join('size_t {!s}'.format(c_name(flag.long or flag.short))
                                                        for flag in flags)
    t_flags = '\n{indent}/* options without arguments */\n{indent}{t_flags};'.format(indent=_indent, t_flags=t_flags) \
        if t_flags != '' else ''
    t_options = ';\n{indent}'.format(indent=_indent).join('char *{!s}'.format(c_name(opt.long or opt.short))
                                                          for opt in options)
    t_options = '\n{indent}/* options with arguments */\n{indent}{t_options};'.format(indent=_indent,
                                                                                      t_options=t_options) \
        if t_options != '' else ''
    t_defaults = ', '.join(to_c(leaf.value) for leaf in leafs)
    t_defaults = re.sub(r'"(.*?)"', r'(char *) "\1"', t_defaults)
    t_defaults = '\n{indent}'.format(indent=_indent * 2).join(textwrap.wrap(t_defaults, 72))
    t_defaults = '\n{indent}{t_defaults},'.format(indent=_indent * 2, t_defaults=t_defaults) if t_defaults != '' else ''
    t_elems_cmds = ',\n{indent}'.format(indent=_indent * 2).join(c_command(cmd) for cmd in commands)
    t_elems_cmds = '\n{indent}{t_elems_cmds}'.format(indent=_indent * 2,
                                                     t_elems_cmds=t_elems_cmds) if t_elems_cmds != '' else ''
    t_elems_args = ',\n{indent}'.format(indent=_indent * 2).join(c_argument(arg) for arg in arguments)
    t_elems_args = '\n{indent}{t_elems_args}'.format(indent=_indent * 2,
                                                     t_elems_args=t_elems_args) if t_elems_args != '' else ''
    t_elems_opts = ',\n{indent}'.format(indent=_indent * 2).join(c_option(o) for o in (flags + options))
    t_elems_opts = '\n{indent}{t_elems_opts}'.format(indent=_indent * 2,
                                                     t_elems_opts=t_elems_opts) if t_elems_opts != '' else ''

    '''
    t_elems_n_commands = str(len(commands))
    t_elems_n_arguments = str(len(arguments))
    t_elems_n_options = str(len(flags + options))
    t_elems_n_cmds = str(len(commands))
    t_elems_n = ', '.join(str(len(l)) for l in (commands, arguments, (flags + options)))
    print(
        't_elems_n_commands:', t_elems_n_commands, ';\n',
        't_elems_n_arguments:', t_elems_n_arguments, ';\n',
        't_elems_n_options:', t_elems_n_options, ';\n',
        't_elems_n_cmds:', t_elems_n_cmds, ';\n',
        't_elems_n:', t_elems_n, ';'
    )
    '''

    t_if_command = ' else '.join(c_if_command(command) for command in commands)
    t_if_command = '\n{indent}{t_if_command}'.format(indent=_indent * 2,
                                                     t_if_command=t_if_command) if t_if_command != '' else ''
    t_if_argument = ' else '.join(c_if_argument(arg) for arg in arguments)
    t_if_argument = '\n{indent}{t_if_argument}'.format(
        indent=_indent * 2,
        t_if_argument='\n{indent}'.format(indent=_indent * 2).join(t_if_argument.splitlines())
    ) if t_if_argument != '' else ''
    t_if_flag = ''.join('\n{indent}'.format(indent=_indent * 2).join(c_if_flag(flag).splitlines())
                        for flag in flags)
    t_if_option = ''.join(
        '\n{indent}'.format(indent=_indent * 2).join(c_if_option(opt).splitlines())
        for opt in options
    )

    if not args['--output-name']:
        header_output_name = '<stdout>'
    else:
        base, ext = os.path.splitext(args['--output-name'])
        if ext not in frozenset(('.h', '.c')):
            base = args['--output-name']

        args['--output-name'] = "{base}.c".format(base=base)
        header_output_name = "{base}.h".format(base=base)

    header_name = os.path.basename(header_output_name)

    doc = doc.splitlines()
    doc_n = len(doc)

    template_out = Template(args['--template']).safe_substitute(
        help_message='\n{indent}'.format(indent=_indent).join(to_initializer(doc).splitlines()),
        help_message_n=doc_n,
        usage_pattern='\n{indent}'.format(indent=_indent * 2).join(to_c(usage).splitlines()),
        if_flag=t_if_flag,
        if_option=t_if_option,
        if_command=t_if_command,
        if_argument=t_if_argument,
        defaults=t_defaults,
        elems_cmds=null_if_zero(t_elems_cmds),
        elems_args=null_if_zero(t_elems_args),
        elems_opts=null_if_zero(t_elems_opts),
        t_elems_n_commands=str(len(commands)),
        t_elems_n_arguments=str(len(arguments)),
        t_elems_n_options=str(len(flags + options)),
        header_name=header_name
    )

    template_header_out = Template(args['--template-header']).safe_substitute(
        commands=t_commands,
        arguments=t_arguments,
        flags=t_flags,
        options=t_options,
        help_message_n=doc_n,
        # nargs=t_nargs
    ).replace('$header_no_ext', os.path.splitext(header_name)[0].upper())

    if args['--output-name'] is None:
        print(template_out.strip(), '\n')
    else:
        try:
            with open(sys.stdout if args['--output-name'] in (None, "<stdout>") else args['--output-name'], 'w') as f:
                f.write(template_out.strip() + '\n')

            with open(sys.stdout if header_output_name == "<stdout>" else header_output_name, 'w') as f:
                f.write(template_header_out.strip() + '\n')

        except IOError as e:
            sys.exit(str(e))