def main(): 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() except IOError as e: sys.exit(e) doc = args['<docopt>'] usage = 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) fsm = ragel_ast(pattern) leafs, commands, arguments, flags, options = parse_leafs(pattern) command_fields = '\n '.join( map(lambda c: 'int {0};'.format(clean_name(c)), commands)) flag_fields = '\n '.join( map(lambda c: 'int {0};'.format(clean_name(c)), flags)) option_fields = '\n '.join( map(lambda c: 'char* {0};'.format(clean_name(c)), options)) argument_fields = '\n '.join( map(lambda c: 'char* {0};'.format(clean_name(c)), arguments)) command_actions = '\n '.join( map( lambda c: 'action command_{0}{{ fsm->opt->{0} = 1; }}'.format( clean_name(c)), commands)) flag_actions = '\n '.join( map( lambda c: 'action option_{0}{{ fsm->opt->{0} = 1; }}'.format( clean_name(c)), flags)) option_actions = '\n '.join( map( lambda c: 'action option_{0}{{ fsm->opt->{0} = strdup(fsm->buffer); }}'. format(clean_name(c)), options)) argument_actions = '\n '.join( map( lambda c: 'action argument_{0}{{ fsm->opt->{0} = strdup(fsm->buffer); }}'. format(clean_name(c)), arguments)) options_with_defaults = filter(lambda x: x.value is not None, options) option_defaults = '\n '.join( map( lambda c: 'fsm->opt->{0} = strdup("{1}");'.format( clean_name(c), c.value), options_with_defaults)) usage = '\n '.join( map(lambda l: 'fprintf(stdout, "{0}\\n");'.format(l), doc.split('\n'))) file = os.path.join(os.path.dirname(os.path.realpath(__file__)), "template.rl") print( Template(open(file).read()).safe_substitute( fsm=fsm, usage=usage, command_fields=command_fields, flag_fields=flag_fields, option_fields=option_fields, argument_fields=argument_fields, command_actions=command_actions, flag_actions=flag_actions, option_actions=option_actions, argument_actions=argument_actions, option_defaults=option_defaults, ))
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) 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)
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))