示例#1
0
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