BSTR CMUSHclientDoc::ExportXML(short Type, LPCTSTR Name) { CString strResult; CString strName = Name; // trim spaces, force name to lower-case CheckObjectName (strName, false); char * p = NULL; try { CMemFile f; // open memory file for writing CArchive ar(&f, CArchive::store); // see if trigger exists, if not return EMPTY switch (Type) { case 0: // trigger { CTrigger * t; if (GetTriggerMap ().Lookup (strName, t)) { Save_Header_XML (ar, "triggers", false); Save_One_Trigger_XML (ar, t); Save_Footer_XML (ar, "triggers"); } // end of item existing } break; case 1: // alias { CAlias * t; if (GetAliasMap ().Lookup (strName, t)) { Save_Header_XML (ar, "aliases", false); Save_One_Alias_XML (ar, t); Save_Footer_XML (ar, "aliases"); } // end of item existing } break; case 2: // timer { CTimer * t; if (GetTimerMap ().Lookup (strName, t)) { Save_Header_XML (ar, "timers", false); Save_One_Timer_XML (ar, t); Save_Footer_XML (ar, "timers"); } // end of item existing } break; case 3: // macro { for (int i = 0; i < NUMITEMS (strMacroDescriptions); i++) { if (strMacroDescriptions [i].CompareNoCase (strName) == 0) { Save_Header_XML (ar, "macros", false); Save_One_Macro_XML (ar, i); Save_Footer_XML (ar, "macros"); } // end of item existing } // end of finding which one } break; case 4: // variable { CVariable * t; if (GetVariableMap ().Lookup (strName, t)) { Save_Header_XML (ar, "variables", false); Save_One_Variable_XML (ar, t); Save_Footer_XML (ar, "variables"); } // end of item existing } break; case 5: // keypad { for (int i = 0; i < NUMITEMS (strKeypadNames); i++) { if (strKeypadNames [i].CompareNoCase (strName) == 0) { Save_Header_XML (ar, "keypad", false); Save_One_Keypad_XML (ar, i); Save_Footer_XML (ar, "keypad"); } // end of item existing } // end of finding which one } break; } // end of switch ar.Close(); int nLength = f.GetLength (); p = (char *) f.Detach (); strResult = CString (p, nLength); free (p); // remove memory allocated in CMemFile p = NULL; } // end of try block catch (CException* e) { if (p) free (p); // remove memory allocated in CMemFile e->Delete(); strResult.Empty (); } // end of catch return strResult.AllocSysString(); } // end of CMUSHclientDoc::ExportXML
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