rb_info plugin and button,action+context name helper

rb_info is just a test plugin

just some info from the running rockbox install

the real star here is the generator scripts to make actions_helper.c and button_helper.c

Change-Id: I23f7bbdae3f2cffca2490c4df40bb13b0b5d5064
This commit is contained in:
William Wilgus 2021-11-12 20:50:20 -05:00 committed by William Wilgus
parent 3d07ec46ee
commit b39acee3ab
12 changed files with 908 additions and 1 deletions

View file

@ -1,6 +1,8 @@
sha1.c
gcc-support.c
pluginlib_actions.c
action_helper.c
button_helper.c
helper.c
icon_helper.c
arg_helper.c

View file

@ -0,0 +1 @@
/*DUMMY_FILE_DONT_CHANGEME*/

View file

@ -0,0 +1,34 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2021 William Wilgus
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
/* action_helper provides a way to turn numeric action/context into strings
* the file action_helper.c is generated at compile time
* ACTION_ and CONTEXT_ are stripped from the strings and replaced when
* action_name and context_name are called,
* NOTE: both share the same static buffer sized as the largest string possible
*/
#ifndef _ACTION_HELPER_H_
#define _ACTION_HELPER_H_
char* action_name(int action);
char* context_name(int context);
#endif /* _ACTION_HELPER_H_ */

209
apps/plugins/lib/action_helper.pl Executable file
View file

@ -0,0 +1,209 @@
#!/usr/bin/env perl
############################################################################
# __________ __ ___.
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
# \/ \/ \/ \/ \/
# $action_helper$
#
# Copyright (C) 2021 William Wilgus
#
# All files in this archive are subject to the GNU General Public License.
# See the file COPYING in the source tree root for full license agreement.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
############################################################################
#expects -E source input on STDIN
use strict;
use warnings;
my @actions = ();
my @contexts = ();
my @action_offset = ();
my @context_offset = ();
my $action_ct = 0;
my $context_ct = 0;
my $len_max_action = 0;
my $len_max_context = 0;
my $len_min_action = -1;
my $len_min_context = -1;
while(my $line = <STDIN>)
{
chomp($line);
if($line =~ /^\s*(ACTION_[^\s]+)(\s*=.*)?,\s*$/)
{
$actions[$action_ct] = $1;
$action_ct++;
}
elsif($line =~ /^\s*(LAST_ACTION_PLACEHOLDER)(\s*=.*)?,\s*$/)
{ #special case don't save actual name
$actions[$action_ct] = "";
$action_ct++;
}
elsif($line =~ /^\s*(PLA_[^\s]+)(\s*=.*)?,\s*$/)
{
$actions[$action_ct] = $1;
$action_ct++;
}
elsif($line =~ /^\s*(CONTEXT_[^\s]+)(\s*=.*)?,\s*$/)
{
$contexts[$context_ct] = $1;
$context_ct++;
}
}
print <<EOF
/* Don't change this file! */
/* It is automatically generated of action.h */
#include "plugin.h"
#include "action_helper.h"
EOF
;
#dump actions
my $offset = 0;
print "static const char action_names[]= \n";
for(my $i = 0; $i < $action_ct; $i++){
my $act = $actions[$i];
$act =~ s/ACTION_USB_HID_/%s/ig; # strip the common part
$act =~ s/ACTION_/%s/ig; # strip the common part
my $actlen = length($act);
if ($actlen < $len_min_action or $len_min_action == -1){
$len_min_action = $actlen;
}
if ($actions[$i] ne $act){
printf "/*%s*/\"%s\\0\"\n", substr($actions[$i], 0, -($actlen - 2)), $act;
} else {
print "\"$act\\0\" \n";
}
my $slen = length($actions[$i]) + 1; #NULL terminator
if ($slen > $len_max_action) { $len_max_action = $slen; }
push(@action_offset, {'name' => $actions[$i], 'offset' => $offset});
$offset += length($act) + 1; # NULL terminator
}
printf "\"\";/* %d + \\0 */\n\n", $offset;
@actions = ();
#dump contexts
$offset = 0;
print "static const char context_names[]= \n";
for(my $i = 0; $i < $context_ct; $i++){
my $ctx = $contexts[$i];
$ctx =~ s/CONTEXT_/%s/ig; # strip the common part
my $ctxlen = length($ctx);
if ($ctxlen < 5){
$ctx = $contexts[$i];
$ctxlen = length($ctx);
}
if ($ctxlen < $len_min_context or $len_min_context == -1){
$len_min_context = $ctxlen;
}
if ($contexts[$i] ne $ctx){
printf "/*%s*/\"%s\\0\"\n", substr($contexts[$i], 0, -($ctxlen - 2)), $ctx;
} else {
print "\"$ctx\\0\" \n";
}
my $slen = length($contexts[$i]) + 1; # NULL terminator
if ($slen > $len_max_context) { $len_max_context = $slen; }
push(@context_offset, {'name' => $contexts[$i], 'offset' => $offset});
$offset += length($ctx) + 1; # NULL terminator
}
printf "\"\";/* %d + \\0 */\n\n", $offset;
@contexts = ();
printf "#define ACTION_CT %d\n", $action_ct;
print "static const uint16_t action_offsets[ACTION_CT] = {\n";
foreach my $define (@action_offset)
{
printf("%d, /*%s*/\n", @$define{'offset'}, @$define{'name'});
}
print "};\n\n";
@action_offset = ();
printf "#define CONTEXT_CT %d\n", $context_ct;
print "#if 0 /* context_names is small enough to walk the string instead */\n";
print "static const uint16_t context_offsets[CONTEXT_CT] = {\n";
foreach my $define (@context_offset)
{
printf("%d, /*%s*/\n", @$define{'offset'}, @$define{'name'});
}
print "};\n#endif\n\n";
@context_offset = ();
printf "#define ACTIONBUFSZ %d\n", $len_max_action;
printf "#define CONTEXTBUFSZ %d\n\n", $len_max_context;
if ($len_max_action > $len_max_context)
{
print "static char name_buf[ACTIONBUFSZ];\n";
}
else
{
print "static char name_buf[CONTEXTBUFSZ];\n";
}
print <<EOF
char* action_name(int action)
{
if (action >= 0 && action < ACTION_CT)
{
uint16_t offset = action_offsets[action];
const char *act = &action_names[offset];
if (action < ACTION_USB_HID_FIRST)
rb->snprintf(name_buf, ACTIONBUFSZ, act, "ACTION_");
else
rb->snprintf(name_buf, ACTIONBUFSZ, act, "ACTION_USB_HID_");
}
else
rb->snprintf(name_buf, ACTIONBUFSZ, "ACTION_UNKNOWN");
return name_buf;
}
/* walk string increment offset for each NULL if desired offset found, return */
static const char *context_getoffset(int offset)
{
const char *names = context_names;
const size_t len = sizeof(context_names) - 1;
int current = 0;
if (offset > 0)
{
const char *pos = names;
const char *end = names + len;
while (pos < end)
{
if (*pos++ == '\\0')
{
current++;
if (offset == current)
return pos;
pos += $len_min_context; /* each string is at least this long */
}
}
}
return names;
}
char* context_name(int context)
{
const char *ctx;
if (context >= 0 && context < CONTEXT_CT)
{
#if 0
uint16_t offset = context_offsets[context];
ctx = &context_names[offset];
#else
ctx = context_getoffset(context);
#endif
}
else
ctx = "%sUNKNOWN";
rb->snprintf(name_buf, CONTEXTBUFSZ, ctx, "CONTEXT_");
return name_buf;
}
EOF
;

View file

@ -0,0 +1 @@
/*DUMMY_FILE_DONT_CHANGEME*/

View file

@ -0,0 +1,38 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2021 William Wilgus
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef _BUTTON_HELPER_H_
#define _BUTTON_HELPER_H_
struct available_button
{
const char* name;
unsigned long value;
};
/* *available_buttons is holding a pointer to the first element of an array
* of struct available_button it is set up in such a way due to the file being
* generated at compile time you can still call it as such though
* eg available_buttons[0] or available_buttons[available_button_count] (NULL SENTINEL, 0)*/
extern const struct available_button * const available_buttons;
extern const int available_button_count;
int get_button_names(char *buf, size_t bufsz, unsigned long button);
#endif /* _BUTTON_HELPER_H_ */

View file

@ -0,0 +1,98 @@
#!/usr/bin/env perl
############################################################################
# __________ __ ___.
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
# \/ \/ \/ \/ \/
# $Id$
#
# Copyright (C) 2009 by Maurus Cuelenaere
# Copyright (C) 2021 by William Wilgus
#
# All files in this archive are subject to the GNU General Public License.
# See the file COPYING in the source tree root for full license agreement.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
############################################################################
#expects -dM -E source input on STDIN
use strict;
use warnings;
my $svnrev = '$Revision$';
my @buttons = ();
my $count = 1; #null sentinel
my $val;
my $def;
while(my $line = <STDIN>)
{
chomp($line);
if($line =~ /^#define (BUTTON_[^\s]+) (.+)$/)
{
$def = "{\"$1\", $2},\n";
$val = $2;
if($val =~ /^0/)
{
$val = oct($val)
}
else
{
$val = 0xFFFFFFFF; #only used for sorting
}
push(@buttons, {'name' => $1, 'value' => $val, 'def' => $def});
$count = $count + 1;
}
}
my @sorted = sort { @$a{'value'} <=> @$b{'value'} } @buttons;
print <<EOF
/* Don't change this file! */
/* It is automatically generated of button.h */
#include "plugin.h"
#include "button.h"
#include "button_helper.h"
static const struct available_button buttons[$count] = {
EOF
;
$count--; # don't count the sentinel
foreach my $button (@sorted)
{
printf " %s", @$button{'def'};
}
print <<EOF
{"\\0", 0} /* sentinel */
};
const int available_button_count = $count;
const struct available_button * const available_buttons = buttons;
int get_button_names(char *buf, size_t bufsz, unsigned long button)
{
int len = 0;
buf[0] = '\\0';
const struct available_button *btn = buttons;
while(btn->name[0] != '\\0')
{
if(btn->value == 0)
{
if (button == 0)
{
buf[0] = '\\0';
len = rb->strlcat(buf, btn->name, bufsz);
return len;
}
}
else if ((button & btn->value) == btn->value)
{
if (len > 0)
rb->strlcat(buf, " | ", bufsz);
len = rb->strlcat(buf, btn->name, bufsz);
}
btn++;
}
return len;
}
EOF
;