diff --git a/statusfile.c b/statusfile.c index ba3915af..8c2e78d4 100644 --- a/statusfile.c +++ b/statusfile.c @@ -52,6 +52,9 @@ #include "lld.h" #include "exebuf.h" +#define CLEAN_LOCKED 1 +#define CLEAN_MISSING 2 + static int parameterChange = 0; /*-----------------------------------------------------------------------*/ int StatusFileTask(void *data) @@ -217,6 +220,94 @@ static int listRestoreErr(pRestoreObj self, SConnection * pCon) return 1; } +/*-----------------------------------------------------------------------*/ +static int cleanRestoreErr(pRestoreObj self, SConnection * pCon, int hard) +{ + char command[1024]; + char message[1024]; + char *errMsg = NULL; + int status; + int newErrList; + pDynString data = NULL; + pStringDict dict; + int count_in = 0; + int count_ex = 0; + + if (!self->errList) + return 1; + + data = CreateDynString(256,256); + if (data == NULL) { + SCWrite(pCon,"ERROR: out of memory cleaning errors",eError); + return 0; + } + dict = CreateStringDict(); + if (dict == NULL) { + SCWrite(pCon,"ERROR: out of memory cleaning errors",eError); + DeleteDynString(data); + return 0; + } + /* create new list */ + newErrList = LLDstringCreate(); + if (newErrList < 0) { + SCWrite(pCon,"ERROR: out of blobs cleaning errors",eError); + DeleteDynString(data); + DeleteStringDict(dict); + return 0; + } + status = LLDnodePtr2First(self->errList); + while (status == 1) { + LLDstringData(self->errList, command); + status = LLDnodePtr2Next(self->errList); + if (status != 1) { + /* Error */ + errMsg = "ERROR: unpaired error cleaning errors"; + break; + } + LLDstringData(self->errList, message); + if (command[0] == '#' || message[0] != '#') { + /* Error */ + errMsg = "ERROR: sequence error cleaning errors"; + break; + } + DynStringClear(data); + DynStringConcat(data, command); + DynStringConcat(data, message); + status = LLDnodePtr2Next(self->errList); + ++count_in; + /* Skip duplicate messages */ + if (StringDictExists(dict, GetCharArray(data))) + continue; + /* Skip "configured locked!" messages */ + if (hard == CLEAN_LOCKED && + strstr(message, "#ERR: ERROR: variable ") && + strstr(message, " is configured locked!")) + continue; + /* Skip "not found" messages */ + if (hard == CLEAN_MISSING && + strstr(message, "#ERR: Object ") && + strstr(message, "not found")) + continue; + /* add to dictionary and new list */ + StringDictAddPair(dict, GetCharArray(data), ""); + LLDstringAppend(newErrList, command); + LLDstringAppend(newErrList, message); + ++count_ex; + } + if (errMsg) { + SCWrite(pCon, errMsg, eError); + LLDstringDelete(newErrList); + } else { + /* swap lists */ + LLDstringDelete(self->errList); + self->errList = newErrList; + SCPrintf(pCon, eLog, "CleanErr: %d pairs in, %d pairs out", count_in, count_ex); + } + DeleteDynString(data); + DeleteStringDict(dict); + return 1; +} + /*-----------------------------------------------------------------------*/ int RestoreStatus(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) @@ -245,6 +336,13 @@ int RestoreStatus(SConnection * pCon, SicsInterp * pSics, void *pData, } else { if (strcasecmp(argv[1], "listerr") == 0) { return listRestoreErr(self, pCon); + } else if (strcasecmp(argv[1], "cleanerr") == 0) { + if (argc > 2 && strcasecmp(argv[2], "locked") == 0) + return cleanRestoreErr(self, pCon, CLEAN_LOCKED); + else if (argc > 2 && strcasecmp(argv[2], "missing") == 0) + return cleanRestoreErr(self, pCon, CLEAN_MISSING); + else + return cleanRestoreErr(self, pCon, 0); } else if (strcasecmp(argv[1], "killerr") == 0) { if (self->errList >= 0) { LLDdeleteBlob(self->errList);