static int qspGetVarTextIndex(QSPVar *var, QSP_CHAR *str, QSP_BOOL isCreate) { QSP_CHAR *uStr; QSPVarIndex *ind; int i, n = var->IndsCount; qspUpperStr(uStr = qspGetNewText(str, -1)); if (n > 0) { ind = (QSPVarIndex *)bsearch(uStr, var->Indices, n, sizeof(QSPVarIndex), qspIndStringCompare); if (ind) { free(uStr); return ind->Index; } } if (isCreate) { var->IndsCount++; if (n >= var->IndsBufSize) { var->IndsBufSize = n + 8; var->Indices = (QSPVarIndex *)realloc( var->Indices, var->IndsBufSize * sizeof(QSPVarIndex)); } i = n - 1; while (i >= 0 && qspStrsComp(var->Indices[i].Str, uStr) > 0) { var->Indices[i + 1] = var->Indices[i]; --i; } ++i; n = var->ValsCount; var->Indices[i].Str = uStr; var->Indices[i].Index = n; return n; } free(uStr); return -1; }
int qspObjIndex(QSP_CHAR *name) { int i, objNameLen, bufSize; QSP_CHAR *uName, *buf; if (!qspCurObjectsCount) return -1; qspUpperStr(uName = qspGetNewText(name, -1)); bufSize = 32; buf = (QSP_CHAR *)malloc(bufSize * sizeof(QSP_CHAR)); for (i = 0; i < qspCurObjectsCount; ++i) { objNameLen = qspStrLen(qspCurObjects[i].Desc); if (objNameLen >= bufSize) { bufSize = objNameLen + 8; buf = (QSP_CHAR *)realloc(buf, bufSize * sizeof(QSP_CHAR)); } qspStrCopy(buf, qspCurObjects[i].Desc); qspUpperStr(buf); if (!qspStrsComp(buf, uName)) { free(uName); free(buf); return i; } } free(uName); free(buf); return -1; }
QSPVar *qspVarReference(const QSP_CHAR *name, QSP_BOOL isCreate) { int i; QSPVar *var; QSP_CHAR *uName; unsigned char bCode; if (*name == QSP_STRCHAR[0]) ++name; if (!(*name) || qspIsDigit(*name) || qspStrPBrk(name, QSP_DELIMS)) { qspSetError(QSP_ERR_NOTCORRECTNAME); return nullptr; } qspUpperStr(uName = qspGetNewText(name, -1)); bCode = 0; for (i = 0; uName[i]; ++i) bCode = qspRand8[bCode ^ (unsigned char)uName[i]]; var = qspVars + QSP_VARSSEEK * bCode; for (i = 0; i < QSP_VARSSEEK; ++i) { if (!var->Name) { if (isCreate) var->Name = uName; else free(uName); return var; } if (!qspStrsComp(var->Name, uName)) { free(uName); return var; } ++var; } free(uName); qspSetError(QSP_ERR_TOOMANYVARS); return nullptr; }
static int qspActIndex(QSP_CHAR *name) { int i, actNameLen, bufSize; QSP_CHAR *uName, *buf; if (!qspCurActionsCount) return -1; qspUpperStr(uName = qspGetNewText(name, -1)); bufSize = 64; buf = (QSP_CHAR *)malloc(bufSize * sizeof(QSP_CHAR)); for (i = 0; i < qspCurActionsCount; ++i) { actNameLen = qspStrLen(qspCurActions[i].Desc); if (actNameLen >= bufSize) { bufSize = actNameLen + 16; buf = (QSP_CHAR *)realloc(buf, bufSize * sizeof(QSP_CHAR)); } qspStrCopy(buf, qspCurActions[i].Desc); qspUpperStr(buf); if (!qspStrsComp(buf, uName)) { free(uName); free(buf); return i; } } free(uName); free(buf); return -1; }
static int qspActIndex(QSPString name) { QSPString uName, bufName; int i, actNameLen, bufSize; QSP_CHAR *buf; if (!qspCurActionsCount) return -1; uName = qspGetNewText(name); qspUpperStr(&uName); bufSize = 64; buf = (QSP_CHAR *)malloc(bufSize * sizeof(QSP_CHAR)); for (i = 0; i < qspCurActionsCount; ++i) { actNameLen = qspStrLen(qspCurActions[i].Desc); if (actNameLen > bufSize) { bufSize = actNameLen + 16; buf = (QSP_CHAR *)realloc(buf, bufSize * sizeof(QSP_CHAR)); } memcpy(buf, qspCurActions[i].Desc.Str, actNameLen * sizeof(QSP_CHAR)); bufName = qspStringFromLen(buf, actNameLen); qspUpperStr(&bufName); if (!qspStrsComp(bufName, uName)) { qspFreeString(uName); free(buf); return i; } } qspFreeString(uName); free(buf); return -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; }
static int qspProcessEOLExtensions(QSPLineOfCode *s, int count, QSPLineOfCode **strs) { QSPLineOfCode *ret; QSPString str, eol, eolExt; int len, lastNum = 0, i = 0, bufSize = 8, newCount = 0; ret = (QSPLineOfCode *)malloc(bufSize * sizeof(QSPLineOfCode)); eolExt = QSP_STATIC_STR(QSP_PREEOLEXT QSP_EOLEXT); while (i < count) { qspAddText(&str, s[i].Str, QSP_TRUE); len = qspStrLen(str); if (len >= QSP_STATIC_LEN(QSP_PREEOLEXT QSP_EOLEXT)) { eol = str; eol.Str += len - QSP_STATIC_LEN(QSP_PREEOLEXT QSP_EOLEXT); while (!qspStrsComp(eol, eolExt)) { if (++i == count) break; str.End -= QSP_STATIC_LEN(QSP_EOLEXT); qspAddText(&str, s[i].Str, QSP_FALSE); len = qspStrLen(str); eol = str; eol.Str += len - QSP_STATIC_LEN(QSP_PREEOLEXT QSP_EOLEXT); } } if (newCount >= bufSize) { bufSize = newCount + 16; ret = (QSPLineOfCode *)realloc(ret, bufSize * sizeof(QSPLineOfCode)); } qspInitLineOfCode(ret + newCount++, str, lastNum); ++i; lastNum = s[i].LineNum; } *strs = ret; return newCount; }
void qspStatementLocal(QSP_CHAR *s) { QSPVariant v; QSPVar *var; QSP_BOOL isVarFound; QSP_CHAR *curPos, *varName, *commaPos, *eqPos; int i, groupInd, count, bufSize, oldRefreshCount; s = qspSkipSpaces(s); if (!(*s)) { qspSetError(QSP_ERR_SYNTAX); return; } groupInd = qspSavedVarsGroupsCount - 1; count = bufSize = qspSavedVarsGroups[groupInd].VarsCount; isVarFound = QSP_FALSE; curPos = s; eqPos = qspStrPos(curPos, QSP_EQUAL, QSP_FALSE); if (eqPos) *eqPos = 0; while (1) { /* Skip type char */ if (*curPos == QSP_STRCHAR[0]) ++curPos; /* Get variable's name */ commaPos = qspStrPos(curPos, QSP_COMMA, QSP_FALSE); if (commaPos) { *commaPos = 0; varName = (eqPos ? qspGetVarNameOnly(curPos) : qspDelSpc(curPos)); *commaPos = QSP_COMMA[0]; } else varName = (eqPos ? qspGetVarNameOnly(curPos) : qspDelSpc(curPos)); qspUpperStr(varName); /* Check for the existence */ for (i = 0; i < count; ++i) { if (!qspStrsComp(varName, qspSavedVarsGroups[groupInd].Vars[i].Name)) { isVarFound = QSP_TRUE; break; } } /* Get variable's data */ if (isVarFound) { /* Already exists */ isVarFound = QSP_FALSE; free(varName); } else { /* Add variable to the local group */ if (!(var = qspVarReference(varName, QSP_FALSE))) { free(varName); if (eqPos) *eqPos = QSP_EQUAL[0]; return; } if (count >= bufSize) { bufSize = count + 4; qspSavedVarsGroups[groupInd].Vars = (QSPVar *)realloc(qspSavedVarsGroups[groupInd].Vars, bufSize * sizeof(QSPVar)); } qspMoveVar(qspSavedVarsGroups[groupInd].Vars + count, var); qspSavedVarsGroups[groupInd].Vars[count].Name = varName; qspSavedVarsGroups[groupInd].VarsCount = ++count; } if (!commaPos) break; curPos = qspSkipSpaces(commaPos + QSP_LEN(QSP_COMMA)); if (!(*curPos)) { qspSetError(QSP_ERR_SYNTAX); if (eqPos) *eqPos = QSP_EQUAL[0]; return; } } if (eqPos) { oldRefreshCount = qspRefreshCount; v = qspExprValue(eqPos + QSP_LEN(QSP_EQUAL)); if (qspRefreshCount != oldRefreshCount || qspErrorNum) { *eqPos = QSP_EQUAL[0]; return; } varName = qspDelSpcCanRetSelf(s); qspSetVarValue(varName, &v, QSP_EQUAL[0]); if (varName != s) free(varName); if (v.IsStr) free(QSP_STR(v)); *eqPos = QSP_EQUAL[0]; } }
static int qspIndStringCompare(const void *name, const void *compareTo) { return qspStrsComp((QSP_CHAR *)name, ((QSPVarIndex *)compareTo)->Str); }
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; }