static TCHAR *parseAddAlias(ARGUMENTSINFO *ai) { int res; char *szHelp, *szArgsA; if (ai->argc != 3) return NULL; TCHAR *cur = ai->targv[1]; while (isValidTokenChar(*cur)) cur++; ptrT alias(mir_tstrndup(ai->targv[1], cur - ai->targv[1])); int argc; TCHAR **argv; getArguments(cur, &argv, &argc); deRegisterToken(alias); addToAliasRegister(alias, argc, argv, ai->targv[2]); TCHAR *szArgs = NULL; for (int i = 0; i < argc; i++) { if (i == 0) szArgs = (TCHAR*)mir_calloc((_tcslen(argv[i]) + 2)*sizeof(TCHAR)); else szArgs = (TCHAR*)mir_realloc(szArgs, (_tcslen(szArgs) + _tcslen(argv[i]) + 2)*sizeof(TCHAR)); _tcscat(szArgs, argv[i]); if (i != argc - 1) _tcscat(szArgs, _T(",")); } if (szArgs != NULL && argc > 0) { szArgsA = mir_t2a(szArgs); size_t size = 32 + strlen(szArgsA); szHelp = (char *)mir_alloc(size); memset(szHelp, '\0', 32 + strlen(szArgsA)); mir_snprintf(szHelp, size, LPGEN("Alias")"\t(%s)\t"LPGEN("user defined"), szArgsA); res = registerIntToken(alias, parseTranslateAlias, TRF_FUNCTION | TRF_UNPARSEDARGS, szHelp); mir_free(szArgsA); } else { szHelp = (char*)mir_alloc(32); memset(szHelp, '\0', 32); mir_snprintf(szHelp, 32, LPGEN("Alias")"\t\t"LPGEN("user defined")); res = registerIntToken(alias, parseTranslateAlias, TRF_FIELD | TRF_UNPARSEDARGS, szHelp); } mir_free(szArgs); mir_free(szHelp); return (res == 0) ? mir_tstrdup(_T("")) : NULL; }
/* pretty much the main loop */ static TCHAR* replaceDynVars(TCHAR* szTemplate, FORMATINFO* fi) { TCHAR *string, *cur, // current position (pnt only) *tcur, // temp cur (pnt only) *scur, // start of variable(pnt only) *parsedToken, // parsed result (dyn alloc) **argv, // arguments (dyn alloc) **pargv, // dyn alloc *token; // variable name (pnt only) int argc = 0, i, scurPos, curPos, tmpVarPos; size_t pos; FORMATINFO afi; TOKENREGISTEREX *tr; ARGUMENTSINFO ai = { 0 }; string = mir_tstrdup(szTemplate); if (string == NULL) return NULL; cur = tcur = scur = token = parsedToken = NULL; pargv = argv = NULL; //fi->pCount = 0; memcpy(&afi, fi, sizeof(afi)); for (pos = 0; pos < mir_tstrlen(string); pos++) { // string may move in memory, iterate by remembering the position in the string cur = string+pos; // mir_free memory from last iteration, this way we can bail out at any time in the loop mir_free(parsedToken); for (i = 0; i < argc; i ++) mir_free(argv[i]); mir_free(argv); argc = 0; tcur = scur = token = parsedToken = NULL; pargv = argv = NULL; // new round if (*cur == DONTPARSE_CHAR) { memmove(cur, cur+1, (mir_tstrlen(cur+1)+1)*sizeof(TCHAR)); if (*cur == DONTPARSE_CHAR) continue; while ( (*cur != DONTPARSE_CHAR) && (*cur != 0)) cur++; memmove(cur, cur+1, (mir_tstrlen(cur+1)+1)*sizeof(TCHAR)); pos = cur-string-1; continue; } // remove end of lines else if ((!_tcsncmp(cur, _T("\r\n"), 2)) && (gParseOpts.bStripEOL)) { memmove(cur, cur+2, (mir_tstrlen(cur+2)+1)*sizeof(TCHAR)); pos = cur-string-1; continue; } else if ((*cur == '\n' && gParseOpts.bStripEOL) || (*cur == ' ' && gParseOpts.bStripWS)) { memmove(cur, cur+1, (mir_tstrlen(cur+1)+1)*sizeof(TCHAR)); pos = cur - string - 1; continue; } // remove comments else if (!_tcsncmp(cur, _T(COMMENT_STRING), mir_tstrlen(_T(COMMENT_STRING)))) { scur = cur; while ( _tcsncmp(cur, _T("\r\n"), 2) && *cur != '\n' && *cur != 0) cur++; if (*cur == 0) { *scur = 0; string = (TCHAR*)mir_realloc(string, (mir_tstrlen(string)+1)*sizeof(TCHAR)); continue; } memmove(scur, cur, (mir_tstrlen(cur)+1)*sizeof(TCHAR)); pos = scur-string-1; continue; } else if ((*cur != FIELD_CHAR) && (*cur != FUNC_CHAR) && (*cur != FUNC_ONCE_CHAR)) { if (gParseOpts.bStripAll) { memmove(cur, cur+1, (mir_tstrlen(cur+1)+1)*sizeof(TCHAR)); pos = cur - string - 1; } continue; } scur = tcur = cur+1; while (isValidTokenChar(*tcur)) tcur++; if (tcur == cur) { fi->eCount++; continue; } token = (TCHAR*)mir_alloc((tcur-scur+1)*sizeof(TCHAR)); if (token == NULL) { fi->eCount++; return NULL; } memset(token, '\0', (tcur-scur+1)*sizeof(TCHAR)); _tcsncpy(token, cur+1, tcur-scur); // cur points to FIELD_CHAR or FUNC_CHAR tmpVarPos = -1; tr = NULL; if (*cur==FIELD_CHAR) { for(i = 0; i < fi->cbTemporaryVarsSize; i += 2) { if (mir_tstrcmp(fi->tszaTemporaryVars[i], token) == 0) { tmpVarPos = i; break; } } } if (tmpVarPos < 0) tr = searchRegister(token, (*cur==FIELD_CHAR)?TRF_FIELD:TRF_FUNCTION); mir_free(token); if (tmpVarPos < 0 && tr == NULL) { fi->eCount++; // token not found, continue continue; } scur = cur; // store this pointer for later use if (*cur == FIELD_CHAR) { size_t len = mir_tstrlen(tr != NULL ? tr->tszTokenString : fi->tszaTemporaryVars[tmpVarPos]); cur++; if (*(cur + len) != FIELD_CHAR) { // the next char after the token should be % fi->eCount++; continue; } cur += len+1; } else if ((*cur == FUNC_CHAR) || (*cur == FUNC_ONCE_CHAR)) { TCHAR *argcur; cur += mir_tstrlen(tr->tszTokenString)+1; argcur = getArguments(cur, &argv, &argc); if ((argcur == cur) || (argcur == NULL)) { fi->eCount++; // error getting arguments continue; } cur = argcur; // arguments for (i=0;i<argc;i++) { if (argv[i] != NULL) { if (!(tr->flags&TRF_UNPARSEDARGS)) { afi.tszFormat = argv[i]; afi.eCount = afi.pCount = 0; argv[i] = formatString(&afi); fi->eCount += afi.eCount; fi->pCount += afi.pCount; mir_free(afi.szFormat); } } if (argv[i] == NULL) argv[i] = mir_tstrdup(_T("")); } } // cur should now point at the character after FIELD_CHAR or after the last ')' if (tr != NULL) { pargv = ( TCHAR** )mir_alloc((argc+1)*sizeof(TCHAR*)); if (pargv == NULL) { fi->eCount++; return NULL; } for (i=0;i<argc;i++) pargv[i+1] = argv[i]; pargv[0] = tr->tszTokenString; memset(&ai, 0, sizeof(ai)); ai.cbSize = sizeof(ai); ai.argc = argc+1; ai.targv = pargv; ai.fi = fi; if ((*scur == FUNC_ONCE_CHAR) || (*scur == FIELD_CHAR)) ai.flags |= AIF_DONTPARSE; parsedToken = parseFromRegister(&ai); mir_free(pargv); } else parsedToken = fi->tszaTemporaryVars[tmpVarPos + 1]; if (parsedToken == NULL) { fi->eCount++; continue; } //replaced a var if (ai.flags & AIF_FALSE ) fi->eCount++; else fi->pCount++; // 'special' chars need to be taken care of (DONTPARSE, TRYPARSE, \r\n) // if the var contains the escape character, this character must be doubled, we don't want it to act as an esacpe char /*for (tcur=parsedToken;*tcur != '\0';tcur++) { if (*tcur == DONTPARSE_CHAR) {//|| (*(var+pos) == ')')) { parsedToken = mir_realloc(parsedToken, mir_strlen(parsedToken) + 2); if (parsedToken == NULL) { fi->err = EMEM; return NULL; } memcpy(tcur+1, tcur, mir_strlen(tcur)+1); tcur++; } }*/ size_t parsedTokenLen = mir_tstrlen(parsedToken); size_t initStrLen = mir_tstrlen(string); size_t tokenLen = cur-scur; scurPos = scur-string; curPos = cur-string; if (tokenLen < parsedTokenLen) { // string needs more memory string = (TCHAR*)mir_realloc(string, (initStrLen-tokenLen+parsedTokenLen+1)*sizeof(TCHAR)); if (string == NULL) { fi->eCount++; return NULL; } } scur = string+scurPos; cur = string+curPos; memmove(scur + parsedTokenLen, cur, (mir_tstrlen(cur)+1)*sizeof(TCHAR)); memcpy(scur, parsedToken, parsedTokenLen*sizeof(TCHAR)); { size_t len = mir_tstrlen(string); string = (TCHAR*)mir_realloc(string, (len+1)*sizeof(TCHAR)); } if (( ai.flags & AIF_DONTPARSE ) || tmpVarPos >= 0) pos += parsedTokenLen; pos--; // parse the same pos again, it changed if (tr == NULL) parsedToken = NULL; // To avoid mir_free } if (parsedToken != NULL) mir_free(parsedToken); for (i = 0; i < argc; i ++) mir_free(argv[i]); mir_free(argv); return (TCHAR*)mir_realloc(string, (mir_tstrlen(string)+1)*sizeof(TCHAR)); }