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); }
QSP_CHAR *qspReplaceText(QSP_CHAR *txt, QSP_CHAR *searchTxt, QSP_CHAR *repTxt) { int txtLen, oldTxtLen, bufSize, searchLen, repLen, len; QSP_CHAR *newTxt, *pos = qspStrStr(txt, searchTxt); if (!pos) return qspGetNewText(txt, -1); bufSize = 256; txtLen = oldTxtLen = 0; searchLen = qspStrLen(searchTxt); repLen = qspStrLen(repTxt); newTxt = (QSP_CHAR *)malloc(bufSize * sizeof(QSP_CHAR)); do { len = (int)(pos - txt); if ((txtLen += len + repLen) >= bufSize) { bufSize = txtLen + 128; newTxt = (QSP_CHAR *)realloc(newTxt, bufSize * sizeof(QSP_CHAR)); } qspStrNCopy(newTxt + oldTxtLen, txt, len); qspStrCopy(newTxt + oldTxtLen + len, repTxt); oldTxtLen = txtLen; txt = pos + searchLen; pos = qspStrStr(txt, searchTxt); } while (pos); return qspGetAddText(newTxt, txt, txtLen, -1); }
int qspSplitStr(QSP_CHAR *str, QSP_CHAR *delim, QSP_CHAR ***res) { int allocChars, count = 0, bufSize = 8, delimLen = qspStrLen(delim); QSP_CHAR *newStr, **ret, *curPos = str, *found = qspStrStr(str, delim); ret = (QSP_CHAR **)malloc(bufSize * sizeof(QSP_CHAR *)); while (found) { allocChars = (int)(found - curPos); newStr = (QSP_CHAR *)malloc((allocChars + 1) * sizeof(QSP_CHAR)); qspStrNCopy(newStr, curPos, allocChars); newStr[allocChars] = 0; if (++count > bufSize) { bufSize += 16; ret = (QSP_CHAR **)realloc(ret, bufSize * sizeof(QSP_CHAR *)); } ret[count - 1] = newStr; curPos = found + delimLen; found = qspStrStr(curPos, delim); } newStr = (QSP_CHAR *)malloc((qspStrLen(curPos) + 1) * sizeof(QSP_CHAR)); qspStrCopy(newStr, curPos); if (++count > bufSize) ret = (QSP_CHAR **)realloc(ret, count * sizeof(QSP_CHAR *)); ret[count - 1] = newStr; *res = ret; return count; }
QSP_CHAR *qspStrPos(QSP_CHAR *txt, QSP_CHAR *str, QSP_BOOL isIsolated) { QSP_BOOL isLastDelim; int strLen, c1, c2, c3; QSP_CHAR quot, *pos = qspStrStr(txt, str); if (!pos) return 0; if (!(isIsolated || qspStrPBrk(txt, QSP_QUOTS QSP_LQUOT QSP_LRBRACK QSP_LSBRACK))) return pos; strLen = qspStrLen(str); pos = qspStrEnd(txt) - strLen + 1; c1 = c2 = c3 = 0; isLastDelim = QSP_TRUE; while (txt < pos) { if (qspIsInList(QSP_QUOTS, *txt)) { quot = *txt; while (++txt < pos) if (*txt == quot && *(++txt) != quot) break; if (txt >= pos) return 0; isLastDelim = QSP_TRUE; } if (*txt == QSP_LRBRACK[0]) ++c1; else if (*txt == QSP_RRBRACK[0]) { if (c1) --c1; } else if (*txt == QSP_LSBRACK[0]) ++c2; else if (*txt == QSP_RSBRACK[0]) { if (c2) --c2; } else if (*txt == QSP_LQUOT[0]) ++c3; else if (*txt == QSP_RQUOT[0]) { if (c3) --c3; } if (!(c1 || c2 || c3)) { if (isIsolated) { if (qspIsInList(QSP_DELIMS, *txt)) isLastDelim = QSP_TRUE; else if (isLastDelim) { if (qspIsInListEOL(QSP_DELIMS, txt[strLen]) && !qspStrsNComp(txt, str, strLen)) return txt; isLastDelim = QSP_FALSE; } } else if (!qspStrsNComp(txt, str, strLen)) return txt; } ++txt; } return 0; }
static void qspSetVarValue(QSP_CHAR *name, QSPVariant *v, QSP_CHAR op) { QSPVariant v2; QSP_BOOL isSingleValue, notFirstValue = QSP_FALSE; QSP_CHAR *newValPos, *newCommaPos, *valPos, *commaPos = name; int oldRefreshCount = qspRefreshCount; if (v->IsStr) { valPos = QSP_PSTR(v); isSingleValue = QSP_FALSE; /* Multiple values by default */ } else isSingleValue = QSP_TRUE; while (1) { newCommaPos = qspStrPos(commaPos, QSP_COMMA, QSP_FALSE); if (newCommaPos) { *newCommaPos = 0; if (isSingleValue) { if (notFirstValue) qspSetVar(commaPos, &v2, op); else qspSetVar(commaPos, v, op); if (qspRefreshCount != oldRefreshCount || qspErrorNum) { *newCommaPos = QSP_COMMA[0]; break; } } else { newValPos = qspStrStr(valPos, QSP_VALSDELIM); if (newValPos) { notFirstValue = QSP_TRUE; v2.IsStr = QSP_TRUE; QSP_STR(v2) = qspGetNewText(valPos, (int)(newValPos - valPos)); qspSetVar(commaPos, &v2, op); if (qspRefreshCount != oldRefreshCount || qspErrorNum) { *newCommaPos = QSP_COMMA[0]; break; } if (v2.IsStr) free(QSP_STR(v2)); valPos = newValPos + QSP_LEN(QSP_VALSDELIM); } else /* The last value */ { isSingleValue = QSP_TRUE; if (notFirstValue) { v2.IsStr = QSP_TRUE; QSP_STR(v2) = qspGetNewText(valPos, -1); qspSetVar(commaPos, &v2, op); } else qspSetVar(commaPos, v, op); if (qspRefreshCount != oldRefreshCount || qspErrorNum) { *newCommaPos = QSP_COMMA[0]; break; } } } *newCommaPos = QSP_COMMA[0]; } else /* The last variable */ { if (notFirstValue) /* Not a first value */ { if (!isSingleValue) { v2.IsStr = QSP_TRUE; QSP_STR(v2) = qspGetNewText(valPos, -1); } qspSetVar(commaPos, &v2, op); } else qspSetVar(commaPos, v, op); break; } commaPos = newCommaPos + QSP_LEN(QSP_COMMA); } if (notFirstValue && v2.IsStr) free(QSP_STR(v2)); }