CString CMUSHclientDoc::FixSendText (const CString strSource, const int iSendTo, const t_regexp * regexp, // regular expression (for triggers, aliases) const char * sLanguage, // language for send-to-script const bool bMakeWildcardsLower, const bool bExpandVariables, // convert @foo const bool bExpandWildcards, // convert %x const bool bFixRegexps, // convert \ to \\ for instance const bool bIsRegexp, // true = regexp trigger const bool bThrowExceptions) { CString strOutput; // result of expansion const char * pText, * pStartOfGroup; pText = pStartOfGroup = strSource; while (*pText) { switch (*pText) { /* -------------------------------------------------------------------- * * Variable expansion - @foo becomes <contents of foo> * * -------------------------------------------------------------------- */ case '@': { if (!bExpandVariables) { pText++; // just copy the @ break; } // copy up to the @ sign strOutput += CString (pStartOfGroup, pText - pStartOfGroup); pText++; // skip the @ // @@ becomes @ if (*pText == '@') { pStartOfGroup = ++pText; strOutput += "@"; continue; } const char * pName; bool bEscape = bFixRegexps; // syntax @!variable defeats the escaping if (*pText == '!') { pText++; bEscape = false; } pName = pText; // find end of variable name while (*pText) if (*pText == '_' || isalnum ((unsigned char) *pText)) pText++; else break; /* -------------------------------------------------------------------- * * We have a variable - look it up and do internal replacements * * -------------------------------------------------------------------- */ CString strVariableName (pName, pText - pName); if (strVariableName.IsEmpty ()) { if (bThrowExceptions) ThrowErrorException ("@ must be followed by a variable name"); } // end of no variable name else { CVariable * variable_item; strVariableName.MakeLower (); if (GetVariableMap ().Lookup (strVariableName, variable_item)) { // fix up so regexps don't get confused with [ etc. inside variable CString strVariableContents; if (bEscape) { const char * pi; // allow for doubling in size, plus terminating null char * po = strVariableContents.GetBuffer ((variable_item->strContents.GetLength () * 2) + 1); for (pi = variable_item->strContents; *pi; pi++) { if (((unsigned char) *pi) < ' ') continue; // drop non-printables if (bIsRegexp) if (!isalnum ((unsigned char) *pi) && *pi != ' ') { *po++ = '\\'; // escape it *po++ = *pi; } else *po++ = *pi; // just copy it else // not regexp if (*pi != '*') *po++ = *pi; // copy all except asterisks } *po = 0; // terminating null strVariableContents.ReleaseBuffer (-1); } // end of escaping wanted else strVariableContents = variable_item->strContents; // in the "send" box may need to convert script expansions etc. if (!bFixRegexps) strVariableContents = FixWildcard ((const char *) strVariableContents, false, // not force variables to lowercase iSendTo, sLanguage).c_str (); // fix up HTML sequences if we are sending it to a log file if (m_bLogHTML && iSendTo == eSendToLogFile) strVariableContents = FixHTMLString (strVariableContents); strOutput += strVariableContents; } // end of name existing in variable map else { if (bThrowExceptions) ThrowErrorException ("Variable '%s' is not defined.", (LPCTSTR) strVariableName); } // end of variable does not exist } // end of not empty name // get ready for next batch from beyond the variable pStartOfGroup = pText; } break; // end of '@' /* -------------------------------------------------------------------- * * Wildcard substitution - %1 becomes <contents of wildcard 1> * * - %<foo> becomes <contents of wildcard "foo" * * - %% becomes % * * -------------------------------------------------------------------- */ case '%': if (!bExpandWildcards) { pText++; // just copy the % break; } // see what comes after the % symbol switch (pText [1]) { /* -------------------------------------------------------------------- * * %% * * -------------------------------------------------------------------- */ case '%': // copy up to - and including - the percent sign strOutput += CString (pStartOfGroup, pText - pStartOfGroup + 1); // get ready for next batch from beyond the %% pText += 2; // don't reprocess the %% pStartOfGroup = pText; break; // end of %% /* -------------------------------------------------------------------- * * %0 to %9 * * -------------------------------------------------------------------- */ case '0': // a digit? case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { // copy up to the percent sign strOutput += CString (pStartOfGroup, pText - pStartOfGroup); // output the appropriate replacement text if (regexp) { CString strWildcard = FixWildcard (regexp->GetWildcard (string (1, *++pText)), bMakeWildcardsLower, iSendTo, sLanguage).c_str (); // fix up HTML sequences if we are sending it to a log file if (m_bLogHTML && iSendTo == eSendToLogFile) strWildcard = FixHTMLString (strWildcard); strOutput += strWildcard; } // get ready for next batch from beyond the digit pStartOfGroup = ++pText; } break; // end of %(digit) (eg. %2) /* -------------------------------------------------------------------- * * %<name> * * -------------------------------------------------------------------- */ case '<': { // copy up to the % sign strOutput += CString (pStartOfGroup, pText - pStartOfGroup); pText +=2; // skip the %< const char * pName = pText; // find end of wildcard name while (*pText) if (*pText != '>') pText++; else break; string sWildcardName (pName, pText - pName); if (!sWildcardName.empty () && regexp) { CString strWildcard = FixWildcard (regexp->GetWildcard (sWildcardName), bMakeWildcardsLower, iSendTo, sLanguage).c_str (); // fix up HTML sequences if we are sending it to a log file if (m_bLogHTML && iSendTo == eSendToLogFile) strWildcard = FixHTMLString (strWildcard); strOutput += strWildcard; } // get ready for next batch from beyond the name if (*pText == '>') pText++; pStartOfGroup = pText; } break; // end of %<foo> /* -------------------------------------------------------------------- * * %C - clipboard contents * * -------------------------------------------------------------------- */ case 'C': case 'c': { // copy up to the percent sign strOutput += CString (pStartOfGroup, pText - pStartOfGroup); CString strClipboard; if (GetClipboardContents (strClipboard, m_bUTF_8)) strOutput += strClipboard; else if (bThrowExceptions) ThrowErrorException ("No text on the Clipboard"); // get ready for next batch from beyond the 'c' pText += 2; pStartOfGroup = pText; } break; // end of %c /* -------------------------------------------------------------------- * * %(something else) * * -------------------------------------------------------------------- */ default: pText++; break; } // end of switch on character after '%' break; // end of '%(something)' /* -------------------------------------------------------------------- * * All other characters - just increment pointer so we can copy later * * -------------------------------------------------------------------- */ default: pText++; break; } // end of switch on *pText } // end of not end of string yet // copy last group strOutput += pStartOfGroup; return strOutput; } // end of CMUSHclientDoc::FixSendText
BSTR CMUSHclientDoc::FixupHTML(LPCTSTR StringToConvert) { CString strResult = FixHTMLString (StringToConvert); return strResult.AllocSysString(); } // end of CMUSHclientDoc::FixupHTML