#!/usr/bin/perl -w use strict; my (%OPS, %MAP, %DOC, $map); my $xml = shift @ARGV; open F, "cat @ARGV |" or die "OPS*: $!"; while () { /(\w+) "(.+)"/ or die "$.: parse error"; $OPS{$1} = $2; } close F; while () { if (/^struct binding_t Op.*{ \/\* map: (.*) \*\//) { $map = $1; $DOC{$map} = ""; } if ($map and /^\s*\*\*\s*(.*)/) { $DOC{$map} .= "$1\n"; } if ($map and /{\s*"(.+)"\s*,\s*(\w+)\s*,\s*(?:"([^"]+)"|(\w+))\s*}/) { my ($function, $op, $binding) = ($1, $2, $3 || $4); $binding =~ s/&/&/; # for , try CamelCasing into $binding =~ s/<(.)(.+)>/<\U$1\E$2>/; $binding =~ s//>/; $binding =~ s/ /<Space>/; $binding =~ s/^\\033/Esc /; $binding =~ s/^\\010/<Backspace>/; $binding =~ s/^\\(0\d+)$/'^'.chr(64+oct($1))/e; $binding =~ s/^\\(0\d+)(.)/'^'.chr(64+oct($1)) ." $2"/e; $binding =~ s/\\t/<Tab>/; $binding =~ s/M_ENTER_S/<Return>/; $binding =~ s/NULL//; die "unknown key $binding" if $binding =~ /\\[^\\]|<|>/; die "unknown OP $op" unless $OPS{$op}; $MAP{$map} .= "<$function>$binding$OPS{$op}\n"; } if ($map and /^}/) { undef $map; } } open XML, $xml or die "$xml: $!"; while () { if (/__print_map\((.*)\)/) { my $map = $1; unless ($MAP{$map}) { warn "map $map undefined"; next; } print < $map menu $DOC{$map} Default $map function bindings FunctionDefault keyDescription $MAP{$map}
EOT delete $MAP{$1}; } else { print; } } close XML; warn "unprinted maps: ". join(" ", keys %MAP) if %MAP;