We are currently experiencing downtime impacting viewing & cloning the Mesa repo, and some GitLab pages returning 503. Please see #freedesktop on IRC for more updates.

Commit ca60d2b5 authored by Keith Packard's avatar Keith Packard

Polite typechecking for test and edit expressions. Helps catch errors in

    the font configuration.
parent 59e149e7
2005-01-28 Keith Packard <keithp@keithp.com>
* src/fcint.h:
* src/fcname.c: (FcNameBool):
* src/fcxml.c: (FcTypeName), (FcTypecheckValue), (FcTypecheckExpr),
(FcTestCreate), (FcEditCreate), (FcConfigLexBool), (FcParseBool),
(FcParseAlias), (FcParseInclude), (FcParseTest), (FcParseEdit):
Polite typechecking for test and edit expressions. Helps
catch errors in the font configuration.
2005-01-15 Alan Coopersmith <alan.coopersmith@sun.com> 2005-01-15 Alan Coopersmith <alan.coopersmith@sun.com>
reviewed by: Keith Packard <keithp@keithp.com> reviewed by: Keith Packard <keithp@keithp.com>
......
...@@ -609,13 +609,6 @@ FcConfigerror (char *fmt, ...); ...@@ -609,13 +609,6 @@ FcConfigerror (char *fmt, ...);
char * char *
FcConfigSaveField (const char *field); FcConfigSaveField (const char *field);
FcTest *
FcTestCreate (FcMatchKind kind,
FcQual qual,
const FcChar8 *field,
FcOp compare,
FcExpr *expr);
void void
FcTestDestroy (FcTest *test); FcTestDestroy (FcTest *test);
...@@ -649,9 +642,6 @@ FcExprCreateOp (FcExpr *left, FcOp op, FcExpr *right); ...@@ -649,9 +642,6 @@ FcExprCreateOp (FcExpr *left, FcOp op, FcExpr *right);
void void
FcExprDestroy (FcExpr *e); FcExprDestroy (FcExpr *e);
FcEdit *
FcEditCreate (const char *field, FcOp op, FcExpr *expr, FcValueBinding binding);
void void
FcEditDestroy (FcEdit *e); FcEditDestroy (FcEdit *e);
...@@ -697,7 +687,7 @@ FcListPatternMatchAny (const FcPattern *p, ...@@ -697,7 +687,7 @@ FcListPatternMatchAny (const FcPattern *p,
/* fcname.c */ /* fcname.c */
FcBool FcBool
FcNameBool (FcChar8 *v, FcBool *result); FcNameBool (const FcChar8 *v, FcBool *result);
/* fcpat.c */ /* fcpat.c */
void void
......
...@@ -274,7 +274,7 @@ FcNameConstant (FcChar8 *string, int *result) ...@@ -274,7 +274,7 @@ FcNameConstant (FcChar8 *string, int *result)
} }
FcBool FcBool
FcNameBool (FcChar8 *v, FcBool *result) FcNameBool (const FcChar8 *v, FcBool *result)
{ {
char c0, c1; char c0, c1;
......
...@@ -42,27 +42,6 @@ ...@@ -42,27 +42,6 @@
#undef STRICT #undef STRICT
#endif #endif
FcTest *
FcTestCreate (FcMatchKind kind,
FcQual qual,
const FcChar8 *field,
FcOp compare,
FcExpr *expr)
{
FcTest *test = (FcTest *) malloc (sizeof (FcTest));
if (test)
{
FcMemAlloc (FC_MEM_TEST, sizeof (FcTest));
test->next = 0;
test->kind = kind;
test->qual = qual;
test->field = (char *) FcStrCopy (field);
test->op = compare;
test->expr = expr;
}
return test;
}
void void
FcTestDestroy (FcTest *test) FcTestDestroy (FcTest *test)
...@@ -269,22 +248,6 @@ FcExprDestroy (FcExpr *e) ...@@ -269,22 +248,6 @@ FcExprDestroy (FcExpr *e)
free (e); free (e);
} }
FcEdit *
FcEditCreate (const char *field, FcOp op, FcExpr *expr, FcValueBinding binding)
{
FcEdit *e = (FcEdit *) malloc (sizeof (FcEdit));
if (e)
{
e->next = 0;
e->field = field; /* already saved in grammar */
e->op = op;
e->expr = expr;
e->binding = binding;
}
return e;
}
void void
FcEditDestroy (FcEdit *e) FcEditDestroy (FcEdit *e)
{ {
...@@ -528,6 +491,187 @@ FcConfigMessage (FcConfigParse *parse, FcConfigSeverity severe, char *fmt, ...) ...@@ -528,6 +491,187 @@ FcConfigMessage (FcConfigParse *parse, FcConfigSeverity severe, char *fmt, ...)
va_end (args); va_end (args);
} }
static char *
FcTypeName (FcType type)
{
switch (type) {
case FcTypeVoid:
return "void";
case FcTypeInteger:
case FcTypeDouble:
return "number";
case FcTypeString:
return "string";
case FcTypeBool:
return "bool";
case FcTypeMatrix:
return "matrix";
case FcTypeCharSet:
return "charset";
case FcTypeFTFace:
return "FT_Face";
case FcTypeLangSet:
return "langset";
default:
return "unknown";
}
}
static void
FcTypecheckValue (FcConfigParse *parse, FcType value, FcType type)
{
if (value == FcTypeInteger)
value = FcTypeDouble;
if (type == FcTypeInteger)
type = FcTypeDouble;
if (value != type)
{
if ((value == FcTypeLangSet && type == FcTypeString) ||
(value == FcTypeString && type == FcTypeLangSet))
return;
FcConfigMessage (parse, FcSevereWarning, "saw %s, expected %s",
FcTypeName (value), FcTypeName (type));
}
}
static void
FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type)
{
const FcObjectType *o;
const FcConstant *c;
switch (expr->op) {
case FcOpInteger:
case FcOpDouble:
FcTypecheckValue (parse, FcTypeDouble, type);
break;
case FcOpString:
FcTypecheckValue (parse, FcTypeString, type);
break;
case FcOpMatrix:
FcTypecheckValue (parse, FcTypeMatrix, type);
break;
case FcOpBool:
FcTypecheckValue (parse, FcTypeBool, type);
break;
case FcOpCharSet:
FcTypecheckValue (parse, FcTypeCharSet, type);
break;
case FcOpNil:
break;
case FcOpField:
o = FcNameGetObjectType (expr->u.field);
if (o)
FcTypecheckValue (parse, o->type, type);
break;
case FcOpConst:
c = FcNameGetConstant (expr->u.constant);
if (c)
{
o = FcNameGetObjectType (c->object);
if (o)
FcTypecheckValue (parse, o->type, type);
}
break;
case FcOpQuest:
FcTypecheckExpr (parse, expr->u.tree.left, FcTypeBool);
FcTypecheckExpr (parse, expr->u.tree.right->u.tree.left, type);
FcTypecheckExpr (parse, expr->u.tree.right->u.tree.right, type);
break;
case FcOpAssign:
case FcOpAssignReplace:
break;
case FcOpEqual:
case FcOpNotEqual:
case FcOpLess:
case FcOpLessEqual:
case FcOpMore:
case FcOpMoreEqual:
case FcOpContains:
case FcOpNotContains:
case FcOpListing:
FcTypecheckValue (parse, FcTypeBool, type);
break;
case FcOpComma:
case FcOpOr:
case FcOpAnd:
case FcOpPlus:
case FcOpMinus:
case FcOpTimes:
case FcOpDivide:
FcTypecheckExpr (parse, expr->u.tree.left, type);
FcTypecheckExpr (parse, expr->u.tree.right, type);
break;
case FcOpNot:
FcTypecheckValue (parse, FcTypeBool, type);
FcTypecheckExpr (parse, expr->u.tree.left, FcTypeBool);
break;
case FcOpFloor:
case FcOpCeil:
case FcOpRound:
case FcOpTrunc:
FcTypecheckValue (parse, FcTypeDouble, type);
FcTypecheckExpr (parse, expr->u.tree.left, FcTypeDouble);
break;
default:
break;
}
}
static FcTest *
FcTestCreate (FcConfigParse *parse,
FcMatchKind kind,
FcQual qual,
const FcChar8 *field,
FcOp compare,
FcExpr *expr)
{
FcTest *test = (FcTest *) malloc (sizeof (FcTest));
if (test)
{
const FcObjectType *o;
FcMemAlloc (FC_MEM_TEST, sizeof (FcTest));
test->next = 0;
test->kind = kind;
test->qual = qual;
test->field = (char *) FcStrCopy (field);
test->op = compare;
test->expr = expr;
o = FcNameGetObjectType (test->field);
if (o)
FcTypecheckExpr (parse, expr, o->type);
}
return test;
}
static FcEdit *
FcEditCreate (FcConfigParse *parse,
const char *field,
FcOp op,
FcExpr *expr,
FcValueBinding binding)
{
FcEdit *e = (FcEdit *) malloc (sizeof (FcEdit));
if (e)
{
const FcObjectType *o;
e->next = 0;
e->field = field; /* already saved in grammar */
e->op = op;
e->expr = expr;
e->binding = binding;
o = FcNameGetObjectType (e->field);
if (o)
FcTypecheckExpr (parse, expr, o->type);
}
return e;
}
static void static void
FcVStackPush (FcConfigParse *parse, FcVStack *vstack) FcVStackPush (FcConfigParse *parse, FcVStack *vstack)
{ {
...@@ -1091,15 +1235,14 @@ FcParseMatrix (FcConfigParse *parse) ...@@ -1091,15 +1235,14 @@ FcParseMatrix (FcConfigParse *parse)
} }
static FcBool static FcBool
FcConfigLexBool (const FcChar8 *bool) FcConfigLexBool (FcConfigParse *parse, const FcChar8 *bool)
{ {
if (*bool == 't' || *bool == 'T') FcBool result = FcFalse;
return FcTrue;
if (*bool == 'y' || *bool == 'Y') if (!FcNameBool (bool, &result))
return FcTrue; FcConfigMessage (parse, FcSevereWarning, "\"%s\" is not known boolean",
if (*bool == '1') bool);
return FcTrue; return result;
return FcFalse;
} }
static void static void
...@@ -1115,7 +1258,7 @@ FcParseBool (FcConfigParse *parse) ...@@ -1115,7 +1258,7 @@ FcParseBool (FcConfigParse *parse)
FcConfigMessage (parse, FcSevereError, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
return; return;
} }
FcVStackPushBool (parse, FcConfigLexBool (s)); FcVStackPushBool (parse, FcConfigLexBool (parse, s));
FcStrFree (s); FcStrFree (s);
} }
...@@ -1247,7 +1390,8 @@ FcParseAlias (FcConfigParse *parse) ...@@ -1247,7 +1390,8 @@ FcParseAlias (FcConfigParse *parse)
} }
if (prefer) if (prefer)
{ {
edit = FcEditCreate (FcConfigSaveField ("family"), edit = FcEditCreate (parse,
FcConfigSaveField ("family"),
FcOpPrepend, FcOpPrepend,
prefer, prefer,
FcValueBindingWeak); FcValueBindingWeak);
...@@ -1259,7 +1403,8 @@ FcParseAlias (FcConfigParse *parse) ...@@ -1259,7 +1403,8 @@ FcParseAlias (FcConfigParse *parse)
if (accept) if (accept)
{ {
next = edit; next = edit;
edit = FcEditCreate (FcConfigSaveField ("family"), edit = FcEditCreate (parse,
FcConfigSaveField ("family"),
FcOpAppend, FcOpAppend,
accept, accept,
FcValueBindingWeak); FcValueBindingWeak);
...@@ -1271,7 +1416,8 @@ FcParseAlias (FcConfigParse *parse) ...@@ -1271,7 +1416,8 @@ FcParseAlias (FcConfigParse *parse)
if (def) if (def)
{ {
next = edit; next = edit;
edit = FcEditCreate (FcConfigSaveField ("family"), edit = FcEditCreate (parse,
FcConfigSaveField ("family"),
FcOpAppendLast, FcOpAppendLast,
def, def,
FcValueBindingWeak); FcValueBindingWeak);
...@@ -1282,7 +1428,7 @@ FcParseAlias (FcConfigParse *parse) ...@@ -1282,7 +1428,7 @@ FcParseAlias (FcConfigParse *parse)
} }
if (edit) if (edit)
{ {
test = FcTestCreate (FcMatchPattern, test = FcTestCreate (parse, FcMatchPattern,
FcQualAny, FcQualAny,
(FcChar8 *) FC_FAMILY, (FcChar8 *) FC_FAMILY,
FcOpEqual, FcOpEqual,
...@@ -1437,7 +1583,7 @@ FcParseInclude (FcConfigParse *parse) ...@@ -1437,7 +1583,7 @@ FcParseInclude (FcConfigParse *parse)
return; return;
} }
i = FcConfigGetAttribute (parse, "ignore_missing"); i = FcConfigGetAttribute (parse, "ignore_missing");
if (i && FcConfigLexBool ((FcChar8 *) i) == FcTrue) if (i && FcConfigLexBool (parse, (FcChar8 *) i) == FcTrue)
ignore_missing = FcTrue; ignore_missing = FcTrue;
if (!FcConfigParseAndLoad (parse->config, s, !ignore_missing)) if (!FcConfigParseAndLoad (parse->config, s, !ignore_missing))
parse->error = FcTrue; parse->error = FcTrue;
...@@ -1553,7 +1699,7 @@ FcParseTest (FcConfigParse *parse) ...@@ -1553,7 +1699,7 @@ FcParseTest (FcConfigParse *parse)
FcConfigMessage (parse, FcSevereWarning, "missing test expression"); FcConfigMessage (parse, FcSevereWarning, "missing test expression");
return; return;
} }
test = FcTestCreate (kind, qual, name, compare, expr); test = FcTestCreate (parse, kind, qual, name, compare, expr);
if (!test) if (!test)
{ {
FcConfigMessage (parse, FcSevereError, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
...@@ -1626,7 +1772,7 @@ FcParseEdit (FcConfigParse *parse) ...@@ -1626,7 +1772,7 @@ FcParseEdit (FcConfigParse *parse)
} }
} }
expr = FcPopBinary (parse, FcOpComma); expr = FcPopBinary (parse, FcOpComma);
edit = FcEditCreate ((char *) FcStrCopy (name), mode, expr, binding); edit = FcEditCreate (parse, (char *) FcStrCopy (name), mode, expr, binding);
if (!edit) if (!edit)
{ {
FcConfigMessage (parse, FcSevereError, "out of memory"); FcConfigMessage (parse, FcSevereError, "out of memory");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment