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; }
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_CHAR *qspFormatText(QSP_CHAR *txt, QSP_BOOL canReturnSelf) { QSPVariant val; QSP_CHAR *newTxt, *lPos, *rPos; int oldRefreshCount, len, txtLen, oldTxtLen, bufSize; if (qspGetVarNumValue(QSP_FMT("DISABLESUBEX"))) { if (canReturnSelf) return txt; return qspGetNewText(txt, -1); } lPos = qspStrStr(txt, QSP_LSUBEX); if (!lPos) { if (canReturnSelf) return txt; return qspGetNewText(txt, -1); } bufSize = 256; newTxt = (QSP_CHAR *)malloc(bufSize * sizeof(QSP_CHAR)); txtLen = oldTxtLen = 0; oldRefreshCount = qspRefreshCount; do { len = (int)(lPos - txt); if ((txtLen += len) >= bufSize) { bufSize = txtLen + 128; newTxt = (QSP_CHAR *)realloc(newTxt, bufSize * sizeof(QSP_CHAR)); } qspStrNCopy(newTxt + oldTxtLen, txt, len); oldTxtLen = txtLen; txt = lPos + QSP_LEN(QSP_LSUBEX); rPos = qspStrPos(txt, QSP_RSUBEX, QSP_FALSE); if (!rPos) { qspSetError(QSP_ERR_BRACKNOTFOUND); free(newTxt); return 0; } *rPos = 0; val = qspExprValue(txt); *rPos = QSP_RSUBEX[0]; if (qspRefreshCount != oldRefreshCount || qspErrorNum) { free(newTxt); return 0; } qspConvertVariantTo(&val, QSP_TRUE); if ((txtLen += qspStrLen(QSP_STR(val))) >= bufSize) { bufSize = txtLen + 128; newTxt = (QSP_CHAR *)realloc(newTxt, bufSize * sizeof(QSP_CHAR)); } qspStrCopy(newTxt + oldTxtLen, QSP_STR(val)); free(QSP_STR(val)); oldTxtLen = txtLen; txt = rPos + QSP_LEN(QSP_RSUBEX); lPos = qspStrStr(txt, QSP_LSUBEX); } while (lPos); return qspGetAddText(newTxt, txt, txtLen, -1); }
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; }
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; }