static FcValueList *
FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding)
{
    FcValueList	*l;

    if (!e)
	return 0;
    l = (FcValueList *) malloc (sizeof (FcValueList));
    if (!l)
	return 0;
    FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList));
    if (FC_OP_GET_OP (e->op) == FcOpComma)
    {
	l->value = FcConfigEvaluate (p, e->u.tree.left);
	l->next = FcConfigValues (p, e->u.tree.right, binding);
    }
    else
    {
	l->value = FcConfigEvaluate (p, e);
	l->next = NULL;
    }
    l->binding = binding;
    if (l->value.type == FcTypeVoid)
    {
	FcValueList  *next = FcValueListNext(l);

	FcMemFree (FC_MEM_VALLIST, sizeof (FcValueList));
	free (l);
	l = next;
    }

    return l;
}
static FcValueList *
FcConfigMatchValueList (FcPattern	*p,
			FcTest		*t,
			FcValueList	*values)
{
    FcValueList	    *ret = 0;
    FcExpr	    *e = t->expr;
    FcValue	    value;
    FcValueList	    *v;

    while (e)
    {
	/* Compute the value of the match expression */
	if (FC_OP_GET_OP (e->op) == FcOpComma)
	{
	    value = FcConfigEvaluate (p, e->u.tree.left);
	    e = e->u.tree.right;
	}
	else
	{
	    value = FcConfigEvaluate (p, e);
	    e = 0;
	}

	for (v = values; v; v = FcValueListNext(v))
	{
	    /* Compare the pattern value to the match expression value */
	    if (FcConfigCompareValue (&v->value, t->op, &value))
	    {
		if (!ret)
		    ret = v;
	    }
	    else
	    {
		if (t->qual == FcQualAll)
		{
		    ret = 0;
		    break;
		}
	    }
	}
	FcValueDestroy (value);
    }
    return ret;
}
Exemple #3
0
void FcExprPrint(const FcExpr *expr) {
    if (!expr)
        printf("none");
    else
        switch (FC_OP_GET_OP(expr->op)) {
        case FcOpInteger:
            printf("%d", expr->u.ival);
            break;
        case FcOpDouble:
            printf("%g", expr->u.dval);
            break;
        case FcOpString:
            printf("\"%s\"", expr->u.sval);
            break;
        case FcOpMatrix:
            printf("[");
            FcExprPrint(expr->u.mexpr->xx);
            printf(" ");
            FcExprPrint(expr->u.mexpr->xy);
            printf("; ");
            FcExprPrint(expr->u.mexpr->yx);
            printf(" ");
            FcExprPrint(expr->u.mexpr->yy);
            printf("]");
            break;
        case FcOpRange:
            break;
        case FcOpBool:
            printf("%s", expr->u.bval ? "true" : "false");
            break;
        case FcOpCharSet:
            printf("charset\n");
            break;
        case FcOpLangSet:
            printf("langset:");
            FcLangSetPrint(expr->u.lval);
            printf("\n");
            break;
        case FcOpNil:
            printf("nil\n");
            break;
        case FcOpField:
            printf("%s ", FcObjectName(expr->u.name.object));
            switch ((int)expr->u.name.kind) {
            case FcMatchPattern:
                printf("(pattern) ");
                break;
            case FcMatchFont:
                printf("(font) ");
                break;
            }
            break;
        case FcOpConst:
            printf("%s", expr->u.constant);
            break;
        case FcOpQuest:
            FcExprPrint(expr->u.tree.left);
            printf(" quest ");
            FcExprPrint(expr->u.tree.right->u.tree.left);
            printf(" colon ");
            FcExprPrint(expr->u.tree.right->u.tree.right);
            break;
        case FcOpAssign:
        case FcOpAssignReplace:
        case FcOpPrependFirst:
        case FcOpPrepend:
        case FcOpAppend:
        case FcOpAppendLast:
        case FcOpOr:
        case FcOpAnd:
        case FcOpEqual:
        case FcOpNotEqual:
        case FcOpLess:
        case FcOpLessEqual:
        case FcOpMore:
        case FcOpMoreEqual:
        case FcOpContains:
        case FcOpListing:
        case FcOpNotContains:
        case FcOpPlus:
        case FcOpMinus:
        case FcOpTimes:
        case FcOpDivide:
        case FcOpComma:
            FcExprPrint(expr->u.tree.left);
            printf(" ");
            switch (FC_OP_GET_OP(expr->op)) {
            case FcOpAssign:
                printf("Assign");
                break;
            case FcOpAssignReplace:
                printf("AssignReplace");
                break;
            case FcOpPrependFirst:
                printf("PrependFirst");
                break;
            case FcOpPrepend:
                printf("Prepend");
                break;
            case FcOpAppend:
                printf("Append");
                break;
            case FcOpAppendLast:
                printf("AppendLast");
                break;
            case FcOpOr:
                printf("Or");
                break;
            case FcOpAnd:
                printf("And");
                break;
            case FcOpEqual:
                printf("Equal");
                FcOpFlagsPrint(expr->op);
                break;
            case FcOpNotEqual:
                printf("NotEqual");
                FcOpFlagsPrint(expr->op);
                break;
            case FcOpLess:
                printf("Less");
                break;
            case FcOpLessEqual:
                printf("LessEqual");
                break;
            case FcOpMore:
                printf("More");
                break;
            case FcOpMoreEqual:
                printf("MoreEqual");
                break;
            case FcOpContains:
                printf("Contains");
                break;
            case FcOpListing:
                printf("Listing");
                FcOpFlagsPrint(expr->op);
                break;
            case FcOpNotContains:
                printf("NotContains");
                break;
            case FcOpPlus:
                printf("Plus");
                break;
            case FcOpMinus:
                printf("Minus");
                break;
            case FcOpTimes:
                printf("Times");
                break;
            case FcOpDivide:
                printf("Divide");
                break;
            case FcOpComma:
                printf("Comma");
                break;
            default:
                break;
            }
            printf(" ");
            FcExprPrint(expr->u.tree.right);
            break;
        case FcOpNot:
            printf("Not ");
            FcExprPrint(expr->u.tree.left);
            break;
        case FcOpFloor:
            printf("Floor ");
            FcExprPrint(expr->u.tree.left);
            break;
        case FcOpCeil:
            printf("Ceil ");
            FcExprPrint(expr->u.tree.left);
            break;
        case FcOpRound:
            printf("Round ");
            FcExprPrint(expr->u.tree.left);
            break;
        case FcOpTrunc:
            printf("Trunc ");
            FcExprPrint(expr->u.tree.left);
            break;
        case FcOpInvalid:
            printf("Invalid");
            break;
        }
}
Exemple #4
0
void FcOpPrint(FcOp op_) {
    FcOp op = FC_OP_GET_OP(op_);

    switch (op) {
    case FcOpInteger:
        printf("Integer");
        break;
    case FcOpDouble:
        printf("Double");
        break;
    case FcOpString:
        printf("String");
        break;
    case FcOpMatrix:
        printf("Matrix");
        break;
    case FcOpRange:
        printf("Range");
        break;
    case FcOpBool:
        printf("Bool");
        break;
    case FcOpCharSet:
        printf("CharSet");
        break;
    case FcOpLangSet:
        printf("LangSet");
        break;
    case FcOpField:
        printf("Field");
        break;
    case FcOpConst:
        printf("Const");
        break;
    case FcOpAssign:
        printf("Assign");
        break;
    case FcOpAssignReplace:
        printf("AssignReplace");
        break;
    case FcOpPrepend:
        printf("Prepend");
        break;
    case FcOpPrependFirst:
        printf("PrependFirst");
        break;
    case FcOpAppend:
        printf("Append");
        break;
    case FcOpAppendLast:
        printf("AppendLast");
        break;
    case FcOpDelete:
        printf("Delete");
        break;
    case FcOpDeleteAll:
        printf("DeleteAll");
        break;
    case FcOpQuest:
        printf("Quest");
        break;
    case FcOpOr:
        printf("Or");
        break;
    case FcOpAnd:
        printf("And");
        break;
    case FcOpEqual:
        printf("Equal");
        FcOpFlagsPrint(op_);
        break;
    case FcOpNotEqual:
        printf("NotEqual");
        FcOpFlagsPrint(op_);
        break;
    case FcOpLess:
        printf("Less");
        break;
    case FcOpLessEqual:
        printf("LessEqual");
        break;
    case FcOpMore:
        printf("More");
        break;
    case FcOpMoreEqual:
        printf("MoreEqual");
        break;
    case FcOpContains:
        printf("Contains");
        break;
    case FcOpNotContains:
        printf("NotContains");
        break;
    case FcOpPlus:
        printf("Plus");
        break;
    case FcOpMinus:
        printf("Minus");
        break;
    case FcOpTimes:
        printf("Times");
        break;
    case FcOpDivide:
        printf("Divide");
        break;
    case FcOpNot:
        printf("Not");
        break;
    case FcOpNil:
        printf("Nil");
        break;
    case FcOpComma:
        printf("Comma");
        break;
    case FcOpFloor:
        printf("Floor");
        break;
    case FcOpCeil:
        printf("Ceil");
        break;
    case FcOpRound:
        printf("Round");
        break;
    case FcOpTrunc:
        printf("Trunc");
        break;
    case FcOpListing:
        printf("Listing");
        FcOpFlagsPrint(op_);
        break;
    case FcOpInvalid:
        printf("Invalid");
        break;
    }
}
static FcValue
FcConfigEvaluate (FcPattern *p, FcExpr *e)
{
    FcValue	v, vl, vr;
    FcResult	r;
    FcMatrix	*m;
    FcChar8     *str;
    FcOp	op = FC_OP_GET_OP (e->op);

    switch (op) {
    case FcOpInteger:
	v.type = FcTypeInteger;
	v.u.i = e->u.ival;
	break;
    case FcOpDouble:
	v.type = FcTypeDouble;
	v.u.d = e->u.dval;
	break;
    case FcOpString:
	v.type = FcTypeString;
	v.u.s = e->u.sval;
	v = FcValueSave (v);
	break;
    case FcOpMatrix:
	v.type = FcTypeMatrix;
	v.u.m = e->u.mval;
	v = FcValueSave (v);
	break;
    case FcOpCharSet:
	v.type = FcTypeCharSet;
	v.u.c = e->u.cval;
	v = FcValueSave (v);
	break;
    case FcOpLangSet:
	v.type = FcTypeLangSet;
	v.u.l = e->u.lval;
	v = FcValueSave (v);
	break;
    case FcOpBool:
	v.type = FcTypeBool;
	v.u.b = e->u.bval;
	break;
    case FcOpField:
	r = FcPatternObjectGet (p, e->u.object, 0, &v);
	if (r != FcResultMatch)
	    v.type = FcTypeVoid;
	v = FcValueSave (v);
	break;
    case FcOpConst:
	if (FcNameConstant (e->u.constant, &v.u.i))
	    v.type = FcTypeInteger;
	else
	    v.type = FcTypeVoid;
	break;
    case FcOpQuest:
	vl = FcConfigEvaluate (p, e->u.tree.left);
	if (vl.type == FcTypeBool)
	{
	    if (vl.u.b)
		v = FcConfigEvaluate (p, e->u.tree.right->u.tree.left);
	    else
		v = FcConfigEvaluate (p, e->u.tree.right->u.tree.right);
	}
	else
	    v.type = FcTypeVoid;
	FcValueDestroy (vl);
	break;
    case FcOpEqual:
    case FcOpNotEqual:
    case FcOpLess:
    case FcOpLessEqual:
    case FcOpMore:
    case FcOpMoreEqual:
    case FcOpContains:
    case FcOpNotContains:
    case FcOpListing:
	vl = FcConfigEvaluate (p, e->u.tree.left);
	vr = FcConfigEvaluate (p, e->u.tree.right);
	v.type = FcTypeBool;
	v.u.b = FcConfigCompareValue (&vl, e->op, &vr);
	FcValueDestroy (vl);
	FcValueDestroy (vr);
	break;	
    case FcOpOr:
    case FcOpAnd:
    case FcOpPlus:
    case FcOpMinus:
    case FcOpTimes:
    case FcOpDivide:
	vl = FcConfigEvaluate (p, e->u.tree.left);
	vr = FcConfigEvaluate (p, e->u.tree.right);
	vl = FcConfigPromote (vl, vr);
	vr = FcConfigPromote (vr, vl);
	if (vl.type == vr.type)
	{
	    switch (vl.type) {
	    case FcTypeDouble:
		switch (op) {
		case FcOpPlus:	
		    v.type = FcTypeDouble;
		    v.u.d = vl.u.d + vr.u.d;
		    break;
		case FcOpMinus:
		    v.type = FcTypeDouble;
		    v.u.d = vl.u.d - vr.u.d;
		    break;
		case FcOpTimes:
		    v.type = FcTypeDouble;
		    v.u.d = vl.u.d * vr.u.d;
		    break;
		case FcOpDivide:
		    v.type = FcTypeDouble;
		    v.u.d = vl.u.d / vr.u.d;
		    break;
		default:
		    v.type = FcTypeVoid;
		    break;
		}
		if (v.type == FcTypeDouble &&
		    v.u.d == (double) (int) v.u.d)
		{
		    v.type = FcTypeInteger;
		    v.u.i = (int) v.u.d;
		}
		break;
	    case FcTypeBool:
		switch (op) {
		case FcOpOr:
		    v.type = FcTypeBool;
		    v.u.b = vl.u.b || vr.u.b;
		    break;
		case FcOpAnd:
		    v.type = FcTypeBool;
		    v.u.b = vl.u.b && vr.u.b;
		    break;
		default:
		    v.type = FcTypeVoid;
		    break;
		}
		break;
	    case FcTypeString:
		switch (op) {
		case FcOpPlus:
		    v.type = FcTypeString;
		    str = FcStrPlus (vl.u.s, vr.u.s);
		    v.u.s = FcSharedStr (str);
		    FcStrFree (str);
			
		    if (!v.u.s)
			v.type = FcTypeVoid;
		    break;
		default:
		    v.type = FcTypeVoid;
		    break;
		}
		break;
	    case FcTypeMatrix:
		switch (op) {
		case FcOpTimes:
		    v.type = FcTypeMatrix;
		    m = malloc (sizeof (FcMatrix));
		    if (m)
		    {
			FcMemAlloc (FC_MEM_MATRIX, sizeof (FcMatrix));
			FcMatrixMultiply (m, vl.u.m, vr.u.m);
			v.u.m = m;
		    }
		    else
		    {
			v.type = FcTypeVoid;
		    }
		    break;
		default:
		    v.type = FcTypeVoid;
		    break;
		}
		break;
	    case FcTypeCharSet:
		switch (op) {
		case FcOpPlus:
		    v.type = FcTypeCharSet;
		    v.u.c = FcCharSetUnion (vl.u.c, vr.u.c);
		    if (!v.u.c)
			v.type = FcTypeVoid;
		    break;
		case FcOpMinus:
		    v.type = FcTypeCharSet;
		    v.u.c = FcCharSetSubtract (vl.u.c, vr.u.c);
		    if (!v.u.c)
			v.type = FcTypeVoid;
		    break;
		default:
		    v.type = FcTypeVoid;
		    break;
		}
		break;
	    case FcTypeLangSet:
		switch (op) {
		case FcOpPlus:
		    v.type = FcTypeLangSet;
		    v.u.l = FcLangSetUnion (vl.u.l, vr.u.l);
		    if (!v.u.l)
			v.type = FcTypeVoid;
		    break;
		case FcOpMinus:
		    v.type = FcTypeLangSet;
		    v.u.l = FcLangSetSubtract (vl.u.l, vr.u.l);
		    if (!v.u.l)
			v.type = FcTypeVoid;
		    break;
		default:
		    v.type = FcTypeVoid;
		    break;
		}
		break;
	    default:
		v.type = FcTypeVoid;
		break;
	    }
	}
	else
	    v.type = FcTypeVoid;
	FcValueDestroy (vl);
	FcValueDestroy (vr);
	break;
    case FcOpNot:
	vl = FcConfigEvaluate (p, e->u.tree.left);
	switch (vl.type) {
	case FcTypeBool:
	    v.type = FcTypeBool;
	    v.u.b = !vl.u.b;
	    break;
	default:
	    v.type = FcTypeVoid;
	    break;
	}
	FcValueDestroy (vl);
	break;
    case FcOpFloor:
	vl = FcConfigEvaluate (p, e->u.tree.left);
	switch (vl.type) {
	case FcTypeInteger:
	    v = vl;
	    break;
	case FcTypeDouble:
	    v.type = FcTypeInteger;
	    v.u.i = FcDoubleFloor (vl.u.d);
	    break;
	default:
	    v.type = FcTypeVoid;
	    break;
	}
	FcValueDestroy (vl);
	break;
    case FcOpCeil:
	vl = FcConfigEvaluate (p, e->u.tree.left);
	switch (vl.type) {
	case FcTypeInteger:
	    v = vl;
	    break;
	case FcTypeDouble:
	    v.type = FcTypeInteger;
	    v.u.i = FcDoubleCeil (vl.u.d);
	    break;
	default:
	    v.type = FcTypeVoid;
	    break;
	}
	FcValueDestroy (vl);
	break;
    case FcOpRound:
	vl = FcConfigEvaluate (p, e->u.tree.left);
	switch (vl.type) {
	case FcTypeInteger:
	    v = vl;
	    break;
	case FcTypeDouble:
	    v.type = FcTypeInteger;
	    v.u.i = FcDoubleRound (vl.u.d);
	    break;
	default:
	    v.type = FcTypeVoid;
	    break;
	}
	FcValueDestroy (vl);
	break;
    case FcOpTrunc:
	vl = FcConfigEvaluate (p, e->u.tree.left);
	switch (vl.type) {
	case FcTypeInteger:
	    v = vl;
	    break;
	case FcTypeDouble:
	    v.type = FcTypeInteger;
	    v.u.i = FcDoubleTrunc (vl.u.d);
	    break;
	default:
	    v.type = FcTypeVoid;
	    break;
	}
	FcValueDestroy (vl);
	break;
    default:
	v.type = FcTypeVoid;
	break;
    }
    return v;
}
FcBool
FcConfigCompareValue (const FcValue	*left_o,
		      FcOp		op_,
		      const FcValue	*right_o)
{
    FcValue	left = FcValueCanonicalize(left_o);
    FcValue	right = FcValueCanonicalize(right_o);
    FcBool	ret = FcFalse;
    FcOp	op = FC_OP_GET_OP (op_);
    int		flags = FC_OP_GET_FLAGS (op_);

    left = FcConfigPromote (left, right);
    right = FcConfigPromote (right, left);
    if (left.type == right.type)
    {
	switch (left.type) {
	case FcTypeInteger:
	    break;	/* FcConfigPromote prevents this from happening */
	case FcTypeDouble:
	    switch (op) {
	    case FcOpEqual:
	    case FcOpContains:
	    case FcOpListing:
		ret = left.u.d == right.u.d;
		break;
	    case FcOpNotEqual:
	    case FcOpNotContains:
		ret = left.u.d != right.u.d;
		break;
	    case FcOpLess:
		ret = left.u.d < right.u.d;
		break;
	    case FcOpLessEqual:
		ret = left.u.d <= right.u.d;
		break;
	    case FcOpMore:
		ret = left.u.d > right.u.d;
		break;
	    case FcOpMoreEqual:
		ret = left.u.d >= right.u.d;
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeBool:
	    switch (op) {
	    case FcOpEqual:
	    case FcOpContains:
	    case FcOpListing:
		ret = left.u.b == right.u.b;
		break;
	    case FcOpNotEqual:
	    case FcOpNotContains:
		ret = left.u.b != right.u.b;
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeString:
	    switch (op) {
	    case FcOpEqual:
	    case FcOpListing:
		if (flags & FcOpFlagIgnoreBlanks)
		    ret = FcStrCmpIgnoreBlanksAndCase (left.u.s, right.u.s) == 0;
		else
		    ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0;
		break;
	    case FcOpContains:
		ret = FcStrStrIgnoreCase (left.u.s, right.u.s) != 0;
		break;
	    case FcOpNotEqual:
		if (flags & FcOpFlagIgnoreBlanks)
		    ret = FcStrCmpIgnoreBlanksAndCase (left.u.s, right.u.s) != 0;
		else
		    ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0;
		break;
	    case FcOpNotContains:
		ret = FcStrStrIgnoreCase (left.u.s, right.u.s) == 0;
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeMatrix:
	    switch (op) {
	    case FcOpEqual:
	    case FcOpContains:
	    case FcOpListing:
		ret = FcMatrixEqual (left.u.m, right.u.m);
		break;
	    case FcOpNotEqual:
	    case FcOpNotContains:
		ret = !FcMatrixEqual (left.u.m, right.u.m);
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeCharSet:
	    switch (op) {
	    case FcOpContains:
	    case FcOpListing:
		/* left contains right if right is a subset of left */
		ret = FcCharSetIsSubset (right.u.c, left.u.c);
		break;
	    case FcOpNotContains:
		/* left contains right if right is a subset of left */
		ret = !FcCharSetIsSubset (right.u.c, left.u.c);
		break;
	    case FcOpEqual:
		ret = FcCharSetEqual (left.u.c, right.u.c);
		break;
	    case FcOpNotEqual:
		ret = !FcCharSetEqual (left.u.c, right.u.c);
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeLangSet:
	    switch (op) {
	    case FcOpContains:
	    case FcOpListing:
		ret = FcLangSetContains (left.u.l, right.u.l);
		break;
	    case FcOpNotContains:
		ret = !FcLangSetContains (left.u.l, right.u.l);
		break;
	    case FcOpEqual:
		ret = FcLangSetEqual (left.u.l, right.u.l);
		break;
	    case FcOpNotEqual:
		ret = !FcLangSetEqual (left.u.l, right.u.l);
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeVoid:
	    switch (op) {
	    case FcOpEqual:
	    case FcOpContains:
	    case FcOpListing:
		ret = FcTrue;
		break;
	    default:
		break;
	    }
	    break;
	case FcTypeFTFace:
	    switch (op) {
	    case FcOpEqual:
	    case FcOpContains:
	    case FcOpListing:
		ret = left.u.f == right.u.f;
		break;
	    case FcOpNotEqual:
	    case FcOpNotContains:
		ret = left.u.f != right.u.f;
		break;
	    default:
		break;
	    }
	    break;
	}
    }
    else
    {
	if (op == FcOpNotEqual || op == FcOpNotContains)
	    ret = FcTrue;
    }
    return ret;
}