FS#12132 patch 6, part 1: tagnavi.config: Add support for string

truncation in tagnavi %formats using the standard
"%{width}.{truncation}s" format syntax.

String truncation is especially useful when using part of a string
tag, filename, or basename for sorting and %strip'ing.  (Basename
support is forthcoming in a subsequent commit.)

Also renovated the format_str() code a bit (improved structuring,
removed code duplication) and increased the maximum length of a printf
conversion specification to 20 characters.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30229 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Hohmuth 2011-07-31 16:26:31 +00:00
parent 936494f9c5
commit accea18ded

View file

@ -1074,9 +1074,9 @@ static bool show_search_progress(bool init, int count)
static int format_str(struct tagcache_search *tcs, struct display_format *fmt, static int format_str(struct tagcache_search *tcs, struct display_format *fmt,
char *buf, int buf_size) char *buf, int buf_size)
{ {
char fmtbuf[8]; char fmtbuf[20];
bool read_format = false; bool read_format = false;
int fmtbuf_pos = 0; unsigned fmtbuf_pos = 0;
int parpos = 0; int parpos = 0;
int buf_pos = 0; int buf_pos = 0;
int i; int i;
@ -1097,46 +1097,66 @@ static int format_str(struct tagcache_search *tcs, struct display_format *fmt,
if (read_format) if (read_format)
{ {
fmtbuf[fmtbuf_pos++] = fmt->formatstr[i]; char formatchar = fmt->formatstr[i];
if (fmtbuf_pos >= buf_size)
fmtbuf[fmtbuf_pos++] = formatchar;
if (fmtbuf_pos >= sizeof fmtbuf)
{ {
logf("format parse error"); logf("format parse error");
return -2; return -2;
} }
if (fmt->formatstr[i] == 's') if (formatchar == 's' || formatchar == 'd')
{ {
unsigned space_left = buf_size - buf_pos;
char tmpbuf[space_left + 1];
char *result;
fmtbuf[fmtbuf_pos] = '\0'; fmtbuf[fmtbuf_pos] = '\0';
read_format = false; read_format = false;
switch (formatchar)
{
case 's':
if (fmt->tags[parpos] == tcs->type) if (fmt->tags[parpos] == tcs->type)
{ {
snprintf(&buf[buf_pos], buf_size - buf_pos, fmtbuf, tcs->result); result = tcs->result;
} }
else else
{ {
/* Need to fetch the tag data. */ /* Need to fetch the tag data. */
if (!tagcache_retrieve(tcs, tcs->idx_id, fmt->tags[parpos], int tag = fmt->tags[parpos];
&buf[buf_pos], buf_size - buf_pos))
if (!tagcache_retrieve(tcs, tcs->idx_id,
(tag == tag_virt_basename ?
tag_filename : tag),
tmpbuf, space_left))
{ {
logf("retrieve failed"); logf("retrieve failed");
return -3; return -3;
} }
}
buf_pos += strlen(&buf[buf_pos]); if (tag == tag_virt_basename
parpos++; && (result = strrchr(tmpbuf, '/')) != NULL)
}
else if (fmt->formatstr[i] == 'd')
{ {
fmtbuf[fmtbuf_pos] = '\0'; result++;
read_format = false;
snprintf(&buf[buf_pos], buf_size - buf_pos, fmtbuf,
tagcache_get_numeric(tcs, fmt->tags[parpos]));
buf_pos += strlen(&buf[buf_pos]);
parpos++;
} }
continue; else
result = tmpbuf;
}
snprintf(&buf[buf_pos], space_left, fmtbuf, result);
break;
case 'd':
snprintf(&buf[buf_pos], space_left, fmtbuf,
tagcache_get_numeric(tcs, fmt->tags[parpos]));
} }
buf_pos += strlen(&buf[buf_pos]);
parpos++;
}
}
else
buf[buf_pos++] = fmt->formatstr[i]; buf[buf_pos++] = fmt->formatstr[i];
if (buf_pos - 1 >= buf_size) if (buf_pos - 1 >= buf_size)