From: Behdad Esfahbod Date: Tue, 10 Feb 2009 00:13:07 +0000 (-0500) Subject: [fcformat] Refactor and restructure code for upcoming changes X-Git-Tag: 2.7.0~98 X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=27b3e2dddf6a89c66e8d79f4a28b1a0653e8e100;p=fontconfig.git [fcformat] Refactor and restructure code for upcoming changes Also makes it thread-safe. --- diff --git a/src/fcformat.c b/src/fcformat.c index a780f56..415114b 100644 --- a/src/fcformat.c +++ b/src/fcformat.c @@ -40,58 +40,96 @@ message (const char *fmt, ...) } -static FcChar8 *scratch1; -static FcChar8 *scratch2; -static const FcChar8 *format_orig; - -static const FcChar8 * -interpret_percent (FcPattern *pat, - FcStrBuf *buf, - const FcChar8 *format) +typedef struct _FcFormatContext { - int width, before; + const FcChar8 *format_orig; + const FcChar8 *format; + int format_len; + FcChar8 *scratch; +} FcFormatContext; - /* parse an optional width specifier */ - width = strtol (format, (char **) &format, 10); +static void +FcFormatContextInit (FcFormatContext *c, + const FcChar8 *format) +{ + c->format_orig = c->format = format; + c->format_len = strlen ((const char *) format); + c->scratch = malloc (c->format_len + 1); +} - before = buf->len; +static void +FcFormatContextDone (FcFormatContext *c) +{ + if (c) + { + free (c->scratch); + } +} - switch (*format) { - case '{': +static FcBool +consume_char (FcFormatContext *c, + FcChar8 term) +{ + if (*c->format != term) { - FcChar8 *p; - FcPatternElt *e; + message ("Pattern format error: expected '%c' at %d", + term, c->format - c->format_orig + 1); + return FcFalse; + } - format++; /* skip over '{' */ + c->format++; + return FcTrue; +} - p = (FcChar8 *) strpbrk ((const char *) format, "}"); - if (!p) - { - message ("Pattern format missing closing brace"); - break; - } - /* extract the element name */ - memcpy (scratch1, format, p - format); - scratch1[p - format] = '\0'; +static void +interpret_percent (FcFormatContext *c, + FcPattern *pat, + FcStrBuf *buf) +{ + int width, before; + FcChar8 *p; + FcPatternElt *e; - e = FcPatternObjectFindElt (pat, FcObjectFromName ((const char *) scratch1)); - if (e) - { - FcValueListPtr l; - l = FcPatternEltValues(e); - FcNameUnparseValueList (buf, l, '\0'); - } + if (!consume_char (c, '%')) + return; + + if (*c->format == '%') /* "%%" */ + { + FcStrBufChar (buf, *c->format++); + return; + } + + /* parse an optional width specifier */ + width = strtol ((const char *) c->format, (char **) &c->format, 10); + + before = buf->len; + + if (!consume_char (c, '{')) + return; - p++; /* skip over '}' */ - format = p; - break; + p = (FcChar8 *) strpbrk ((const char *) c->format, "}" /* "=?:}" */); + if (!p) + { + message ("Pattern format missing closing brace for opening brace at %d", + c->format-1 - c->format_orig + 1); + return; } - default: - message ("Pattern format has invalid character after '%%' at %d", - format - format_orig); - break; + /* extract the element name */ + memcpy (c->scratch, c->format, p - c->format); + c->scratch[p - c->format] = '\0'; + c->format = p; + + e = FcPatternObjectFindElt (pat, FcObjectFromName ((const char *) c->scratch)); + if (e) + { + FcValueListPtr l; + l = FcPatternEltValues(e); + FcNameUnparseValueList (buf, l, '\0'); } + /* handle filters, if any */ + /* XXX */ + /* align to width */ if (!buf->failed) { @@ -122,7 +160,7 @@ interpret_percent (FcPattern *pat, } } - return format; + consume_char (c, '}'); } static char escaped_char(const char ch) @@ -139,54 +177,43 @@ static char escaped_char(const char ch) } } -static const FcChar8 * -interpret (FcPattern *pat, - FcStrBuf *buf, - const FcChar8 *format, - FcChar8 term) +static void +interpret (FcFormatContext *c, + FcPattern *pat, + FcStrBuf *buf, + FcChar8 term) { - const FcChar8 *end; - - for (end = format; *end && *end != term;) + for (; *c->format && *c->format != term;) { - switch (*end) + switch (*c->format) { case '\\': - end++; /* skip over '\\' */ - FcStrBufChar (buf, escaped_char (*end++)); + c->format++; /* skip over '\\' */ + if (*c->format) + FcStrBufChar (buf, escaped_char (*c->format++)); continue; case '%': - end++; /* skip over '%' */ - if (*end == '%') - break; - end = interpret_percent (pat, buf, end); + interpret_percent (c, pat, buf); continue; } - FcStrBufChar (buf, *end); - end++; + FcStrBufChar (buf, *c->format++); } - if (*end != term) + if (*c->format != term) message ("Pattern format ended while looking for '%c'", term); - - return end; } FcChar8 * FcPatternFormat (FcPattern *pat, const FcChar8 *format) { - int len; FcStrBuf buf; + FcFormatContext c; FcStrBufInit (&buf, 0, 0); - len = strlen ((const char *) format); - scratch1 = malloc (len); - scratch2 = malloc (len); - format_orig = format; + FcFormatContextInit (&c, format); - interpret (pat, &buf, format, '\0'); + interpret (&c, pat, &buf, '\0'); - free (scratch1); - free (scratch2); + FcFormatContextDone (&c); return FcStrBufDone (&buf); }