1
0
Fork 0
forked from len0rd/rockbox

skin engine small cleanup optimize find_tag() remove string copy

since we now have the length of tag names thru the param_pos var

we can simplify the find tag function to skip if the length doesn't match
this allows us to no longer make a string copy in order to terminate
the buffer

move some of the more frequently encountered tags to the top of the
lookup list

only SKIN_TOKEN_UNKNOWN position matters as its empty string is used
as the sentinel

Change-Id: Ib82d081a9ebedc228768845ae54a3d9466faaef1
This commit is contained in:
William Wilgus 2024-11-24 17:18:32 -05:00 committed by William Wilgus
parent 303fc090a7
commit ff9da12763
4 changed files with 90 additions and 90 deletions

View file

@ -501,7 +501,6 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
const char* bookmark;
const char *open_square_bracket = NULL;
char tag_name[MAX_TAG_LENGTH];
const char* tag_args;
const struct tag_info *tag;
struct skin_tag_parameter* params = NULL;
@ -513,25 +512,14 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
int optional = 0;
/* Checking the tag name */
for (i=0; cursor[i] && i<MAX_TAG_LENGTH; i++)
tag_name[i] = cursor[i];
/* First we check the two characters after the '%', then a single char */
tag = NULL;
i = MAX_TAG_LENGTH;
while (!tag && i > 1)
{
tag_name[i-1] = '\0';
tag = find_tag(tag_name);
i--;
}
tag = find_tag(cursor);
if(!tag)
{
skin_error(ILLEGAL_TAG, cursor);
return 0;
}
cursor += i;
cursor += tag->param_pos - 1; /*strlen(tag->name)*/;
/* Copying basic tag info */
if(element->type != CONDITIONAL && element->type != VIEWPORT)

View file

@ -78,11 +78,8 @@ static void skip_enumlist(const char** document)
void skip_tag(const char** document)
{
char tag_name[MAX_TAG_LENGTH];
int i;
bool qmark;
const struct tag_info *tag;
const char *cursor;
if(**document == TAGSYM)
(*document)++;
@ -96,22 +93,8 @@ void skip_tag(const char** document)
}
else
{
cursor = *document;
/* Checking the tag name */
for (i=0; cursor[i] && i<MAX_TAG_LENGTH; i++)
tag_name[i] = cursor[i];
/* First we check the two characters after the '%', then a single char */
tag = NULL;
i = MAX_TAG_LENGTH;
while (!tag && i > 1)
{
tag_name[i-1] = '\0';
tag = find_tag(tag_name);
i--;
}
tag = find_tag(*document);
if (tag)
{
*document += tag->param_pos - 1; /*strlen(tag->name)*/

View file

@ -19,15 +19,17 @@
*
****************************************************************************/
#include "tag_table.h"
#include <string.h>
#include "tag_table.h"
#include "debug.h"
#define BAR_PARAMS "?[iP][iP][iP][iP]|s*"
/* The tag definition table */
static const struct tag_info legal_tags[] =
static const struct tag_info legal_tags[] =
{
/*{type,namelen+1,name\0param,flags}*/
#define TAG(type,name,param,flag) {(type),sizeof(name),(name "\0" param),(flag)}
TAG(SKIN_TOKEN_ALIGN_CENTER, "ac", "", 0),
TAG(SKIN_TOKEN_ALIGN_LEFT, "al", "", 0),
TAG(SKIN_TOKEN_ALIGN_LEFT_RTL, "aL", "", 0),
@ -39,6 +41,48 @@ static const struct tag_info legal_tags[] =
TAG(SKIN_TOKEN_LOGICAL_AND, "and", "T*", SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_LOGICAL_OR, "or", "T*", SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_FILE_BITRATE, "fb", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_CODEC, "fc", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_FREQUENCY, "ff", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_FREQUENCY_KHZ, "fk", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "fm", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_NAME, "fn", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_PATH, "fp", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_SIZE, "fs", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_VBR, "fv", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_DIRECTORY, "d" , "I", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_BITRATE, "Fb", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_CODEC, "Fc", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_FREQUENCY, "Ff", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_FREQUENCY_KHZ, "Fk", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "Fm", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_NAME, "Fn", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_PATH, "Fp", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_SIZE, "Fs", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_VBR, "Fv", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_DIRECTORY, "D" , "I", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SF|[IP][IP]I", 0|NOBREAK),
TAG(SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S|[IT]I", 0),
TAG(SKIN_TOKEN_IMAGE_BACKDROP, "X" , "f", SKIN_REFRESH_STATIC|NOBREAK),
TAG(SKIN_TOKEN_IMAGE_DISPLAY, "x", "SF|II", SKIN_REFRESH_STATIC|NOBREAK),
TAG(SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT,"x9", "S", 0),
TAG(SKIN_TOKEN_VIEWPORT_ENABLE, "Vd" , "S", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_UIVIEWPORT_ENABLE, "VI" , "S", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_VIEWPORT_CUSTOMLIST, "Vp" , "IC", SKIN_REFRESH_DYNAMIC|NOBREAK),
TAG(SKIN_TOKEN_VIEWPORT_FGCOLOUR, "Vf" , "s", SKIN_REFRESH_STATIC|NOBREAK),
TAG(SKIN_TOKEN_VIEWPORT_BGCOLOUR, "Vb" , "s", SKIN_REFRESH_STATIC|NOBREAK),
TAG(SKIN_TOKEN_VIEWPORT_TEXTSTYLE, "Vs" , "S|s", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP,"Vg" , "SS|s", SKIN_REFRESH_STATIC|NOBREAK),
TAG(SKIN_TOKEN_VIEWPORT_DRAWONBG, "VB" , "", SKIN_REFRESH_STATIC|NOBREAK),
TAG(SKIN_TOKEN_VIEWPORT_CONDITIONAL, "Vl" , "S[IP][IP][ip][ip]i", 0),
TAG(SKIN_TOKEN_UIVIEWPORT_LOAD, "Vi" , "s[IP][IP][ip][ip]i", 0),
TAG(SKIN_TOKEN_VIEWPORT_LOAD, "V" , "[IP][IP][ip][ip]i", 0),
TAG(SKIN_TOKEN_BATTERY_PERCENT, "bl" , BAR_PARAMS, SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_BATTERY_VOLTS, "bv", "", SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_BATTERY_TIME, "bt", "", SKIN_REFRESH_DYNAMIC),
@ -67,28 +111,6 @@ static const struct tag_info legal_tags[] =
TAG(SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON, "cu", "", SKIN_RTC_REFRESH),
TAG(SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN, "cw", "", SKIN_RTC_REFRESH),
TAG(SKIN_TOKEN_FILE_BITRATE, "fb", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_CODEC, "fc", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_FREQUENCY, "ff", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_FREQUENCY_KHZ, "fk", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "fm", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_NAME, "fn", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_PATH, "fp", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_SIZE, "fs", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_VBR, "fv", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_DIRECTORY, "d" , "I", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_BITRATE, "Fb", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_CODEC, "Fc", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_FREQUENCY, "Ff", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_FREQUENCY_KHZ, "Fk", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "Fm", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_NAME, "Fn", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_PATH, "Fp", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_SIZE, "Fs", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_VBR, "Fv", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_FILE_DIRECTORY, "D" , "I", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_METADATA_ARTIST, "ia", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_METADATA_COMPOSER, "ic", "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_METADATA_ALBUM, "id", "", SKIN_REFRESH_STATIC),
@ -176,20 +198,12 @@ static const struct tag_info legal_tags[] =
TAG(SKIN_TOKEN_DISABLE_THEME, "wd", "", 0|NOBREAK),
TAG(SKIN_TOKEN_DRAW_INBUILTBAR, "wi", "", SKIN_REFRESH_STATIC|NOBREAK),
TAG(SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SF|[IP][IP]I", 0|NOBREAK),
TAG(SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S|[IT]I", 0),
TAG(SKIN_TOKEN_IMAGE_DISPLAY, "x", "SF|II", SKIN_REFRESH_STATIC|NOBREAK),
TAG(SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT,"x9", "S", 0),
TAG(SKIN_TOKEN_LOAD_FONT, "Fl" , "IF|I", 0|NOBREAK),
TAG(SKIN_TOKEN_ALBUMART_LOAD, "Cl" , "[iP][iP][iP][iP]|ss", 0|NOBREAK),
TAG(SKIN_TOKEN_ALBUMART_DISPLAY, "Cd" , "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_ALBUMART_FOUND, "C" , "", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_VIEWPORT_ENABLE, "Vd" , "S", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_UIVIEWPORT_ENABLE, "VI" , "S", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_VIEWPORT_CUSTOMLIST, "Vp" , "IC", SKIN_REFRESH_DYNAMIC|NOBREAK),
TAG(SKIN_TOKEN_LIST_TITLE_TEXT, "Lt" , "", SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_LIST_ITEM_TEXT, "LT", "|IS", SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_LIST_ITEM_ROW, "LR", "", SKIN_REFRESH_DYNAMIC),
@ -201,16 +215,6 @@ static const struct tag_info legal_tags[] =
TAG(SKIN_TOKEN_LIST_ITEM_IS_SELECTED, "Lc" , "", SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_LIST_NEEDS_SCROLLBAR, "LB", BAR_PARAMS, SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_VIEWPORT_FGCOLOUR, "Vf" , "s", SKIN_REFRESH_STATIC|NOBREAK),
TAG(SKIN_TOKEN_VIEWPORT_BGCOLOUR, "Vb" , "s", SKIN_REFRESH_STATIC|NOBREAK),
TAG(SKIN_TOKEN_VIEWPORT_TEXTSTYLE, "Vs" , "S|s", SKIN_REFRESH_STATIC),
TAG(SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP,"Vg" , "SS|s", SKIN_REFRESH_STATIC|NOBREAK),
TAG(SKIN_TOKEN_VIEWPORT_DRAWONBG, "VB" , "", SKIN_REFRESH_STATIC|NOBREAK),
TAG(SKIN_TOKEN_VIEWPORT_CONDITIONAL, "Vl" , "S[IP][IP][ip][ip]i", 0),
TAG(SKIN_TOKEN_UIVIEWPORT_LOAD, "Vi" , "s[IP][IP][ip][ip]i", 0),
TAG(SKIN_TOKEN_VIEWPORT_LOAD, "V" , "[IP][IP][ip][ip]i", 0),
TAG(SKIN_TOKEN_TOP_QUICKSETTING_NAME, "QT" , "", SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_TOP_QUICKSETTING_VALUE, "Qt" , "", SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_RIGHT_QUICKSETTING_NAME, "QR" , "", SKIN_REFRESH_DYNAMIC),
@ -220,7 +224,6 @@ static const struct tag_info legal_tags[] =
TAG(SKIN_TOKEN_LEFT_QUICKSETTING_NAME, "QL" , "", SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_LEFT_QUICKSETTING_VALUE, "Ql" , "", SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_IMAGE_BACKDROP, "X" , "f", SKIN_REFRESH_STATIC|NOBREAK),
/* This uses the bar tag params also but the first item can be a string
* and we don't allow no params. */
TAG(SKIN_TOKEN_SETTING, "St" , "[Sip]|[ip][ip][ip]s*", SKIN_REFRESH_DYNAMIC),
@ -230,7 +233,7 @@ static const struct tag_info legal_tags[] =
/* HACK Alert (jdgordon): The next two tags have hacks so we could
* add a S param at the front without breaking old skins.
* [SD]D <- handled by the callback, allows SD or S or D params
* [SI]III[SI]|SN <- SIIIIS|S or IIIIS|S
* [SI]III[SI]|SN <- SIIIIS|S or IIIIS|S
* keep in sync with parse_touchregion() and parse_lasttouch() */
TAG(SKIN_TOKEN_LASTTOUCH, "Tl" , "|[SD]D", SKIN_REFRESH_DYNAMIC),
TAG(SKIN_TOKEN_TOUCHREGION, "T" , "[Sip][ip][ip][ip][Sip]|S*", 0|NOBREAK),
@ -264,26 +267,35 @@ static const char legal_escape_characters[] = "%(,);#<|>";
/*
* Just does a straight search through the tag table to find one by
* the given name
* the given name, n denotes command length and length name will be truncated to
*/
const struct tag_info* find_tag(const char* name)
static const struct tag_info* search_tag(const char* name, int n)
{
const struct tag_info* current = legal_tags;
/*
/*
* Continue searching so long as we have a non-empty name string
* and the name of the current element doesn't match the name
* we're searching for
* we're searching for, param_pos contains the length of name
* including the Null \0 character
*/
while(strcmp(current->name, name) && current->name[0] != '\0')
current++;
if(current->name[0] == '\0')
while(current->param_pos > 1
&& (current->param_pos != n || strncmp(current->name, name, n - 1) != 0))
{
current++;
}
if(current->param_pos <= 1) /*param_pos of 1 is an empty string '\0'*/
{
//DEBUGF("!NOT FOUND! %s %d %.*s\n", __func__, -1, n-1, name);
return NULL;
}
else
{
//DEBUGF("%s %d %s\n", __func__, current->type, current->name);
return current;
}
}
@ -299,3 +311,20 @@ int find_escape_character(char lookup)
else
return 0;
}
/*
* Finds a tag by name and returns its parameter list, or an empty
* string if the tag is not found in the table
*/
const struct tag_info* find_tag(const char *name)
{
/* First we check three then two characters after the '%', then a single char */
const struct tag_info *tag = NULL;
int i = MAX_TAG_LENGTH;
while (!tag && i > 1)
{
tag = search_tag(name, i);
i--;
}
return tag;
}

View file

@ -354,14 +354,14 @@ struct tag_info
int flags;
};
/*
/*
* Finds a tag by name and returns its parameter list, or an empty
* string if the tag is not found in the table
*/
const struct tag_info* find_tag(const char* name);
const struct tag_info* find_tag(const char *name);
/*
* Determines whether a character is legal to escape or not. If
* Determines whether a character is legal to escape or not. If
* lookup is not found in the legal escape characters string, returns
* false, otherwise returns true
*/