Beispiel #1
0
/// Extracts the nth substring from a delimited string
/// This is a wxWidgets port of MFC's AfxExtractSubString
/// @param string Holds the returned substring
/// @param fullString String to extract the substring from
/// @param subString Zero-based index of the substring to extract
/// @param separator Character used to separator the substrings
/// @return True if the substring was extracted, false if not
bool wxExtractSubString(wxString& string, const wxChar* fullString,
    wxUint32 subString, wxChar separator)
{
    //------Last Verified------//
    // - Nov 27, 2004
    wxCHECK(fullString != (wxChar*)NULL, false);
    
    string.Clear();

    while (subString--)
    {
        fullString = wxStrchr(fullString, separator);
        if (fullString == NULL)
        {
            string.Clear();        // return empty string as well
            return (false);
        }
        fullString++;       // point past the separator
    }
    const wxChar* end = wxStrchr(fullString, separator);
    wxInt32 length = (end == NULL) ? wxStrlen_(fullString) :
        (wxInt32)(end - fullString);
    wxASSERT(length >= 0);
    memcpy(string.GetWriteBuf(length), fullString, length * sizeof(wxChar));
    string.UngetWriteBuf();     // Need to call ReleaseBuffer 
                                // after calling GetBufferSetLength
    return (true);
}
Beispiel #2
0
void CrtTestCase::Strchr()
{
    // test that searching for a wide character in a narrow string simply
    // doesn't find it but doesn't fail with an assert (#11487)
    const wxUniChar smiley = *wxString::FromUTF8("\xe2\x98\xba").begin();

    CPPUNIT_ASSERT( !wxStrchr("hello", smiley) );

    // but searching for an explicitly wide character does find it
    CPPUNIT_ASSERT( wxStrchr(wxString::FromUTF8(":-) == \xe2\x98\xba"),
                    static_cast<wchar_t>(smiley)) );
}
Beispiel #3
0
// -------------------------------------------------------------------------------- //
wxString guFileDnDEncode( const wxString &file )
{
  wxString RetVal;
  wxString HexCode;
  size_t index;
  wxCharBuffer CharBuffer = file.ToUTF8();
  size_t StrLen = strlen( CharBuffer );

  for( index = 0; index < StrLen; index++ )
  {
    wxChar C = CharBuffer[ index ];
    {
      static const wxChar marks[] = wxT( " -_.\"/+!~*()'[]%" ); //~!@#$&*()=:/,;?+'

      if( ( C >= 'a' && C <= 'z' ) ||
          ( C >= 'A' && C <= 'Z' ) ||
          ( C >= '0' && C <= '9' ) ||
          wxStrchr( marks, C ) )
      {
        RetVal += C;
      }
      else
      {
        HexCode.Printf( wxT( "%%%02X" ), C & 0xFF );
        RetVal += HexCode;
      }
    }
  }
  return RetVal;
}
inline wxString GetNextField(const wxString& str, size_t& cookie)
{
	// These are taken to seperate "fields"
	static const wxChar* s_delims = wxT("\t\n\x0b\x0c\r !\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~");
	
	wxString field;
	ECharType curType = ECTNone;
	for (; cookie < str.Length(); ++cookie) {
		wxChar c = str[cookie];

		if ((c >= wxT('0')) && (c <= wxT('9'))) {
			if (curType == ECTText) {
				break;
			}

			curType = ECTInteger;
			field += c;
		} else if (wxStrchr(s_delims, c)) {
			if (curType == ECTNone) {
				continue;
			} else {
				break;
			}
		} else {
			if (curType == ECTInteger) {
				break;
			}

			curType = ECTText;
			field += c;
		}
	}

	return field;
}
Beispiel #5
0
wxString wxFileConfig::GetLocalFileName(const wxChar *szFile)
{
#ifdef __VMS__ // On VMS I saw the problem that the home directory was appended
   // twice for the configuration file. Does that also happen for other
   // platforms?
   wxString str = wxT( '.' ); 
#else
   wxString str = GetLocalDir();
#endif
   
  #if defined( __UNIX__ ) && !defined( __VMS )
    str << wxT('.');
  #endif

  str << szFile;

  #ifdef __WXMSW__
    if ( wxStrchr(szFile, wxT('.')) == NULL )
      str << wxT(".ini");
  #endif


  #ifdef __WXMAC__
     str << " Preferences";
  #endif
  return str;
}
Beispiel #6
0
bool wxGetFullHostName(wxChar *buf, int sz)
{
    bool ok = wxGetHostNameInternal(buf, sz);

    if ( ok )
    {
        if ( !wxStrchr(buf, wxT('.')) )
        {
            struct hostent *host = gethostbyname(wxSafeConvertWX2MB(buf));
            if ( !host )
            {
                wxLogSysError(_("Cannot get the official hostname"));

                ok = false;
            }
            else
            {
                // the canonical name
                wxStrlcpy(buf, wxSafeConvertMB2WX(host->h_name), sz);
            }
        }
        //else: it's already a FQDN (BSD behaves this way)
    }

    return ok;
}
Beispiel #7
0
// -------------------------------------------------------------------------------- //
wxString guURLEncode( const wxString &url )
{
    static const wxChar marks[] = wxT( "-_.\"!~*()'" );

	wxString RetVal;
    wxChar CurChar;

    wxCharBuffer CharBuffer = url.ToUTF8();
	int Index;
	int Count = strlen( CharBuffer );

	for( Index = 0; Index < Count; ++Index )
	{
		CurChar = CharBuffer[ Index ];

        if( ( CurChar >= 'a' && CurChar <= 'z' ) || ( CurChar >= 'A' && CurChar <= 'Z' ) ||
            ( CurChar >= '0' && CurChar <= '9' ) || wxStrchr( marks, CurChar ) )
		{
	        RetVal += CurChar;
	    }
	    else if( CurChar == wxT( ' ' ) )
	    {
		    RetVal += wxT( "+" );
		}
		else
		{
            RetVal += wxString::Format( wxT( "%%%02X" ), CurChar & 0xFF );
		}
	}

    //guLogMessage( wxT( "URLEncode: '%s' => '%s'" ), url.c_str(), RetVal.c_str() );

	return RetVal;
}
Beispiel #8
0
void wxMacConvertNewlines10To13( wxChar * data )
{
    wxChar * buf =  data ;
    while( (buf=wxStrchr(buf,0x0a)) != NULL )
    {
        *buf = 0x0d ;
        buf++ ;
    }
}
Beispiel #9
0
int ecUtils::Chop(const wxString& str, wxArrayString &ar, const wxString& sep,
                  bool bObserveStrings/*=false*/,bool bBackslashQuotes/*=false*/)
{
    ar.Clear();
    
    const wxChar* pszSep = (const wxChar*) sep;
    const wxChar* psz = (const wxChar*) str;
    
    int i=0;
    for(;;){
        // Skip multiple separators
        while(*psz && wxStrchr(pszSep,*psz)){
            psz++;
        }
        if(!*psz){
            return i;
        }
        wxString strTok;
        if(bObserveStrings){
            bool bInString=FALSE;
            do{
                if(*psz == wxT('\\') && bBackslashQuotes && psz[1]){
                    strTok += psz[1];
                    psz++;
                } else if(*psz == wxT('"')){
                    bInString ^= 1;
                } else if (!bInString && *psz && NULL != wxStrchr(pszSep,*psz)) {
                    break;
                } else {
                    strTok+=*psz;
                }
            } while (*++psz);
        } else {
            const wxChar* pszStart=psz;
            do {
                psz++;
            } while (*psz && ! wxStrchr(pszSep,*psz));
            strTok=wxString(pszStart,psz-pszStart);
        }
        ar.Add(strTok);
        i++;
    }
    return ar.GetCount();
}
Beispiel #10
0
bool wxDatabaseConfig::RenameEntry(const wxString& oldName, const wxString& newName) 
{ 
	wxASSERT_MSG(!wxStrchr(oldName, wxCONFIG_PATH_SEPARATOR), wxT("RenameEntry(): paths are not supported")); 

	dbentries entries;
	if ( FindEntries(newName, entries)) return false; 
	entries.clear();
	if (!FindEntries(oldName, entries)) return false; 

	return WriteEntry(entries[0], newName, entries[0].value); 
} 
Beispiel #11
0
bool wxDatabaseConfig::WriteEntry(dbentry& entry, const wxString& name, const wxString& value)
{
	if (name.empty()) return false;
	wxASSERT_MSG(!wxStrchr(name, wxCONFIG_PATH_SEPARATOR), wxT("WriteEntry(): paths are not supported")); 

	m_pStatementSqlEditEntry->SetParamInt(3, entry.id);
	m_pStatementSqlEditEntry->SetParamString(1, name);
	m_pStatementSqlEditEntry->SetParamString(2, value);
	m_self->ExecuteStatement(m_pStatementSqlEditEntry);
	return true;
}
Beispiel #12
0
bool wxRegKey::Rename(const wxString& szNewName)
{
    wxCHECK_MSG( !m_strKey.empty(), false, wxT("registry hives can't be renamed") );

    if ( !Exists() ) {
        wxLogError(_("Registry key '%s' does not exist, cannot rename it."),
                   GetFullName(this));

        return false;
    }

    // do we stay in the same hive?
    bool inSameHive = !wxStrchr(szNewName, REG_SEPARATOR);

    // construct the full new name of the key
    wxRegKey keyDst;

    if ( inSameHive ) {
        // rename the key to the new name under the same parent
        wxString strKey = m_strKey.BeforeLast(REG_SEPARATOR);
        if ( !strKey.empty() ) {
            // don't add '\\' in the start if strFullNewName is empty
            strKey += REG_SEPARATOR;
        }

        strKey += szNewName;

        keyDst.SetName(GetStdKeyFromHkey(m_hRootKey), strKey);
    }
    else {
        // this is the full name already
        keyDst.SetName(szNewName);
    }

    bool ok = keyDst.Create(false /* fail if alredy exists */);
    if ( !ok ) {
        wxLogError(_("Registry key '%s' already exists."),
                   GetFullName(&keyDst));
    }
    else {
        ok = Copy(keyDst) && DeleteSelf();
    }

    if ( !ok ) {
        wxLogError(_("Failed to rename the registry key '%s' to '%s'."),
                   GetFullName(this), GetFullName(&keyDst));
    }
    else {
        m_hRootKey = keyDst.m_hRootKey;
        m_strKey = keyDst.m_strKey;
    }

    return ok;
}
Beispiel #13
0
/*
Returns a string which is equal to the string pointed to by p, but up to the
point where p contains an character that's not allowed.
Allowable characters are letters and numbers, and characters pointed to by
the parameter allowedChars.

For example, if p points to "abcde-@-_", and allowedChars is "-_",
this function returns "abcde-".
*/
static wxString GetOptionName(const wxChar *p,
    const wxChar *allowedChars)
{
    wxString argName;

    while ( *p && (wxIsalnum(*p) || wxStrchr(allowedChars, *p)) )
    {
        argName += *p++;
    }

    return argName;
}
Beispiel #14
0
void wxMacConvertNewlines10To13( wxString * data )
{
    size_t len = data->Length() ;

    if ( data->Length() == 0 || wxStrchr(data->c_str(),0x0a)==NULL)
        return ;

    wxString temp(*data) ;
    wxStringBuffer buf(*data,len ) ;
    memcpy( buf , temp.c_str() , (len+1)*sizeof(wxChar) ) ;
    wxMacConvertNewlines10To13( buf ) ;
}
Beispiel #15
0
/*
Returns a string which is equal to the string pointed to by p, but up to the
point where p contains an character that's not allowed.
Allowable characters are letters and numbers, and characters pointed to by
the parameter allowedChars.

For example, if p points to "abcde-@-_", and allowedChars is "-_",
this function returns "abcde-".
*/
static wxString GetOptionName(wxString::const_iterator p,
                              wxString::const_iterator end,
                              const wxChar *allowedChars)
{
    wxString argName;

    while ( p != end && (wxIsalnum(*p) || wxStrchr(allowedChars, *p)) )
    {
        argName += *p++;
    }

    return argName;
}
Beispiel #16
0
void StringTestCase::Constructors()
{
    CPPUNIT_ASSERT_EQUAL( "", wxString('Z', 0) );
    CPPUNIT_ASSERT_EQUAL( "Z", wxString('Z') );
    CPPUNIT_ASSERT_EQUAL( "ZZZZ", wxString('Z', 4) );
    CPPUNIT_ASSERT_EQUAL( "Hell", wxString("Hello", 4) );
    CPPUNIT_ASSERT_EQUAL( "Hello", wxString("Hello", 5) );

#if wxUSE_UNICODE
    CPPUNIT_ASSERT_EQUAL( L"", wxString(L'Z', 0) );
    CPPUNIT_ASSERT_EQUAL( L"Z", wxString(L'Z') );
    CPPUNIT_ASSERT_EQUAL( L"ZZZZ", wxString(L'Z', 4) );
    CPPUNIT_ASSERT_EQUAL( L"Hell", wxString(L"Hello", 4) );
    CPPUNIT_ASSERT_EQUAL( L"Hello", wxString(L"Hello", 5) );
#endif // wxUSE_UNICODE

    CPPUNIT_ASSERT_EQUAL( 0, wxString(wxString(), 17).length() );

#if wxUSE_UNICODE_UTF8
    // This string has 3 characters (<h>, <e'> and <l>), not 4 when using UTF-8
    // locale!
    if ( wxConvLibc.IsUTF8() )
    {
        wxString s3("h\xc3\xa9llo", 4);
        CPPUNIT_ASSERT_EQUAL( 3, s3.length() );
        CPPUNIT_ASSERT_EQUAL( 'l', (char)s3[2] );
    }
#endif // wxUSE_UNICODE_UTF8


    static const char *s = "?really!";
    const char *start = wxStrchr(s, 'r');
    const char *end = wxStrchr(s, '!');
    CPPUNIT_ASSERT_EQUAL( "really", wxString(start, end) );

    // test if creating string from NULL C pointer works:
    CPPUNIT_ASSERT_EQUAL( "", wxString((const char *)NULL) );
}
Beispiel #17
0
wxString wxFileConfig::GetGlobalFileName(const wxChar *szFile)
{
  wxString str = GetGlobalDir();
  str << szFile;

  if ( wxStrchr(szFile, wxT('.')) == NULL )
  #ifdef  __UNIX__
    str << wxT(".conf");
  #elif defined( __WXMAC__ )
     str << " Preferences";
  #else   // Windows
    str << wxT(".ini");
  #endif  // UNIX/Win

  return str;
}
Beispiel #18
0
bool wxGetHostName(wxChar *buf, int sz)
{
    bool ok = wxGetHostNameInternal(buf, sz);

    if ( ok )
    {
        // BSD systems return the FQDN, we only want the hostname, so extract
        // it (we consider that dots are domain separators)
        wxChar *dot = wxStrchr(buf, wxT('.'));
        if ( dot )
        {
            // nuke it
            *dot = wxT('\0');
        }
    }

    return ok;
}
Beispiel #19
0
bool wxDatabaseConfig::AddEntry(dbentry& parent, const wxString& name, const wxString* value)
{
	if (name.empty()) return false;
	wxASSERT_MSG(!wxStrchr(name, wxCONFIG_PATH_SEPARATOR), wxT("AddEntry(): paths are not supported")); 

	m_pStatementSqlAddEntry->SetParamInt(1, parent.id);
	m_pStatementSqlAddEntry->SetParamString(2, name);
	if (value == NULL)
	{
		m_pStatementSqlAddEntry->SetParamNull(3);
	}
	else
	{
		wxString strValue(*value);
		m_pStatementSqlAddEntry->SetParamString(3, strValue);
	}
	m_self->ExecuteStatement(m_pStatementSqlAddEntry);
	return true;
}
Beispiel #20
0
// sanitize entry or group name: insert '\\' before any special characters
static wxString FilterOutEntryName(const wxString& str)
{
  wxString strResult;
  strResult.Alloc(str.Len());

  for ( const wxChar *pc = str.c_str(); *pc != wxT('\0'); pc++ ) {
    wxChar c = *pc;

    // we explicitly allow some of "safe" chars and 8bit ASCII characters
    // which will probably never have special meaning
    // NB: note that wxCONFIG_IMMUTABLE_PREFIX and wxCONFIG_PATH_SEPARATOR
    //     should *not* be quoted
    if ( !wxIsalnum(c) && !wxStrchr(wxT("@_/-!.*%"), c) && ((c & 0x80) == 0) )
      strResult += wxT('\\');

    strResult += c;
  }

  return strResult;
}
Beispiel #21
0
void wxDatabaseConfig::GetChildren(dbentry& parent, dbentries* groups, dbentries* entries, bool recursive)
{ 
	dbentries wild;
	m_self->FindEntries(parent.path+wxCONFIG_PATH_SEPARATOR+'%', wild);

	for (dbentries::iterator it = wild.begin(); it != wild.end(); ++it)
	{
		wxString localpath(it->path.Right(it->path.Length()-parent.path.Length()-1));
		if (!recursive && wxStrchr(localpath, wxCONFIG_PATH_SEPARATOR)) continue;
		if (it->isgroup)
		{
			if (groups == NULL) continue;
			groups->push_back(*it);
		}
		else
		{
			if (entries == NULL) continue;
			entries->push_back(*it);
		}
	}
}
Beispiel #22
0
bool IsSpaceChar(wxChar c, const wxChar *spaceChars = wxT("\t "))
{
	return wxStrchr(spaceChars, c) != NULL;
}
Beispiel #23
0
bool MfStatusCache::DoLoad(const wxTextFile& file, int version)
{
   bool isFmtOk = true;

   CacheFileFormat fmt;
   if ( version == BuildVersion(1, 1) )
   {
      fmt = CacheFile_1_1;
   }
   else if ( version == BuildVersion(1, 0) )
   {
      fmt = CacheFile_1_0;
   }
   else
   {
      fmt = CacheFile_Max;
   }

   // read the data
   wxString str, name;
   str.Alloc(1024);     // avoid extra memory allocations
   name.Alloc(1024);

   MailFolderStatus status;

   size_t count = file.GetLineCount();
   for ( size_t n = 1; n < count; n++ )
   {
      str = file[n];

      // first get the end of the full folder name knowing that we should
      // skip all "::" as they could have only resulted from quoting a ':'
      // in the folder name and so the loop below looks for the first ':'
      // not followed by another ':'
      const wxChar *p = wxStrchr(str, CACHE_DELIMITER_CH);
      while ( p && p[1] == CACHE_DELIMITER_CH )
      {
         p = wxStrchr(p + 2, CACHE_DELIMITER_CH);
      }

      if ( !p )
      {
         wxLogError(_("Missing '%c' at line %d."), CACHE_DELIMITER_CH, n + 1);

         isFmtOk = false;

         break;
      }

      name = wxString(str.c_str(), p);

      // now unquote ':' which were doubled by Save()
      name.Replace(CACHE_DELIMITER CACHE_DELIMITER, CACHE_DELIMITER);

      // get the rest
      status.Init();
      switch ( fmt )
      {
         case CacheFile_1_0:
            isFmtOk = wxSscanf(p + 1,
                             _T("%lu") CACHE_DELIMITER
                             _T("%lu") CACHE_DELIMITER
                             _T("%lu"),
                             &status.total,
                             &status.unread,
                             &status.flagged) == 3;
            break;

         default:
            FAIL_MSG( _T("unknown cache file format") );
            // fall through nevertheless

         case CacheFile_1_1:
            isFmtOk = wxSscanf(p + 1,
                             _T("%lu") CACHE_DELIMITER
                             _T("%lu") CACHE_DELIMITER 
                             _T("%lu") CACHE_DELIMITER
                             _T("%lu"),
                             &status.total,
                             &status.newmsgs,
                             &status.unread,
                             &status.flagged) == 4;
      }

      if ( !isFmtOk )
      {
         wxLogError(_("Missing field(s) at line %d."), n + 1);

         break;
      }

      // ignore the folders which were deleted during the last program run
      MFolder *folder = MFolder::Get(name);
      if ( folder )
      {
         folder->DecRef();

         // do add the entry to the cache
         size_t entry = m_folderNames.Add(name);
         m_folderData.Insert(new MailFolderStatus(status), entry);
      }
      else
      {
         wxLogDebug(_T("Removing deleted folder '%s' from status cache."),
                    name.c_str());
      }
   }

   if ( !isFmtOk )
   {
      wxLogWarning(_("Your mail folder status cache file (%s) was corrupted."),
                   file.GetName());

      return false;
   }

   return true;
}
Beispiel #24
0
bool wxLocale::Init(int language, int flags)
{
#if WXWIN_COMPATIBILITY_2_8
    wxASSERT_MSG( !(flags & wxLOCALE_CONV_ENCODING),
                  wxS("wxLOCALE_CONV_ENCODING is no longer supported, add charset to your catalogs") );
#endif

    bool ret = true;

    int lang = language;
    if (lang == wxLANGUAGE_DEFAULT)
    {
        // auto detect the language
        lang = GetSystemLanguage();
    }

    // We failed to detect system language, so we will use English:
    if (lang == wxLANGUAGE_UNKNOWN)
    {
        return false;
    }

    const wxLanguageInfo *info = GetLanguageInfo(lang);

    // Unknown language:
    if (info == NULL)
    {
        wxLogError(wxS("Unknown language %i."), lang);
        return false;
    }

    wxString name = info->Description;
    wxString canonical = info->CanonicalName;
    wxString locale;

    // Set the locale:
#if defined(__OS2__)
    const char *retloc = wxSetlocale(LC_ALL , wxEmptyString);
#elif defined(__UNIX__) && !defined(__WXMAC__)
    if (language != wxLANGUAGE_DEFAULT)
        locale = info->CanonicalName;

    const char *retloc = wxSetlocaleTryUTF8(LC_ALL, locale);

    const wxString langOnly = ExtractLang(locale);
    if ( !retloc )
    {
        // Some C libraries don't like xx_YY form and require xx only
        retloc = wxSetlocaleTryUTF8(LC_ALL, langOnly);
    }

#if wxUSE_FONTMAP
    // some systems (e.g. FreeBSD and HP-UX) don't have xx_YY aliases but
    // require the full xx_YY.encoding form, so try using UTF-8 because this is
    // the only thing we can do generically
    //
    // TODO: add encodings applicable to each language to the lang DB and try
    //       them all in turn here
    if ( !retloc )
    {
        const wxChar **names =
            wxFontMapperBase::GetAllEncodingNames(wxFONTENCODING_UTF8);
        while ( *names )
        {
            retloc = wxSetlocale(LC_ALL, locale + wxS('.') + *names++);
            if ( retloc )
                break;
        }
    }
#endif // wxUSE_FONTMAP

    if ( !retloc )
    {
        // Some C libraries (namely glibc) still use old ISO 639,
        // so will translate the abbrev for them
        wxString localeAlt;
        if ( langOnly == wxS("he") )
            localeAlt = wxS("iw") + ExtractNotLang(locale);
        else if ( langOnly == wxS("id") )
            localeAlt = wxS("in") + ExtractNotLang(locale);
        else if ( langOnly == wxS("yi") )
            localeAlt = wxS("ji") + ExtractNotLang(locale);
        else if ( langOnly == wxS("nb") )
            localeAlt = wxS("no_NO");
        else if ( langOnly == wxS("nn") )
            localeAlt = wxS("no_NY");

        if ( !localeAlt.empty() )
        {
            retloc = wxSetlocaleTryUTF8(LC_ALL, localeAlt);
            if ( !retloc )
                retloc = wxSetlocaleTryUTF8(LC_ALL, ExtractLang(localeAlt));
        }
    }

    if ( !retloc )
        ret = false;

#ifdef __AIX__
    // at least in AIX 5.2 libc is buggy and the string returned from
    // setlocale(LC_ALL) can't be passed back to it because it returns 6
    // strings (one for each locale category), i.e. for C locale we get back
    // "C C C C C C"
    //
    // this contradicts IBM own docs but this is not of much help, so just work
    // around it in the crudest possible manner
    char* p = const_cast<char*>(wxStrchr(retloc, ' '));
    if ( p )
        *p = '\0';
#endif // __AIX__

#elif defined(__WIN32__)
    const char *retloc = "C";
    if ( language != wxLANGUAGE_DEFAULT )
    {
        if ( info->WinLang == 0 )
        {
            wxLogWarning(wxS("Locale '%s' not supported by OS."), name.c_str());
            // retloc already set to "C"
        }
        else // language supported by Windows
        {
            // Windows CE doesn't have SetThreadLocale() and there doesn't seem
            // to be any equivalent
#ifndef __WXWINCE__
            const wxUint32 lcid = info->GetLCID();

            // change locale used by Windows functions
            ::SetThreadLocale(lcid);
#endif

            // and also call setlocale() to change locale used by the CRT
            locale = info->GetLocaleName();
            if ( locale.empty() )
            {
                ret = false;
            }
            else // have a valid locale
            {
                retloc = wxSetlocale(LC_ALL, locale);
            }
        }
    }
    else // language == wxLANGUAGE_DEFAULT
    {
        retloc = wxSetlocale(LC_ALL, wxEmptyString);
    }

#if wxUSE_UNICODE && (defined(__VISUALC__) || defined(__MINGW32__))
    // VC++ setlocale() (also used by Mingw) can't set locale to languages that
    // can only be written using Unicode, therefore wxSetlocale() call fails
    // for such languages but we don't want to report it as an error -- so that
    // at least message catalogs can be used.
    if ( !retloc )
    {
        if ( wxGetANSICodePageForLocale(LOCALE_USER_DEFAULT).empty() )
        {
            // we set the locale to a Unicode-only language, don't treat the
            // inability of CRT to use it as an error
            retloc = "C";
        }
    }
#endif // CRT not handling Unicode-only languages

    if ( !retloc )
        ret = false;
#elif defined(__WXMAC__)
    if (lang == wxLANGUAGE_DEFAULT)
        locale = wxEmptyString;
    else
        locale = info->CanonicalName;

    const char *retloc = wxSetlocale(LC_ALL, locale);

    if ( !retloc )
    {
        // Some C libraries don't like xx_YY form and require xx only
        retloc = wxSetlocale(LC_ALL, ExtractLang(locale));
    }
#else
    wxUnusedVar(flags);
    return false;
    #define WX_NO_LOCALE_SUPPORT
#endif

#ifndef WX_NO_LOCALE_SUPPORT
    if ( !ret )
    {
        wxLogWarning(_("Cannot set locale to language \"%s\"."), name.c_str());

        // continue nevertheless and try to load at least the translations for
        // this language
    }

    if ( !DoInit(name, canonical, retloc) )
    {
        ret = false;
    }

    if (IsOk()) // setlocale() succeeded
        m_language = lang;

    // NB: don't use 'lang' here, 'language'
    wxTranslations *t = wxTranslations::Get();
    if ( t )
    {
        t->SetLanguage(static_cast<wxLanguage>(language));

        if ( flags & wxLOCALE_LOAD_DEFAULT )
            t->AddStdCatalog();
    }

    return ret;
#endif // !WX_NO_LOCALE_SUPPORT
}
Beispiel #25
0
/* static */
wxString wxFileType::ExpandCommand(const wxString& command,
                                   const wxFileType::MessageParameters& params)
{
    bool hasFilename = false;

    wxString str;
    for ( const wxChar *pc = command.c_str(); *pc != wxT('\0'); pc++ ) {
        if ( *pc == wxT('%') ) {
            switch ( *++pc ) {
                case wxT('s'):
                    // '%s' expands into file name (quoted because it might
                    // contain spaces) - except if there are already quotes
                    // there because otherwise some programs may get confused
                    // by double double quotes
#if 0
                    if ( *(pc - 2) == wxT('"') )
                        str << params.GetFileName();
                    else
                        str << wxT('"') << params.GetFileName() << wxT('"');
#endif
                    str << params.GetFileName();
                    hasFilename = true;
                    break;

                case wxT('t'):
                    // '%t' expands into MIME type (quote it too just to be
                    // consistent)
                    str << wxT('\'') << params.GetMimeType() << wxT('\'');
                    break;

                case wxT('{'):
                    {
                        const wxChar *pEnd = wxStrchr(pc, wxT('}'));
                        if ( pEnd == NULL ) {
                            wxString mimetype;
                            wxLogWarning(_("Unmatched '{' in an entry for mime type %s."),
                                         params.GetMimeType().c_str());
                            str << wxT("%{");
                        }
                        else {
                            wxString param(pc + 1, pEnd - pc - 1);
                            str << wxT('\'') << params.GetParamValue(param) << wxT('\'');
                            pc = pEnd;
                        }
                    }
                    break;

                case wxT('n'):
                case wxT('F'):
                    // TODO %n is the number of parts, %F is an array containing
                    //      the names of temp files these parts were written to
                    //      and their mime types.
                    break;

                default:
                    wxLogDebug(wxT("Unknown field %%%c in command '%s'."),
                               *pc, command.c_str());
                    str << *pc;
            }
        }
        else {
            str << *pc;
        }
    }

    // metamail(1) man page states that if the mailcap entry doesn't have '%s'
    // the program will accept the data on stdin so normally we should append
    // "< %s" to the end of the command in such case, but not all commands
    // behave like this, in particular a common test is 'test -n "$DISPLAY"'
    // and appending "< %s" to this command makes the test fail... I don't
    // know of the correct solution, try to guess what we have to do.

    // test now carried out on reading file so test should never get here
    if ( !hasFilename && !str.empty()
#ifdef __UNIX__
                      && !str.StartsWith(_T("test "))
#endif // Unix
       ) {
        str << wxT(" < '") << params.GetFileName() << wxT('\'');
    }

    return str;
}
Beispiel #26
0
void frmMainConfig::DisplayFile(const wxString &str)
{
	lines.Clear();

	filetype = wxTextFileType_Unix;
	wxStringTokenizer strtok;
	wxArrayString *unknownCategory = 0;

	if (str.Find('\r') >= 0)
	{
		if (str.Find(wxT("\n\r")) >= 0 || str.Find(wxT("\r\n")))
			filetype = wxTextFileType_Dos;
		else
			filetype = wxTextFileType_Mac;

		strtok.SetString(wxTextBuffer::Translate(str, wxTextFileType_Unix), wxT("\n"), wxTOKEN_RET_EMPTY);
	}
	else
		strtok.SetString(str, wxT("\n"), wxTOKEN_RET_EMPTY);

	while (strtok.HasMoreTokens())
	{
		pgConfigOrgLine *line = new pgConfigOrgLine(strtok.GetNextToken());
		lines.Add(line);

		// identify option
		bool isComment = false;
		const wxChar *p = line->text.c_str();

		// identify keywords
		while (*p && wxStrchr(wxT("# \n"), *p))
		{
			if (*p == '#')
				isComment = true;
			p++;
		}

		if (!*p)
			isComment = true;

		line->isComment = isComment;

		const wxChar *p2 = p;
		while (*p2 && *p2 != '#' && *p2 != ' ' && *p2 != '\t' && *p2 != '=')
			p2++;

		if (p2 != p)
		{
			wxString keyword = line->text.Mid(p - line->text.c_str(), p2 - p);

			pgSettingItemHashmap::iterator it = options.find(keyword);

			pgSettingItem *item;
			if (it == options.end())
			{
				if (isComment)
					continue;

				item = new pgSettingItem;
				item->name = keyword;
				item->category = _("Unknown");
				item->short_desc = _("Unknown option");
				item->extra_desc = _("This option is present in the configuration file, but not known to the configuration tool.");
				item->SetType(wxT("string"));

				options[item->name] = item;

				if (!unknownCategory)
				{
					unknownCategory = new wxArrayString;
					categories[item->category] = unknownCategory;
				}
				unknownCategory->Add(item->name);
			}
			else
				item = it->second;


			if (!isComment || !item->orgLine || item->orgLine->isComment)
			{
				line->item = item;
				if (item->orgLine)
					item->orgLine->item = 0;
				item->orgLine = line;
			}
			while (*p2 && *p2 != '=')
				p2++;

			p2++;   // skip =
			while (*p2 && wxStrchr(wxT(" \t"), *p2))
				p2++;

			wxChar quoteChar = 0;
			if (wxStrchr(wxT("'\""), *p2))
				quoteChar = *p2++;

			const wxChar *p3 = p2;
			while (*p3)
			{
				if (*p3 == quoteChar || (!quoteChar && wxStrchr(wxT(" \t#"), *p3)))
					break;
				p3++;
			}
			if (p2 != p3)
			{
				line->value = line->text.Mid(p2 - line->text.c_str(), p3 - p2);
				if (quoteChar)
					p3++;

				const wxChar *p4 = p3;
				while (*p4 && wxStrchr(wxT(" \t#"), *p4))
					p4++;

				line->commentIndent = line->text.Mid(p3 - line->text.c_str(), p4 - p3);
				line->comment = p4;
			}
		}
	}

	cfgList->DeleteAllItems();

	// we want to show options ordered by category/name
	// category might be localized, and we want a distinct category ordering

	FillList(wxT("listen_addresses"));          // Connections and Authentication / Connection Settings
	FillList(wxT("authentication_timeout"));    // Connections and Authentication / Security and Authentication
	FillList(wxT("check_function_bodies"));     // Client Connection Defaults / Statement Behaviour
	FillList(wxT("lc_messages"));               // Client Connection Defaults / Locale and Formatting
	FillList(wxT("explain_pretty_print"));      // Client Connection Defaults / Other Defaults
	FillList(wxT("enable_hashjoin"));           // Query Tuning / Planner Method Configuration
	FillList(wxT("cpu_operator_cost"));         // Query Tuning / Planner Cost Constants
	if (!conn || !conn->GetIsGreenplum())       // Greenplum doesn't have the Genetic Query Optimizer
		FillList(wxT("geqo"));                  // Query Tuning / Genetic Query Optimizer
	FillList(wxT("default_statistics_target")); // Query Tuning / Other Planner Options
	FillList(wxT("deadlock_timeout"));          // Lock Management
	FillList(wxT("shared_buffers"));            // Resource Usage / Memory
	FillList(wxT("max_fsm_pages"));             // Resource Usage / Free Space Map
	FillList(wxT("bgwriter_delay"));            // Resource Usage
	FillList(wxT("max_files_per_process"));     // Resource Usage / Kernel Resources
	FillList(wxT("log_connections"));           // Reporting and Logging / What to Log
	FillList(wxT("client_min_messages"));       // Reporting and Logging / When to Log
	FillList(wxT("log_destination"));           // Reporting and Logging / Where to Log
	FillList(wxT("stats_command_string"), wxT("track_activities"));      // Statistics / Query and Index Statistics Collector
	FillList(wxT("log_executor_stats"));        // Statistics / Monitoring
	FillList(wxT("fsync"));                     // Write-Ahead Log / Settings
	FillList(wxT("checkpoint_segments"));       // Write-Ahead Log / Checkpoints
	FillList(wxT("add_missing_from"));          // Version and Platform Compatibility / Previous PostgreSQL Version
	FillList(wxT("transform_null_equals"));     // Version and Platform Compatibility / Other Platforms and Clients
	if (!conn || !conn->GetIsGreenplum())       // Greenplum doesn't have trace_notify visible
		FillList(wxT("trace_notify"));          // Developer Options
	FillList(wxT("hba_file"));                  // Ungrouped


	// for all we didn't get
	while (!categories.empty())
	{
		pgCategoryHashmap::iterator it = categories.begin();
		wxString missed = it->first;
		FillList(it->second);
		categories.erase(it);
	}
}
Beispiel #27
0
int wxCmdLineParser::Parse(bool showUsage)
{
    bool maybeOption = true;    // can the following arg be an option?
    bool ok = true;             // true until an error is detected
    bool helpRequested = false; // true if "-h" was given
    bool hadRepeatableParam = false; // true if found param with MULTIPLE flag

    size_t currentParam = 0;    // the index in m_paramDesc

    size_t countParam = m_data->m_paramDesc.GetCount();
    wxString errorMsg;

    Reset();

    // parse everything
    wxString arg;
    size_t count = m_data->m_arguments.size();
    for ( size_t n = 1; ok && (n < count); n++ )    // 0 is program name
    {
        arg = m_data->m_arguments[n];

        // special case: "--" should be discarded and all following arguments
        // should be considered as parameters, even if they start with '-' and
        // not like options (this is POSIX-like)
        if ( arg == wxT("--") )
        {
            maybeOption = false;

            continue;
        }

        // empty argument or just '-' is not an option but a parameter
        if ( maybeOption && arg.length() > 1 &&
                // FIXME-UTF8: use wc_str() after removing ANSI build
                wxStrchr(m_data->m_switchChars.c_str(), arg[0u]) )
        {
            bool isLong;
            wxString name;
            int optInd = wxNOT_FOUND;   // init to suppress warnings

            // an option or a switch: find whether it's a long or a short one
            if ( arg.length() >= 3 && arg[0u] == wxT('-') && arg[1u] == wxT('-') )
            {
                // a long one
                isLong = true;

                // Skip leading "--"
                wxString::const_iterator p = arg.begin() + 2;

                bool longOptionsEnabled = AreLongOptionsEnabled();

                name = GetLongOptionName(p, arg.end());

                if (longOptionsEnabled)
                {
                    optInd = m_data->FindOptionByLongName(name);
                    if ( optInd == wxNOT_FOUND )
                    {
                        errorMsg << wxString::Format(_("Unknown long option '%s'"), name.c_str())
                                 << wxT('\n');
                    }
                }
                else
                {
                    optInd = wxNOT_FOUND; // Sanity check

                    // Print the argument including leading "--"
                    name.Prepend( wxT("--") );
                    errorMsg << wxString::Format(_("Unknown option '%s'"), name.c_str())
                             << wxT('\n');
                }

            }
            else // not a long option
            {
                isLong = false;

                // a short one: as they can be cumulated, we try to find the
                // longest substring which is a valid option
                wxString::const_iterator p = arg.begin() + 1;

                name = GetShortOptionName(p, arg.end());

                size_t len = name.length();
                do
                {
                    if ( len == 0 )
                    {
                        // we couldn't find a valid option name in the
                        // beginning of this string
                        errorMsg << wxString::Format(_("Unknown option '%s'"), name.c_str())
                                 << wxT('\n');

                        break;
                    }
                    else
                    {
                        optInd = m_data->FindOption(name.Left(len));

                        // will try with one character less the next time
                        len--;
                    }
                }
                while ( optInd == wxNOT_FOUND );

                len++;  // compensates extra len-- above
                if ( (optInd != wxNOT_FOUND) && (len != name.length()) )
                {
                    // first of all, the option name is only part of this
                    // string
                    name = name.Left(len);

                    // our option is only part of this argument, there is
                    // something else in it - it is either the value of this
                    // option or other switches if it is a switch
                    if ( m_data->m_options[(size_t)optInd].kind
                            == wxCMD_LINE_SWITCH )
                    {
                        // pretend that all the rest of the argument is the
                        // next argument, in fact
                        wxString arg2 = arg[0u];
                        arg2 += arg.Mid(len + 1); // +1 for leading '-'

                        m_data->m_arguments.insert
                            (m_data->m_arguments.begin() + n + 1, arg2);
                        count++;

                        // only leave the part which wasn't extracted into the
                        // next argument in this one
                        arg = arg.Left(len + 1);
                    }
                    //else: it's our value, we'll deal with it below
                }
            }

            if ( optInd == wxNOT_FOUND )
            {
                ok = false;

                continue;   // will break, in fact
            }

            // look at what follows:

            // +1 for leading '-'
            wxString::const_iterator p = arg.begin() + 1 + name.length();
            wxString::const_iterator end = arg.end();

            if ( isLong )
                ++p;    // for another leading '-'

            wxCmdLineOption& opt = m_data->m_options[(size_t)optInd];
            if ( opt.kind == wxCMD_LINE_SWITCH )
            {
                // we must check that there is no value following the switch
                if ( p != arg.end() )
                {
                    errorMsg << wxString::Format(_("Unexpected characters following option '%s'."), name.c_str())
                             << wxT('\n');
                    ok = false;
                }
                else // no value, as expected
                {
                    // nothing more to do
                    opt.SetHasValue();

                    if ( opt.flags & wxCMD_LINE_OPTION_HELP )
                    {
                        helpRequested = true;

                        // it's not an error, but we still stop here
                        ok = false;
                    }
                }
            }
            else // it's an option. not a switch
            {
                switch ( p == end ? '\0' : (*p).GetValue() )
                {
                    case '=':
                    case ':':
                        // the value follows
                        ++p;
                        break;

                    case '\0':
                        // the value is in the next argument
                        if ( ++n == count )
                        {
                            // ... but there is none
                            errorMsg << wxString::Format(_("Option '%s' requires a value."),
                                                         name.c_str())
                                     << wxT('\n');

                            ok = false;
                        }
                        else
                        {
                            // ... take it from there
                            p = m_data->m_arguments[n].begin();
                            end = m_data->m_arguments[n].end();
                        }
                        break;

                    default:
                        // the value is right here: this may be legal or
                        // not depending on the option style
                        if ( opt.flags & wxCMD_LINE_NEEDS_SEPARATOR )
                        {
                            errorMsg << wxString::Format(_("Separator expected after the option '%s'."),
                                                         name.c_str())
                                    << wxT('\n');

                            ok = false;
                        }
                }

                if ( ok )
                {
                    wxString value(p, end);
                    switch ( opt.type )
                    {
                        default:
                            wxFAIL_MSG( wxT("unknown option type") );
                            // still fall through

                        case wxCMD_LINE_VAL_STRING:
                            opt.SetStrVal(value);
                            break;

                        case wxCMD_LINE_VAL_NUMBER:
                            {
                                long val;
                                if ( value.ToLong(&val) )
                                {
                                    opt.SetLongVal(val);
                                }
                                else
                                {
                                    errorMsg << wxString::Format(_("'%s' is not a correct numeric value for option '%s'."),
                                                                 value.c_str(), name.c_str())
                                             << wxT('\n');

                                    ok = false;
                                }
                            }
                            break;

                        case wxCMD_LINE_VAL_DOUBLE:
                            {
                                double val;
                                if ( value.ToDouble(&val) )
                                {
                                    opt.SetDoubleVal(val);
                                }
                                else
                                {
                                    errorMsg << wxString::Format(_("'%s' is not a correct numeric value for option '%s'."),
                                                                 value.c_str(), name.c_str())
                                             << wxT('\n');

                                    ok = false;
                                }
                            }
                            break;

#if wxUSE_DATETIME
                        case wxCMD_LINE_VAL_DATE:
                            {
                                wxDateTime dt;
                                wxString::const_iterator end;
                                if ( !dt.ParseDate(value, &end) || end != value.end() )
                                {
                                    errorMsg << wxString::Format(_("Option '%s': '%s' cannot be converted to a date."),
                                                                 name.c_str(), value.c_str())
                                             << wxT('\n');

                                    ok = false;
                                }
                                else
                                {
                                    opt.SetDateVal(dt);
                                }
                            }
                            break;
#endif // wxUSE_DATETIME
                    }
                }
            }
        }
        else // not an option, must be a parameter
        {
            if ( currentParam < countParam )
            {
                wxCmdLineParam& param = m_data->m_paramDesc[currentParam];

                // TODO check the param type

                m_data->m_parameters.push_back(arg);

                if ( !(param.flags & wxCMD_LINE_PARAM_MULTIPLE) )
                {
                    currentParam++;
                }
                else
                {
                    wxASSERT_MSG( currentParam == countParam - 1,
                                  wxT("all parameters after the one with wxCMD_LINE_PARAM_MULTIPLE style are ignored") );

                    // remember that we did have this last repeatable parameter
                    hadRepeatableParam = true;
                }
            }
            else
            {
                errorMsg << wxString::Format(_("Unexpected parameter '%s'"), arg.c_str())
                         << wxT('\n');

                ok = false;
            }
        }
    }

    // verify that all mandatory options were given
    if ( ok )
    {
        size_t countOpt = m_data->m_options.GetCount();
        for ( size_t n = 0; ok && (n < countOpt); n++ )
        {
            wxCmdLineOption& opt = m_data->m_options[n];
            if ( (opt.flags & wxCMD_LINE_OPTION_MANDATORY) && !opt.HasValue() )
            {
                wxString optName;
                if ( !opt.longName )
                {
                    optName = opt.shortName;
                }
                else
                {
                    if ( AreLongOptionsEnabled() )
                    {
                        optName.Printf( _("%s (or %s)"),
                                        opt.shortName.c_str(),
                                        opt.longName.c_str() );
                    }
                    else
                    {
                        optName.Printf( wxT("%s"),
                                        opt.shortName.c_str() );
                    }
                }

                errorMsg << wxString::Format(_("The value for the option '%s' must be specified."),
                                             optName.c_str())
                         << wxT('\n');

                ok = false;
            }
        }

        for ( ; ok && (currentParam < countParam); currentParam++ )
        {
            wxCmdLineParam& param = m_data->m_paramDesc[currentParam];
            if ( (currentParam == countParam - 1) &&
                 (param.flags & wxCMD_LINE_PARAM_MULTIPLE) &&
                 hadRepeatableParam )
            {
                // special case: currentParam wasn't incremented, but we did
                // have it, so don't give error
                continue;
            }

            if ( !(param.flags & wxCMD_LINE_PARAM_OPTIONAL) )
            {
                errorMsg << wxString::Format(_("The required parameter '%s' was not specified."),
                                             param.description.c_str())
                         << wxT('\n');

                ok = false;
            }
        }
    }

    // if there was an error during parsing the command line, show this error
    // and also the usage message if it had been requested
    if ( !ok && (!errorMsg.empty() || (helpRequested && showUsage)) )
    {
        wxMessageOutput* msgOut = wxMessageOutput::Get();
        if ( msgOut )
        {
            wxString usage;
            if ( showUsage )
                usage = GetUsageString();

            msgOut->Printf( wxT("%s%s"), usage.c_str(), errorMsg.c_str() );
        }
        else
        {
            wxFAIL_MSG( wxT("no wxMessageOutput object?") );
        }
    }

    return ok ? 0 : helpRequested ? -1 : 1;
}
Beispiel #28
0
static CharType *wxDoExpandPath(CharType *buf, const wxString& name)
{
    CharType *d, *s, *nm;
    CharType        lnm[_MAXPATHLEN];
    int             q;

    // Some compilers don't like this line.
//    const CharType    trimchars[] = wxT("\n \t");

    CharType      trimchars[4];
    trimchars[0] = wxT('\n');
    trimchars[1] = wxT(' ');
    trimchars[2] = wxT('\t');
    trimchars[3] = 0;

    static const CharType SEP = wxFILE_SEP_PATH;
#ifdef __WINDOWS__
    //wxUnix2DosFilename(path);
#endif

    buf[0] = wxT('\0');
    if (name.empty())
        return buf;
    nm = ::MYcopystring(static_cast<const CharType*>(name.c_str())); // Make a scratch copy
    CharType *nm_tmp = nm;

    /* Skip leading whitespace and cr */
    while (wxStrchr(trimchars, *nm) != NULL)
        nm++;
    /* And strip off trailing whitespace and cr */
    s = nm + (q = wxStrlen(nm)) - 1;
    while (q-- && wxStrchr(trimchars, *s) != NULL)
        *s = wxT('\0');

    s = nm;
    d = lnm;
#ifdef __WINDOWS__
    q = FALSE;
#else
    q = nm[0] == wxT('\\') && nm[1] == wxT('~');
#endif

    /* Expand inline environment variables */
    while ((*d++ = *s) != 0) {
#  ifndef __WINDOWS__
        if (*s == wxT('\\')) {
            if ((*(d - 1) = *++s)!=0) {
                s++;
                continue;
            } else
                break;
        } else
#  endif
#ifdef __WINDOWS__
        if (*s++ == wxT('$') && (*s == wxT('{') || *s == wxT(')')))
#else
        if (*s++ == wxT('$'))
#endif
        {
            CharType  *start = d;
            int     braces = (*s == wxT('{') || *s == wxT('('));
            CharType  *value;
            while ((*d++ = *s) != 0)
                if (braces ? (*s == wxT('}') || *s == wxT(')')) : !(wxIsalnum(*s) || *s == wxT('_')) )
                    break;
                else
                    s++;
            *--d = 0;
            value = wxGetenv(braces ? start + 1 : start);
            if (value) {
                for ((d = start - 1); (*d++ = *value++) != 0;)
                {
                    // Empty
                }

                d--;
                if (braces && *s)
                    s++;
            }
        }
    }

    /* Expand ~ and ~user */
    wxString homepath;
    nm = lnm;
    if (nm[0] == wxT('~') && !q)
    {
        /* prefix ~ */
        if (nm[1] == SEP || nm[1] == 0)
        {        /* ~/filename */
            homepath = wxGetUserHome(wxEmptyString);
            if (!homepath.empty()) {
                s = (CharType*)(const CharType*)homepath.c_str();
                if (*++nm)
                    nm++;
            }
        } else
        {                /* ~user/filename */
            CharType  *nnm;
            for (s = nm; *s && *s != SEP; s++)
            {
                // Empty
            }
            int was_sep; /* MATTHEW: Was there a separator, or NULL? */
            was_sep = (*s == SEP);
            nnm = *s ? s + 1 : s;
            *s = 0;
            homepath = wxGetUserHome(wxString(nm + 1));
            if (homepath.empty())
            {
                if (was_sep) /* replace only if it was there: */
                    *s = SEP;
                s = NULL;
            }
            else
            {
                nm = nnm;
                s = (CharType*)(const CharType*)homepath.c_str();
            }
        }
    }

    d = buf;
    if (s && *s) { /* MATTHEW: s could be NULL if user '~' didn't exist */
        /* Copy home dir */
        while (wxT('\0') != (*d++ = *s++))
          /* loop */;
        // Handle root home
        if (d - 1 > buf && *(d - 2) != SEP)
          *(d - 1) = SEP;
    }
    s = nm;
    while ((*d++ = *s++) != 0)
    {
        // Empty
    }
    delete[] nm_tmp; // clean up alloc
    /* Now clean up the buffer */
    return wxRealPath(buf);
}
Beispiel #29
0
/* static */
wxString wxFileType::ExpandCommand(const wxString& command,
                                   const wxFileType::MessageParameters& params)
{
    bool hasFilename = false;

    // We consider that only the file names with spaces in them need to be
    // handled specially. This is not perfect, but this can be done easily
    // under all platforms while handling the file names with quotes in them,
    // for example, needs to be done differently.
    const bool needToQuoteFilename = params.GetFileName().find_first_of(" \t")
                                        != wxString::npos;

    wxString str;
    for ( const wxChar *pc = command.c_str(); *pc != wxT('\0'); pc++ ) {
        if ( *pc == wxT('%') ) {
            switch ( *++pc ) {
                case wxT('s'):
                    // don't quote the file name if it's already quoted: notice
                    // that we check for a quote following it and not preceding
                    // it as at least under Windows we can have commands
                    // containing "file://%s" (with quotes) in them so the
                    // argument may be quoted even if there is no quote
                    // directly before "%s" itself
                    if ( needToQuoteFilename && pc[1] != '"' )
                        str << wxT('"') << params.GetFileName() << wxT('"');
                    else
                        str << params.GetFileName();
                    hasFilename = true;
                    break;

                case wxT('t'):
                    // '%t' expands into MIME type (quote it too just to be
                    // consistent)
                    str << wxT('\'') << params.GetMimeType() << wxT('\'');
                    break;

                case wxT('{'):
                    {
                        const wxChar *pEnd = wxStrchr(pc, wxT('}'));
                        if ( pEnd == NULL ) {
                            wxString mimetype;
                            wxLogWarning(_("Unmatched '{' in an entry for mime type %s."),
                                         params.GetMimeType().c_str());
                            str << wxT("%{");
                        }
                        else {
                            wxString param(pc + 1, pEnd - pc - 1);
                            str << wxT('\'') << params.GetParamValue(param) << wxT('\'');
                            pc = pEnd;
                        }
                    }
                    break;

                case wxT('n'):
                case wxT('F'):
                    // TODO %n is the number of parts, %F is an array containing
                    //      the names of temp files these parts were written to
                    //      and their mime types.
                    break;

                default:
                    wxLogDebug(wxT("Unknown field %%%c in command '%s'."),
                               *pc, command.c_str());
                    str << *pc;
            }
        }
        else {
            str << *pc;
        }
    }

    // metamail(1) man page states that if the mailcap entry doesn't have '%s'
    // the program will accept the data on stdin so normally we should append
    // "< %s" to the end of the command in such case, but not all commands
    // behave like this, in particular a common test is 'test -n "$DISPLAY"'
    // and appending "< %s" to this command makes the test fail... I don't
    // know of the correct solution, try to guess what we have to do.

    // test now carried out on reading file so test should never get here
    if ( !hasFilename && !str.empty()
#ifdef __UNIX__
                      && !str.StartsWith(wxT("test "))
#endif // Unix
       )
    {
        str << wxT(" < ");
        if ( needToQuoteFilename )
            str << '"';
        str << params.GetFileName();
        if ( needToQuoteFilename )
            str << '"';
    }

    return str;
}
Beispiel #30
0
void
PGPFilter::DoProcess(String& text,
                     MessageViewer *viewer,
                     MTextStyle& style)
{
   // do we have something looking like a PGP message?
   //
   // there should be a BEGIN line near the start of the message
   const wxChar *beginNext = NULL;
   const wxChar *start = text.c_str();
   for ( size_t numLines = 0; numLines < 10; numLines++ )
   {
      const wxChar *p = start;
      if ( AdvanceIfMatches(&p, PGP_BEGIN_PREFIX) )
      {
         beginNext = p;
         break;
      }

      // try the next line (but only if not already at the end)
      if ( !*p )
         break;

      p = wxStrchr(start, _T('\n'));
      if ( !p )
         break; // no more text

      start = p + 1; // skip '\n' itself
   }

   if ( beginNext )
   {
      // is the message just signed or encrypted?
      bool isKey = false;
      const bool isSigned = AdvanceIfMatches(&beginNext, _T("SIGNED "));
      if ( !isSigned )
      {
         isKey = AdvanceIfMatches(&beginNext, _T("PUBLIC KEY "));
      }

      // this flag tells us if everything is ok so far -- as soon as it becomes
      // false, we skip all subsequent steps
      // We do not know (yet) what to do with public key blocks, so let's consider
      // that they're not ok.
      // TODO: propose to import it into the keyring?
      bool ok = !isKey;

      if ( ok && !AdvanceIfMatches(&beginNext, PGP_BEGIN_SUFFIX) )
      {
         wxLogWarning(_("The BEGIN line doesn't end with expected suffix."));

         ok = false;
      }

      // end of the PGP part
      const wxChar *end = NULL; // unneeded but suppresses the compiler warning
      const wxChar *endNext = NULL; // same
      if ( ok ) // ok, it starts with something valid
      {
         // now locate the end line
         const wxChar *pc = start + text.length() - 1;

         bool foundEnd = false;
         for ( ;; )
         {
            // optimistically suppose that this line will be the END one
            end = pc + 2;

            // find the beginning of this line
            while ( *pc != '\n' && pc >= start )
            {
               pc--;
            }

            // we took one extra char
            pc++;

            if ( AdvanceIfMatches(&pc, PGP_END_PREFIX) )
            {
               endNext = pc;

               foundEnd = true;
               break;
            }

            // undo the above
            pc--;

            if ( pc < start )
            {
               // we exhausted the message without finding the END line, leave
               // foundEnd at false and exit the loop
               break;
            }

            pc--;
            ASSERT_MSG( *pc == '\r', _T("line doesn't end in\"\\r\\n\"?") );
         }

         if ( !foundEnd )
         {
            wxLogWarning(_("END line not found."));

            ok = false;
         }
      }

      // check that the END line matches the BEGIN one
      if ( ok )
      {
         const wxChar * const suffix = isSigned ? PGP_END_SIG_SUFFIX
                                                : PGP_END_CRYPT_SUFFIX;

         if ( !AdvanceIfMatches(&endNext, suffix) )
         {
            wxLogWarning(_("Mismatch between BEGIN and END lines."));

            ok = false;
         }
      }

      // if everything was ok so far, continue with decoding/verifying
      if ( ok )
      {
         // output the part before the BEGIN line, if any
         String prolog(text.c_str(), start);
         if ( !prolog.empty() )
         {
            m_next->Process(prolog, viewer, style);
         }

         CHECK_RET( m_engine, _T("PGP filter can't work without PGP engine") );

         ClickablePGPInfo *pgpInfo = NULL;
         MCryptoEngineOutputLog *
            log = new MCryptoEngineOutputLog(m_msgView->GetWindow());

         String in(start, end),
                out;
         if ( isSigned )
         {
            // pass everything between start and end to PGP for verification
            const MCryptoEngine::Status
               rc = m_engine->VerifySignature(in, out, log);
            pgpInfo = ClickablePGPInfo::
                        CreateFromSigStatusCode(m_engine, rc, m_msgView, log);

            // if we failed to check the signature, we need to remove the
            // BEGIN/END lines from output ourselves (otherwise it would have
            // been done by VerifySignature() itself)
            if ( rc != MCryptoEngine::OK )
            {
               // beginNext points to the end of BEGIN line, go forward to the
               // end of the headers.
               //
               // Normally the end of the headers must be signalled by a blank
               // line, but in practice some implementations, notably Enigmail
               // used with Thunderbird, put a space in this "empty" line, so
               // accept any line containing only spaces as indicating the end
               // of headers.
               const wxChar* startBody = beginNext;
               for ( ;; )
               {
                  startBody = wxStrstr(startBody, _T("\r\n"));
                  if ( !startBody || startBody >= endNext )
                     break; // end of headers not found

                  startBody += 2; // skip "\r\n" we just matched
                  while ( *startBody == ' ' )
                     startBody++;

                  if ( startBody[0] == '\r' && startBody[1] == '\n' )
                  {
                     // we found the end of the headers
                     startBody += 2;
                     break;
                  }
               }

               if ( startBody && startBody < endNext )
               {
                  // endNext currently points to the end of END PGP SIGNATURE
                  // line, rewind to the PGP_BEGIN_SIG line
                  const wxChar *pc = endNext;
                  for ( ;; )
                  {
                     // find the beginning of this line
                     while ( *pc != '\n' && pc >= start )
                     {
                        pc--;
                     }

                     if ( pc < start )
                     {
                        // we exhausted the message without finding the
                        // PGP_BEGIN_SIG line
                        break;
                     }

                     pc++; // skip the "\n"

                     if ( AdvanceIfMatches(&pc, PGP_BEGIN_SIG) )
                     {
                        // chop off PGP_BEGIN_SIG line as well
                        while ( *pc != '\n' && pc >= start )
                           pc--;

                        if ( pc > start )
                        {
                           out = String(startBody, pc - 1);
                        }

                        break;
                     }

                     pc -= 3; // rewind beyond "\r\n"
                     ASSERT_MSG( pc[1] == '\r',
                                  _T("line doesn't end in\"\\r\\n\"?") );
                  }
               }
               else
               {
                  wxLogWarning(_("Blank line separating header "
                                 "from body in PGP message not found."));
               }
            }
         }
         else // encrypted
         {
            // try to decrypt
            MCryptoEngine::Status rc = m_engine->Decrypt(in, out, log);
            switch ( rc )
            {
               case MCryptoEngine::OK:
                  pgpInfo = new PGPInfoGoodMsg(m_msgView);
                  break;

               default:
                  wxLogError(_("Decrypting the PGP message failed."));
                  // fall through

               // if the user cancelled decryption, don't complain about it
               case MCryptoEngine::OPERATION_CANCELED_BY_USER:
                  // using unmodified text is not very helpful here anyhow so
                  // simply replace it with an icon
                  pgpInfo = new PGPInfoBadMsg(m_msgView);
            }
         }

         m_next->Process(out, viewer, style);

         pgpInfo->SetLog(log);
         pgpInfo->SetRaw(in);

         // we want the PGP stuff to stand out
         viewer->InsertText(_T("\r\n"), style);

         viewer->InsertClickable(pgpInfo->GetBitmap(),
                                 pgpInfo,
                                 pgpInfo->GetColour());

            viewer->InsertText(_T("\r\n"), style);

         // output the part after the END line, if any
         String epilog(end);
         if ( !epilog.empty() )
         {
            m_next->Process(epilog, viewer, style);
         }
      }

      if ( ok )
      {
         // skip the normal display below
         return;
      }

      // give a warning (unless this is a KEY blok and display the message normally
      if ( !isKey )
      {
         wxLogWarning(_("This message seems to be PGP signed or encrypted "
                        "but in fact is not."));
      }
   }

   m_next->Process(text, viewer, style);
}