summaryrefslogtreecommitdiff
path: root/apps/plugins/lib/action_helper.pl
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lib/action_helper.pl')
-rwxr-xr-xapps/plugins/lib/action_helper.pl209
1 files changed, 209 insertions, 0 deletions
diff --git a/apps/plugins/lib/action_helper.pl b/apps/plugins/lib/action_helper.pl
new file mode 100755
index 0000000000..1dfdcfd070
--- /dev/null
+++ b/apps/plugins/lib/action_helper.pl
@@ -0,0 +1,209 @@
1#!/usr/bin/env perl
2############################################################################
3# __________ __ ___.
4# Open \______ \ ____ ____ | | _\_ |__ _______ ___
5# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8# \/ \/ \/ \/ \/
9# $action_helper$
10#
11# Copyright (C) 2021 William Wilgus
12#
13# All files in this archive are subject to the GNU General Public License.
14# See the file COPYING in the source tree root for full license agreement.
15#
16# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17# KIND, either express or implied.
18#
19############################################################################
20#expects -E source input on STDIN
21use strict;
22use warnings;
23
24my @actions = ();
25my @contexts = ();
26my @action_offset = ();
27my @context_offset = ();
28my $action_ct = 0;
29my $context_ct = 0;
30my $len_max_action = 0;
31my $len_max_context = 0;
32my $len_min_action = -1;
33my $len_min_context = -1;
34while(my $line = <STDIN>)
35{
36 chomp($line);
37 if($line =~ /^\s*(ACTION_[^\s]+)(\s*=.*)?,\s*$/)
38 {
39 $actions[$action_ct] = $1;
40 $action_ct++;
41 }
42 elsif($line =~ /^\s*(LAST_ACTION_PLACEHOLDER)(\s*=.*)?,\s*$/)
43 { #special case don't save actual name
44 $actions[$action_ct] = "";
45 $action_ct++;
46 }
47 elsif($line =~ /^\s*(PLA_[^\s]+)(\s*=.*)?,\s*$/)
48 {
49 $actions[$action_ct] = $1;
50 $action_ct++;
51 }
52 elsif($line =~ /^\s*(CONTEXT_[^\s]+)(\s*=.*)?,\s*$/)
53 {
54 $contexts[$context_ct] = $1;
55 $context_ct++;
56 }
57}
58
59print <<EOF
60/* Don't change this file! */
61/* It is automatically generated of action.h */
62#include "plugin.h"
63#include "action_helper.h"
64EOF
65;
66#dump actions
67my $offset = 0;
68print "static const char action_names[]= \n";
69for(my $i = 0; $i < $action_ct; $i++){
70 my $act = $actions[$i];
71 $act =~ s/ACTION_USB_HID_/%s/ig; # strip the common part
72 $act =~ s/ACTION_/%s/ig; # strip the common part
73 my $actlen = length($act);
74 if ($actlen < $len_min_action or $len_min_action == -1){
75 $len_min_action = $actlen;
76 }
77 if ($actions[$i] ne $act){
78 printf "/*%s*/\"%s\\0\"\n", substr($actions[$i], 0, -($actlen - 2)), $act;
79 } else {
80 print "\"$act\\0\" \n";
81 }
82 my $slen = length($actions[$i]) + 1; #NULL terminator
83 if ($slen > $len_max_action) { $len_max_action = $slen; }
84 push(@action_offset, {'name' => $actions[$i], 'offset' => $offset});
85 $offset += length($act) + 1; # NULL terminator
86}
87printf "\"\";/* %d + \\0 */\n\n", $offset;
88@actions = ();
89
90#dump contexts
91$offset = 0;
92print "static const char context_names[]= \n";
93for(my $i = 0; $i < $context_ct; $i++){
94 my $ctx = $contexts[$i];
95 $ctx =~ s/CONTEXT_/%s/ig; # strip the common part
96 my $ctxlen = length($ctx);
97
98 if ($ctxlen < 5){
99 $ctx = $contexts[$i];
100 $ctxlen = length($ctx);
101 }
102
103 if ($ctxlen < $len_min_context or $len_min_context == -1){
104 $len_min_context = $ctxlen;
105 }
106 if ($contexts[$i] ne $ctx){
107 printf "/*%s*/\"%s\\0\"\n", substr($contexts[$i], 0, -($ctxlen - 2)), $ctx;
108 } else {
109 print "\"$ctx\\0\" \n";
110 }
111 my $slen = length($contexts[$i]) + 1; # NULL terminator
112 if ($slen > $len_max_context) { $len_max_context = $slen; }
113 push(@context_offset, {'name' => $contexts[$i], 'offset' => $offset});
114 $offset += length($ctx) + 1; # NULL terminator
115}
116printf "\"\";/* %d + \\0 */\n\n", $offset;
117@contexts = ();
118
119printf "#define ACTION_CT %d\n", $action_ct;
120print "static const uint16_t action_offsets[ACTION_CT] = {\n";
121foreach my $define (@action_offset)
122{
123 printf("%d, /*%s*/\n", @$define{'offset'}, @$define{'name'});
124}
125print "};\n\n";
126@action_offset = ();
127
128printf "#define CONTEXT_CT %d\n", $context_ct;
129print "#if 0 /* context_names is small enough to walk the string instead */\n";
130print "static const uint16_t context_offsets[CONTEXT_CT] = {\n";
131foreach my $define (@context_offset)
132{
133 printf("%d, /*%s*/\n", @$define{'offset'}, @$define{'name'});
134}
135print "};\n#endif\n\n";
136@context_offset = ();
137
138printf "#define ACTIONBUFSZ %d\n", $len_max_action;
139printf "#define CONTEXTBUFSZ %d\n\n", $len_max_context;
140
141if ($len_max_action > $len_max_context)
142{
143 print "static char name_buf[ACTIONBUFSZ];\n";
144}
145else
146{
147 print "static char name_buf[CONTEXTBUFSZ];\n";
148}
149print <<EOF
150
151char* action_name(int action)
152{
153 if (action >= 0 && action < ACTION_CT)
154 {
155 uint16_t offset = action_offsets[action];
156 const char *act = &action_names[offset];
157 if (action < ACTION_USB_HID_FIRST)
158 rb->snprintf(name_buf, ACTIONBUFSZ, act, "ACTION_");
159 else
160 rb->snprintf(name_buf, ACTIONBUFSZ, act, "ACTION_USB_HID_");
161 }
162 else
163 rb->snprintf(name_buf, ACTIONBUFSZ, "ACTION_UNKNOWN");
164 return name_buf;
165}
166
167/* walk string increment offset for each NULL if desired offset found, return */
168static const char *context_getoffset(int offset)
169{
170 const char *names = context_names;
171 const size_t len = sizeof(context_names) - 1;
172 int current = 0;
173 if (offset > 0)
174 {
175 const char *pos = names;
176 const char *end = names + len;
177 while (pos < end)
178 {
179 if (*pos++ == '\\0')
180 {
181 current++;
182 if (offset == current)
183 return pos;
184 pos += $len_min_context; /* each string is at least this long */
185 }
186 }
187 }
188 return names;
189}
190
191char* context_name(int context)
192{
193 const char *ctx;
194 if (context >= 0 && context < CONTEXT_CT)
195 {
196#if 0
197 uint16_t offset = context_offsets[context];
198 ctx = &context_names[offset];
199#else
200 ctx = context_getoffset(context);
201#endif
202 }
203 else
204 ctx = "%sUNKNOWN";
205 rb->snprintf(name_buf, CONTEXTBUFSZ, ctx, "CONTEXT_");
206 return name_buf;
207}
208EOF
209;