<commit_before>/*************************************************************************
 *
 *  $RCSfile: export2.cxx,v $
 *
 *  $Revision: 1.25 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-13 13:51:50 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include "export.hxx"
#include "utf8conv.hxx"
#include <tools/datetime.hxx>
#include <bootstrp/appdef.hxx>
#include <tools/isofallback.hxx>
#include <stdio.h>
#include <osl/file.hxx>
#include <rtl/ustring.hxx>
//
// class ResData();
//

/*****************************************************************************/
ResData::~ResData()
/*****************************************************************************/
{
    if ( pStringList ) {
        // delete existing res. of type StringList
        for ( ULONG i = 0; i < pStringList->Count(); i++ ) {
            ExportListEntry* test = pStringList->GetObject( i );
            if( test != NULL ) delete test;
        }
        delete pStringList;
    }
    if ( pFilterList ) {
        // delete existing res. of type FilterList
        for ( ULONG i = 0; i < pFilterList->Count(); i++ ) {
            ExportListEntry* test = pFilterList->GetObject( i );
            delete test;
        }
        delete pFilterList;
    }
    if ( pItemList ) {
        // delete existing res. of type ItemList
        for ( ULONG i = 0; i < pItemList->Count(); i++ ) {
            ExportListEntry* test = pItemList->GetObject( i );
            delete test;
        }
        delete pItemList;
    }
    if ( pUIEntries ) {
        // delete existing res. of type UIEntries
        for ( ULONG i = 0; i < pUIEntries->Count(); i++ ) {
            ExportListEntry* test = pUIEntries->GetObject( i );
            delete test;
        }
        delete pUIEntries;
    }
}

//
// class Export
//

/*****************************************************************************/
ByteString Export::sLanguages;
ByteString Export::sIsoCode99;
/*****************************************************************************/

/*****************************************************************************/
USHORT Export::GetLangIndex( USHORT nLangId )
/*****************************************************************************/
{
    // removeme
    return 0xFFFF;
}

/*****************************************************************************/
CharSet Export::GetCharSet( USHORT nLangId )
/*****************************************************************************/
{
    // removeme
    //return Langcode2TextEncoding( nLangId );
    return 0;
}

/*****************************************************************************/
USHORT Export::GetLangByIsoLang( const ByteString &rIsoLang )
/*****************************************************************************/
{
    ByteString sLang( rIsoLang );
    sLang.ToUpperAscii();
    return 0xFFFF;
}
/*****************************************************************************/
void Export::SetLanguages( std::vector<ByteString> val ){
/*****************************************************************************/
    aLanguages = val;
    isInitialized = true;
}
/*****************************************************************************/
std::vector<ByteString> Export::GetLanguages(){
/*****************************************************************************/
    return aLanguages;
}

std::vector<ByteString> Export::aLanguages = std::vector<ByteString>();

/*****************************************************************************/
ByteString Export::GetIsoLangByIndex( USHORT nIndex )
/*****************************************************************************/
{
// remove me
    return "";
}

