[fcformat] Add value-count syntax

The format '%{#family}' expands to the number of values for the element
'family', or '0' if no such element exists in the pattern.
This commit is contained in:
Behdad Esfahbod 2009-02-10 05:05:53 -05:00
parent dccbbe83ef
commit b6a23028be
1 changed files with 75 additions and 41 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright © 2008 Red Hat, Inc. * Copyright © 2008,2009 Red Hat, Inc.
* *
* Red Hat Author(s): Behdad Esfahbod * Red Hat Author(s): Behdad Esfahbod
* *
@ -31,7 +31,6 @@
/* /*
* Some ideas for future syntax extensions: * Some ideas for future syntax extensions:
* *
* - number of values for element using '%{#elt}'
* - allow indexing subexprs using '%{[idx]elt1,elt2{subexpr}}' * - allow indexing subexprs using '%{[idx]elt1,elt2{subexpr}}'
* - allow indexing simple tags using '%{elt[idx]}' * - allow indexing simple tags using '%{elt[idx]}'
* - conditional/filtering/deletion on binding (using '(w)'/'(s)' notation) * - conditional/filtering/deletion on binding (using '(w)'/'(s)' notation)
@ -260,45 +259,6 @@ maybe_skip_subexpr (FcFormatContext *c)
FcTrue; FcTrue;
} }
static FcBool
interpret_simple (FcFormatContext *c,
FcPattern *pat,
FcStrBuf *buf)
{
FcPatternElt *e;
FcBool add_colon = FcFalse;
FcBool add_elt_name = FcFalse;
if (consume_char (c, ':'))
add_colon = FcTrue;
if (!read_word (c))
return FcFalse;
if (consume_char (c, '='))
add_elt_name = FcTrue;
e = FcPatternObjectFindElt (pat,
FcObjectFromName ((const char *) c->word));
if (e)
{
FcValueListPtr l;
if (add_colon)
FcStrBufChar (buf, ':');
if (add_elt_name)
{
FcStrBufString (buf, c->word);
FcStrBufChar (buf, '=');
}
l = FcPatternEltValues(e);
FcNameUnparseValueList (buf, l, '\0');
}
return FcTrue;
}
static FcBool static FcBool
interpret_filter (FcFormatContext *c, interpret_filter (FcFormatContext *c,
FcPattern *pat, FcPattern *pat,
@ -415,6 +375,79 @@ interpret_cond (FcFormatContext *c,
return FcTrue; return FcTrue;
} }
static FcBool
interpret_count (FcFormatContext *c,
FcPattern *pat,
FcStrBuf *buf)
{
int count;
FcPatternElt *e;
FcChar8 buf_static[64];
if (!expect_char (c, '#'))
return FcFalse;
if (!read_word (c))
return FcFalse;
count = 0;
e = FcPatternObjectFindElt (pat,
FcObjectFromName ((const char *) c->word));
if (e)
{
FcValueListPtr l;
count++;
for (l = FcPatternEltValues(e);
l->next;
l = l->next)
count++;
}
snprintf (buf_static, sizeof (buf_static), "%d", count);
FcStrBufString (buf, buf_static);
return FcTrue;
}
static FcBool
interpret_simple (FcFormatContext *c,
FcPattern *pat,
FcStrBuf *buf)
{
FcPatternElt *e;
FcBool add_colon = FcFalse;
FcBool add_elt_name = FcFalse;
if (consume_char (c, ':'))
add_colon = FcTrue;
if (!read_word (c))
return FcFalse;
if (consume_char (c, '='))
add_elt_name = FcTrue;
e = FcPatternObjectFindElt (pat,
FcObjectFromName ((const char *) c->word));
if (e)
{
FcValueListPtr l;
if (add_colon)
FcStrBufChar (buf, ':');
if (add_elt_name)
{
FcStrBufString (buf, c->word);
FcStrBufChar (buf, '=');
}
l = FcPatternEltValues(e);
FcNameUnparseValueList (buf, l, '\0');
}
return FcTrue;
}
static FcChar8 * static FcChar8 *
cescape (const FcChar8 *str) cescape (const FcChar8 *str)
{ {
@ -593,6 +626,7 @@ interpret_percent (FcFormatContext *c,
case '+': ret = interpret_filter (c, pat, buf); break; case '+': ret = interpret_filter (c, pat, buf); break;
case '-': ret = interpret_delete (c, pat, buf); break; case '-': ret = interpret_delete (c, pat, buf); break;
case '?': ret = interpret_cond (c, pat, buf); break; case '?': ret = interpret_cond (c, pat, buf); break;
case '#': ret = interpret_count (c, pat, buf); break;
default: ret = interpret_simple (c, pat, buf); break; default: ret = interpret_simple (c, pat, buf); break;
} }