From b6a23028beb3b99022599344ebd8511c12dc7fd0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 10 Feb 2009 05:05:53 -0500 Subject: [PATCH] [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. --- src/fcformat.c | 116 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 41 deletions(-) diff --git a/src/fcformat.c b/src/fcformat.c index 238f8d2..6a463fd 100644 --- a/src/fcformat.c +++ b/src/fcformat.c @@ -1,5 +1,5 @@ /* - * Copyright © 2008 Red Hat, Inc. + * Copyright © 2008,2009 Red Hat, Inc. * * Red Hat Author(s): Behdad Esfahbod * @@ -31,7 +31,6 @@ /* * Some ideas for future syntax extensions: * - * - number of values for element using '%{#elt}' * - allow indexing subexprs using '%{[idx]elt1,elt2{subexpr}}' * - allow indexing simple tags using '%{elt[idx]}' * - conditional/filtering/deletion on binding (using '(w)'/'(s)' notation) @@ -260,45 +259,6 @@ maybe_skip_subexpr (FcFormatContext *c) 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 interpret_filter (FcFormatContext *c, FcPattern *pat, @@ -415,6 +375,79 @@ interpret_cond (FcFormatContext *c, 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 * cescape (const FcChar8 *str) { @@ -593,6 +626,7 @@ interpret_percent (FcFormatContext *c, case '+': ret = interpret_filter (c, pat, buf); break; case '-': ret = interpret_delete (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; } -- 2.39.5