int qspAutoConvertCompare(QSPVariant *v1, QSPVariant *v2)
{
	int res;
	if (v1->IsStr != v2->IsStr)
	{
		if (v2->IsStr)
		{
			if (qspIsCanConvertToNum(v2))
				qspConvertVariantTo(v2, QSP_FALSE);
			else
				qspConvertVariantTo(v1, QSP_TRUE);
		}
		else
		{
			if (qspIsCanConvertToNum(v1))
				qspConvertVariantTo(v1, QSP_FALSE);
			else
				qspConvertVariantTo(v2, QSP_TRUE);
		}
	}
	if (v1->IsStr)
		res = QSP_STRCOLL(QSP_PSTR(v1), QSP_PSTR(v2));
	else
		res = (QSP_PNUM(v1) > QSP_PNUM(v2) ? 1 : (QSP_PNUM(v1) < QSP_PNUM(v2) ? -1 : 0));
	return res;
}
void qspCopyVariant(QSPVariant *dest, QSPVariant *src)
{
	if (dest->IsStr = src->IsStr)
		QSP_PSTR(dest) = qspGetNewText(QSP_PSTR(src), -1);
	else
		QSP_PNUM(dest) = QSP_PNUM(src);
}
Beispiel #3
0
static void qspSetVar(QSP_CHAR *name, QSPVariant *val, QSP_CHAR op) {
  QSPVariant oldVal;
  QSPVar *var;
  int index;
  if (!(var = qspGetVarData(name, QSP_TRUE, &index)))
    return;
  if (op == QSP_EQUAL[0]) {
    if (qspConvertVariantTo(val, *name == QSP_STRCHAR[0])) {
      qspSetError(QSP_ERR_TYPEMISMATCH);
      return;
    }
    qspSetVarValueByReference(var, index, val);
  } else if (op == QSP_ADD[0]) {
    oldVal = qspGetVarValueByReference(var, index, *name == QSP_STRCHAR[0]);
    if (oldVal.IsStr && val->IsStr)
      QSP_STR(oldVal) = qspGetAddText(QSP_STR(oldVal), QSP_PSTR(val), -1, -1);
    else if (qspIsCanConvertToNum(&oldVal) && qspIsCanConvertToNum(val)) {
      qspConvertVariantTo(&oldVal, QSP_FALSE);
      qspConvertVariantTo(val, QSP_FALSE);
      QSP_NUM(oldVal) += QSP_PNUM(val);
      qspConvertVariantTo(&oldVal, *name == QSP_STRCHAR[0]);
    } else {
      if (!oldVal.IsStr) {
        qspSetError(QSP_ERR_TYPEMISMATCH);
        return;
      }
      qspConvertVariantTo(val, QSP_TRUE);
      QSP_STR(oldVal) = qspGetAddText(QSP_STR(oldVal), QSP_PSTR(val), -1, -1);
    }
    qspSetVarValueByReference(var, index, &oldVal);
    if (oldVal.IsStr)
      free(QSP_STR(oldVal));
  } else if (qspIsInList(QSP_SUB QSP_DIV QSP_MUL, op)) {
    if (qspConvertVariantTo(val, QSP_FALSE)) {
      qspSetError(QSP_ERR_TYPEMISMATCH);
      return;
    }
    oldVal = qspGetVarValueByReference(var, index, *name == QSP_STRCHAR[0]);
    if (qspConvertVariantTo(&oldVal, QSP_FALSE)) {
      qspSetError(QSP_ERR_TYPEMISMATCH);
      free(QSP_STR(oldVal));
      return;
    }
    if (op == QSP_SUB[0])
      QSP_NUM(oldVal) -= QSP_PNUM(val);
    else if (op == QSP_DIV[0]) {
      if (!QSP_PNUM(val)) {
        qspSetError(QSP_ERR_DIVBYZERO);
        return;
      }
      QSP_NUM(oldVal) /= QSP_PNUM(val);
    } else
      QSP_NUM(oldVal) *= QSP_PNUM(val);
    qspConvertVariantTo(&oldVal, *name == QSP_STRCHAR[0]);
    qspSetVarValueByReference(var, index, &oldVal);
    if (oldVal.IsStr)
      free(QSP_STR(oldVal));
  }
}
QSP_BOOL qspConvertVariantTo(QSPVariant *val, QSP_BOOL isToString)
{
	int num;
	QSP_CHAR buf[12];
	QSP_BOOL isValid;
	if (val->IsStr)
	{
		if (!isToString)
		{
			num = qspStrToNum(QSP_PSTR(val), &isValid);
			if (!isValid) return QSP_TRUE;
			free(QSP_PSTR(val));
			QSP_PNUM(val) = num;
			val->IsStr = QSP_FALSE;
		}
	}
	else if (isToString)
	{
		QSP_PSTR(val) = qspGetNewText(qspNumToStr(buf, QSP_PNUM(val)), -1);
		val->IsStr = QSP_TRUE;
	}
	return QSP_FALSE;
}
Beispiel #5
0
void qspApplyResult(QSPVar *varRes, QSPVariant *res) {
  QSP_CHAR *text;
  if (varRes->ValsCount) {
    if (text = varRes->Values[0].Str) {
      res->IsStr = QSP_TRUE;
      QSP_PSTR(res) = qspGetNewText(text, -1);
    } else {
      res->IsStr = QSP_FALSE;
      QSP_PNUM(res) = varRes->Values[0].Num;
    }
  } else {
    res->IsStr = QSP_TRUE;
    QSP_PSTR(res) = qspGetNewText(QSP_FMT(""), 0);
  }
}
Beispiel #6
0
int qspArrayPos(QSP_CHAR *varName, QSPVariant *val, int ind, QSP_BOOL isRegExp)
{
	int num, count;
	QSPVar *var;
	QSP_CHAR *str;
	regex_t *regExp;
	QSP_BOOL isString;
	if (!(var = qspVarReferenceWithType(varName, QSP_FALSE, &isString))) return -1;
	if (qspConvertVariantTo(val, isRegExp || isString))
	{
		qspSetError(QSP_ERR_TYPEMISMATCH);
		return -1;
	}
	if (isRegExp)
	{
		regExp = qspRegExpGetCompiled(QSP_PSTR(val));
		if (!regExp) return -1;
	}
	count = var->ValsCount;
	if (ind < 0)
		ind = 0;
	else if (ind > count)
		ind = count;
	while (ind <= count)
	{
		if (val->IsStr)
		{
			if (!(ind < count && (str = var->Values[ind].Str))) str = QSP_FMT("");
			if (isRegExp)
			{
				if (qspRegExpStrMatch(regExp, str)) return ind;
			}
			else if (!qspStrsComp(str, QSP_PSTR(val)))
				return ind;
		}
		else
		{
			num = (ind < count ? var->Values[ind].Num : 0);
			if (num == QSP_PNUM(val)) return ind;
		}
		++ind;
	}
	return -1;
}
Beispiel #7
0
void qspSetVarValueByReference(QSPVar *var, int ind, QSPVariant *val) {
  int count, oldCount = var->ValsCount;
  if (ind >= oldCount) {
    count = var->ValsCount = ind + 1;
    var->Values =
        (QSPVarValue *)realloc(var->Values, count * sizeof(QSPVarValue));
    while (oldCount < count) {
      var->Values[oldCount].Num = 0;
      var->Values[oldCount].Str = nullptr;
      ++oldCount;
    }
  }
  if (ind >= 0) {
    if (val->IsStr)
      var->Values[ind].Str =
          qspGetAddText(var->Values[ind].Str, QSP_PSTR(val), 0, -1);
    else
      var->Values[ind].Num = QSP_PNUM(val);
  }
}
Beispiel #8
0
int qspArrayPos(QSPVariant *args, int argsCount, QSP_BOOL isRegExp)
{
    int num, count, ind;
    QSPVar *var;
    QSPVariant *val;
    QSP_CHAR *str;
    OnigUChar *tempBeg, *tempEnd;
    regex_t *onigExp;
    OnigErrorInfo onigInfo;
    QSP_BOOL isString;
    if (qspConvertVariantTo(args, argsCount == 2))
    {
        qspSetError(QSP_ERR_TYPEMISMATCH);
        return -1;
    }
    if (argsCount == 2)
    {
        str = QSP_STR(args[0]);
        ind = 0;
        val = args + 1;
    }
    else
    {
        qspConvertVariantTo(args + 1, QSP_TRUE);
        str = QSP_STR(args[1]);
        ind = QSP_NUM(args[0]);
        val = args + 2;
        if (ind < 0) ind = 0;
    }
    if (!(var = qspVarReferenceWithType(str, QSP_FALSE, &isString))) return -1;
    if (qspConvertVariantTo(val, isRegExp || isString))
    {
        qspSetError(QSP_ERR_TYPEMISMATCH);
        return -1;
    }
    if (isRegExp)
    {
        tempBeg = (OnigUChar *)QSP_PSTR(val);
        tempEnd = (OnigUChar *)qspStrEnd(QSP_PSTR(val));
        if (onig_new(&onigExp, tempBeg, tempEnd, ONIG_OPTION_DEFAULT, QSP_ONIG_ENC, ONIG_SYNTAX_PERL_NG, &onigInfo))
        {
            qspSetError(QSP_ERR_INCORRECTREGEXP);
            return -1;
        }
    }
    count = var->ValsCount;
    if (ind > count) ind = count;
    while (ind <= count)
    {
        if (val->IsStr)
        {
            if (!(ind < count && (str = var->Values[ind].Str))) str = QSP_FMT("");
            if (isRegExp)
            {
                tempBeg = (OnigUChar *)str;
                tempEnd = (OnigUChar *)qspStrEnd(str);
                if (onig_match(onigExp, tempBeg, tempEnd, tempBeg, 0, ONIG_OPTION_NONE) == tempEnd - tempBeg)
                {
                    onig_free(onigExp);
                    return ind;
                }
            }
            else if (!qspStrsComp(str, QSP_PSTR(val)))
                return ind;
        }
        else
        {
            num = (ind < count ? var->Values[ind].Num : 0);
            if (num == QSP_PNUM(val)) return ind;
        }
        ++ind;
    }
    if (isRegExp) onig_free(onigExp);
    return -1;
}