]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcxml.c
Bug 44826 - <alias> must contain only a single <family>
[fontconfig.git] / src / fcxml.c
index 4d07f9d6cdfec1d76628163baa83c5330ec1fa50..ff30b7bbdaff398971803913619b757ae24a83df 100644 (file)
@@ -145,6 +145,18 @@ FcExprCreateCharSet (FcConfig *config, FcCharSet *charset)
     return e;
 }
 
+static FcExpr *
+FcExprCreateLangSet (FcConfig *config, FcLangSet *langset)
+{
+    FcExpr *e = FcConfigAllocExpr (config);
+    if (e)
+    {
+       e->op = FcOpLangSet;
+       e->u.lval = FcLangSetCopy (langset);
+    }
+    return e;
+}
+
 static FcExpr *
 FcExprCreateField (FcConfig *config, const char *field)
 {
@@ -202,6 +214,9 @@ FcExprDestroy (FcExpr *e)
     case FcOpCharSet:
        FcCharSetDestroy (e->u.cval);
        break;
+    case FcOpLangSet:
+       FcLangSetDestroy (e->u.lval);
+       break;
     case FcOpBool:
        break;
     case FcOpField:
@@ -294,6 +309,7 @@ typedef enum _FcElement {
     FcElementRange,
     FcElementBool,
     FcElementCharSet,
+    FcElementLangSet,
     FcElementName,
     FcElementConst,
     FcElementOr,
@@ -356,6 +372,7 @@ static const struct {
     { "range",         FcElementRange },
     { "bool",          FcElementBool },
     { "charset",       FcElementCharSet },
+    { "langset",       FcElementLangSet },
     { "name",          FcElementName },
     { "const",         FcElementConst },
     { "or",            FcElementOr },
@@ -420,6 +437,7 @@ typedef enum _FcVStackTag {
     FcVStackRange,
     FcVStackBool,
     FcVStackCharSet,
+    FcVStackLangSet,
 
     FcVStackTest,
     FcVStackExpr,
@@ -439,6 +457,7 @@ typedef struct _FcVStack {
        FcRange         range;
        FcBool          bool_;
        FcCharSet       *charset;
+       FcLangSet       *langset;
 
        FcTest          *test;
        FcQual          qual;
@@ -571,6 +590,9 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type)
     case FcOpCharSet:
        FcTypecheckValue (parse, FcTypeCharSet, type);
        break;
+    case FcOpLangSet:
+       FcTypecheckValue (parse, FcTypeLangSet, type);
+       break;
     case FcOpNil:
        break;
     case FcOpField:
@@ -798,6 +820,20 @@ FcVStackPushCharSet (FcConfigParse *parse, FcCharSet *charset)
     return FcTrue;
 }
 
+static FcBool
+FcVStackPushLangSet (FcConfigParse *parse, FcLangSet *langset)
+{
+    FcVStack   *vstack;
+    if (!langset)
+       return FcFalse;
+    vstack = FcVStackCreateAndPush (parse);
+    if (!vstack)
+       return FcFalse;
+    vstack->u.langset = langset;
+    vstack->tag = FcVStackLangSet;
+    return FcTrue;
+}
+
 static FcBool
 FcVStackPushTest (FcConfigParse *parse, FcTest *test)
 {
@@ -895,6 +931,9 @@ FcVStackPopAndDestroy (FcConfigParse *parse)
     case FcVStackCharSet:
        FcCharSetDestroy (vstack->u.charset);
        break;
+    case FcVStackLangSet:
+       FcLangSetDestroy (vstack->u.langset);
+       break;
     case FcVStackTest:
        FcTestDestroy (vstack->u.test);
        break;
@@ -1109,10 +1148,13 @@ FcParseBlank (FcConfigParse *parse)
                goto bail;
            break;
        case FcVStackRange:
-           for (i = v->u.range.begin; i <= v->u.range.end; i++)
+           if (v->u.range.begin <= v->u.range.end)
            {
-               if (!FcBlanksAdd (parse->config->blanks, i))
-                   goto bail;
+             for (i = v->u.range.begin; i <= v->u.range.end; i++)
+             {
+                 if (!FcBlanksAdd (parse->config->blanks, i))
+                     goto bail;
+             }
            }
            break;
        default:
@@ -1389,14 +1431,17 @@ FcParseCharSet (FcConfigParse *parse)
                n++;
            break;
        case FcVStackRange:
-           for (i = vstack->u.range.begin; i <= vstack->u.range.end; i++)
+           if (vstack->u.range.begin <= vstack->u.range.end)
            {
-               if (!FcCharSetAddChar (charset, i))
-               {
-                   FcConfigMessage (parse, FcSevereWarning, "invalid character: 0x%04x", i);
-               }
-               else
-                   n++;
+             for (i = vstack->u.range.begin; i <= vstack->u.range.end; i++)
+             {
+                 if (!FcCharSetAddChar (charset, i))
+                 {
+                     FcConfigMessage (parse, FcSevereWarning, "invalid character: 0x%04x", i);
+                 }
+                 else
+                     n++;
+             }
            }
            break;
        default:
@@ -1411,6 +1456,36 @@ FcParseCharSet (FcConfigParse *parse)
            FcCharSetDestroy (charset);
 }
 
+static void
+FcParseLangSet (FcConfigParse *parse)
+{
+    FcVStack   *vstack;
+    FcLangSet  *langset = FcLangSetCreate ();
+    int n = 0;
+
+    while ((vstack = FcVStackPeek (parse)))
+    {
+       switch (vstack->tag) {
+       case FcVStackString:
+           if (!FcLangSetAdd (langset, vstack->u.string))
+           {
+               FcConfigMessage (parse, FcSevereWarning, "invalid langset: %s", vstack->u.string);
+           }
+           else
+               n++;
+           break;
+       default:
+               FcConfigMessage (parse, FcSevereError, "invalid element in langset");
+               break;
+       }
+       FcVStackPopAndDestroy (parse);
+    }
+    if (n > 0)
+           FcVStackPushLangSet (parse, langset);
+    else
+           FcLangSetDestroy (langset);
+}
+
 static FcBool
 FcConfigLexBinding (FcConfigParse   *parse,
                    const FcChar8   *binding_string,
@@ -1665,6 +1740,9 @@ FcPopExpr (FcConfigParse *parse)
     case FcVStackCharSet:
        expr = FcExprCreateCharSet (parse->config, vstack->u.charset);
        break;
+    case FcVStackLangSet:
+       expr = FcExprCreateLangSet (parse->config, vstack->u.langset);
+       break;
     case FcVStackTest:
        break;
     case FcVStackExpr:
@@ -2086,6 +2164,11 @@ FcPopValue (FcConfigParse *parse)
        if (value.u.c)
            value.type = FcTypeCharSet;
        break;
+    case FcVStackLangSet:
+       value.u.l = FcLangSetCopy (vstack->u.langset);
+       if (value.u.l)
+           value.type = FcTypeLangSet;
+       break;
     default:
        FcConfigMessage (parse, FcSevereWarning, "unknown pattern element %d",
                         vstack->tag);
@@ -2360,6 +2443,9 @@ FcEndElement(void *userData, const XML_Char *name)
     case FcElementCharSet:
        FcParseCharSet (parse);
        break;
+    case FcElementLangSet:
+       FcParseLangSet (parse);
+       break;
     case FcElementSelectfont:
        break;
     case FcElementAcceptfont: