]> git.wh0rd.org - fontconfig.git/commitdiff
[fcformat] Implement 'cescape', 'shescape', and 'xmlescape' converters
authorBehdad Esfahbod <behdad@behdad.org>
Tue, 10 Feb 2009 09:44:54 +0000 (04:44 -0500)
committerBehdad Esfahbod <behdad@behdad.org>
Sun, 15 Feb 2009 21:40:28 +0000 (13:40 -0800)
src/fcformat.c

index 9250ea89bff98301ded3276638ee7c22d1d717eb..238f8d2d93afaf98f54dd7c331faa2e46662f852 100644 (file)
@@ -31,6 +31,7 @@
 /*
  * 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)
@@ -414,18 +415,83 @@ interpret_cond (FcFormatContext *c,
     return FcTrue;
 }
 
+static FcChar8 *
+cescape (const FcChar8 *str)
+{
+    FcStrBuf buf;
+    FcChar8         buf_static[8192];
+
+    FcStrBufInit (&buf, buf_static, sizeof (buf_static));
+    while(*str)
+    {
+       switch (*str)
+       {
+       case '\\':
+       case '"':
+           FcStrBufChar (&buf, '\\');
+           break;
+       }
+       FcStrBufChar (&buf, *str++);
+    }
+    return FcStrBufDone (&buf);
+}
+
+static FcChar8 *
+shescape (const FcChar8 *str)
+{
+    FcStrBuf buf;
+    FcChar8         buf_static[8192];
+
+    FcStrBufInit (&buf, buf_static, sizeof (buf_static));
+    FcStrBufChar (&buf, '\'');
+    while(*str)
+    {
+       if (*str == '\'')
+           FcStrBufString (&buf, (const FcChar8 *) "'\\''");
+       else
+           FcStrBufChar (&buf, *str);
+       str++;
+    }
+    FcStrBufChar (&buf, '\'');
+    return FcStrBufDone (&buf);
+}
+
+static FcChar8 *
+xmlescape (const FcChar8 *str)
+{
+    FcStrBuf buf;
+    FcChar8         buf_static[8192];
+
+    FcStrBufInit (&buf, buf_static, sizeof (buf_static));
+    while(*str)
+    {
+       switch (*str)
+       {
+       case '&': FcStrBufString (&buf, (const FcChar8 *) "&amp;"); break;
+       case '<': FcStrBufString (&buf, (const FcChar8 *) "&lt;");  break;
+       case '>': FcStrBufString (&buf, (const FcChar8 *) "&gt;");  break;
+       default:  FcStrBufChar   (&buf, *str);                      break;
+       }
+       str++;
+    }
+    return FcStrBufDone (&buf);
+}
+
 static FcChar8 *
 convert (FcFormatContext *c,
         const FcChar8   *str)
 {
     if (!read_word (c))
        return NULL;
-    else if (0 == strcmp ((const char *) c->word, "downcase"))
-       return FcStrDowncase (str);
-    else if (0 == strcmp ((const char *) c->word, "basename"))
-       return FcStrBasename (str);
-    else if (0 == strcmp ((const char *) c->word, "dirname"))
-       return FcStrDirname (str);
+#define CONVERTER(name, func) \
+    else if (0 == strcmp ((const char *) c->word, name))\
+       return func (str)
+    CONVERTER ("downcase",  FcStrDowncase);
+    CONVERTER ("basename",  FcStrBasename);
+    CONVERTER ("dirname",   FcStrDirname);
+    CONVERTER ("cescape",   cescape);
+    CONVERTER ("shescape",  shescape);
+    CONVERTER ("xmlescape", xmlescape);
 
     message ("unknown converter \"%s\"",
             c->word);
@@ -578,17 +644,16 @@ interpret_expr (FcFormatContext *c,
 FcChar8 *
 FcPatternFormat (FcPattern *pat, const FcChar8 *format)
 {
-    FcStrBuf buf;
+    FcStrBuf        buf;
+    FcChar8         buf_static[8192];
     FcFormatContext c;
-    FcBool ret;
+    FcBool          ret;
 
-    FcStrBufInit (&buf, 0, 0);
+    FcStrBufInit (&buf, buf_static, sizeof (buf_static));
     if (!FcFormatContextInit (&c, format))
        return NULL;
 
     ret = interpret_expr (&c, pat, &buf, '\0');
-    if (buf.failed)
-       ret = FcFalse;
 
     FcFormatContextDone (&c);
     if (ret)