Makefile: remove spurious tab
[xcsoar.git] / tools / xci2cpp.pl
blobdcc5bf89c1f41f313ddc3fb062cde4f56b06e421
1 #!/usr/bin/perl
3 use strict;
4 use warnings;
5 use Data::Dumper;
7 my @modes = qw(default pan infobox Menu);
8 my $i = 0;
9 my %mode_map = map { $_ => $i++ } @modes;
11 my @events;
12 my %events2;
13 my @keys;
14 my @gestures;
15 my @gc;
16 my @nmea;
17 my @labels;
19 # Generate a key for the %indices table, to check for duplicates
20 sub get_key(\%) {
21 my $record = shift;
23 return unless defined $record->{type};
25 my $key = $record->{type};
26 $key .= '_' . $record->{mode} if defined $record->{mode};
28 if (defined $record->{location}) {
29 $key .= '_' . $record->{location};
30 } elsif (defined $record->{data}) {
31 $key .= '_' . $record->{data};
34 return $key;
37 sub append(\@\%\%) {
38 my ($all, $indices, $record) = @_;
40 my $key = get_key(%$record);
41 if (defined $key) {
42 if (exists $indices->{$key}) {
43 # this entry exists already - overwrite it
44 my $i = $indices->{$key};
45 $all->[$i] = $record;
46 return;
49 my $i = scalar @$all;
50 $indices->{$key} = $i;
53 # append new entry
54 push @$all, $record;
57 sub get_mode($) {
58 my $name = shift;
59 return $mode_map{$name} if exists $mode_map{$name};
60 push @modes, $name;
61 my $i = $#modes;
62 $mode_map{$name} = $i;
63 return $i;
66 sub commit(\%) {
67 my ($rec) = @_;
69 return unless $rec->{type};
71 my $line = $rec->{line};
72 die unless $line;
74 # Make event
75 my $event_id = 0;
76 foreach my $e (@{$rec->{event}}) {
77 my ($handler, $misc) = split(/ /, $e, 2);
78 my $e = [ $handler, $misc, $event_id ];
79 my $dump = Dumper($e);
80 $event_id = $events2{$dump};
81 unless (defined $event_id) {
82 push @events, $e;
83 $event_id = @events;
84 $events2{$dump} = $event_id;
88 my $mode = $rec->{mode} || die "Invalid entry near $line - no mode\n";
89 foreach my $m (split(/ /, $mode)) {
90 my $mode_id = get_mode($m);
91 my $label = $rec->{label};
92 $label =~ s|\\([^rn\\])|\\\\$1|g if ($label);
93 $label = '' unless defined $label;
94 my $location = $rec->{location};
95 push @labels, [ $mode_id, $label, $location, $event_id ]
96 if defined $location;
98 next unless $event_id > 0;
100 # Key output
101 if ($rec->{type} eq "key") {
102 my $data = $rec->{data} ;
103 if (length($data)<1) {
104 die "Invalid entry near $line - no key\n";
106 if (length($data) == 1) {
107 $data = uc($data);
108 $data = qq{(int)'$data'};
109 } else {
110 $data = "KEY_$data";
113 push @keys, [ $mode_id, $data, $event_id ];
114 } elsif ($rec->{type} eq "gce") {
115 my $data = $rec->{data} || die "Invalid entry near $line - no GCE data\n";
116 push @gc, [ $mode_id, $data, $event_id ];
117 } elsif ($rec->{type} eq "ne") {
118 my $data = $rec->{data} || die "Invalid entry near $line - no NE data\n";
119 push @nmea, [ $mode_id, $data, $event_id ];
120 } elsif ($rec->{type} eq "gesture") {
121 my $data = $rec->{data} || die "Invalid entry near $line - no Gesture data\n";
122 push @gestures, [ $mode_id, $event_id, $data ];
123 } elsif ($rec->{type} ne "none") {
124 die "Invalid record near $line - No valid type";
129 my @all;
130 my %indices;
132 my $current = { event => [] };
133 my $line = 0;
135 while (<>) {
136 chomp;
137 $line++;
138 next if (/^#/);
140 if (/^\s*$/) {
141 append(@all, %indices, %$current);
142 $current = { event => [] };
144 # We don't need the quotes - ignore for now
145 } elsif (/^event\s*=\s*"*([^"]*)"*$/) {
146 my $val = $1;
147 $val =~ s/\s*$//;
148 push @{$current->{event}}, $val;
149 } elsif (/^([a-z0-9]+)\s*=\s*"*([^"]*)"*$/) {
150 my $key = $1;
151 my $val = $2;
152 $val =~ s/\s*$//;
153 $current->{$key} = $val;
154 $current->{line} = $line unless exists $current->{line};
155 } else {
156 print STDERR "Error on $line - $_\n";
161 append(@all, %indices, %$current);
163 foreach my $record (@all) {
164 commit(%$record);
167 sub c_string($) {
168 my $value = shift;
169 return 'NULL' unless defined $value;
170 return qq|_T("$value")|;
173 print "static const TCHAR *const default_modes[] = {\n";
174 splice @modes, 0, 4;
175 foreach my $m (@modes) {
176 $m = c_string($m);
177 print " $m,\n";
179 print " NULL\n";
180 print "};\n";
182 print "static constexpr InputConfig::Event default_events[] = {\n";
183 foreach my $e (@events) {
184 my ($handler, $misc, $next_id) = @$e;
185 $misc = '' unless defined $misc;
186 $misc = c_string($misc);
187 print " { InputEvents::event$handler, $misc, $next_id },\n";
189 print "};\n";
191 print "static constexpr struct flat_event_map default_key2event[] = {\n";
192 foreach my $k (@keys) {
193 my ($mode, $key, $event) = @$k;
194 print " { $mode, $key, $event },\n";
196 print " { 0, 0, 0 },\n";
197 print "};\n";
199 print "static constexpr struct flat_event_map default_gc2event[] = {\n";
200 foreach my $k (@gc) {
201 my ($mode, $key, $event) = @$k;
202 print " { $mode, GCE_$key, $event },\n";
204 print " { 0, 0, 0 },\n";
205 print "};\n";
207 print "static constexpr struct flat_event_map default_n2event[] = {\n";
208 foreach my $k (@nmea) {
209 my ($mode, $key, $event) = @$k;
210 print " { $mode, $key, $event },\n";
212 print " { 0, 0, 0 },\n";
213 print "};\n";
215 print "static constexpr struct flat_label default_labels[] = {\n";
216 foreach my $l (@labels) {
217 my ($mode, $label, $location, $event) = @$l;
218 print qq| { $mode, $location, $event, _T("$label") },\n|;
220 print " { 0, 0, 0, NULL },\n";
221 print "};\n";
223 print "static constexpr struct flat_gesture_map default_gesture2event[] = {\n";
224 foreach my $g (@gestures) {
225 my ($mode, $event, $data) = @$g;
226 print " { $mode, $event, _T(\"$data\") },\n";
228 print " { 0, 0, NULL },\n";
229 print "};\n";