/*****************************************************************************/
void Export::QuotHTML( ByteString &rString )
/*****************************************************************************/
{
    ByteString sReturn;
    BOOL bBreak = FALSE;
    for ( USHORT i = 0; i < rString.Len(); i++ ) {
        ByteString sTemp = rString.Copy( i );
        if ( sTemp.Search( "<Arg n=" ) == 0 ) {
            while ( i < rString.Len() && rString.GetChar( i ) != '>' ) {
                 sReturn += rString.GetChar( i );
                i++;
            }
            if ( rString.GetChar( i ) == '>' ) {
                sReturn += ">";
                i++;
            }
        }
        if ( i < rString.Len()) {
            switch ( rString.GetChar( i )) {
                case '<':
                    sReturn += "<";
                break;

                case '>':
                    sReturn += ">";
                break;

                case '\"':
                    sReturn += """;
                break;

                case '\'':
                    sReturn += "'";
                break;

                case '&':
                    if ((( i + 4 ) < rString.Len()) &&
                        ( rString.Copy( i, 5 ) == "&" ))
                            sReturn += rString.GetChar( i );
                    else
                        sReturn += "&";
                break;

                default:
                    sReturn += rString.GetChar( i );
                break;
            }
        }
    }
    rString = sReturn;
}

/*****************************************************************************/
void Export::UnquotHTML( ByteString &rString )
/*****************************************************************************/
{
    ByteString sReturn;
    while ( rString.Len()) {
        if ( rString.Copy( 0, 5 ) == "&" ) {
            sReturn += "&";
            rString.Erase( 0, 5 );
        }
        else if ( rString.Copy( 0, 4 ) == "<" ) {
            sReturn += "<";
            rString.Erase( 0, 4 );
        }
        else if ( rString.Copy( 0, 4 ) == ">" ) {
            sReturn += ">";
            rString.Erase( 0, 4 );
        }
        else if ( rString.Copy( 0, 6 ) == """ ) {
            sReturn += "\"";
            rString.Erase( 0, 6 );
        }
        else if ( rString.Copy( 0, 6 ) == "'" ) {
            sReturn += "\'";
            rString.Erase( 0, 6 );
        }
        else {
            sReturn += rString.GetChar( 0 );
            rString.Erase( 0, 1 );
        }
    }
    rString = sReturn;
}

/*****************************************************************************/
bool Export::LanguageAllowed( const ByteString &nLanguage )
/*****************************************************************************/
{
    return std::find( aLanguages.begin() , aLanguages.end() , nLanguage ) != aLanguages.end();
}

bool Export::isInitialized = false;

/*****************************************************************************/
void Export::InitLanguages( bool bMergeMode ){
/*****************************************************************************/
    ByteString sTmp;
    ByteStringBoolHashMap aEnvLangs;
    for ( USHORT x = 0; x < sLanguages.GetTokenCount( ',' ); x++ ){
        sTmp = sLanguages.GetToken( x, ',' ).GetToken( 0, '=' );
        sTmp.EraseLeadingAndTrailingChars();
        if( bMergeMode && ( sTmp.EqualsIgnoreCaseAscii("de") || sTmp.EqualsIgnoreCaseAscii("en-US") )){}
        else if( !( (sTmp.GetChar(0)=='x' || sTmp.GetChar(0)=='X') && sTmp.GetChar(1)=='-' ) )
            aLanguages.push_back( sTmp );
    }
    isInitialized = true;
}

/*****************************************************************************/
ByteString Export::GetFallbackLanguage( const ByteString nLanguage )
/*****************************************************************************/
{
    ByteString sFallback=nLanguage;
    GetIsoFallback( sFallback );
    return sFallback;
}

/*****************************************************************************/
void Export::FillInFallbacks( ResData *pResData )
/*****************************************************************************/
{
    ByteString sCur;
    for( long int n = 0; n < aLanguages.size(); n++ ){
        sCur = aLanguages[ n ];
        if( !sCur.EqualsIgnoreCaseAscii("de") && !sCur.EqualsIgnoreCaseAscii("en-US") ){
            ByteString nFallbackIndex = GetFallbackLanguage( sCur );
            if( nFallbackIndex.Len() ){
                if ( !pResData->sText[ sCur ].Len())
                    pResData->sText[ sCur ] =
                        pResData->sText[ nFallbackIndex ];

                if ( !pResData->sHelpText[ sCur ].Len())
                    pResData->sHelpText[ sCur ] =
                        pResData->sHelpText[ nFallbackIndex ];

                if ( !pResData->sQuickHelpText[ sCur ].Len())
                    pResData->sQuickHelpText[ sCur ] =
                        pResData->sQuickHelpText[ nFallbackIndex ];

                if ( !pResData->sTitle[ sCur ].Len())
                    pResData->sTitle[ sCur ] =
                        pResData->sTitle[ nFallbackIndex ];

                if ( pResData->pStringList )
                    FillInListFallbacks(
                        pResData->pStringList, sCur, nFallbackIndex );

                if ( pResData->pFilterList )
                    FillInListFallbacks(
                        pResData->pFilterList, sCur, nFallbackIndex );

                if ( pResData->pItemList )
                    FillInListFallbacks(
                        pResData->pItemList, sCur, nFallbackIndex );

                if ( pResData->pUIEntries )
                    FillInListFallbacks(
                        pResData->pUIEntries, sCur, nFallbackIndex );
            }
        }
    }
}

/*****************************************************************************/
void Export::FillInListFallbacks(
    ExportList *pList, const ByteString &nSource, const ByteString &nFallback )
/*****************************************************************************/
{

    for ( ULONG i = 0; i < pList->Count(); i++ ) {
        ExportListEntry *pEntry = pList->GetObject( i );
        if ( !( *pEntry )[ nSource ].Len())
             ( *pEntry )[ nSource ] = ( *pEntry )[ nFallback ];
    }
}

/*****************************************************************************/
ByteString Export::GetTimeStamp()
/*****************************************************************************/
{
//  return "xx.xx.xx";
    char buf[20];
    Time aTime;

    snprintf(buf, sizeof(buf), "%8d %02d:%02d:%02d", Date().GetDate(),
        aTime.GetHour(), aTime.GetMin(), aTime.GetSec());
    return ByteString(buf);
}

/*****************************************************************************/
BOOL Export::ConvertLineEnds(
    ByteString sSource, ByteString sDestination )
/*****************************************************************************/
{
    String sSourceFile( sSource, RTL_TEXTENCODING_ASCII_US );
    String sDestinationFile( sDestination, RTL_TEXTENCODING_ASCII_US );

    SvFileStream aSource( sSourceFile, STREAM_READ );
    if ( !aSource.IsOpen())
        return FALSE;
    SvFileStream aDestination( sDestinationFile, STREAM_STD_WRITE | STREAM_TRUNC );
    if ( !aDestination.IsOpen()) {
        aSource.Close();
        return FALSE;
    }

    ByteString sLine;

    while ( !aSource.IsEof()) {
        aSource.ReadLine( sLine );
        if ( !aSource.IsEof()) {
            sLine.EraseAllChars( '\r' );
            aDestination.WriteLine( sLine );
        }
        else
            aDestination.WriteByteString( sLine );
    }

    aSource.Close();
    aDestination.Close();

    return TRUE;
}

/*****************************************************************************/
ByteString Export::GetNativeFile( ByteString sSource )
/*****************************************************************************/
{
    DirEntry aTemp( GetTempFile());
    ByteString sReturn( aTemp.GetFull(), RTL_TEXTENCODING_ASCII_US );

    for ( USHORT i = 0; i < 10; i++ )
        if ( ConvertLineEnds( sSource, sReturn ))
            return sReturn;

    return "";
}

/*****************************************************************************/
DirEntry Export::GetTempFile()
/*****************************************************************************/
{
#ifdef WNT
    String sTempDir( GetEnv( "TEMP" ), RTL_TEXTENCODING_ASCII_US );
#else
//  String sTempDir( GetEnv( "HOME" ), RTL_TEXTENCODING_ASCII_US );
    String sTempDir( String::CreateFromAscii( "/tmp" ));
#endif

    rtl::OUString* sTempFilename = new rtl::OUString();
    int nRC = osl::FileBase::createTempFile( 0 , 0 , sTempFilename );
    if( nRC ) printf(" osl::FileBase::createTempFile RC = %d",nRC);
    ByteString sTmp( sTempFilename->getStr() , RTL_TEXTENCODING_UTF8 );
#ifdef WNT
    sTmp.SearchAndReplace("file:///","");
    sTmp.SearchAndReplaceAll('/','\\');
#else
    sTmp.SearchAndReplace("file://","");
#endif
    DirEntry aDirEntry( sTmp );
    delete sTempFilename;
    return aDirEntry;
}
<commit_msg>INTEGRATION: CWS help2 (1.23.12); FILE MERGED 2004/07/13 16:49:11 ihi 1.23.12.4: #104752# Forced Language switch 2004/07/07 17:21:51 ihi 1.23.12.3: RESYNC: (1.23-1.24); FILE MERGED 2004/06/01 11:28:58 ihi 1.23.12.2: #i27675# '\n' removed from GetTimeStamp method 2004/05/18 16:32:32 ihi 1.23.12.1: Assertion log fix / mergebuild join<commit_after>/*************************************************************************
 *
 *  $RCSfile: export2.cxx,v $
 *
 *  $Revision: 1.26 $
 *
 *  last change: $Author: kz $ $Date: 2004-08-30 17:30:29 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include "export.hxx"
#include "utf8conv.hxx"
#include <tools/datetime.hxx>
#include <bootstrp/appdef.hxx>
#include <tools/isofallback.hxx>
#include <stdio.h>
#include <osl/file.hxx>
#include <rtl/ustring.hxx>
//
// class ResData();
//

/*****************************************************************************/
ResData::~ResData()
/*****************************************************************************/
{
    if ( pStringList ) {
        // delete existing res. of type StringList
        for ( ULONG i = 0; i < pStringList->Count(); i++ ) {
            ExportListEntry* test = pStringList->GetObject( i );
            if( test != NULL ) delete test;
        }
        delete pStringList;
    }
    if ( pFilterList ) {
        // delete existing res. of type FilterList
        for ( ULONG i = 0; i < pFilterList->Count(); i++ ) {
            ExportListEntry* test = pFilterList->GetObject( i );
            delete test;
        }
        delete pFilterList;
    }
    if ( pItemList ) {
        // delete existing res. of type ItemList
        for ( ULONG i = 0; i < pItemList->Count(); i++ ) {
            ExportListEntry* test = pItemList->GetObject( i );
            delete test;
        }
        delete pItemList;
    }
    if ( pUIEntries ) {
        // delete existing res. of type UIEntries
        for ( ULONG i = 0; i < pUIEntries->Count(); i++ ) {
            ExportListEntry* test = pUIEntries->GetObject( i );
            delete test;
        }
        delete pUIEntries;
    }
}

//
// class Export
//

/*****************************************************************************/
ByteString Export::sLanguages;
ByteString Export::sForcedLanguages;
ByteString Export::sIsoCode99;
/*****************************************************************************/

/*****************************************************************************/
USHORT Export::GetLangIndex( USHORT nLangId )
/*****************************************************************************/
{
    // removeme
    return 0xFFFF;
}

/*****************************************************************************/
CharSet Export::GetCharSet( USHORT nLangId )
/*****************************************************************************/
{
    // removeme
    //return Langcode2TextEncoding( nLangId );
    return 0;
}

/*****************************************************************************/
USHORT Export::GetLangByIsoLang( const ByteString &rIsoLang )
/*****************************************************************************/
{
    // removeme
    ByteString sLang( rIsoLang );
    sLang.ToUpperAscii();
    return 0xFFFF;
}
/*****************************************************************************/
void Export::SetLanguages( std::vector<ByteString> val ){
/*****************************************************************************/
    aLanguages = val;
    isInitialized = true;
}
/*****************************************************************************/
std::vector<ByteString> Export::GetLanguages(){
/*****************************************************************************/
    return aLanguages;
}
/*****************************************************************************/
std::vector<ByteString> Export::GetForcedLanguages(){
/*****************************************************************************/
    return aForcedLanguages;
}
std::vector<ByteString> Export::aLanguages       = std::vector<ByteString>();
std::vector<ByteString> Export::aForcedLanguages = std::vector<ByteString>();

/*****************************************************************************/
ByteString Export::GetIsoLangByIndex( USHORT nIndex )
/*****************************************************************************/
{
// remove me
    return "";
}

/*****************************************************************************/
void Export::QuotHTML( ByteString &rString )
/*****************************************************************************/
{
    ByteString sReturn;
    BOOL bBreak = FALSE;
    for ( USHORT i = 0; i < rString.Len(); i++ ) {
        ByteString sTemp = rString.Copy( i );
        if ( sTemp.Search( "<Arg n=" ) == 0 ) {
            while ( i < rString.Len() && rString.GetChar( i ) != '>' ) {
                 sReturn += rString.GetChar( i );
                i++;
            }
            if ( rString.GetChar( i ) == '>' ) {
                sReturn += ">";
                i++;
            }
        }
        if ( i < rString.Len()) {
            switch ( rString.GetChar( i )) {
                case '<':
                    sReturn += "<";
                break;

                case '>':
                    sReturn += ">";
                break;

                case '\"':
                    sReturn += """;
                break;

                case '\'':
                    sReturn += "'";
                break;

                case '&':
                    if ((( i + 4 ) < rString.Len()) &&
                        ( rString.Copy( i, 5 ) == "&" ))
                            sReturn += rString.GetChar( i );
                    else
                        sReturn += "&";
                break;

                default:
                    sReturn += rString.GetChar( i );
                break;
            }
        }
    }
    rString = sReturn;
}

/*****************************************************************************/
void Export::UnquotHTML( ByteString &rString )
/*****************************************************************************/
{
    ByteString sReturn;
    while ( rString.Len()) {
        if ( rString.Copy( 0, 5 ) == "&" ) {
            sReturn += "&";
            rString.Erase( 0, 5 );
        }
        else if ( rString.Copy( 0, 4 ) == "<" ) {
            sReturn += "<";
            rString.Erase( 0, 4 );
        }
        else if ( rString.Copy( 0, 4 ) == ">" ) {
            sReturn += ">";
            rString.Erase( 0, 4 );
        }
        else if ( rString.Copy( 0, 6 ) == """ ) {
            sReturn += "\"";
            rString.Erase( 0, 6 );
        }
        else if ( rString.Copy( 0, 6 ) == "'" ) {
            sReturn += "\'";
            rString.Erase( 0, 6 );
        }
        else {
            sReturn += rString.GetChar( 0 );
            rString.Erase( 0, 1 );
        }
    }
    rString = sReturn;
}

/*****************************************************************************/
bool Export::LanguageAllowed( const ByteString &nLanguage )
/*****************************************************************************/
{
    return std::find( aLanguages.begin() , aLanguages.end() , nLanguage ) != aLanguages.end();
}

bool Export::isInitialized = false;

/*****************************************************************************/
void Export::InitLanguages( bool bMergeMode ){
/*****************************************************************************/
    ByteString sTmp;
    ByteStringBoolHashMap aEnvLangs;
    for ( USHORT x = 0; x < sLanguages.GetTokenCount( ',' ); x++ ){
        sTmp = sLanguages.GetToken( x, ',' ).GetToken( 0, '=' );
        sTmp.EraseLeadingAndTrailingChars();
        if( bMergeMode && ( sTmp.EqualsIgnoreCaseAscii("de") || sTmp.EqualsIgnoreCaseAscii("en-US") )){}
        else if( !( (sTmp.GetChar(0)=='x' || sTmp.GetChar(0)=='X') && sTmp.GetChar(1)=='-' ) )
            aLanguages.push_back( sTmp );
    }
    InitForcedLanguages( bMergeMode );
    isInitialized = true;
}
/*****************************************************************************/
void Export::InitForcedLanguages( bool bMergeMode ){
/*****************************************************************************/
    ByteString sTmp;
    ByteStringBoolHashMap aEnvLangs;
    for ( USHORT x = 0; x < sForcedLanguages.GetTokenCount( ',' ); x++ ){
        sTmp = sForcedLanguages.GetToken( x, ',' ).GetToken( 0, '=' );
        sTmp.EraseLeadingAndTrailingChars();
        if( bMergeMode && ( sTmp.EqualsIgnoreCaseAscii("de") || sTmp.EqualsIgnoreCaseAscii("en-US") )){}
        else if( !( (sTmp.GetChar(0)=='x' || sTmp.GetChar(0)=='X') && sTmp.GetChar(1)=='-' ) )
            aForcedLanguages.push_back( sTmp );
    }
}

/*****************************************************************************/
ByteString Export::GetFallbackLanguage( const ByteString nLanguage )
/*****************************************************************************/
{
    ByteString sFallback=nLanguage;
    GetIsoFallback( sFallback );
    return sFallback;
}

/*****************************************************************************/
void Export::FillInFallbacks( ResData *pResData )
/*****************************************************************************/
{
    ByteString sCur;
    for( long int n = 0; n < aLanguages.size(); n++ ){
        sCur = aLanguages[ n ];
        if( !sCur.EqualsIgnoreCaseAscii("de") && !sCur.EqualsIgnoreCaseAscii("en-US") ){
            ByteString nFallbackIndex = GetFallbackLanguage( sCur );
            if( nFallbackIndex.Len() ){
                if ( !pResData->sText[ sCur ].Len())
                    pResData->sText[ sCur ] =
                        pResData->sText[ nFallbackIndex ];

                if ( !pResData->sHelpText[ sCur ].Len())
                    pResData->sHelpText[ sCur ] =
                        pResData->sHelpText[ nFallbackIndex ];

                if ( !pResData->sQuickHelpText[ sCur ].Len())
                    pResData->sQuickHelpText[ sCur ] =
                        pResData->sQuickHelpText[ nFallbackIndex ];

                if ( !pResData->sTitle[ sCur ].Len())
                    pResData->sTitle[ sCur ] =
                        pResData->sTitle[ nFallbackIndex ];

                if ( pResData->pStringList )
                    FillInListFallbacks(
                        pResData->pStringList, sCur, nFallbackIndex );

                if ( pResData->pFilterList )
                    FillInListFallbacks(
                        pResData->pFilterList, sCur, nFallbackIndex );

                if ( pResData->pItemList )
                    FillInListFallbacks(
                        pResData->pItemList, sCur, nFallbackIndex );

                if ( pResData->pUIEntries )
                    FillInListFallbacks(
                        pResData->pUIEntries, sCur, nFallbackIndex );
            }
        }
    }
}

/*****************************************************************************/
void Export::FillInListFallbacks(
    ExportList *pList, const ByteString &nSource, const ByteString &nFallback )
/*****************************************************************************/
{

    for ( ULONG i = 0; i < pList->Count(); i++ ) {
        ExportListEntry *pEntry = pList->GetObject( i );
        if ( !( *pEntry )[ nSource ].Len())
             ( *pEntry )[ nSource ] = ( *pEntry )[ nFallback ];
    }
}

/*****************************************************************************/
ByteString Export::GetTimeStamp()
/*****************************************************************************/
{
//  return "xx.xx.xx";
    char buf[20];
    Time aTime;

    snprintf(buf, sizeof(buf), "%8d %02d:%02d:%02d", Date().GetDate(),
        aTime.GetHour(), aTime.GetMin(), aTime.GetSec());
    return ByteString(buf);
}

/*****************************************************************************/
BOOL Export::ConvertLineEnds(
    ByteString sSource, ByteString sDestination )
/*****************************************************************************/
{
    String sSourceFile( sSource, RTL_TEXTENCODING_ASCII_US );
    String sDestinationFile( sDestination, RTL_TEXTENCODING_ASCII_US );

    SvFileStream aSource( sSourceFile, STREAM_READ );
    if ( !aSource.IsOpen())
        return FALSE;
    SvFileStream aDestination( sDestinationFile, STREAM_STD_WRITE | STREAM_TRUNC );
    if ( !aDestination.IsOpen()) {
        aSource.Close();
        return FALSE;
    }

    ByteString sLine;

    while ( !aSource.IsEof()) {
        aSource.ReadLine( sLine );
        if ( !aSource.IsEof()) {
            sLine.EraseAllChars( '\r' );
            aDestination.WriteLine( sLine );
        }
        else
            aDestination.WriteByteString( sLine );
    }

    aSource.Close();
    aDestination.Close();

    return TRUE;
}

/*****************************************************************************/
ByteString Export::GetNativeFile( ByteString sSource )
/*****************************************************************************/
{
    DirEntry aTemp( GetTempFile());
    ByteString sReturn( aTemp.GetFull(), RTL_TEXTENCODING_ASCII_US );

    for ( USHORT i = 0; i < 10; i++ )
        if ( ConvertLineEnds( sSource, sReturn ))
            return sReturn;

    return "";
}

/*****************************************************************************/
DirEntry Export::GetTempFile()
/*****************************************************************************/
{
#ifdef WNT
    String sTempDir( GetEnv( "TEMP" ), RTL_TEXTENCODING_ASCII_US );
#else
//  String sTempDir( GetEnv( "HOME" ), RTL_TEXTENCODING_ASCII_US );
    String sTempDir( String::CreateFromAscii( "/tmp" ));
#endif

    rtl::OUString* sTempFilename = new rtl::OUString();
    int nRC = osl::FileBase::createTempFile( 0 , 0 , sTempFilename );
    if( nRC ) printf(" osl::FileBase::createTempFile RC = %d",nRC);
    ByteString sTmp( sTempFilename->getStr() , RTL_TEXTENCODING_UTF8 );
#ifdef WNT
    sTmp.SearchAndReplace("file:///","");
    sTmp.SearchAndReplaceAll('/','\\');
#else
    sTmp.SearchAndReplace("file://","");
#endif
    DirEntry aDirEntry( sTmp );
    delete sTempFilename;
    return aDirEntry;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: srciter.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2007-10-30 12:29:49 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_transex3.hxx"

#include "srciter.hxx"
#include <stdio.h>

//
// class SourceTreeIterator
//

/*****************************************************************************/
SourceTreeIterator::SourceTreeIterator(
    const ByteString &rRootDirectory, const ByteString &rVersion , bool bLocal_in )
/*****************************************************************************/
                : bInExecute( FALSE ) , bLocal( bLocal_in )
{
    (void) rVersion ;

    if(!bLocal){
        rtl::OUString sRootDirectory( rRootDirectory.GetBuffer() , rRootDirectory.Len() , RTL_TEXTENCODING_UTF8 );
        aRootDirectory = transex::Directory( sRootDirectory );
    }
}

/*****************************************************************************/
SourceTreeIterator::~SourceTreeIterator()
/*****************************************************************************/
{
}

/*****************************************************************************/
void SourceTreeIterator::ExecuteDirectory( transex::Directory& aDirectory )
/*****************************************************************************/
{
    if ( bInExecute ) {
        rtl::OUString sDirName = aDirectory.getDirectoryName();

        static rtl::OUString WCARD1 ( rtl::OUString::createFromAscii( "unxlngi" ) );
        static rtl::OUString WCARD2 ( rtl::OUString::createFromAscii( "unxsoli" ) );
        static rtl::OUString WCARD3 ( rtl::OUString::createFromAscii( "wntmsci" ) );
        static rtl::OUString WCARD4 ( rtl::OUString::createFromAscii( "unxsols" ) );
        static rtl::OUString WCARD5 ( rtl::OUString::createFromAscii( "common" ) );
        static rtl::OUString WCARD6 ( rtl::OUString::createFromAscii( "unxmacx" ) );
        static rtl::OUString WCARD7 ( rtl::OUString::createFromAscii( "unxlngx" ) );
        static rtl::OUString WCARD8 ( rtl::OUString::createFromAscii( "unxsolsx" ) );
        static rtl::OUString WCARD9 ( rtl::OUString::createFromAscii( "unxsolsu" ) );
        static rtl::OUString WCARD10 ( rtl::OUString::createFromAscii( "wntmscx" ) );

        if( sDirName.indexOf( WCARD1 , 0 ) > -1 ||
            sDirName.indexOf( WCARD2 , 0 ) > -1 ||
            sDirName.indexOf( WCARD3 , 0 ) > -1 ||
            sDirName.indexOf( WCARD4 , 0 ) > -1 ||
            sDirName.indexOf( WCARD5 , 0 ) > -1 ||
            sDirName.indexOf( WCARD6 , 0 ) > -1 ||
            sDirName.indexOf( WCARD7 , 0 ) > -1 ||
            sDirName.indexOf( WCARD8 , 0 ) > -1 ||
            sDirName.indexOf( WCARD9 , 0 ) > -1 ||
            sDirName.indexOf( WCARD10 , 0 ) > -1
           )    return;
        //printf("**** %s \n", OUStringToOString( sDirName , RTL_TEXTENCODING_UTF8 , sDirName.getLength() ).getStr() );
        aDirectory.setSkipLinks( bSkipLinks );
        aDirectory.readDirectory();
        OnExecuteDirectory( aDirectory.getFullName() );
        if ( aDirectory.getSubDirectories().size() )
            for ( ULONG i=0;i < aDirectory.getSubDirectories().size();i++ )
                ExecuteDirectory( aDirectory.getSubDirectories()[ i ] );
    }
}

/*****************************************************************************/
BOOL SourceTreeIterator::StartExecute()
/*****************************************************************************/
{

    bInExecute = TRUE;                  // FIXME
    ExecuteDirectory( aRootDirectory );

    if ( bInExecute ) {                 // FIXME
        bInExecute = FALSE;
        return TRUE;
    }
    return FALSE;
}

/*****************************************************************************/
void SourceTreeIterator::EndExecute()
/*****************************************************************************/
{
    bInExecute = FALSE;
}

/*****************************************************************************/
void SourceTreeIterator::OnExecuteDirectory( const rtl::OUString &rDirectory )
/*****************************************************************************/
{
    fprintf( stdout, "%s\n", rtl::OUStringToOString( rDirectory, RTL_TEXTENCODING_UTF8, rDirectory.getLength() ).getStr() );
}
<commit_msg>INTEGRATION: CWS l10ntooling11 (1.9.20); FILE MERGED 2008/02/11 16:52:29 ihi 1.9.20.1: #i85733# skip all sub dirs if the file no_localization is found<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: srciter.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: rt $ $Date: 2008-02-18 15:10:58 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_transex3.hxx"

#include "srciter.hxx"
#include <stdio.h>
#include <tools/fsys.hxx>

//
// class SourceTreeIterator
//

/*****************************************************************************/
SourceTreeIterator::SourceTreeIterator(
    const ByteString &rRootDirectory, const ByteString &rVersion , bool bLocal_in )
/*****************************************************************************/
                : bInExecute( FALSE ) , bLocal( bLocal_in )
{
    (void) rVersion ;

    if(!bLocal){
        rtl::OUString sRootDirectory( rRootDirectory.GetBuffer() , rRootDirectory.Len() , RTL_TEXTENCODING_UTF8 );
        aRootDirectory = transex::Directory( sRootDirectory );
    }
}

/*****************************************************************************/
SourceTreeIterator::~SourceTreeIterator()
/*****************************************************************************/
{
}

/*****************************************************************************/
void SourceTreeIterator::ExecuteDirectory( transex::Directory& aDirectory )
/*****************************************************************************/
{
    if ( bInExecute ) {
        rtl::OUString sDirName = aDirectory.getDirectoryName();

        static rtl::OUString WCARD1 ( rtl::OUString::createFromAscii( "unxlngi" ) );
        static rtl::OUString WCARD2 ( rtl::OUString::createFromAscii( "unxsoli" ) );
        static rtl::OUString WCARD3 ( rtl::OUString::createFromAscii( "wntmsci" ) );
        static rtl::OUString WCARD4 ( rtl::OUString::createFromAscii( "unxsols" ) );
        static rtl::OUString WCARD5 ( rtl::OUString::createFromAscii( "common" ) );
        static rtl::OUString WCARD6 ( rtl::OUString::createFromAscii( "unxmacx" ) );
        static rtl::OUString WCARD7 ( rtl::OUString::createFromAscii( "unxlngx" ) );
        static rtl::OUString WCARD8 ( rtl::OUString::createFromAscii( "unxsolsx" ) );
        static rtl::OUString WCARD9 ( rtl::OUString::createFromAscii( "unxsolsu" ) );
        static rtl::OUString WCARD10 ( rtl::OUString::createFromAscii( "wntmscx" ) );

        if( sDirName.indexOf( WCARD1 , 0 ) > -1 ||
            sDirName.indexOf( WCARD2 , 0 ) > -1 ||
            sDirName.indexOf( WCARD3 , 0 ) > -1 ||
            sDirName.indexOf( WCARD4 , 0 ) > -1 ||
            sDirName.indexOf( WCARD5 , 0 ) > -1 ||
            sDirName.indexOf( WCARD6 , 0 ) > -1 ||
            sDirName.indexOf( WCARD7 , 0 ) > -1 ||
            sDirName.indexOf( WCARD8 , 0 ) > -1 ||
            sDirName.indexOf( WCARD9 , 0 ) > -1 ||
            sDirName.indexOf( WCARD10 , 0 ) > -1
           )    return;
        //printf("**** %s \n", OUStringToOString( sDirName , RTL_TEXTENCODING_UTF8 , sDirName.getLength() ).getStr() );

        rtl::OUString sDirNameTmp = aDirectory.getFullName();
        ByteString sDirNameTmpB( OUStringToOString( sDirNameTmp , RTL_TEXTENCODING_UTF8 , sDirName.getLength() ).getStr() );

#ifdef WNT
        sDirNameTmpB.Append( ByteString("\\no_localization") );
#else
        sDirNameTmpB.Append( ByteString("/no_localization") );
#endif
        //printf("**** %s \n", OUStringToOString( sDirNameTmp , RTL_TEXTENCODING_UTF8 , sDirName.getLength() ).getStr() );

        DirEntry aDE( sDirNameTmpB.GetBuffer() );
        if( aDE.Exists() )
        {
            //printf("#### no_localization file found ... skipping");
            return;
        }

        aDirectory.setSkipLinks( bSkipLinks );
        aDirectory.readDirectory();
        OnExecuteDirectory( aDirectory.getFullName() );
        if ( aDirectory.getSubDirectories().size() )
            for ( ULONG i=0;i < aDirectory.getSubDirectories().size();i++ )
                ExecuteDirectory( aDirectory.getSubDirectories()[ i ] );
    }
}

/*****************************************************************************/
BOOL SourceTreeIterator::StartExecute()
/*****************************************************************************/
{

    bInExecute = TRUE;                  // FIXME
    ExecuteDirectory( aRootDirectory );

    if ( bInExecute ) {                 // FIXME
        bInExecute = FALSE;
        return TRUE;
    }
    return FALSE;
}

/*****************************************************************************/
void SourceTreeIterator::EndExecute()
/*****************************************************************************/
{
    bInExecute = FALSE;
}

/*****************************************************************************/
void SourceTreeIterator::OnExecuteDirectory( const rtl::OUString &rDirectory )
/*****************************************************************************/
{
    fprintf( stdout, "%s\n", rtl::OUStringToOString( rDirectory, RTL_TEXTENCODING_UTF8, rDirectory.getLength() ).getStr() );
}
<|endoftext|>


<commit_before>#include "mega.h"
#include "gtest/gtest.h"
#include "test.h"
#include <stdio.h>
#include <fstream>

bool gRunningInCI = false;
bool gTestingInvalidArgs = false;
std::string USER_AGENT = "Integration Tests with GoogleTest framework";

namespace {

class MegaLogger : public mega::Logger
{
public:
    void log(const char* time, int loglevel, const char* source, const char* message)
    {
        std::ostringstream os;

        os << "[";
        if (time)
        {
            os << time;
        }
        else
        {
            auto t = std::time(NULL);
            char ts[50];
            if (!std::strftime(ts, sizeof(ts), "%H:%M:%S", std::gmtime(&t)))
            {
                ts[0] = '\0';
            }
            os << ts;
        }
        os << "] " << mega::SimpleLogger::toStr(static_cast<mega::LogLevel>(loglevel)) << ": " << message;

        if (source)
        {
            os << " (" << source << ")";
        }
        os << std::endl;

        if (loglevel <= mega::SimpleLogger::logCurrentLevel)
        {
            if (gRunningInCI)
            {
                if (!mLogFile.is_open())
                {
                    mLogFile.open("test_integration.log");
                }
                mLogFile << os.str() << std::flush;
            }
            else
            {
#ifndef _WIN32
                std::cout << os.str() << std::flush;
#endif
                if (!gTestingInvalidArgs)
                {
                    ASSERT_NE(loglevel, mega::logError) << os.str();
                }
            }
#ifdef _WIN32
            OutputDebugStringA(os.str().c_str());
#endif
        }
    }

private:
    std::ofstream mLogFile;
};

} // anonymous

int main (int argc, char *argv[])
{
    if (!getenv("MEGA_EMAIL") || !getenv("MEGA_PWD") || !getenv("MEGA_EMAIL_AUX") || !getenv("MEGA_PWD_AUX"))
    {
        std::cout << "please set username and password env variables for test" << std::endl;
        return 1;
    }

    std::vector<char*> myargv1(argv, argv + argc);
    std::vector<char*> myargv2;

    for (auto it = myargv1.begin(); it != myargv1.end(); ++it)
    {
        if (std::string(*it) == "--CI")
        {
            gRunningInCI = true;
            argc -= 1;
        }
        else if (std::string(*it).substr(0, 12) == "--USERAGENT:")
        {
            USER_AGENT = std::string(*it).substr(12);
            argc -= 1;
        }
        else if (std::string(*it).substr(0, 9) == "--APIURL:")
        {
            mega::MegaClient::APIURL = std::string(*it).substr(9);
            argc -= 1;
        }
        else
        {
            myargv2.push_back(*it);
        }
    }

    MegaLogger megaLogger;

    mega::SimpleLogger::setLogLevel(mega::logMax);
    mega::SimpleLogger::setOutputClass(&megaLogger);

#if defined(_WIN32) && defined(NO_READLINE)
    using namespace mega;
    WinConsole* wc = new CONSOLE_CLASS;
    wc->setShellConsole();
#endif

    ::testing::InitGoogleTest(&argc, myargv2.data());
    return RUN_ALL_TESTS();
}
<commit_msg>use mega::m_gmtime for thread safety<commit_after>#include "mega.h"
#include "gtest/gtest.h"
#include "test.h"
#include <stdio.h>
#include <fstream>

bool gRunningInCI = false;
bool gTestingInvalidArgs = false;
std::string USER_AGENT = "Integration Tests with GoogleTest framework";

namespace {

class MegaLogger : public mega::Logger
{
public:
    void log(const char* time, int loglevel, const char* source, const char* message)
    {
        std::ostringstream os;

        os << "[";
        if (time)
        {
            os << time;
        }
        else
        {
            auto t = std::time(NULL);
            char ts[50];
            struct tm dt;
            mega::m_gmtime(t, &dt);
            if (!std::strftime(ts, sizeof(ts), "%H:%M:%S", &dt))
            {
                ts[0] = '\0';
            }
            os << ts;
        }
        os << "] " << mega::SimpleLogger::toStr(static_cast<mega::LogLevel>(loglevel)) << ": " << message;

        if (source)
        {
            os << " (" << source << ")";
        }
        os << std::endl;

        if (loglevel <= mega::SimpleLogger::logCurrentLevel)
        {
            if (gRunningInCI)
            {
                if (!mLogFile.is_open())
                {
                    mLogFile.open("test_integration.log");
                }
                mLogFile << os.str() << std::flush;
            }
            else
            {
#ifndef _WIN32
                std::cout << os.str() << std::flush;
#endif
                if (!gTestingInvalidArgs)
                {
                    ASSERT_NE(loglevel, mega::logError) << os.str();
                }
            }
#ifdef _WIN32
            OutputDebugStringA(os.str().c_str());
#endif
        }
    }

private:
    std::ofstream mLogFile;
};

} // anonymous

int main (int argc, char *argv[])
{
    if (!getenv("MEGA_EMAIL") || !getenv("MEGA_PWD") || !getenv("MEGA_EMAIL_AUX") || !getenv("MEGA_PWD_AUX"))
    {
        std::cout << "please set username and password env variables for test" << std::endl;
        return 1;
    }

    std::vector<char*> myargv1(argv, argv + argc);
    std::vector<char*> myargv2;

    for (auto it = myargv1.begin(); it != myargv1.end(); ++it)
    {
        if (std::string(*it) == "--CI")
        {
            gRunningInCI = true;
            argc -= 1;
        }
        else if (std::string(*it).substr(0, 12) == "--USERAGENT:")
        {
            USER_AGENT = std::string(*it).substr(12);
            argc -= 1;
        }
        else if (std::string(*it).substr(0, 9) == "--APIURL:")
        {
            mega::MegaClient::APIURL = std::string(*it).substr(9);
            argc -= 1;
        }
        else
        {
            myargv2.push_back(*it);
        }
    }

    MegaLogger megaLogger;

    mega::SimpleLogger::setLogLevel(mega::logMax);
    mega::SimpleLogger::setOutputClass(&megaLogger);

#if defined(_WIN32) && defined(NO_READLINE)
    using namespace mega;
    WinConsole* wc = new CONSOLE_CLASS;
    wc->setShellConsole();
#endif

    ::testing::InitGoogleTest(&argc, myargv2.data());
    return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>/******************************************************************************\
* File:          dir.cpp
* Purpose:       Implementation of class 'wxExDir'
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/extension/dir.h>
#include <wx/extension/util.h>

class wxExDirTraverser: public wxDirTraverser
{
public:
  wxExDirTraverser(wxExDir& dir)
    : m_Dir(dir)
    {}

  virtual wxDirTraverseResult OnDir(const wxString& dirname)
  {
    if (m_Dir.Cancelled())
    {
      return wxDIR_STOP;
    }

    if (m_Dir.GetFlags() & wxDIR_DIRS)
    {
      m_Dir.OnDir(dirname);
    }

    if (wxIsMainThread())
    {
      if (wxTheApp != NULL)
      {
        wxTheApp->Yield();
      }
    }
    else
    {
      wxThread::This()->Yield();
    }

    return wxDIR_CONTINUE;
  }

  virtual wxDirTraverseResult OnFile(const wxString& filename)
  {
    if (m_Dir.Cancelled())
    {
      return wxDIR_STOP;
    }

    wxFileName file(filename);

    if (wxExMatchesOneOf(file, m_Dir.GetFileSpec()))
    {
      m_Dir.OnFile(filename);
    }

    if (wxIsMainThread())
    {
      if (wxTheApp != NULL)
      {
        wxTheApp->Yield();
      }
    }
    else
    {
      wxThread::This()->Yield();
    }

    return wxDIR_CONTINUE;
  }

private:
  wxExDir& m_Dir;
};

wxExDir::wxExDir(const wxString& fullpath, const wxString& filespec, int flags)
  : wxDir(fullpath)
  , m_FileSpec(filespec)
  , m_Flags(flags)
{
}

size_t wxExDir::FindFiles()
{
  if (!IsOpened()) return 0;

  // Using m_FileSpec here does not work, as it might
  // contain several specs (*.cpp;*.h), wxDir does not handle that.
  // Do not combine into one, Ubuntu complains.
  wxExDirTraverser traverser(*this);
  return Traverse(traverser, wxEmptyString, m_Flags);
}
<commit_msg>simplified OnFile<commit_after>/******************************************************************************\
* File:          dir.cpp
* Purpose:       Implementation of class 'wxExDir'
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/extension/dir.h>
#include <wx/extension/util.h>

class wxExDirTraverser: public wxDirTraverser
{
public:
  wxExDirTraverser(wxExDir& dir)
    : m_Dir(dir)
    {}

  virtual wxDirTraverseResult OnDir(const wxString& dirname)
  {
    if (m_Dir.Cancelled())
    {
      return wxDIR_STOP;
    }

    if (m_Dir.GetFlags() & wxDIR_DIRS)
    {
      m_Dir.OnDir(dirname);
    }

    if (wxIsMainThread())
    {
      if (wxTheApp != NULL)
      {
        wxTheApp->Yield();
      }
    }
    else
    {
      wxThread::This()->Yield();
    }

    return wxDIR_CONTINUE;
  }

  virtual wxDirTraverseResult OnFile(const wxString& filename)
  {
    if (m_Dir.Cancelled())
    {
      return wxDIR_STOP;
    }

    if (wxExMatchesOneOf(filename, m_Dir.GetFileSpec()))
    {
      m_Dir.OnFile(filename);
    }

    if (wxIsMainThread())
    {
      if (wxTheApp != NULL)
      {
        wxTheApp->Yield();
      }
    }
    else
    {
      wxThread::This()->Yield();
    }

    return wxDIR_CONTINUE;
  }

private:
  wxExDir& m_Dir;
};

wxExDir::wxExDir(const wxString& fullpath, const wxString& filespec, int flags)
  : wxDir(fullpath)
  , m_FileSpec(filespec)
  , m_Flags(flags)
{
}

size_t wxExDir::FindFiles()
{
  if (!IsOpened()) return 0;

  // Using m_FileSpec here does not work, as it might
  // contain several specs (*.cpp;*.h), wxDir does not handle that.
  // Do not combine into one, Ubuntu complains.
  wxExDirTraverser traverser(*this);
  return Traverse(traverser, wxEmptyString, m_Flags);
}
<|endoftext|>


<commit_before>/******************************************************************************\
* File:          svn.cpp
* Purpose:       Implementation of wxExSVN class
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/extension/svn.h>
#include <wx/extension/configdlg.h>
#include <wx/extension/defs.h>
#include <wx/extension/log.h>
#include <wx/extension/stc.h>
#include <wx/extension/util.h>

#if wxUSE_GUI

wxExSTCEntryDialog* wxExSVN::m_STCEntryDialog = NULL;

wxExSVN::wxExSVN(int command_id, const wxString& fullpath)
  : m_Type(GetType(command_id))
  , m_FullPath(fullpath)
{
  Initialize();
}

wxExSVN::wxExSVN(wxExSVNType type, const wxString& fullpath)
  : m_Type(type)
  , m_FullPath(fullpath)
{
  Initialize();
}

void wxExSVN::Cleanup()
{
  delete m_STCEntryDialog;
}

bool wxExSVN::DirExists(const wxFileName& filename)
{
  wxFileName path(filename);
  path.AppendDir(".svn");
  return path.DirExists();
}

wxStandardID wxExSVN::Execute(wxWindow* parent)
{
  const wxString svn_flags_name = wxString::Format("svn/flags%d", m_Type);
  const wxString svn_flags_contents = wxConfigBase::Get()->Read(svn_flags_name);

  if (parent != NULL)
  {
    std::vector<wxExConfigItem> v;

    if (m_Type == SVN_COMMIT)
    {
      v.push_back(wxExConfigItem(
        _("Revision comment"),
        CONFIG_COMBOBOX,
        wxEmptyString,
        true)); // required
    }

    if (m_FullPath.empty() && m_Type != SVN_HELP)
    {
      v.push_back(wxExConfigItem(
        _("Base folder"),
        CONFIG_COMBOBOXDIR,
        wxEmptyString,
        true)); // required
    }

    if (UseFlags())
    {
      wxConfigBase::Get()->Write(_("Flags"), svn_flags_contents);
      v.push_back(wxExConfigItem(_("Flags")));
    }

    if (UseSubcommand())
    {
      v.push_back(wxExConfigItem(_("Subcommand")));
    }

    m_ReturnCode = (wxStandardID)wxExConfigDialog(parent,
      v,
      m_Caption).ShowModal();

    if (m_ReturnCode == wxID_CANCEL)
    {
      return m_ReturnCode;
    }
  }

  const wxString cwd = wxGetCwd();

  wxString file;

  if (m_FullPath.empty())
  {
    wxSetWorkingDirectory(wxExConfigFirstOf(wxConfigBase::Get()->Read(_("Base folder"))));
  }
  else
  {
    file = " \"" + m_FullPath + "\"";
  }

  wxString comment;

  if (m_Type == SVN_COMMIT)
  {
    comment =
      " -m \"" + wxExConfigFirstOf(wxConfigBase::Get()->Read(_("Revision comment")))
      + "\"";
  }

  wxString flags;
  wxString subcommand;

  if (UseSubcommand())
  {
    subcommand = wxConfigBase::Get()->Read(_("Subcommand"));

    if (!subcommand.empty())
    {
      subcommand = " " + subcommand;
    }
  }

  if (UseFlags())
  {
    flags = wxConfigBase::Get()->Read(_("Flags"));

    wxConfigBase::Get()->Write(svn_flags_name, flags);

    m_CommandWithFlags = m_Command + " " + flags;

    if (!flags.empty())
    {
      flags += " ";
    }
  }

  const wxString command =
    "svn " + flags + m_Command + subcommand + comment + file;

  wxArrayString output;
  wxArrayString errors;
  m_Output.clear();

  if (wxExecute(
    command,
    output,
    errors) == -1)
  {
    if (m_Output.empty())
    {
      m_Output = "Could not execute: " + command;
    }

    m_ReturnCode = wxID_ABORT;
    return m_ReturnCode;
  }

  wxExLog::Get()->Log(command);

  if (m_FullPath.empty())
  {
    wxSetWorkingDirectory(cwd);
  }

  // First output the errors.
  for (size_t i = 0; i < errors.GetCount(); i++)
  {
    m_Output += errors[i] + "\n";
  }

  // Then the normal output, will be empty if there are errors.
  for (size_t j = 0; j < output.GetCount(); j++)
  {
    m_Output += output[j] + "\n";
  }

  return wxID_OK;
}

wxStandardID wxExSVN::ExecuteAndShowOutput(wxWindow* parent)
{
  // If an error occurred, already shown by wxExecute itself.
  if (Execute(parent) == wxID_OK)
  {
    ShowOutput(parent);
  }

  return m_ReturnCode;
}

wxExSVNType wxExSVN::GetType(int command_id) const
{
  switch (command_id)
  {
    case ID_EDIT_SVN_BLAME: return SVN_BLAME; break;
    case ID_EDIT_SVN_CAT: return SVN_CAT; break;
    case ID_EDIT_SVN_COMMIT: return SVN_COMMIT; break;
    case ID_EDIT_SVN_DIFF: return SVN_DIFF; break;
    case ID_EDIT_SVN_HELP: return SVN_HELP; break;
    case ID_EDIT_SVN_INFO: return SVN_INFO; break;
    case ID_EDIT_SVN_LOG: return SVN_LOG; break;
    case ID_EDIT_SVN_REVERT: return SVN_REVERT; break;
    case ID_EDIT_SVN_STAT: return SVN_STAT; break;
    case ID_EDIT_SVN_UPDATE: return SVN_UPDATE; break;
    default:
      wxFAIL;
      return SVN_STAT;
      break;
  }
}

void wxExSVN::Initialize()
{
  switch (m_Type)
  {
    case SVN_BLAME:  m_Caption = "SVN Blame"; break;
    case SVN_CAT:    m_Caption = "SVN Cat"; break;
    case SVN_COMMIT: m_Caption = "SVN Commit"; break;
    case SVN_DIFF:   m_Caption = "SVN Diff"; break;
    case SVN_HELP:   m_Caption = "SVN Help"; break;
    case SVN_INFO:   m_Caption = "SVN Info"; break;
    case SVN_LOG:    m_Caption = "SVN Log"; break;
    case SVN_REVERT: m_Caption = "SVN Revert"; break;
    case SVN_STAT:   m_Caption = "SVN Stat"; break;
    case SVN_UPDATE: m_Caption = "SVN Update"; break;
    default:
      wxFAIL;
      break;
  }

  m_Command = m_Caption.AfterFirst(' ').Lower();

  // Currently no flags, as no command was executed.
  m_CommandWithFlags = m_Command;

  m_Output.clear();
  m_ReturnCode = wxID_NONE;
}

void wxExSVN::ShowOutput(wxWindow* parent) const
{
  switch (m_ReturnCode)
  {
    case wxID_CANCEL:
      break;

    case wxID_ABORT:
      wxMessageBox(m_Output);
      break;

    case wxID_OK:
    {
      const wxString caption = m_Caption +
        (!m_FullPath.empty() ? " " +
            wxFileName(m_FullPath).GetFullName():
            wxString(wxEmptyString));

      // Create a dialog for contents.
      if (m_STCEntryDialog == NULL)
      {
        m_STCEntryDialog = new wxExSTCEntryDialog(
          parent,
          caption,
          m_Output,
          wxEmptyString,
          wxOK,
          wxID_ANY,
          wxDefaultPosition, wxSize(575, 250));
      }
      else
      {
        m_STCEntryDialog->SetText(m_Output);
        m_STCEntryDialog->SetTitle(caption);

        // Reset a previous lexer.
        if (!m_STCEntryDialog->GetLexer().empty())
        {
          m_STCEntryDialog->SetLexer(wxEmptyString);
        }
      }

      // Add a lexer if we specified a path, asked for cat or blame
      // and there is a lexer.
      if (
        !m_FullPath.empty() &&
        (m_Type == SVN_CAT || m_Type == SVN_BLAME))
      {
        const wxExFileName fn(m_FullPath);

        if (!fn.GetLexer().GetScintillaLexer().empty())
        {
          m_STCEntryDialog->SetLexer(fn.GetLexer().GetScintillaLexer());
        }
      }

      m_STCEntryDialog->Show();
    }
    break;

    default:
      wxFAIL;
      break;
  }
}

bool wxExSVN::UseFlags() const
{
  return m_Type != SVN_UPDATE && m_Type != SVN_HELP;
}

bool wxExSVN::UseSubcommand() const
{
  return m_Type == SVN_HELP;
}

#endif
<commit_msg>add assert on the parent<commit_after>/******************************************************************************\
* File:          svn.cpp
* Purpose:       Implementation of wxExSVN class
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/extension/svn.h>
#include <wx/extension/configdlg.h>
#include <wx/extension/defs.h>
#include <wx/extension/log.h>
#include <wx/extension/stc.h>
#include <wx/extension/util.h>

#if wxUSE_GUI

wxExSTCEntryDialog* wxExSVN::m_STCEntryDialog = NULL;

wxExSVN::wxExSVN(int command_id, const wxString& fullpath)
  : m_Type(GetType(command_id))
  , m_FullPath(fullpath)
{
  Initialize();
}

wxExSVN::wxExSVN(wxExSVNType type, const wxString& fullpath)
  : m_Type(type)
  , m_FullPath(fullpath)
{
  Initialize();
}

void wxExSVN::Cleanup()
{
  delete m_STCEntryDialog;
}

bool wxExSVN::DirExists(const wxFileName& filename)
{
  wxFileName path(filename);
  path.AppendDir(".svn");
  return path.DirExists();
}

wxStandardID wxExSVN::Execute(wxWindow* parent)
{
  const wxString svn_flags_name = wxString::Format("svn/flags%d", m_Type);
  const wxString svn_flags_contents = wxConfigBase::Get()->Read(svn_flags_name);

  if (parent != NULL)
  {
    std::vector<wxExConfigItem> v;

    if (m_Type == SVN_COMMIT)
    {
      v.push_back(wxExConfigItem(
        _("Revision comment"),
        CONFIG_COMBOBOX,
        wxEmptyString,
        true)); // required
    }

    if (m_FullPath.empty() && m_Type != SVN_HELP)
    {
      v.push_back(wxExConfigItem(
        _("Base folder"),
        CONFIG_COMBOBOXDIR,
        wxEmptyString,
        true)); // required
    }

    if (UseFlags())
    {
      wxConfigBase::Get()->Write(_("Flags"), svn_flags_contents);
      v.push_back(wxExConfigItem(_("Flags")));
    }

    if (UseSubcommand())
    {
      v.push_back(wxExConfigItem(_("Subcommand")));
    }

    m_ReturnCode = (wxStandardID)wxExConfigDialog(parent,
      v,
      m_Caption).ShowModal();

    if (m_ReturnCode == wxID_CANCEL)
    {
      return m_ReturnCode;
    }
  }

  const wxString cwd = wxGetCwd();

  wxString file;

  if (m_FullPath.empty())
  {
    wxSetWorkingDirectory(wxExConfigFirstOf(wxConfigBase::Get()->Read(_("Base folder"))));
  }
  else
  {
    file = " \"" + m_FullPath + "\"";
  }

  wxString comment;

  if (m_Type == SVN_COMMIT)
  {
    comment =
      " -m \"" + wxExConfigFirstOf(wxConfigBase::Get()->Read(_("Revision comment")))
      + "\"";
  }

  wxString flags;
  wxString subcommand;

  if (UseSubcommand())
  {
    subcommand = wxConfigBase::Get()->Read(_("Subcommand"));

    if (!subcommand.empty())
    {
      subcommand = " " + subcommand;
    }
  }

  if (UseFlags())
  {
    flags = wxConfigBase::Get()->Read(_("Flags"));

    wxConfigBase::Get()->Write(svn_flags_name, flags);

    m_CommandWithFlags = m_Command + " " + flags;

    if (!flags.empty())
    {
      flags += " ";
    }
  }

  const wxString command =
    "svn " + flags + m_Command + subcommand + comment + file;

  wxArrayString output;
  wxArrayString errors;
  m_Output.clear();

  if (wxExecute(
    command,
    output,
    errors) == -1)
  {
    if (m_Output.empty())
    {
      m_Output = "Could not execute: " + command;
    }

    m_ReturnCode = wxID_ABORT;
    return m_ReturnCode;
  }

  wxExLog::Get()->Log(command);

  if (m_FullPath.empty())
  {
    wxSetWorkingDirectory(cwd);
  }

  // First output the errors.
  for (size_t i = 0; i < errors.GetCount(); i++)
  {
    m_Output += errors[i] + "\n";
  }

  // Then the normal output, will be empty if there are errors.
  for (size_t j = 0; j < output.GetCount(); j++)
  {
    m_Output += output[j] + "\n";
  }

  return wxID_OK;
}

wxStandardID wxExSVN::ExecuteAndShowOutput(wxWindow* parent)
{
  // We must have a parent.
  wxASSERT(parent != NULL);

  // If an error occurred, already shown by wxExecute itself.
  if (Execute(parent) == wxID_OK)
  {
    ShowOutput(parent);
  }

  return m_ReturnCode;
}

wxExSVNType wxExSVN::GetType(int command_id) const
{
  switch (command_id)
  {
    case ID_EDIT_SVN_BLAME: return SVN_BLAME; break;
    case ID_EDIT_SVN_CAT: return SVN_CAT; break;
    case ID_EDIT_SVN_COMMIT: return SVN_COMMIT; break;
    case ID_EDIT_SVN_DIFF: return SVN_DIFF; break;
    case ID_EDIT_SVN_HELP: return SVN_HELP; break;
    case ID_EDIT_SVN_INFO: return SVN_INFO; break;
    case ID_EDIT_SVN_LOG: return SVN_LOG; break;
    case ID_EDIT_SVN_REVERT: return SVN_REVERT; break;
    case ID_EDIT_SVN_STAT: return SVN_STAT; break;
    case ID_EDIT_SVN_UPDATE: return SVN_UPDATE; break;
    default:
      wxFAIL;
      return SVN_STAT;
      break;
  }
}

void wxExSVN::Initialize()
{
  switch (m_Type)
  {
    case SVN_BLAME:  m_Caption = "SVN Blame"; break;
    case SVN_CAT:    m_Caption = "SVN Cat"; break;
    case SVN_COMMIT: m_Caption = "SVN Commit"; break;
    case SVN_DIFF:   m_Caption = "SVN Diff"; break;
    case SVN_HELP:   m_Caption = "SVN Help"; break;
    case SVN_INFO:   m_Caption = "SVN Info"; break;
    case SVN_LOG:    m_Caption = "SVN Log"; break;
    case SVN_REVERT: m_Caption = "SVN Revert"; break;
    case SVN_STAT:   m_Caption = "SVN Stat"; break;
    case SVN_UPDATE: m_Caption = "SVN Update"; break;
    default:
      wxFAIL;
      break;
  }

  m_Command = m_Caption.AfterFirst(' ').Lower();

  // Currently no flags, as no command was executed.
  m_CommandWithFlags = m_Command;

  m_Output.clear();
  m_ReturnCode = wxID_NONE;
}

void wxExSVN::ShowOutput(wxWindow* parent) const
{
  switch (m_ReturnCode)
  {
    case wxID_CANCEL:
      break;

    case wxID_ABORT:
      wxMessageBox(m_Output);
      break;

    case wxID_OK:
    {
      const wxString caption = m_Caption +
        (!m_FullPath.empty() ? " " +
            wxFileName(m_FullPath).GetFullName():
            wxString(wxEmptyString));

      // Create a dialog for contents.
      if (m_STCEntryDialog == NULL)
      {
        m_STCEntryDialog = new wxExSTCEntryDialog(
          parent,
          caption,
          m_Output,
          wxEmptyString,
          wxOK,
          wxID_ANY,
          wxDefaultPosition, wxSize(575, 250));
      }
      else
      {
        m_STCEntryDialog->SetText(m_Output);
        m_STCEntryDialog->SetTitle(caption);

        // Reset a previous lexer.
        if (!m_STCEntryDialog->GetLexer().empty())
        {
          m_STCEntryDialog->SetLexer(wxEmptyString);
        }
      }

      // Add a lexer if we specified a path, asked for cat or blame
      // and there is a lexer.
      if (
        !m_FullPath.empty() &&
        (m_Type == SVN_CAT || m_Type == SVN_BLAME))
      {
        const wxExFileName fn(m_FullPath);

        if (!fn.GetLexer().GetScintillaLexer().empty())
        {
          m_STCEntryDialog->SetLexer(fn.GetLexer().GetScintillaLexer());
        }
      }

      m_STCEntryDialog->Show();
    }
    break;

    default:
      wxFAIL;
      break;
  }
}

bool wxExSVN::UseFlags() const
{
  return m_Type != SVN_UPDATE && m_Type != SVN_HELP;
}

bool wxExSVN::UseSubcommand() const
{
  return m_Type == SVN_HELP;
}

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/app/breakpad_win.h"

#include <windows.h>
#include <tchar.h>
#include <vector>

#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/file_version_info.h"
#include "base/registry.h"
#include "base/string_util.h"
#include "base/win_util.h"
#include "chrome/app/google_update_client.h"
#include "chrome/app/hard_error_handler_win.h"
#include "chrome/common/env_vars.h"
#include "chrome/common/result_codes.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/installer/util/google_update_settings.h"
#include "breakpad/src/client/windows/handler/exception_handler.h"

namespace {

const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\";
const wchar_t kChromePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices";

// This is the well known SID for the system principal.
const wchar_t kSystemPrincipalSid[] =L"S-1-5-18";

google_breakpad::ExceptionHandler* g_breakpad = NULL;

std::vector<wchar_t*>* url_chunks = NULL;

// Dumps the current process memory.
extern "C" void __declspec(dllexport) __cdecl DumpProcess() {
  if (g_breakpad)
    g_breakpad->WriteMinidump();
}

// Returns the custom info structure based on the dll in parameter and the
// process type.
static google_breakpad::CustomClientInfo* custom_info = NULL;
google_breakpad::CustomClientInfo* GetCustomInfo(const std::wstring& dll_path,
                                                 const std::wstring& type) {
  scoped_ptr<FileVersionInfo>
      version_info(FileVersionInfo::CreateFileVersionInfo(dll_path));

  std::wstring version, product;
  if (version_info.get()) {
    // Get the information from the file.
    product = version_info->product_short_name();
    version = version_info->product_version();
    if (!version_info->is_official_build())
      version.append(L"-devel");
  } else {
    // No version info found. Make up the values.
     product = L"Chrome";
     version = L"0.0.0.0-devel";
  }

  google_breakpad::CustomInfoEntry ver_entry(L"ver", version.c_str());
  google_breakpad::CustomInfoEntry prod_entry(L"prod", product.c_str());
  google_breakpad::CustomInfoEntry plat_entry(L"plat", L"Win32");
  google_breakpad::CustomInfoEntry type_entry(L"ptype", type.c_str());

  if (type == L"renderer") {
    // If we're a renderer create entries for the URL. Currently we only allow
    // each chunk to be 64 characters, which isn't enough for a URL. As a hack
    // we create 8 entries and split the URL across the entries.
    google_breakpad::CustomInfoEntry url1(L"url-chunk-1", L"");
    google_breakpad::CustomInfoEntry url2(L"url-chunk-2", L"");
    google_breakpad::CustomInfoEntry url3(L"url-chunk-3", L"");
    google_breakpad::CustomInfoEntry url4(L"url-chunk-4", L"");
    google_breakpad::CustomInfoEntry url5(L"url-chunk-5", L"");
    google_breakpad::CustomInfoEntry url6(L"url-chunk-6", L"");
    google_breakpad::CustomInfoEntry url7(L"url-chunk-7", L"");
    google_breakpad::CustomInfoEntry url8(L"url-chunk-8", L"");

    static google_breakpad::CustomInfoEntry entries[] =
        { ver_entry, prod_entry, plat_entry, type_entry, url1, url2, url3,
          url4, url5, url6, url7, url8 };

    std::vector<wchar_t*>* tmp_url_chunks = new std::vector<wchar_t*>(8);
    for (size_t i = 0; i < 8; ++i)
      (*tmp_url_chunks)[i] = entries[4 + i].value;
    url_chunks = tmp_url_chunks;

    static google_breakpad::CustomClientInfo custom_info = {entries,
                                                            arraysize(entries)};

    return &custom_info;
  }
  static google_breakpad::CustomInfoEntry entries[] = {ver_entry,
                                                       prod_entry,
                                                       plat_entry,
                                                       type_entry};

  static google_breakpad::CustomClientInfo custom_info = {entries,
                                                          arraysize(entries)};

  return &custom_info;
}

// Contains the information needed by the worker thread.
struct CrashReporterInfo {
  google_breakpad::CustomClientInfo* custom_info;
  std::wstring dll_path;
  std::wstring process_type;
};

// This callback is executed when the browser process has crashed, after
// the crash dump has been created. We need to minimize the amount of work
// done here since we have potentially corrupted process. Our job is to
// spawn another instance of chrome which will show a 'chrome has crashed'
// dialog. This code needs to live in the exe and thus has no access to
// facilities such as the i18n helpers.
bool DumpDoneCallback(const wchar_t*, const wchar_t*, void*,
                      EXCEPTION_POINTERS* ex_info,
                      MDRawAssertionInfo*, bool) {
  // If the exception is because there was a problem loading a delay-loaded
  // module, then show the user a dialog explaining the problem and then exit.
  if (DelayLoadFailureExceptionMessageBox(ex_info))
    return true;

  // We set CHROME_CRASHED env var. If the CHROME_RESTART is present.
  // This signals the child process to show the 'chrome has crashed' dialog.
  if (!::GetEnvironmentVariableW(env_vars::kRestartInfo, NULL, 0))
    return true;
  ::SetEnvironmentVariableW(env_vars::kShowRestart, L"1");
  // Now we just start chrome browser with the same command line.
  STARTUPINFOW si = {sizeof(si)};
  PROCESS_INFORMATION pi;
  if (::CreateProcessW(NULL, ::GetCommandLineW(), NULL, NULL, FALSE,
                       CREATE_UNICODE_ENVIRONMENT, NULL, NULL, &si, &pi)) {
    ::CloseHandle(pi.hProcess);
    ::CloseHandle(pi.hThread);
  }
  // After this return we will be terminated. The actual return value is
  // not used at all.
  return true;
}

// Previous unhandled filter. Will be called if not null when we
// intercept a crash.
LPTOP_LEVEL_EXCEPTION_FILTER previous_filter = NULL;

// Exception filter used when breakpad is not enabled. We just display
// the "Do you want to restart" message and then we call the previous filter.
long WINAPI ChromeExceptionFilter(EXCEPTION_POINTERS* info) {
  DumpDoneCallback(NULL, NULL, NULL, info, NULL, false);

  if (previous_filter)
    return previous_filter(info);

  return EXCEPTION_EXECUTE_HANDLER;
}

extern "C" void __declspec(dllexport) __cdecl SetActiveRendererURL(
    const wchar_t* url_cstring) {
  DCHECK(url_cstring);
  if (!url_chunks)
    return;

  std::wstring url(url_cstring);
  size_t num_chunks = url_chunks->size();
  size_t chunk_index = 0;
  size_t url_size = url.size();

  // Split the url across all the chunks.
  for (size_t url_offset = 0;
       chunk_index < num_chunks && url_offset < url_size; ++chunk_index) {
    size_t current_chunk_size = std::min(url_size - url_offset,
        static_cast<size_t>(
            google_breakpad::CustomInfoEntry::kValueMaxLength - 1));
    url._Copy_s((*url_chunks)[chunk_index],
                google_breakpad::CustomInfoEntry::kValueMaxLength,
                current_chunk_size, url_offset);
    (*url_chunks)[chunk_index][current_chunk_size] = L'\0';
    url_offset += current_chunk_size;
  }

  // And null terminate any unneeded chunks.
  for (; chunk_index < num_chunks; ++chunk_index)
    (*url_chunks)[chunk_index][0] = L'\0';
}

}  // namespace

// This function is executed by the child process that DumpDoneCallback()
// spawned and basically just shows the 'chrome has crashed' dialog if
// the CHROME_CRASHED environment variable is present.
bool ShowRestartDialogIfCrashed(bool* exit_now) {
  if (!::GetEnvironmentVariableW(env_vars::kShowRestart, NULL, 0))
    return false;

  DWORD len = ::GetEnvironmentVariableW(env_vars::kRestartInfo, NULL, 0);
  if (!len)
    return true;

  // We wrap the call to MessageBoxW with a SEH handler because it some
  // machines with CursorXP, PeaDict or with FontExplorer installed it crashes
  // uncontrollably here. Being this a best effort deal we better go away.
#pragma warning(push)
#pragma warning(disable:4509)  // warning: SEH used but dlg_strings has a dtor.
  __try {
    wchar_t* restart_data = new wchar_t[len + 1];
    ::GetEnvironmentVariableW(env_vars::kRestartInfo, restart_data, len);
    restart_data[len] = 0;
    // The CHROME_RESTART var contains the dialog strings separated by '|'.
    // See PrepareRestartOnCrashEnviroment() function for details.
    std::vector<std::wstring> dlg_strings;
    SplitString(restart_data, L'|', &dlg_strings);
    delete[] restart_data;
    if (dlg_strings.size() < 3)
      return true;

    // If the UI layout is right-to-left, we need to pass the appropriate MB_XXX
    // flags so that an RTL message box is displayed.
    UINT flags = MB_OKCANCEL | MB_ICONWARNING;
    if (dlg_strings[2] == env_vars::kRtlLocale)
      flags |= MB_RIGHT | MB_RTLREADING;

    // Show the dialog now. It is ok if another chrome is started by the
    // user since we have not initialized the databases.
    *exit_now = (IDOK != ::MessageBoxW(NULL, dlg_strings[1].c_str(),
                                       dlg_strings[0].c_str(), flags));
  } __except(EXCEPTION_EXECUTE_HANDLER) {
    // Its not safe to continue executing, exit silently here.
    ::ExitProcess(ResultCodes::RESPAWN_FAILED);
  }
#pragma warning(pop)
  return true;
}

static DWORD __stdcall InitCrashReporterThread(void* param) {
  CrashReporterInfo* info = reinterpret_cast<CrashReporterInfo*>(param);

  // GetCustomInfo can take a few milliseconds to get the file information, so
  // we do it here so it can run in a separate thread.
  info->custom_info = GetCustomInfo(info->dll_path, info->process_type);

  const CommandLine& command = *CommandLine::ForCurrentProcess();
  bool full_dump = command.HasSwitch(switches::kFullMemoryCrashReport);
  bool use_crash_service = command.HasSwitch(switches::kNoErrorDialogs) ||
                           GetEnvironmentVariable(L"CHROME_HEADLESS", NULL, 0);

  google_breakpad::ExceptionHandler::MinidumpCallback callback = NULL;

  if (info->process_type == L"browser") {
    // We install the post-dump callback only for the browser process. It
    // spawns a new browser process.
    callback = &DumpDoneCallback;
  }

  std::wstring pipe_name;
  if (use_crash_service) {
    // Crash reporting is done by crash_service.exe.
    pipe_name = kChromePipeName;
  } else {
    // We want to use the Google Update crash reporting. We need to check if the
    // user allows it first.
    if (!GoogleUpdateSettings::GetCollectStatsConsent()) {
      // The user did not allow Google Update to send crashes, we need to use
      // our default crash handler instead, but only for the browser process.
      if (callback)
        InitDefaultCrashCallback();
      return 0;
    }

    // Build the pipe name. It can be either:
    // System-wide install: "NamedPipe\GoogleCrashServices\S-1-5-18"
    // Per-user install: "NamedPipe\GoogleCrashServices\<user SID>"
    std::wstring user_sid;
    if (InstallUtil::IsPerUserInstall(info->dll_path.c_str())) {
      if (!win_util::GetUserSidString(&user_sid)) {
        delete info;
        return -1;
      }
    } else {
      user_sid = kSystemPrincipalSid;
    }

    pipe_name = kGoogleUpdatePipeName;
    pipe_name += user_sid;
  }

  // Get the alternate dump directory. We use the temp path.
  wchar_t temp_dir[MAX_PATH] = {0};
  ::GetTempPathW(MAX_PATH, temp_dir);

  MINIDUMP_TYPE dump_type = full_dump ? MiniDumpWithFullMemory : MiniDumpNormal;

  g_breakpad = new google_breakpad::ExceptionHandler(temp_dir, NULL, callback,
                   NULL, google_breakpad::ExceptionHandler::HANDLER_ALL,
                   dump_type, pipe_name.c_str(), info->custom_info);

  if (!g_breakpad->IsOutOfProcess()) {
    // The out-of-process handler is unavailable.
    ::SetEnvironmentVariable(env_vars::kNoOOBreakpad,
                             info->process_type.c_str());
  } else {
    // Tells breakpad to handle breakpoint and single step exceptions.
    // This might break JIT debuggers, but at least it will always
    // generate a crashdump for these exceptions.
    g_breakpad->set_handle_debug_exceptions(true);
  }

  delete info;
  return 0;
}

void InitDefaultCrashCallback() {
  previous_filter = SetUnhandledExceptionFilter(ChromeExceptionFilter);
}

void InitCrashReporterWithDllPath(const std::wstring& dll_path) {
  const CommandLine& command = *CommandLine::ForCurrentProcess();
  if (!command.HasSwitch(switches::kDisableBreakpad)) {
    // Disable the message box for assertions.
    _CrtSetReportMode(_CRT_ASSERT, 0);

    // Query the custom_info now because if we do it in the thread it's going to
    // fail in the sandbox. The thread will delete this object.
    CrashReporterInfo* info = new CrashReporterInfo;
    info->process_type = command.GetSwitchValue(switches::kProcessType);
    if (info->process_type.empty())
      info->process_type = L"browser";

    info->dll_path = dll_path;

    // If this is not the browser, we can't be sure that we will be able to
    // initialize the crash_handler in another thread, so we run it right away.
    // This is important to keep the thread for the browser process because
    // it may take some times to initialize the crash_service process.  We use
    // the Windows worker pool to make better reuse of the thread.
    if (info->process_type != L"browser") {
      InitCrashReporterThread(info);
    } else {
      if (QueueUserWorkItem(
              &InitCrashReporterThread, info, WT_EXECUTELONGFUNCTION) == 0) {
        // We failed to queue to the worker pool, initialize in this thread.
        InitCrashReporterThread(info);
      }
    }
  }
}
<commit_msg>Adding chrome start-up parameters to information passed back in breakpad crash - we collect the first two params : switch-1 and switch-2 - up to 64 chars, then it truncates<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/app/breakpad_win.h"

#include <windows.h>
#include <shellapi.h>
#include <tchar.h>
#include <vector>

#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/file_version_info.h"
#include "base/registry.h"
#include "base/string_util.h"
#include "base/win_util.h"
#include "chrome/app/google_update_client.h"
#include "chrome/app/hard_error_handler_win.h"
#include "chrome/common/env_vars.h"
#include "chrome/common/result_codes.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/installer/util/google_update_settings.h"
#include "breakpad/src/client/windows/handler/exception_handler.h"

namespace {

const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\";
const wchar_t kChromePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices";

// This is the well known SID for the system principal.
const wchar_t kSystemPrincipalSid[] =L"S-1-5-18";

google_breakpad::ExceptionHandler* g_breakpad = NULL;

std::vector<wchar_t*>* g_url_chunks = NULL;

// Dumps the current process memory.
extern "C" void __declspec(dllexport) __cdecl DumpProcess() {
  if (g_breakpad)
    g_breakpad->WriteMinidump();
}

// Reduces the size of the string |str| to a max of 64 chars. Required because
// breakpad's CustomInfoEntry raises an invalid_parameter error if the string
// we want to set is longer.
std::wstring TrimToBreakpadMax(const std::wstring& str) {
  std::wstring shorter(str);
  return shorter.substr(0,
      google_breakpad::CustomInfoEntry::kValueMaxLength - 1);
}

// Returns the custom info structure based on the dll in parameter and the
// process type.
static google_breakpad::CustomClientInfo* custom_info = NULL;
google_breakpad::CustomClientInfo* GetCustomInfo(const std::wstring& dll_path,
                                                 const std::wstring& type) {
  scoped_ptr<FileVersionInfo>
      version_info(FileVersionInfo::CreateFileVersionInfo(dll_path));

  std::wstring version, product;
  if (version_info.get()) {
    // Get the information from the file.
    product = version_info->product_short_name();
    version = version_info->product_version();
    if (!version_info->is_official_build())
      version.append(L"-devel");
  } else {
    // No version info found. Make up the values.
     product = L"Chrome";
     version = L"0.0.0.0-devel";
  }

  // Common entries.
  google_breakpad::CustomInfoEntry ver_entry(L"ver", version.c_str());
  google_breakpad::CustomInfoEntry prod_entry(L"prod", product.c_str());
  google_breakpad::CustomInfoEntry plat_entry(L"plat", L"Win32");
  google_breakpad::CustomInfoEntry type_entry(L"ptype", type.c_str());

  if (type == L"renderer") {
    // If we're a renderer create entries for the URL. Currently we only allow
    // each chunk to be 64 characters, which isn't enough for a URL. As a hack
    // we create 8 entries and split the URL across the entries.
    google_breakpad::CustomInfoEntry url1(L"url-chunk-1", L"");
    google_breakpad::CustomInfoEntry url2(L"url-chunk-2", L"");
    google_breakpad::CustomInfoEntry url3(L"url-chunk-3", L"");
    google_breakpad::CustomInfoEntry url4(L"url-chunk-4", L"");
    google_breakpad::CustomInfoEntry url5(L"url-chunk-5", L"");
    google_breakpad::CustomInfoEntry url6(L"url-chunk-6", L"");
    google_breakpad::CustomInfoEntry url7(L"url-chunk-7", L"");
    google_breakpad::CustomInfoEntry url8(L"url-chunk-8", L"");

    static google_breakpad::CustomInfoEntry entries[] =
        { ver_entry, prod_entry, plat_entry, type_entry,
          url1, url2, url3, url4, url5, url6, url7, url8 };

    std::vector<wchar_t*>* tmp_url_chunks = new std::vector<wchar_t*>(8);
    for (size_t i = 0; i < 8; ++i)
      (*tmp_url_chunks)[i] = entries[4 + i].value;
    g_url_chunks = tmp_url_chunks;

    static google_breakpad::CustomClientInfo custom_info_renderer
        = {entries, arraysize(entries)};
    return &custom_info_renderer;
  }

  // Browser-specific entries.
  google_breakpad::CustomInfoEntry switch1(L"switch-1", L"");
  google_breakpad::CustomInfoEntry switch2(L"switch-2", L"");

  // Get the first two command line switches if they exist. The CommandLine
  // class does not allow to enumerate the switches so we do it by hand.
  int num_args = 0;
  wchar_t** args = ::CommandLineToArgvW(::GetCommandLineW(), &num_args);
  if (args) {
    if (num_args > 1)
      switch1.set_value(TrimToBreakpadMax(args[1]).c_str());
    if (num_args > 2)
      switch2.set_value(TrimToBreakpadMax(args[2]).c_str());
  }

  static google_breakpad::CustomInfoEntry entries[] =
      {ver_entry, prod_entry, plat_entry, type_entry, switch1, switch2};
  static google_breakpad::CustomClientInfo custom_info_browser =
      {entries, arraysize(entries)};
  return &custom_info_browser;
}

// Contains the information needed by the worker thread.
struct CrashReporterInfo {
  google_breakpad::CustomClientInfo* custom_info;
  std::wstring dll_path;
  std::wstring process_type;
};

// This callback is executed when the browser process has crashed, after
// the crash dump has been created. We need to minimize the amount of work
// done here since we have potentially corrupted process. Our job is to
// spawn another instance of chrome which will show a 'chrome has crashed'
// dialog. This code needs to live in the exe and thus has no access to
// facilities such as the i18n helpers.
bool DumpDoneCallback(const wchar_t*, const wchar_t*, void*,
                      EXCEPTION_POINTERS* ex_info,
                      MDRawAssertionInfo*, bool) {
  // If the exception is because there was a problem loading a delay-loaded
  // module, then show the user a dialog explaining the problem and then exit.
  if (DelayLoadFailureExceptionMessageBox(ex_info))
    return true;

  // We set CHROME_CRASHED env var. If the CHROME_RESTART is present.
  // This signals the child process to show the 'chrome has crashed' dialog.
  if (!::GetEnvironmentVariableW(env_vars::kRestartInfo, NULL, 0))
    return true;
  ::SetEnvironmentVariableW(env_vars::kShowRestart, L"1");
  // Now we just start chrome browser with the same command line.
  STARTUPINFOW si = {sizeof(si)};
  PROCESS_INFORMATION pi;
  if (::CreateProcessW(NULL, ::GetCommandLineW(), NULL, NULL, FALSE,
                       CREATE_UNICODE_ENVIRONMENT, NULL, NULL, &si, &pi)) {
    ::CloseHandle(pi.hProcess);
    ::CloseHandle(pi.hThread);
  }
  // After this return we will be terminated. The actual return value is
  // not used at all.
  return true;
}

// Previous unhandled filter. Will be called if not null when we
// intercept a crash.
LPTOP_LEVEL_EXCEPTION_FILTER previous_filter = NULL;

// Exception filter used when breakpad is not enabled. We just display
// the "Do you want to restart" message and then we call the previous filter.
long WINAPI ChromeExceptionFilter(EXCEPTION_POINTERS* info) {
  DumpDoneCallback(NULL, NULL, NULL, info, NULL, false);

  if (previous_filter)
    return previous_filter(info);

  return EXCEPTION_EXECUTE_HANDLER;
}

extern "C" void __declspec(dllexport) __cdecl SetActiveRendererURL(
    const wchar_t* url_cstring) {
  DCHECK(url_cstring);
  if (!g_url_chunks)
    return;

  std::wstring url(url_cstring);
  size_t num_chunks = g_url_chunks->size();
  size_t chunk_index = 0;
  size_t url_size = url.size();

  // Split the url across all the chunks.
  for (size_t url_offset = 0;
       chunk_index < num_chunks && url_offset < url_size; ++chunk_index) {
    size_t current_chunk_size = std::min(url_size - url_offset,
        static_cast<size_t>(
            google_breakpad::CustomInfoEntry::kValueMaxLength - 1));
    url._Copy_s((*g_url_chunks)[chunk_index],
                google_breakpad::CustomInfoEntry::kValueMaxLength,
                current_chunk_size, url_offset);
    (*g_url_chunks)[chunk_index][current_chunk_size] = L'\0';
    url_offset += current_chunk_size;
  }

  // And null terminate any unneeded chunks.
  for (; chunk_index < num_chunks; ++chunk_index)
    (*g_url_chunks)[chunk_index][0] = L'\0';
}

}  // namespace

// This function is executed by the child process that DumpDoneCallback()
// spawned and basically just shows the 'chrome has crashed' dialog if
// the CHROME_CRASHED environment variable is present.
bool ShowRestartDialogIfCrashed(bool* exit_now) {
  if (!::GetEnvironmentVariableW(env_vars::kShowRestart, NULL, 0))
    return false;

  DWORD len = ::GetEnvironmentVariableW(env_vars::kRestartInfo, NULL, 0);
  if (!len)
    return true;

  // We wrap the call to MessageBoxW with a SEH handler because it some
  // machines with CursorXP, PeaDict or with FontExplorer installed it crashes
  // uncontrollably here. Being this a best effort deal we better go away.
#pragma warning(push)
#pragma warning(disable:4509)  // warning: SEH used but dlg_strings has a dtor.
  __try {
    wchar_t* restart_data = new wchar_t[len + 1];
    ::GetEnvironmentVariableW(env_vars::kRestartInfo, restart_data, len);
    restart_data[len] = 0;
    // The CHROME_RESTART var contains the dialog strings separated by '|'.
    // See PrepareRestartOnCrashEnviroment() function for details.
    std::vector<std::wstring> dlg_strings;
    SplitString(restart_data, L'|', &dlg_strings);
    delete[] restart_data;
    if (dlg_strings.size() < 3)
      return true;

    // If the UI layout is right-to-left, we need to pass the appropriate MB_XXX
    // flags so that an RTL message box is displayed.
    UINT flags = MB_OKCANCEL | MB_ICONWARNING;
    if (dlg_strings[2] == env_vars::kRtlLocale)
      flags |= MB_RIGHT | MB_RTLREADING;

    // Show the dialog now. It is ok if another chrome is started by the
    // user since we have not initialized the databases.
    *exit_now = (IDOK != ::MessageBoxW(NULL, dlg_strings[1].c_str(),
                                       dlg_strings[0].c_str(), flags));
  } __except(EXCEPTION_EXECUTE_HANDLER) {
    // Its not safe to continue executing, exit silently here.
    ::ExitProcess(ResultCodes::RESPAWN_FAILED);
  }
#pragma warning(pop)
  return true;
}

static DWORD __stdcall InitCrashReporterThread(void* param) {
  CrashReporterInfo* info = reinterpret_cast<CrashReporterInfo*>(param);

  // GetCustomInfo can take a few milliseconds to get the file information, so
  // we do it here so it can run in a separate thread.
  info->custom_info = GetCustomInfo(info->dll_path, info->process_type);

  const CommandLine& command = *CommandLine::ForCurrentProcess();
  bool full_dump = command.HasSwitch(switches::kFullMemoryCrashReport);
  bool use_crash_service = command.HasSwitch(switches::kNoErrorDialogs) ||
                           GetEnvironmentVariable(L"CHROME_HEADLESS", NULL, 0);

  google_breakpad::ExceptionHandler::MinidumpCallback callback = NULL;

  if (info->process_type == L"browser") {
    // We install the post-dump callback only for the browser process. It
    // spawns a new browser process.
    callback = &DumpDoneCallback;
  }

  std::wstring pipe_name;
  if (use_crash_service) {
    // Crash reporting is done by crash_service.exe.
    pipe_name = kChromePipeName;
  } else {
    // We want to use the Google Update crash reporting. We need to check if the
    // user allows it first.
    if (!GoogleUpdateSettings::GetCollectStatsConsent()) {
      // The user did not allow Google Update to send crashes, we need to use
      // our default crash handler instead, but only for the browser process.
      if (callback)
        InitDefaultCrashCallback();
      return 0;
    }

    // Build the pipe name. It can be either:
    // System-wide install: "NamedPipe\GoogleCrashServices\S-1-5-18"
    // Per-user install: "NamedPipe\GoogleCrashServices\<user SID>"
    std::wstring user_sid;
    if (InstallUtil::IsPerUserInstall(info->dll_path.c_str())) {
      if (!win_util::GetUserSidString(&user_sid)) {
        delete info;
        return -1;
      }
    } else {
      user_sid = kSystemPrincipalSid;
    }

    pipe_name = kGoogleUpdatePipeName;
    pipe_name += user_sid;
  }

  // Get the alternate dump directory. We use the temp path.
  wchar_t temp_dir[MAX_PATH] = {0};
  ::GetTempPathW(MAX_PATH, temp_dir);

  MINIDUMP_TYPE dump_type = full_dump ? MiniDumpWithFullMemory : MiniDumpNormal;

  g_breakpad = new google_breakpad::ExceptionHandler(temp_dir, NULL, callback,
                   NULL, google_breakpad::ExceptionHandler::HANDLER_ALL,
                   dump_type, pipe_name.c_str(), info->custom_info);

  if (!g_breakpad->IsOutOfProcess()) {
    // The out-of-process handler is unavailable.
    ::SetEnvironmentVariable(env_vars::kNoOOBreakpad,
                             info->process_type.c_str());
  } else {
    // Tells breakpad to handle breakpoint and single step exceptions.
    // This might break JIT debuggers, but at least it will always
    // generate a crashdump for these exceptions.
    g_breakpad->set_handle_debug_exceptions(true);
  }

  delete info;
  return 0;
}

void InitDefaultCrashCallback() {
  previous_filter = SetUnhandledExceptionFilter(ChromeExceptionFilter);
}

void InitCrashReporterWithDllPath(const std::wstring& dll_path) {
  const CommandLine& command = *CommandLine::ForCurrentProcess();
  if (!command.HasSwitch(switches::kDisableBreakpad)) {
    // Disable the message box for assertions.
    _CrtSetReportMode(_CRT_ASSERT, 0);

    // Query the custom_info now because if we do it in the thread it's going to
    // fail in the sandbox. The thread will delete this object.
    CrashReporterInfo* info = new CrashReporterInfo;
    info->process_type = command.GetSwitchValue(switches::kProcessType);
    if (info->process_type.empty())
      info->process_type = L"browser";

    info->dll_path = dll_path;

    // If this is not the browser, we can't be sure that we will be able to
    // initialize the crash_handler in another thread, so we run it right away.
    // This is important to keep the thread for the browser process because
    // it may take some times to initialize the crash_service process.  We use
    // the Windows worker pool to make better reuse of the thread.
    if (info->process_type != L"browser") {
      InitCrashReporterThread(info);
    } else {
      if (QueueUserWorkItem(
              &InitCrashReporterThread, info, WT_EXECUTELONGFUNCTION) == 0) {
        // We failed to queue to the worker pool, initialize in this thread.
        InitCrashReporterThread(info);
      }
    }
  }
}
<|endoftext|>