1#! /usr/bin/perl 2 3# Copyright (C) 2010, 2011 Richard Levitte <richard@levitte.org> 4# 5# This program is made available under the GNU GPL version 2.0 or 6# greater. See the accompanying file COPYING for details. 7# 8# This program is distributed WITHOUT ANY WARRANTY; without even the 9# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 10# PURPOSE. 11 12use warnings; 13use strict; 14 15my $mtn = $ENV{'MTN'} || 'mtn'; 16$ENV{'LANG'} = 'C'; 17 18open MANPAGE,"$mtn manpage|" || die "Couldn't start 'mtn manpage': $!\n"; 19 20my $current_command = "mtn"; 21my %options_noarg = (); 22my %options_arg = (); 23my %command_options = (); 24my %command_args = (); 25my %commands = ( $current_command => {} ); 26 27while (<MANPAGE>) { 28 chomp; 29 next if ! m|^\.IP\s|; 30 31 # Because the manpage has a lot of dashes escaped, let's unescape them. 32 s/\\-/-/g; 33 34 if (m|^\.IP "(--[^"]*)"|) { 35 my $opts = $1; 36 $opts =~ s|\[\s*(-[a-zA-Z\@])\s*\](\s*<arg>\s*)|$2/ $1$2|g; 37 $opts =~ s|\[\s*(-[a-zA-Z\@])\s*\]|/ $1 |g; 38 foreach (split(m|\s*/\s*|, $opts)) { 39# print STDERR "DEBUG[$current_command]: opt = $_\n"; 40 my $current_option; 41 if (m|^\s*(-[-a-zA-Z\@]*)\s+\<arg\>\s*$|) { 42 $current_option = $1; 43 $options_arg{$current_option} = 1; 44 } elsif (m|^\s*(-[-a-zA-Z\@]*)\s*$|) { 45 $current_option = $1; 46 $options_noarg{$current_option} = 1; 47 } 48 $command_options{$current_command} = [] 49 if (!defined $command_options{$current_command}); 50 push @{$command_options{$current_command}}, $current_option; 51 } 52 } elsif (m|^\.IP "\\fB(.*)\s\\fP ([^"]*)"|) { 53 $current_command = "mtn $1"; 54 $commands{$current_command} = {}; 55 my $current_command_args = $2; 56 $current_command_args =~ s|[\[\]]||g; 57 $current_command_args =~ s|\.\.\.\s*$| \.\.\.|; 58 $command_args{$current_command} = 59 [ split(m|\s+|,$current_command_args) ]; 60 61 my $parent_command = ""; 62 for my $commandlet (split(m|\s+|,$current_command)) { 63# print STDERR "DEBUG[$current_command]: parent command = $parent_command\n"; 64# print STDERR "DEBUG[$current_command]: commandlet = $commandlet\n"; 65 if ($parent_command eq "") { 66 $parent_command = $commandlet; 67 } else { 68 $commands{$parent_command} = {} 69 if !defined $commands{$parent_command}; 70 $commands{$parent_command}->{$commandlet} = 1; 71 $parent_command .= " " . $commandlet; 72 } 73 } 74 } elsif (m|^\.IP "\\fB(.*)\s\\fP"|) { 75 $current_command = "mtn $1"; 76 $commands{$current_command} = {}; 77 78 my $parent_command = ""; 79 for my $commandlet (split(m|\s+|,$current_command)) { 80# print STDERR "DEBUG[$current_command]: parent command = $parent_command\n"; 81# print STDERR "DEBUG[$current_command]: commandlet = $commandlet\n"; 82 if ($parent_command eq "") { 83 $parent_command = $commandlet; 84 } else { 85 $commands{$parent_command} = {} 86 if !defined $commands{$parent_command}; 87 $commands{$parent_command}->{$commandlet} = 1; 88 $parent_command .= " " . $commandlet; 89 } 90 } 91 } 92} 93 94#print STDERR "DEBUG: command keys: \n ",join("\n ", sort keys %commands),"\n"; 95 96print "declare -a _monotone_options_noarg\n"; 97print "_monotone_options_noarg=(\n " 98 ,join("\n ", sort keys %options_noarg),"\n)\n"; 99 100print "declare -a _monotone_options_arg\n"; 101print "_monotone_options_arg=(\n " 102 ,join("\n ", sort keys %options_arg),"\n)\n"; 103 104print "declare -A _monotone_options_arg_fns\n"; 105print "_monotone_options_arg_fns=(\n"; 106print " [--authors-file]=_monotone_files\n"; 107print " [--bind]=_monotone_address_port\n"; 108print " [--branch]=_monotone_branches [-b]=_monotone_branches\n"; 109print " [--branches-file]=_monotone_files\n"; 110print " [--confdir]=_monotone_dirs\n"; 111print " [--conflicts-file]=_monotone_files\n"; 112print " [--db]=_monotone_databases [-d]=_monotone_databases\n"; 113print " [--dump]=_monotone_files\n"; 114print " [--export-marks]=_monotone_files\n"; 115print " [--from]=_monotone_revisions\n"; 116print " [--import-marks]=_monotone_files\n"; 117print " [--keydir]=_monotone_dirs\n"; 118print " [--key]=_monotone_key [-k]=_monotone_public_key\n"; 119print " [--key-to-push]=_monotone_public_key\n"; 120print " [--log]=_monotone_files\n"; 121print " [--message_file]=_monotone_files\n"; 122print " [--pid-file]=_monotone_files\n"; 123print " [--rcfile]=_monotone_files\n"; 124print " [--refs]=_monotone_refs\n"; 125print " [--remote-stdio-host]=_monotone_address_port\n"; 126print " [--resolve-conflicts-file]=_monotone_files\n"; 127print " [--revision]=_monotone_revisions [-r]=_monotone_revisions\n"; 128print " [--root]=_monotone_dirs\n"; 129print " [--ssh-sign]=_monotone_ssh_sign\n"; 130print " [--ticker]=_monotone_ticker\n"; 131print " [--xargs]=_monotone_files\n"; 132print " [-@]=_monotone_files\n"; 133print ")\n"; 134 135print "declare -A _monotone_aliases\n"; 136 137print "_monotone_aliases['mtn au']='mtn automate'\n"; 138print "_monotone_aliases['mtn di']='mtn diff'\n"; 139print "_monotone_aliases['mtn ls']='mtn list'\n"; 140print "_monotone_aliases['mtn list dbs']='mtn list databases'\n"; 141 142print "declare -A _monotone_command_options\n"; 143print "declare -A _monotone_command_args\n"; 144print "declare -A _monotone_commands\n"; 145 146foreach my $key (sort keys %commands) { 147# print STDERR "DEBUG: key = $key\n"; 148 print "_monotone_commands['$key']='" 149 ,join(" ",sort keys %{$commands{$key}}) 150 ,"'\n" if %{$commands{$key}}; 151 print "_monotone_command_args['$key']='" 152 ,join(" ",@{$command_args{$key}}) 153 ,"'\n" if $command_args{$key}; 154 print "_monotone_command_options['$key']='" 155 ,join(" ",sort @{$command_options{$key}}),"'\n" 156 if $command_options{$key}; 157 print "### Missing $key\n" 158 if (!%{$commands{$key}} && 159 !$command_args{$key} && 160 !$command_options{$key}); 161} 162