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); }
QSPVariant qspGetVarValueByReference(QSPVar *var, int ind, QSP_BOOL isStringType) { QSPVariant ret; QSP_CHAR *text; if (ind >= 0 && ind < var->ValsCount) { if (ret.IsStr = isStringType) { text = var->Values[ind].Str; QSP_STR(ret) = (text ? qspGetNewText(text, -1) : qspGetNewText(QSP_FMT(""), 0)); } else QSP_NUM(ret) = var->Values[ind].Num; return ret; } return qspGetEmptyVariant(isStringType); }
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); } }
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 qspSearchPlayList(QSP_CHAR *file) { QSP_CHAR *uName, *buf; int i, bufSize, itemLen, len; if (!qspPLFilesCount) return -1; len = qspStrLen(file); qspUpperStr(uName = qspGetNewText(file, len)); bufSize = 32; buf = (QSP_CHAR *)malloc(bufSize * sizeof(QSP_CHAR)); for (i = 0; i < qspPLFilesCount; ++i) { itemLen = qspStrLen(qspPLFiles[i]); if (itemLen >= bufSize) { bufSize = itemLen + 8; buf = (QSP_CHAR *)realloc(buf, bufSize * sizeof(QSP_CHAR)); } qspStrCopy(buf, qspPLFiles[i]); qspUpperStr(buf); if (!qspStrsNComp(buf, uName, len) && qspIsInListEOL(QSP_PLVOLUMEDELIM, buf[len])) { free(uName); free(buf); return i; } } free(uName); free(buf); return -1; }
void qspRefreshPlayList() { QSP_CHAR **s, *file, *str, *pos; int count = qspPLFilesCount; if (!count) return; qspCopyStrs(&s, qspPLFiles, 0, count); qspClearPlayList(QSP_FALSE); while (--count >= 0) { str = s[count]; pos = qspStrChar(str, QSP_PLVOLUMEDELIM[0]); if (pos) *pos = 0; if (qspIsAnyString(str)) { file = qspGetAbsFromRelPath(str); if (qspSearchPlayList(str) < 0 && qspCallIsPlayingFile(file)) { if (pos) *pos = QSP_PLVOLUMEDELIM[0]; qspPLFiles[qspPLFilesCount++] = qspGetNewText(str, -1); } free(file); } free(str); } free(s); }
void qspAddAction(QSPVariant *args, int count, QSPLineOfCode *code, int start, int end, QSP_BOOL isManageLines) { QSPCurAct *act; QSP_CHAR *imgPath; if (qspActIndex(QSP_STR(args[0])) >= 0) return; if (qspCurActionsCount == QSP_MAXACTIONS) { qspSetError(QSP_ERR_CANTADDACTION); return; } if (count == 2 && qspIsAnyString(QSP_STR(args[1]))) imgPath = qspGetAbsFromRelPath(QSP_STR(args[1])); else imgPath = 0; act = qspCurActions + qspCurActionsCount++; act->Image = imgPath; act->Desc = qspGetNewText(QSP_STR(args[0]), -1); qspCopyPrepLines(&act->OnPressLines, code, start, end); act->OnPressLinesCount = end - start; act->Location = qspRealCurLoc; act->ActIndex = qspRealActIndex; act->StartLine = qspRealLine; act->IsManageLines = isManageLines; qspIsActionsChanged = QSP_TRUE; }
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(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; }
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; }
QSP_BOOL qspStatementShowMenu(QSPVariant *args, int count, QSP_CHAR **jumpTo, int extArg) { int ind, maxItems, len; QSPVar *var; QSP_CHAR *imgPath, *str, *pos, *pos2; if (!(var = qspVarReferenceWithType(QSP_STR(args[0]), QSP_FALSE, 0))) return QSP_FALSE; qspClearMenu(QSP_FALSE); qspCallDeleteMenu(); if (count == 1) { ind = 0; maxItems = QSP_MAXMENUITEMS; } else { ind = QSP_NUM(args[1]); if (ind < 0) ind = 0; if (count == 2) maxItems = QSP_MAXMENUITEMS; else { maxItems = QSP_NUM(args[2]); if (maxItems < 0) maxItems = 0; } } while (ind < var->ValsCount) { if (qspCurMenuItems == maxItems) break; if (!((str = var->Values[ind].Str) && qspIsAnyString(str))) break; if (!(pos2 = qspInStrRChars(str, QSP_MENUDELIM, 0))) { qspSetError(QSP_ERR_COLONNOTFOUND); return QSP_FALSE; } if (qspCurMenuItems == QSP_MAXMENUITEMS) { qspSetError(QSP_ERR_CANTADDMENUITEM); return QSP_FALSE; } if (pos = qspInStrRChars(str, QSP_MENUDELIM, pos2)) { len = (int)(pos2 - pos) - 1; imgPath = (qspIsAnyString(++pos2) ? qspGetAbsFromRelPath(pos2) : 0); } else { pos = pos2; len = -1; imgPath = 0; } qspCurMenuLocs[qspCurMenuItems++] = qspGetNewText(pos + 1, len); *pos = 0; qspCallAddMenuItem(str, imgPath); *pos = QSP_MENUDELIM[0]; if (imgPath) free(imgPath); ++ind; } if (qspCurMenuItems) qspCallShowMenu(); return QSP_FALSE; }
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); }
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); }
QSP_CHAR *qspCallInputBox(QSP_CHAR *text) { /* Здесь вводим текст */ QSPCallState state; QSP_CHAR *buffer; AS3_Val args; char *strUTF8; char *resText; int maxLen = 511; if (qspCallBacks[QSP_CALL_INPUTBOX].IsSet) { qspSaveCallState(&state, QSP_TRUE, QSP_FALSE); if (text) { strUTF8 = qspW2C(text); args = AS3_Array("StrType", strUTF8); free(strUTF8); } else args = AS3_Array("StrType", 0); AS3_Call(qspCallBacks[QSP_CALL_INPUTBOX].FuncVal, qspCallBacks[QSP_CALL_INPUTBOX].ThisVal, args); AS3_Release(args); flyield(); resText = AS3_StringValue(result); AS3_Release(result); buffer = qspC2W(resText); free(resText); qspRestoreCallState(&state); } else buffer = qspGetNewText(QSP_FMT(""), 0); return buffer; }
QSP_BOOL qspStatementAddObject(QSPVariant *args, int count, QSP_CHAR **jumpTo, int extArg) { QSPObj *obj; int i, objInd; QSP_CHAR *imgPath; if (count == 3) { objInd = QSP_NUM(args[2]) - 1; if (objInd < 0 || objInd > qspCurObjectsCount) return QSP_FALSE; } else objInd = qspCurObjectsCount; if (qspCurObjectsCount == QSP_MAXOBJECTS) { qspSetError(QSP_ERR_CANTADDOBJECT); return QSP_FALSE; } if (qspCurSelObject >= objInd) qspCurSelObject = -1; if (count >= 2 && qspIsAnyString(QSP_STR(args[1]))) imgPath = qspGetAbsFromRelPath(QSP_STR(args[1])); else imgPath = 0; for (i = qspCurObjectsCount; i > objInd; --i) qspCurObjects[i] = qspCurObjects[i - 1]; ++qspCurObjectsCount; obj = qspCurObjects + objInd; obj->Image = imgPath; obj->Desc = qspGetNewText(QSP_STR(args[0]), -1); qspIsObjectsChanged = QSP_TRUE; qspExecLocByVarNameWithArgs(QSP_FMT("ONOBJADD"), args, (count < 3 ? count : 2)); return QSP_FALSE; }
QSPVariant qspGetEmptyVariant(QSP_BOOL isStringType) { QSPVariant ret; if (ret.IsStr = isStringType) QSP_STR(ret) = qspGetNewText(QSP_FMT(""), 0); else QSP_NUM(ret) = 0; return ret; }
static void qspCopyVar(QSPVar *dest, QSPVar *src, int start, int count) { QSP_CHAR *str; int i, maxCount, newInd; if (start < 0) start = 0; maxCount = src->ValsCount - start; if (count <= 0 || maxCount <= 0) { qspInitVarData(dest); return; } if (count < maxCount) maxCount = count; dest->ValsCount = maxCount; dest->Values = (QSPVarValue *)malloc(maxCount * sizeof(QSPVarValue)); for (i = 0; i < maxCount; ++i) { dest->Values[i].Num = src->Values[i + start].Num; str = src->Values[i + start].Str; dest->Values[i].Str = (str ? qspGetNewText(str, -1) : 0); } dest->IndsBufSize = 0; dest->Indices = 0; count = 0; for (i = 0; i < src->IndsCount; ++i) { newInd = src->Indices[i].Index - start; if (newInd >= 0 && newInd < maxCount) { if (count >= dest->IndsBufSize) { dest->IndsBufSize = count + 16; dest->Indices = (QSPVarIndex *)realloc(dest->Indices, dest->IndsBufSize * sizeof(QSPVarIndex)); } dest->Indices[count].Index = newInd; dest->Indices[count].Str = qspGetNewText(src->Indices[i].Str, -1); ++count; } } dest->IndsCount = count; }
QSPVariant qspArrayMinMaxItem(QSP_CHAR *name, QSP_BOOL isMin) { QSPVar *var; QSP_CHAR *str; QSP_BOOL isString; int curInd, count; QSPVariant res; if (!(var = qspVarReferenceWithType(name, QSP_FALSE, &isString))) return qspGetEmptyVariant(QSP_FALSE); curInd = -1; count = var->ValsCount; while (--count >= 0) { if (isString) { str = var->Values[count].Str; if (str && *str) { if (curInd >= 0) { if (isMin) { if (QSP_STRCOLL(str, var->Values[curInd].Str) < 0) curInd = count; } else if (QSP_STRCOLL(str, var->Values[curInd].Str) > 0) curInd = count; } else curInd = count; } } else if (curInd >= 0) { if (isMin) { if (var->Values[count].Num < var->Values[curInd].Num) curInd = count; } else if (var->Values[count].Num > var->Values[curInd].Num) curInd = count; } else curInd = count; } if (curInd < 0) return qspGetEmptyVariant(isString); if (res.IsStr = isString) QSP_STR(res) = qspGetNewText(var->Values[curInd].Str, -1); else QSP_NUM(res) = var->Values[curInd].Num; return res; }
void qspCopyPrepLines(QSPLineOfCode **dest, QSPLineOfCode *src, int start, int end) { QSPLineOfCode *line; int i, count = end - start; if (src && count) { *dest = (QSPLineOfCode *)malloc(count * sizeof(QSPLineOfCode)); line = *dest; while (start < end) { line->Str = qspGetNewText(src[start].Str); line->LineNum = src[start].LineNum; count = line->StatsCount = src[start].StatsCount; if (count) { line->Stats = (QSPCachedStat *)malloc(count * sizeof(QSPCachedStat)); for (i = 0; i < count; ++i) { line->Stats[i].Stat = src[start].Stats[i].Stat; line->Stats[i].EndPos = src[start].Stats[i].EndPos; line->Stats[i].ParamPos = src[start].Stats[i].ParamPos; } } else line->Stats = 0; line->IsMultiline = src[start].IsMultiline; if (src[start].Label.Str) line->Label = qspGetNewText(src[start].Label); else line->Label = qspNullString; ++line; ++start; } } else *dest = 0; }
QSP_CHAR *qspCallInputBox(QSP_CHAR *text) { /* «десь вводим текст */ QSPCallState state; QSP_CHAR *buffer; int maxLen = 511; if (qspCallBacks[QSP_CALL_INPUTBOX]) { qspSaveCallState(&state, QSP_TRUE, QSP_FALSE); buffer = (QSP_CHAR *)malloc((maxLen + 1) * sizeof(QSP_CHAR)); *buffer = 0; qspCallBacks[QSP_CALL_INPUTBOX](text, buffer, maxLen); buffer[maxLen] = 0; qspRestoreCallState(&state); } else buffer = qspGetNewText(QSP_FMT(""), 0); return buffer; }
QSP_CHAR *qspCallPlayerInfo(QSP_CHAR *text) { /* «десь получаем строку по заданному параметру */ QSPCallState state; QSP_CHAR *buffer; int maxLen = 511; if (qspCallBacks[QSP_CALL_PLAYERINFO]) { qspSaveCallState(&state, QSP_TRUE, QSP_FALSE); buffer = (QSP_CHAR *)malloc((maxLen + 1) * sizeof(QSP_CHAR)); *buffer = 0; qspCallBacks[QSP_CALL_PLAYERINFO](text, buffer, maxLen); buffer[maxLen] = 0; qspRestoreCallState(&state); } else buffer = qspGetNewText(QSP_FMT(""), 0); return buffer; }
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; }
QSP_CHAR *qspGetAllActionsAsCode() { int len = 0, count, i; QSP_CHAR *res, *temp; res = qspGetNewText(QSP_FMT(""), 0); for (i = 0; i < qspCurActionsCount; ++i) { len = qspAddText(&res, QSP_FMT("ACT '"), len, 5, QSP_FALSE); temp = qspReplaceText(qspCurActions[i].Desc, QSP_FMT("'"), QSP_FMT("''")); len = qspAddText(&res, temp, len, -1, QSP_FALSE); free(temp); if (qspCurActions[i].Image) { len = qspAddText(&res, QSP_FMT("','"), len, 3, QSP_FALSE); temp = qspReplaceText(qspCurActions[i].Image + qspQstPathLen, QSP_FMT("'"), QSP_FMT("''")); len = qspAddText(&res, temp, len, -1, QSP_FALSE); free(temp); } len = qspAddText(&res, QSP_FMT("':"), len, 2, QSP_FALSE); count = qspCurActions[i].OnPressLinesCount; if (count == 1 && qspIsAnyString(qspCurActions[i].OnPressLines->Str)) len = qspAddText(&res, qspCurActions[i].OnPressLines->Str, len, -1, QSP_FALSE); else { if (count >= 2) { len = qspAddText(&res, QSP_STRSDELIM, len, QSP_LEN(QSP_STRSDELIM), QSP_FALSE); temp = qspJoinPrepLines(qspCurActions[i].OnPressLines, count, QSP_STRSDELIM); len = qspAddText(&res, temp, len, -1, QSP_FALSE); free(temp); } len = qspAddText(&res, QSP_STRSDELIM QSP_FMT("END"), len, QSP_LEN(QSP_STRSDELIM) + 3, QSP_FALSE); } len = qspAddText(&res, QSP_STRSDELIM, len, QSP_LEN(QSP_STRSDELIM), QSP_FALSE); } return res; }
static QSP_CHAR *qspGetVarNameOnly(QSP_CHAR *s) { QSP_CHAR *brackPos = qspStrChar(s, QSP_LSBRACK[0]); if (brackPos) return qspGetNewText(s, (int)(brackPos - s)); return qspDelSpc(s); }
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)); }
static int qspProcessPreformattedStrings(QSPString data, QSPLineOfCode **strs) { QSPLineOfCode *ret, *line; QSP_BOOL isNewLine; QSP_CHAR *str, *pos, quot = 0; QSPString strsDelim; int lineNum = 0, lastLineNum = 0, count = 0, quotsCount = 0, strLen = 0, bufSize = 8, strBufSize = 256; str = (QSP_CHAR *)malloc(strBufSize * sizeof(QSP_CHAR)); ret = (QSPLineOfCode *)malloc(bufSize * sizeof(QSPLineOfCode)); strsDelim = QSP_STATIC_STR(QSP_STRSDELIM); pos = data.Str; while (pos < data.End) { isNewLine = (qspStrsNComp(data, strsDelim, QSP_STATIC_LEN(QSP_STRSDELIM)) == 0); if (isNewLine) ++lineNum; if (quotsCount || quot || !isNewLine) { if (strLen >= strBufSize) { strBufSize = strLen + 256; str = (QSP_CHAR *)realloc(str, strBufSize * sizeof(QSP_CHAR)); } str[strLen++] = *pos; if (quot) { if (*pos == quot) { if (++pos < data.End && *pos == quot) { if (strLen >= strBufSize) { strBufSize = strLen + 256; str = (QSP_CHAR *)realloc(str, strBufSize * sizeof(QSP_CHAR)); } str[strLen++] = *pos++; } else quot = 0; } else ++pos; } else { if (*pos == QSP_LQUOT[0]) ++quotsCount; else if (*pos == QSP_RQUOT[0]) { if (quotsCount) --quotsCount; } else if (qspIsInList(QSP_QUOTS, *pos)) quot = *pos; ++pos; } } else { if (count >= bufSize) { bufSize = count + 16; ret = (QSPLineOfCode *)realloc(ret, bufSize * sizeof(QSPLineOfCode)); } line = ret + count++; line->Str = qspGetNewText(qspDelSpc(qspStringFromLen(str, strLen))); line->LineNum = lastLineNum; line->Label = qspNullString; line->Stats = 0; lastLineNum = lineNum; strLen = 0; pos += QSP_STATIC_LEN(QSP_STRSDELIM); } data.Str = pos; } if (count >= bufSize) ret = (QSPLineOfCode *)realloc(ret, (count + 1) * sizeof(QSPLineOfCode)); line = ret + count++; line->Str = qspGetNewText(qspDelSpc(qspStringFromLen(str, strLen))); line->LineNum = lastLineNum; line->Label = qspNullString; line->Stats = 0; free(str); *strs = ret; return count; }