<commit_before>/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org 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 version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org.  If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/

/* system headers */
#include "system.h"
#include <tchar.h>

#include "file_url.h"
#include "path_helper.hxx"

#include <osl/diagnose.h>
#include <osl/mutex.h>
#include <osl/signal.h>
#ifndef __MINGW32__
#include <DbgHelp.h>
#endif
#include <ErrorRep.h>
#include <systools/win32/uwinapi.h>

typedef struct _oslSignalHandlerImpl
{
    oslSignalHandlerFunction      Handler;
    void*                         pData;
    struct _oslSignalHandlerImpl* pNext;
} oslSignalHandlerImpl;

static sal_Bool               bErrorReportingEnabled = sal_True;
static sal_Bool               bInitSignal = sal_False;
static oslMutex               SignalListMutex;
static oslSignalHandlerImpl*  SignalList;

static long WINAPI SignalHandlerFunction(LPEXCEPTION_POINTERS lpEP);

static sal_Bool InitSignal(void)
{
    HMODULE hFaultRep;

    SignalListMutex = osl_createMutex();

    SetUnhandledExceptionFilter(SignalHandlerFunction);

    hFaultRep = LoadLibrary( "faultrep.dll" );
    if ( hFaultRep )
    {
#ifdef __MINGW32__
typedef BOOL (WINAPI *pfn_ADDEREXCLUDEDAPPLICATIONW)(LPCWSTR);
#endif
        pfn_ADDEREXCLUDEDAPPLICATIONW       pfn = (pfn_ADDEREXCLUDEDAPPLICATIONW)GetProcAddress( hFaultRep, "AddERExcludedApplicationW" );
        if ( pfn )
            pfn( L"SOFFICE.EXE" );
        FreeLibrary( hFaultRep );
    }

    return sal_True;
}

static sal_Bool DeInitSignal(void)
{
    SetUnhandledExceptionFilter(NULL);

    osl_destroyMutex(SignalListMutex);

    return sal_False;
}

static oslSignalAction CallSignalHandler(oslSignalInfo *pInfo)
{
    oslSignalHandlerImpl* pHandler = SignalList;
    oslSignalAction Action = osl_Signal_ActCallNextHdl;

    while (pHandler != NULL)
    {
        if ((Action = pHandler->Handler(pHandler->pData, pInfo)) != osl_Signal_ActCallNextHdl)
            break;

        pHandler = pHandler->pNext;
    }

    return Action;
}

/*****************************************************************************/
/* SignalHandlerFunction    */
/*****************************************************************************/

#define REPORTENV_PARAM     "-crashreportenv:"
#define REPORTENV_PARAM2    "/crashreportenv:"

static BOOL ReportCrash( LPEXCEPTION_POINTERS lpEP )
{
    BOOL    fSuccess = FALSE;
    BOOL    fAutoReport = FALSE;
    TCHAR   szBuffer[1024];
    ::osl::LongPathBuffer< sal_Char > aPath( MAX_LONG_PATH );
    LPTSTR  lpFilePart;
    PROCESS_INFORMATION ProcessInfo;
    STARTUPINFO StartupInfo;
    int     argi;

    if ( !bErrorReportingEnabled )
        return FALSE;

    /* Check if crash reporter was disabled by command line */

    for ( argi = 1; argi < __argc; argi++ )
    {
        if (
            0 == stricmp( __argv[argi], "-nocrashreport" ) ||
            0 == stricmp( __argv[argi], "/nocrashreport" )
            )
            return FALSE;
        else if (
            0 == stricmp( __argv[argi], "-autocrashreport" ) ||
            0 == stricmp( __argv[argi], "/autocrashreport" )
            )
            fAutoReport = TRUE;
        else if (
            0 == strnicmp( __argv[argi], REPORTENV_PARAM, strlen(REPORTENV_PARAM) ) ||
            0 == strnicmp( __argv[argi], REPORTENV_PARAM2, strlen(REPORTENV_PARAM2) )
            )
        {
            const char *envparam = __argv[argi] + strlen(REPORTENV_PARAM);
            const char *delim = strchr(envparam, '=' );

            if ( delim )
            {
                CHAR    *lpVariable;
                CHAR    *lpValue;
                const char *variable = envparam;
                size_t variable_len = delim - envparam;
                const char *value = delim + 1;
                size_t value_len = strlen(envparam) - variable_len - 1;

                if ( '\"' == *value )
                {
                    const char *quote;

                    value++;
                    value_len--;

                    quote = strchr( value, '\"' );
                    if ( quote )
                        value_len = quote - value;
                }

                lpVariable = reinterpret_cast< CHAR* >( _alloca( variable_len + 1 ) );
                memcpy( lpVariable, variable, variable_len );
                lpVariable[variable_len] = 0;

                lpValue = reinterpret_cast< CHAR* >( _alloca( value_len + 1) );
                memcpy( lpValue, value, value_len );
                lpValue[value_len] = 0;

                SetEnvironmentVariable( lpVariable, lpValue );
            }
        }
    }

    if ( SearchPath( NULL, TEXT( "crashrep.exe" ), NULL, aPath.getBufSizeInSymbols(), aPath, &lpFilePart ) )
    {
        ZeroMemory( &StartupInfo, sizeof(StartupInfo) );
        StartupInfo.cb = sizeof(StartupInfo.cb);

        sntprintf( szBuffer, elementsof(szBuffer),
            _T("%s -p %u -excp 0x%p -t %u%s"),
            aPath,
            GetCurrentProcessId(),
            lpEP,
            GetCurrentThreadId(),
            fAutoReport ? _T(" -noui -send") : _T(" -noui") );

        if (
            CreateProcess(
                NULL,
                szBuffer,
                NULL,
                NULL,
                FALSE,
#ifdef UNICODE
                CREATE_UNICODE_ENVIRONMENT,
#else
                0,
#endif
                NULL, NULL, &StartupInfo, &ProcessInfo )
            )
        {
            DWORD   dwExitCode;

            WaitForSingleObject( ProcessInfo.hProcess, INFINITE );
            if ( GetExitCodeProcess( ProcessInfo.hProcess, &dwExitCode ) && 0 == dwExitCode )

            fSuccess = TRUE;

        }
    }

    return fSuccess;
}

/*****************************************************************************/
/* SignalHandlerFunction    */
/*****************************************************************************/

static BOOL WINAPI IsWin95A(void)
{
    OSVERSIONINFO   ovi;

    ZeroMemory( &ovi, sizeof(ovi) );
    ovi.dwOSVersionInfoSize = sizeof(ovi);

    if ( GetVersionEx( &ovi ) )
        /* See MSDN January 2000 documentation of GetVersionEx */
        return  (ovi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
                (ovi.dwMajorVersion <= 4) &&
                (ovi.dwMinorVersion == 0) &&
                (ovi.dwBuildNumber == 0x040003B6);

    /* Something wrent wrong. So assume we have an older operating prior Win95 */

    return TRUE;
}

/* magic Microsoft C++ compiler exception constant */
#define EXCEPTION_MSC_CPP_EXCEPTION 0xe06d7363

static long WINAPI SignalHandlerFunction(LPEXCEPTION_POINTERS lpEP)
{
    static sal_Bool     bNested = sal_False;
    sal_Bool        bRaiseCrashReporter = sal_False;
    oslSignalInfo   Info;
    oslSignalAction Action;

    Info.UserSignal = lpEP->ExceptionRecord->ExceptionCode;
    Info.UserData   = NULL;

    switch (lpEP->ExceptionRecord->ExceptionCode)
    {
        /* Transform unhandled exceptions into access violations.
           Microsoft C++ compiler (add more for other compilers if necessary).
         */
        case EXCEPTION_MSC_CPP_EXCEPTION:
        case EXCEPTION_ACCESS_VIOLATION:
            Info.Signal = osl_Signal_AccessViolation;
            bRaiseCrashReporter = sal_True;
            break;

        case EXCEPTION_INT_DIVIDE_BY_ZERO:
            Info.Signal = osl_Signal_IntegerDivideByZero;
            bRaiseCrashReporter = sal_True;
            break;

        case EXCEPTION_FLT_DIVIDE_BY_ZERO:
            Info.Signal = osl_Signal_FloatDivideByZero;
            bRaiseCrashReporter = sal_True;
            break;

        case EXCEPTION_BREAKPOINT:
            Info.Signal = osl_Signal_DebugBreak;
            break;

        default:
            Info.Signal = osl_Signal_System;
            bRaiseCrashReporter = sal_True;
            break;
    }

    if ( !bNested )
    {
        bNested = sal_True;

        if ( bRaiseCrashReporter && ReportCrash( lpEP ) || IsWin95A() )
        {
            CallSignalHandler(&Info);
            Action = osl_Signal_ActKillApp;
        }
        else
            Action = CallSignalHandler(&Info);
    }
    else
        Action = osl_Signal_ActKillApp;

    switch ( Action )
    {
        case osl_Signal_ActCallNextHdl:
            return (EXCEPTION_CONTINUE_SEARCH);

        case osl_Signal_ActAbortApp:
            return (EXCEPTION_EXECUTE_HANDLER);

        case osl_Signal_ActKillApp:
            SetErrorMode(SEM_NOGPFAULTERRORBOX);
            exit(255);
            break;
        default:
            break;
    }

    return (EXCEPTION_CONTINUE_EXECUTION);
}

/*****************************************************************************/
/* osl_addSignalHandler */
/*****************************************************************************/
oslSignalHandler SAL_CALL osl_addSignalHandler(oslSignalHandlerFunction Handler, void* pData)
{
    oslSignalHandlerImpl* pHandler;

    OSL_ASSERT(Handler != NULL);

    if (! bInitSignal)
        bInitSignal = InitSignal();

    pHandler = reinterpret_cast< oslSignalHandlerImpl* >( calloc( 1, sizeof(oslSignalHandlerImpl) ) );

    if (pHandler != NULL)
    {
        pHandler->Handler = Handler;
        pHandler->pData   = pData;

        osl_acquireMutex(SignalListMutex);

        pHandler->pNext = SignalList;
        SignalList      = pHandler;

        osl_releaseMutex(SignalListMutex);

        return (pHandler);
    }

    return (NULL);
}

/*****************************************************************************/
/* osl_removeSignalHandler */
/*****************************************************************************/
sal_Bool SAL_CALL osl_removeSignalHandler(oslSignalHandler Handler)
{
    oslSignalHandlerImpl *pHandler, *pPrevious = NULL;

    OSL_ASSERT(Handler != NULL);

    if (! bInitSignal)
        bInitSignal = InitSignal();

    osl_acquireMutex(SignalListMutex);

    pHandler = SignalList;

    while (pHandler != NULL)
    {
        if (pHandler == Handler)
        {
            if (pPrevious)
                pPrevious->pNext = pHandler->pNext;
            else
                SignalList = pHandler->pNext;

            osl_releaseMutex(SignalListMutex);

            if (SignalList == NULL)
                bInitSignal = DeInitSignal();

            free(pHandler);

            return (sal_True);
        }

        pPrevious = pHandler;
        pHandler  = pHandler->pNext;
    }

    osl_releaseMutex(SignalListMutex);

    return (sal_False);
}

/*****************************************************************************/
/* osl_raiseSignal */
/*****************************************************************************/
oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 UserSignal, void* UserData)
{
    oslSignalInfo   Info;
    oslSignalAction Action;

    if (! bInitSignal)
        bInitSignal = InitSignal();

    osl_acquireMutex(SignalListMutex);

    Info.Signal     = osl_Signal_User;
    Info.UserSignal = UserSignal;
    Info.UserData   = UserData;

    Action = CallSignalHandler(&Info);

    osl_releaseMutex(SignalListMutex);

    return (Action);
}

/*****************************************************************************/
/* osl_setErrorReporting */
/*****************************************************************************/
sal_Bool SAL_CALL osl_setErrorReporting( sal_Bool bEnable )
{
    sal_Bool bOld = bErrorReportingEnabled;
    bErrorReportingEnabled = bEnable;

    return bOld;
}
<commit_msg>fwk156: #i113687# Add static cast to get string for CreateProcess function<commit_after>/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2000, 2010 Oracle and/or its affiliates.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org 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 version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org.  If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/

/* system headers */
#include "system.h"
#include <tchar.h>

#include "file_url.h"
#include "path_helper.hxx"

#include <osl/diagnose.h>
#include <osl/mutex.h>
#include <osl/signal.h>
#ifndef __MINGW32__
#include <DbgHelp.h>
#endif
#include <ErrorRep.h>
#include <systools/win32/uwinapi.h>

typedef struct _oslSignalHandlerImpl
{
    oslSignalHandlerFunction      Handler;
    void*                         pData;
    struct _oslSignalHandlerImpl* pNext;
} oslSignalHandlerImpl;

static sal_Bool               bErrorReportingEnabled = sal_True;
static sal_Bool               bInitSignal = sal_False;
static oslMutex               SignalListMutex;
static oslSignalHandlerImpl*  SignalList;

static long WINAPI SignalHandlerFunction(LPEXCEPTION_POINTERS lpEP);

static sal_Bool InitSignal(void)
{
    HMODULE hFaultRep;

    SignalListMutex = osl_createMutex();

    SetUnhandledExceptionFilter(SignalHandlerFunction);

    hFaultRep = LoadLibrary( "faultrep.dll" );
    if ( hFaultRep )
    {
#ifdef __MINGW32__
typedef BOOL (WINAPI *pfn_ADDEREXCLUDEDAPPLICATIONW)(LPCWSTR);
#endif
        pfn_ADDEREXCLUDEDAPPLICATIONW       pfn = (pfn_ADDEREXCLUDEDAPPLICATIONW)GetProcAddress( hFaultRep, "AddERExcludedApplicationW" );
        if ( pfn )
            pfn( L"SOFFICE.EXE" );
        FreeLibrary( hFaultRep );
    }

    return sal_True;
}

static sal_Bool DeInitSignal(void)
{
    SetUnhandledExceptionFilter(NULL);

    osl_destroyMutex(SignalListMutex);

    return sal_False;
}

static oslSignalAction CallSignalHandler(oslSignalInfo *pInfo)
{
    oslSignalHandlerImpl* pHandler = SignalList;
    oslSignalAction Action = osl_Signal_ActCallNextHdl;

    while (pHandler != NULL)
    {
        if ((Action = pHandler->Handler(pHandler->pData, pInfo)) != osl_Signal_ActCallNextHdl)
            break;

        pHandler = pHandler->pNext;
    }

    return Action;
}

/*****************************************************************************/
/* SignalHandlerFunction    */
/*****************************************************************************/

#define REPORTENV_PARAM     "-crashreportenv:"
#define REPORTENV_PARAM2    "/crashreportenv:"

static BOOL ReportCrash( LPEXCEPTION_POINTERS lpEP )
{
    BOOL    fSuccess = FALSE;
    BOOL    fAutoReport = FALSE;
    TCHAR   szBuffer[1024];
    ::osl::LongPathBuffer< sal_Char > aPath( MAX_LONG_PATH );
    LPTSTR  lpFilePart;
    PROCESS_INFORMATION ProcessInfo;
    STARTUPINFO StartupInfo;
    int     argi;

    if ( !bErrorReportingEnabled )
        return FALSE;

    /* Check if crash reporter was disabled by command line */

    for ( argi = 1; argi < __argc; argi++ )
    {
        if (
            0 == stricmp( __argv[argi], "-nocrashreport" ) ||
            0 == stricmp( __argv[argi], "/nocrashreport" )
            )
            return FALSE;
        else if (
            0 == stricmp( __argv[argi], "-autocrashreport" ) ||
            0 == stricmp( __argv[argi], "/autocrashreport" )
            )
            fAutoReport = TRUE;
        else if (
            0 == strnicmp( __argv[argi], REPORTENV_PARAM, strlen(REPORTENV_PARAM) ) ||
            0 == strnicmp( __argv[argi], REPORTENV_PARAM2, strlen(REPORTENV_PARAM2) )
            )
        {
            const char *envparam = __argv[argi] + strlen(REPORTENV_PARAM);
            const char *delim = strchr(envparam, '=' );

            if ( delim )
            {
                CHAR    *lpVariable;
                CHAR    *lpValue;
                const char *variable = envparam;
                size_t variable_len = delim - envparam;
                const char *value = delim + 1;
                size_t value_len = strlen(envparam) - variable_len - 1;

                if ( '\"' == *value )
                {
                    const char *quote;

                    value++;
                    value_len--;

                    quote = strchr( value, '\"' );
                    if ( quote )
                        value_len = quote - value;
                }

                lpVariable = reinterpret_cast< CHAR* >( _alloca( variable_len + 1 ) );
                memcpy( lpVariable, variable, variable_len );
                lpVariable[variable_len] = 0;

                lpValue = reinterpret_cast< CHAR* >( _alloca( value_len + 1) );
                memcpy( lpValue, value, value_len );
                lpValue[value_len] = 0;

                SetEnvironmentVariable( lpVariable, lpValue );
            }
        }
    }

    if ( SearchPath( NULL, TEXT( "crashrep.exe" ), NULL, aPath.getBufSizeInSymbols(), aPath, &lpFilePart ) )
    {
        ZeroMemory( &StartupInfo, sizeof(StartupInfo) );
        StartupInfo.cb = sizeof(StartupInfo.cb);

        sntprintf( szBuffer, elementsof(szBuffer),
            _T("%s -p %u -excp 0x%p -t %u%s"),
            static_cast<sal_Char*>( aPath ),
            GetCurrentProcessId(),
            lpEP,
            GetCurrentThreadId(),
            fAutoReport ? _T(" -noui -send") : _T(" -noui") );

        if (
            CreateProcess(
                NULL,
                szBuffer,
                NULL,
                NULL,
                FALSE,
#ifdef UNICODE
                CREATE_UNICODE_ENVIRONMENT,
#else
                0,
#endif
                NULL, NULL, &StartupInfo, &ProcessInfo )
            )
        {
            DWORD   dwExitCode;

            WaitForSingleObject( ProcessInfo.hProcess, INFINITE );
            if ( GetExitCodeProcess( ProcessInfo.hProcess, &dwExitCode ) && 0 == dwExitCode )

            fSuccess = TRUE;

        }
    }

    return fSuccess;
}

/*****************************************************************************/
/* SignalHandlerFunction    */
/*****************************************************************************/

static BOOL WINAPI IsWin95A(void)
{
    OSVERSIONINFO   ovi;

    ZeroMemory( &ovi, sizeof(ovi) );
    ovi.dwOSVersionInfoSize = sizeof(ovi);

    if ( GetVersionEx( &ovi ) )
        /* See MSDN January 2000 documentation of GetVersionEx */
        return  (ovi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) &&
                (ovi.dwMajorVersion <= 4) &&
                (ovi.dwMinorVersion == 0) &&
                (ovi.dwBuildNumber == 0x040003B6);

    /* Something wrent wrong. So assume we have an older operating prior Win95 */

    return TRUE;
}

/* magic Microsoft C++ compiler exception constant */
#define EXCEPTION_MSC_CPP_EXCEPTION 0xe06d7363

static long WINAPI SignalHandlerFunction(LPEXCEPTION_POINTERS lpEP)
{
    static sal_Bool     bNested = sal_False;
    sal_Bool        bRaiseCrashReporter = sal_False;
    oslSignalInfo   Info;
    oslSignalAction Action;

    Info.UserSignal = lpEP->ExceptionRecord->ExceptionCode;
    Info.UserData   = NULL;

    switch (lpEP->ExceptionRecord->ExceptionCode)
    {
        /* Transform unhandled exceptions into access violations.
           Microsoft C++ compiler (add more for other compilers if necessary).
         */
        case EXCEPTION_MSC_CPP_EXCEPTION:
        case EXCEPTION_ACCESS_VIOLATION:
            Info.Signal = osl_Signal_AccessViolation;
            bRaiseCrashReporter = sal_True;
            break;

        case EXCEPTION_INT_DIVIDE_BY_ZERO:
            Info.Signal = osl_Signal_IntegerDivideByZero;
            bRaiseCrashReporter = sal_True;
            break;

        case EXCEPTION_FLT_DIVIDE_BY_ZERO:
            Info.Signal = osl_Signal_FloatDivideByZero;
            bRaiseCrashReporter = sal_True;
            break;

        case EXCEPTION_BREAKPOINT:
            Info.Signal = osl_Signal_DebugBreak;
            break;

        default:
            Info.Signal = osl_Signal_System;
            bRaiseCrashReporter = sal_True;
            break;
    }

    if ( !bNested )
    {
        bNested = sal_True;

        if ( bRaiseCrashReporter && ReportCrash( lpEP ) || IsWin95A() )
        {
            CallSignalHandler(&Info);
            Action = osl_Signal_ActKillApp;
        }
        else
            Action = CallSignalHandler(&Info);
    }
    else
        Action = osl_Signal_ActKillApp;

    switch ( Action )
    {
        case osl_Signal_ActCallNextHdl:
            return (EXCEPTION_CONTINUE_SEARCH);

        case osl_Signal_ActAbortApp:
            return (EXCEPTION_EXECUTE_HANDLER);

        case osl_Signal_ActKillApp:
            SetErrorMode(SEM_NOGPFAULTERRORBOX);
            exit(255);
            break;
        default:
            break;
    }

    return (EXCEPTION_CONTINUE_EXECUTION);
}

/*****************************************************************************/
/* osl_addSignalHandler */
/*****************************************************************************/
oslSignalHandler SAL_CALL osl_addSignalHandler(oslSignalHandlerFunction Handler, void* pData)
{
    oslSignalHandlerImpl* pHandler;

    OSL_ASSERT(Handler != NULL);

    if (! bInitSignal)
        bInitSignal = InitSignal();

    pHandler = reinterpret_cast< oslSignalHandlerImpl* >( calloc( 1, sizeof(oslSignalHandlerImpl) ) );

    if (pHandler != NULL)
    {
        pHandler->Handler = Handler;
        pHandler->pData   = pData;

        osl_acquireMutex(SignalListMutex);

        pHandler->pNext = SignalList;
        SignalList      = pHandler;

        osl_releaseMutex(SignalListMutex);

        return (pHandler);
    }

    return (NULL);
}

/*****************************************************************************/
/* osl_removeSignalHandler */
/*****************************************************************************/
sal_Bool SAL_CALL osl_removeSignalHandler(oslSignalHandler Handler)
{
    oslSignalHandlerImpl *pHandler, *pPrevious = NULL;

    OSL_ASSERT(Handler != NULL);

    if (! bInitSignal)
        bInitSignal = InitSignal();

    osl_acquireMutex(SignalListMutex);

    pHandler = SignalList;

    while (pHandler != NULL)
    {
        if (pHandler == Handler)
        {
            if (pPrevious)
                pPrevious->pNext = pHandler->pNext;
            else
                SignalList = pHandler->pNext;

            osl_releaseMutex(SignalListMutex);

            if (SignalList == NULL)
                bInitSignal = DeInitSignal();

            free(pHandler);

            return (sal_True);
        }

        pPrevious = pHandler;
        pHandler  = pHandler->pNext;
    }

    osl_releaseMutex(SignalListMutex);

    return (sal_False);
}

/*****************************************************************************/
/* osl_raiseSignal */
/*****************************************************************************/
oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 UserSignal, void* UserData)
{
    oslSignalInfo   Info;
    oslSignalAction Action;

    if (! bInitSignal)
        bInitSignal = InitSignal();

    osl_acquireMutex(SignalListMutex);

    Info.Signal     = osl_Signal_User;
    Info.UserSignal = UserSignal;
    Info.UserData   = UserData;

    Action = CallSignalHandler(&Info);

    osl_releaseMutex(SignalListMutex);

    return (Action);
}

/*****************************************************************************/
/* osl_setErrorReporting */
/*****************************************************************************/
sal_Bool SAL_CALL osl_setErrorReporting( sal_Bool bEnable )
{
    sal_Bool bOld = bErrorReportingEnabled;
    bErrorReportingEnabled = bEnable;

    return bOld;
}
<|endoftext|>


<commit_before>/*
 * Illarionserver - server for the game Illarion
 * Copyright 2011 Illarion e.V.
 *
 * This file is part of Illarionserver.
 *
 * Illarionserver  is  free  software:  you can redistribute it and/or modify it
 * under the terms of the  GNU  General  Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any
 * later version.
 *
 * Illarionserver 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 General Public License for more
 * details.
 *
 * You should have received a copy of the GNU  General Public License along with
 * Illarionserver. If not, see <http://www.gnu.org/licenses/>.
 */

#include "World.hpp"
#include "data/TilesTable.hpp"

#include "a_star.hpp"

namespace pathfinding {

using namespace boost;

character_out_edge_iterator::character_out_edge_iterator(): graph(nullptr), direction(8) {
}

character_out_edge_iterator::character_out_edge_iterator(int i, const Position &p, const world_map_graph &g): position(p), graph(&g), direction(i) {
    valid_step();
}

std::pair<Position, Position> character_out_edge_iterator::operator*() const {
    return std::make_pair(position, Position(position.first + character_moves[direction].first, position.second + character_moves[direction].second));
}

void character_out_edge_iterator::operator++() {
    ++direction;
    valid_step();
}

bool character_out_edge_iterator::operator==(const character_out_edge_iterator &iterator) const {
    return direction == iterator.direction;
}

void character_out_edge_iterator::valid_step() {
    Position new_pos(position.first + character_moves[direction].first, position.second + character_moves[direction].second);
    Field *new_field = World::get()->GetField(::position(new_pos.first, new_pos.second, graph->level));

    while (direction < 8 && (new_field == 0 ||
                             !(new_field->moveToPossible() || new_pos == graph->goal))) {
        ++direction;
        new_pos = Position(position.first + character_moves[direction].first, position.second + character_moves[direction].second);
        new_field = World::get()->GetField(::position(new_pos.first, new_pos.second, graph->level));
    }
}

world_map_graph::world_map_graph(const Position &goal, int level): goal(goal), level(level) {
}

world_map_graph::vertex_descriptor
source(const world_map_graph::edge_descriptor &e, const world_map_graph &g) {
    return e.first;
}

world_map_graph::vertex_descriptor
target(const world_map_graph::edge_descriptor &e, const world_map_graph &g) {
    return e.second;
}

std::pair<world_map_graph::out_edge_iterator, world_map_graph::out_edge_iterator>
out_edges(const world_map_graph::vertex_descriptor &v, const world_map_graph &g) {
    typedef world_map_graph::out_edge_iterator Iterator;
    return std::make_pair(Iterator(0, v, g), Iterator(8, v, g));
}

world_map_graph::degree_size_type
out_degree(const world_map_graph::vertex_descriptor &v, const world_map_graph &g) {
    typedef world_map_graph::out_edge_iterator Iterator;
    world_map_graph::degree_size_type count = 0;
    Iterator end(8, v, g);

    for (Iterator it(0, v, g); it != end; ++it) {
        ++count;
    }

    return count;
}

int num_vertices(const world_map_graph &g) {
    return 1000;
}

distance_heuristic::distance_heuristic(const Vertex &goal): goal(goal) {
    // std::cout << "heuristic goal (" << this->goal.first << ", " << this->goal.second << ")" << std::endl;
}

Cost distance_heuristic::operator()(const Vertex &u) {
    Cost dx = goal.first - u.first;
    Cost dy = goal.second - u.second;
    Cost d = sqrt(dx * dx + dy * dy);
    // std::cout << "from (" << u.first << ", " << u.second << ") to (" << goal.first << ", " << goal.second << "): " << d << std::endl;
    return d;
}

std::size_t edge_hash::operator()(std::pair<Position, Position> const &e) const {
    std::size_t seed = 0;
    boost::hash_combine(seed, e.first.first);
    boost::hash_combine(seed, e.first.second);
    boost::hash_combine(seed, e.second.first);
    boost::hash_combine(seed, e.second.second);
    return seed;
}

weight_calc::weight_calc(int level): level(level) {
}

auto weight_calc::operator[](key_type const &k) -> mapped_type & {
    if (find(k) == end()) {
        auto v = k.second;
        Field *field = World::get()->GetField(::position(v.first, v.second, level));

        if (!field) {
            insert(std::make_pair(k, 1));
        } else {
            auto tileId = field->getTileId();
            insert(std::make_pair(k, Data::Tiles[tileId].walkingCost));
        }
    }

    return at(k);
}

std::size_t vertex_hash::operator()(Position const &u) const {
    std::size_t seed = 0;
    boost::hash_combine(seed, u.first);
    boost::hash_combine(seed, u.second);
    return seed;
}

auto vertex_index_hash::operator[](key_type const &k) -> mapped_type & {
    if (find(k) == end()) {
        insert(std::make_pair(k, ++discovery_counter));
    }

    if (discovery_counter > 400) {
        Logger::debug(LogFacility::Other) << "[PATH FINDING] No path found in vertex_index_hash!" << Log::end;
        throw not_found();
    }

    return at(k);
}

astar_ex_visitor::astar_ex_visitor(const Position &goal): goal(goal) {
}

void astar_ex_visitor::examine_vertex(const Position &u, const world_map_graph &) {
    if (u == goal) {
        Logger::debug(LogFacility::Other) << "[PATH FINDING] Path found in astar_ex_visitor!" << Log::end;
        throw found_goal();
    }
}

void astar_ex_visitor::discover_vertex(const Position &u, const world_map_graph &) {
    ++node_counter;

    if (node_counter > 400) {
        Logger::debug(LogFacility::Other) << "[PATH FINDING] No path found in astar_ex_visitor!" << Log::end;
        throw not_found();
    }
}

auto dist_map::operator[](key_type const &k) -> mapped_type & {
    if (find(k) == end()) {
        insert(std::make_pair(k, std::numeric_limits<Cost>::max()));
    }

    return at(k);
}

auto pred_map::operator[](key_type const &k) -> mapped_type & {
    if (find(k) == end()) {
        insert(std::make_pair(k, k));
    }

    return at(k);
}

bool a_star(const ::position &start_pos, const ::position &goal_pos, std::list<direction> &steps) {
    steps.clear();

    if (start_pos.z != goal_pos.z || start_pos == goal_pos) {
        return false;
    }

    typedef graph_traits<world_map_graph>::vertex_descriptor vertex;
    typedef graph_traits<world_map_graph>::edge_descriptor edge;

    vertex start(start_pos.x, start_pos.y);
    vertex goal(goal_pos.x, goal_pos.y);
    world_map_graph g(goal, goal_pos.z);

    distance_heuristic h(goal);
    h(start);

    weight_calc weights(goal_pos.z);
    boost::associative_property_map<weight_calc> weight(weights);

    pred_map predecessor;
    boost::associative_property_map<pred_map> pred_pmap(predecessor);

    dist_map distance;
    distance[start] = 0;
    boost::associative_property_map<dist_map> dist_pmap(distance);

    dist_map rank;
    rank[start] = h(start);
    boost::associative_property_map<dist_map> rank_pmap(rank);

    vertex_index_hash index_map;
    boost::associative_property_map<vertex_index_hash> index(index_map);

    astar_ex_visitor visitor(goal);

    try {
        astar_search_no_init(g, start, h, weight_map(weight).rank_map(rank_pmap).
                             vertex_index_map(index).predecessor_map(pred_pmap).distance_map(dist_pmap).visitor(visitor));
    } catch (found_goal &fg) {
        vertex v = goal;
        vertex pre = predecessor[v];

        while (v != pre) {
            int dx = v.first - pre.first;
            int dy = v.second - pre.second;
            vertex dir(dx, dy);

            try {
                steps.push_front(character_directions.at(dir));
            } catch (std::out_of_range &) {
                Logger::error(LogFacility::Other) << "direction (" << dir.first << ", " << dir.second << ") is invalid" << Log::end;
            }

            v = pre;
            pre = predecessor[v];
        }

        return true;
    } catch (not_found &nf) {
        return false;
    }

    return false;
}

}

<commit_msg>Fix for boost <1.52<commit_after>/*
 * Illarionserver - server for the game Illarion
 * Copyright 2011 Illarion e.V.
 *
 * This file is part of Illarionserver.
 *
 * Illarionserver  is  free  software:  you can redistribute it and/or modify it
 * under the terms of the  GNU  General  Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any
 * later version.
 *
 * Illarionserver 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 General Public License for more
 * details.
 *
 * You should have received a copy of the GNU  General Public License along with
 * Illarionserver. If not, see <http://www.gnu.org/licenses/>.
 */

#include "World.hpp"
#include "data/TilesTable.hpp"

#include "a_star.hpp"

namespace pathfinding {

using namespace boost;

character_out_edge_iterator::character_out_edge_iterator(): graph(nullptr), direction(8) {
}

character_out_edge_iterator::character_out_edge_iterator(int i, const Position &p, const world_map_graph &g): position(p), graph(&g), direction(i) {
    valid_step();
}

std::pair<Position, Position> character_out_edge_iterator::operator*() const {
    return std::make_pair(position, Position(position.first + character_moves[direction].first, position.second + character_moves[direction].second));
}

void character_out_edge_iterator::operator++() {
    ++direction;
    valid_step();
}

bool character_out_edge_iterator::operator==(const character_out_edge_iterator &iterator) const {
    return direction == iterator.direction;
}

void character_out_edge_iterator::valid_step() {
    Position new_pos(position.first + character_moves[direction].first, position.second + character_moves[direction].second);
    Field *new_field = World::get()->GetField(::position(new_pos.first, new_pos.second, graph->level));

    while (direction < 8 && (new_field == 0 ||
                             !(new_field->moveToPossible() || new_pos == graph->goal))) {
        ++direction;
        new_pos = Position(position.first + character_moves[direction].first, position.second + character_moves[direction].second);
        new_field = World::get()->GetField(::position(new_pos.first, new_pos.second, graph->level));
    }
}

world_map_graph::world_map_graph(const Position &goal, int level): goal(goal), level(level) {
}

world_map_graph::vertex_descriptor
source(const world_map_graph::edge_descriptor &e, const world_map_graph &g) {
    return e.first;
}

world_map_graph::vertex_descriptor
target(const world_map_graph::edge_descriptor &e, const world_map_graph &g) {
    return e.second;
}

std::pair<world_map_graph::out_edge_iterator, world_map_graph::out_edge_iterator>
out_edges(const world_map_graph::vertex_descriptor &v, const world_map_graph &g) {
    typedef world_map_graph::out_edge_iterator Iterator;
    return std::make_pair(Iterator(0, v, g), Iterator(8, v, g));
}

world_map_graph::degree_size_type
out_degree(const world_map_graph::vertex_descriptor &v, const world_map_graph &g) {
    typedef world_map_graph::out_edge_iterator Iterator;
    world_map_graph::degree_size_type count = 0;
    Iterator end(8, v, g);

    for (Iterator it(0, v, g); it != end; ++it) {
        ++count;
    }

    return count;
}

int num_vertices(const world_map_graph &g) {
    return 1000;
}

distance_heuristic::distance_heuristic(const Vertex &goal): goal(goal) {
    // std::cout << "heuristic goal (" << this->goal.first << ", " << this->goal.second << ")" << std::endl;
}

Cost distance_heuristic::operator()(const Vertex &u) {
    Cost dx = goal.first - u.first;
    Cost dy = goal.second - u.second;
    Cost d = sqrt(dx * dx + dy * dy);
    // std::cout << "from (" << u.first << ", " << u.second << ") to (" << goal.first << ", " << goal.second << "): " << d << std::endl;
    return d;
}

std::size_t edge_hash::operator()(std::pair<Position, Position> const &e) const {
    std::size_t seed = 0;
    boost::hash_combine(seed, e.first.first);
    boost::hash_combine(seed, e.first.second);
    boost::hash_combine(seed, e.second.first);
    boost::hash_combine(seed, e.second.second);
    return seed;
}

weight_calc::weight_calc(int level): level(level) {
}

auto weight_calc::operator[](key_type const &k) -> mapped_type & {
    if (find(k) == end()) {
        auto v = k.second;
        Field *field = World::get()->GetField(::position(v.first, v.second, level));

        if (!field) {
            insert(std::make_pair(k, 1));
        } else {
            auto tileId = field->getTileId();
            insert(std::make_pair(k, Data::Tiles[tileId].walkingCost));
        }
    }

    return at(k);
}

std::size_t vertex_hash::operator()(Position const &u) const {
    std::size_t seed = 0;
    boost::hash_combine(seed, u.first);
    boost::hash_combine(seed, u.second);
    return seed;
}

auto vertex_index_hash::operator[](key_type const &k) -> mapped_type & {
    if (find(k) == end()) {
        insert(std::make_pair(k, ++discovery_counter));
    }

    if (discovery_counter > 400) {
        Logger::debug(LogFacility::Other) << "[PATH FINDING] No path found in vertex_index_hash!" << Log::end;
        throw not_found();
    }

    return at(k);
}

astar_ex_visitor::astar_ex_visitor(const Position &goal): goal(goal) {
}

void astar_ex_visitor::examine_vertex(const Position &u, const world_map_graph &) {
    if (u == goal) {
        Logger::debug(LogFacility::Other) << "[PATH FINDING] Path found in astar_ex_visitor!" << Log::end;
        throw found_goal();
    }
}

void astar_ex_visitor::discover_vertex(const Position &u, const world_map_graph &) {
    ++node_counter;

    if (node_counter > 400) {
        Logger::debug(LogFacility::Other) << "[PATH FINDING] No path found in astar_ex_visitor!" << Log::end;
        throw not_found();
    }
}

auto dist_map::operator[](key_type const &k) -> mapped_type & {
    if (find(k) == end()) {
        insert(std::make_pair(k, std::numeric_limits<Cost>::max()));
    }

    return at(k);
}

auto pred_map::operator[](key_type const &k) -> mapped_type & {
    if (find(k) == end()) {
        insert(std::make_pair(k, k));
    }

    return at(k);
}

bool a_star(const ::position &start_pos, const ::position &goal_pos, std::list<direction> &steps) {
    steps.clear();

    if (start_pos.z != goal_pos.z || start_pos == goal_pos) {
        return false;
    }

    typedef graph_traits<world_map_graph>::vertex_descriptor vertex;
    typedef graph_traits<world_map_graph>::edge_descriptor edge;

    vertex start(start_pos.x, start_pos.y);
    vertex goal(goal_pos.x, goal_pos.y);
    world_map_graph g(goal, goal_pos.z);

    distance_heuristic h(goal);
    h(start);

    weight_calc weights(goal_pos.z);
    boost::associative_property_map<weight_calc> weight(weights);

    pred_map predecessor;
    boost::associative_property_map<pred_map> pred_pmap(predecessor);

    dist_map distance;
    distance[start] = 0;
    boost::associative_property_map<dist_map> dist_pmap(distance);

    dist_map rank;
    rank[start] = h(start);
    boost::associative_property_map<dist_map> rank_pmap(rank);

    vertex_index_hash index_map;
    boost::associative_property_map<vertex_index_hash> index(index_map);

    astar_ex_visitor visitor(goal);

    auto color = make_shared_array_property_map(num_vertices(g), white_color, index);

    try {
        astar_search_no_init(g, start, h, visitor, pred_pmap, rank_pmap,
                dist_pmap, weight, color, index, std::less<Cost>(),
                std::plus<Cost>(), std::numeric_limits<Cost>::max(), Cost());
    } catch (found_goal &fg) {
        vertex v = goal;
        vertex pre = predecessor[v];

        while (v != pre) {
            int dx = v.first - pre.first;
            int dy = v.second - pre.second;
            vertex dir(dx, dy);

            try {
                steps.push_front(character_directions.at(dir));
            } catch (std::out_of_range &) {
                Logger::error(LogFacility::Other) << "direction (" << dir.first << ", " << dir.second << ") is invalid" << Log::end;
            }

            v = pre;
            pre = predecessor[v];
        }

        return true;
    } catch (not_found &nf) {
        return false;
    }

    return false;
}

}

<|endoftext|>


<commit_before>#include "CompilerExplorerOptionsWidget.h"
#include "ui_CompilerExplorerOptionsWidget.h"
#include <QFileDialog>
#include "compilerexplorerconstants.h"
#include <QDebug>

namespace compilerExplorer {
namespace gui{

CompilerExplorerOptionsWidget::CompilerExplorerOptionsWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CompilerExplorerOptionsWidget) {
	ui->setupUi(this);
}

CompilerExplorerOptionsWidget::~CompilerExplorerOptionsWidget() {
	delete ui;
}

void CompilerExplorerOptionsWidget::loadSettings(const QSettings &settings) {
	const auto nodejsLocation = settings.value(constants::nodejsFileNameKey, QString()).toString();
	ui->nodejsLocation->setText(nodejsLocation);
	const auto compilerExplorerLocation = settings.value(constants::compilerExplorerLocationKey,
	                                                     QString()).toString();
	ui->compilerExplorerLocation->setText(compilerExplorerLocation);
	const auto useLocalServer = settings.value(constants::useLocalServerKey, true).toBool();
	ui->useLocalServerButton->setChecked(useLocalServer);
	ui->useRemoteServer->setChecked(!useLocalServer);
	const auto localPort = settings.value(constants::localServerPortKey,
	                                            10240).toInt();
	ui->localPort->setValue(localPort);
	const auto remoteServerUrl = settings.value(constants::remoteServerUrlKey,
	                                            QString("https://gcc.godbolt.org/")).toString();
	ui->remoteServerUrl->setText(remoteServerUrl);
	ui->localServerGroupBox->setEnabled(useLocalServer);
	ui->remoteServerUrl->setEnabled(!useLocalServer);
}

void CompilerExplorerOptionsWidget::apply(QSettings &settings) {
	const auto nodejsLocation = settings.value(constants::nodejsFileNameKey, QString()).toString();
	const auto compilerExplorerLocation = settings.value(constants::compilerExplorerLocationKey,
	                                                     QString()).toString();
	const auto useLocalServer = settings.value(constants::useLocalServerKey).toBool();
	const auto remoteServerUrl = settings.value(constants::remoteServerUrlKey, QString()).toString();
	const auto localPort = settings.value(constants::localServerPortKey, 10240).toInt();

	settings.setValue(constants::useLocalServerKey ,ui->useLocalServerButton->isChecked());
	settings.setValue(constants::nodejsFileNameKey, ui->nodejsLocation->text());
	settings.setValue(constants::compilerExplorerLocationKey, ui->compilerExplorerLocation->text());
	settings.setValue(constants::localServerPortKey, ui->localPort->value());
	settings.setValue(constants::remoteServerUrlKey, ui->remoteServerUrl->text());

	if((nodejsLocation != ui->nodejsLocation->text()) ||
	        (compilerExplorerLocation != ui->compilerExplorerLocation->text()) ||
	        useLocalServer != ui->useLocalServerButton->isChecked() ||
	        localPort != ui->localPort->value() ||
	        remoteServerUrl != ui->remoteServerUrl->text()) {
		emit settingsChanged();
	}
}

void CompilerExplorerOptionsWidget::on_toolButton_clicked() {
	QString res = QFileDialog::getOpenFileName(this, tr("NodeJS"),
	                                           QString(), tr("node ") + "(node**)");
	if(!res.isEmpty())
		ui->nodejsLocation->setText(res);
}

void CompilerExplorerOptionsWidget::on_toolButton_2_clicked() {
	QString res = QFileDialog::getExistingDirectory(this);
	if(!res.isEmpty())
		ui->compilerExplorerLocation->setText(res);
}
}
}
<commit_msg>now fixed #14<commit_after>#include "CompilerExplorerOptionsWidget.h"
#include "ui_CompilerExplorerOptionsWidget.h"
#include <QFileDialog>
#include "compilerexplorerconstants.h"
#include <QDebug>

namespace compilerExplorer {
namespace gui{

CompilerExplorerOptionsWidget::CompilerExplorerOptionsWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CompilerExplorerOptionsWidget) {
	ui->setupUi(this);
}

CompilerExplorerOptionsWidget::~CompilerExplorerOptionsWidget() {
	delete ui;
}

void CompilerExplorerOptionsWidget::loadSettings(const QSettings &settings) {
	const auto nodejsLocation = settings.value(constants::nodejsFileNameKey, QString()).toString();
	ui->nodejsLocation->setText(nodejsLocation);
	const auto compilerExplorerLocation = settings.value(constants::compilerExplorerLocationKey,
	                                                     QString()).toString();
	ui->compilerExplorerLocation->setText(compilerExplorerLocation);
	const auto useLocalServer = settings.value(constants::useLocalServerKey, true).toBool();
	ui->useLocalServerButton->setChecked(useLocalServer);
	ui->useRemoteServer->setChecked(!useLocalServer);
	const auto localPort = settings.value(constants::localServerPortKey,
	                                            10240).toInt();
	ui->localPort->setValue(localPort);
	const auto startLocalServer = settings.value(constants::startLocalServerKey, true).toBool();
	const auto remoteServerUrl = settings.value(constants::remoteServerUrlKey,
	                                            QString("https://gcc.godbolt.org/")).toString();
	ui->remoteServerUrl->setText(remoteServerUrl);
	ui->localServerGroupBox->setEnabled(useLocalServer);
	ui->localServerSettingsGroup->setEnabled(startLocalServer);
	ui->remoteServerUrl->setEnabled(!useLocalServer);
}

void CompilerExplorerOptionsWidget::apply(QSettings &settings) {
	const auto nodejsLocation = settings.value(constants::nodejsFileNameKey, QString()).toString();
	const auto compilerExplorerLocation = settings.value(constants::compilerExplorerLocationKey,
	                                                     QString()).toString();
	const auto useLocalServer = settings.value(constants::useLocalServerKey).toBool();
	const auto startLocalServer = settings.value(constants::startLocalServerKey, true).toBool();
	const auto remoteServerUrl = settings.value(constants::remoteServerUrlKey, QString()).toString();
	const auto localPort = settings.value(constants::localServerPortKey, 10240).toInt();

	settings.setValue(constants::useLocalServerKey ,ui->useLocalServerButton->isChecked());
	settings.setValue(constants::startLocalServerKey, ui->localServerSettingsGroup->isChecked());
	settings.setValue(constants::nodejsFileNameKey, ui->nodejsLocation->text());
	settings.setValue(constants::compilerExplorerLocationKey, ui->compilerExplorerLocation->text());
	settings.setValue(constants::localServerPortKey, ui->localPort->value());
	settings.setValue(constants::remoteServerUrlKey, ui->remoteServerUrl->text());

	if((nodejsLocation != ui->nodejsLocation->text()) ||
	        startLocalServer != ui->localServerSettingsGroup->isChecked() ||
	        compilerExplorerLocation != ui->compilerExplorerLocation->text() ||
	        useLocalServer != ui->useLocalServerButton->isChecked() ||
	        localPort != ui->localPort->value() ||
	        remoteServerUrl != ui->remoteServerUrl->text()) {
		emit settingsChanged();
	}
}

void CompilerExplorerOptionsWidget::on_toolButton_clicked() {
	QString res = QFileDialog::getOpenFileName(this, tr("NodeJS"),
	                                           QString(), tr("node ") + "(node**)");
	if(!res.isEmpty())
		ui->nodejsLocation->setText(res);
}

void CompilerExplorerOptionsWidget::on_toolButton_2_clicked() {
	QString res = QFileDialog::getExistingDirectory(this);
	if(!res.isEmpty())
		ui->compilerExplorerLocation->setText(res);
}
}
}
<|endoftext|>


<commit_before>// Copyright (c) 2009 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 "webkit/glue/plugins/plugin_list.h"

#include <tchar.h>

#include <set>

#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/registry.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/webkit_glue.h"

namespace {

const TCHAR kRegistryApps[] =
    _T("Software\\Microsoft\\Windows\\CurrentVersion\\App Paths");
const TCHAR kRegistryFirefox[] = _T("firefox.exe");
const TCHAR kRegistryAcrobat[] = _T("Acrobat.exe");
const TCHAR kRegistryAcrobatReader[] = _T("AcroRd32.exe");
const TCHAR kRegistryWindowsMedia[] = _T("wmplayer.exe");
const TCHAR kRegistryQuickTime[] = _T("QuickTimePlayer.exe");
const TCHAR kRegistryPath[] = _T("Path");
const TCHAR kRegistryFirefoxInstalled[] =
    _T("SOFTWARE\\Mozilla\\Mozilla Firefox");
const TCHAR kRegistryJava[] =
    _T("Software\\JavaSoft\\Java Runtime Environment");
const TCHAR kRegistryBrowserJavaVersion[] = _T("BrowserJavaVersion");
const TCHAR kRegistryCurrentJavaVersion[] = _T("CurrentVersion");
const TCHAR kRegistryJavaHome[] = _T("JavaHome");

// The application path where we expect to find plugins.
void GetAppDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath app_path;
  if (!webkit_glue::GetApplicationDirectory(&app_path))
    return;

  app_path = app_path.AppendASCII("plugins");
  plugin_dirs->insert(app_path);
}

// The executable path where we expect to find plugins.
void GetExeDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath exe_path;
  if (!webkit_glue::GetExeDirectory(&exe_path))
    return;

  exe_path = exe_path.AppendASCII("plugins");
  plugin_dirs->insert(exe_path);
}

// Gets the installed path for a registered app.
bool GetInstalledPath(const TCHAR* app, FilePath* out) {
  std::wstring reg_path(kRegistryApps);
  reg_path.append(L"\\");
  reg_path.append(app);

  RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str());
  std::wstring path;
  if (key.ReadValue(kRegistryPath, &path)) {
    *out = FilePath(path);
    return true;
  }

  return false;
}

// Search the registry at the given path and detect plugin directories.
void GetPluginsInRegistryDirectory(
    HKEY root_key,
    const std::wstring& registry_folder,
    std::set<FilePath>* plugin_dirs) {
  for (RegistryKeyIterator iter(root_key, registry_folder.c_str());
       iter.Valid(); ++iter) {
    // Use the registry to gather plugin across the file system.
    std::wstring reg_path = registry_folder;
    reg_path.append(L"\\");
    reg_path.append(iter.Name());
    RegKey key(root_key, reg_path.c_str());

    std::wstring path;
    if (key.ReadValue(kRegistryPath, &path))
      plugin_dirs->insert(FilePath(path));
  }
}

// Enumerate through the registry key to find all installed FireFox paths.
// FireFox 3 beta and version 2 can coexist. See bug: 1025003
void GetFirefoxInstalledPaths(std::vector<FilePath>* out) {
  RegistryKeyIterator it(HKEY_LOCAL_MACHINE, kRegistryFirefoxInstalled);
  for (; it.Valid(); ++it) {
    std::wstring full_path = std::wstring(kRegistryFirefoxInstalled) + L"\\" +
                             it.Name() + L"\\Main";
    RegKey key(HKEY_LOCAL_MACHINE, full_path.c_str(), KEY_READ);
    std::wstring install_dir;
    if (!key.ReadValue(L"Install Directory", &install_dir))
      continue;
    out->push_back(FilePath(install_dir));
  }
}

// Get plugin directory locations from the Firefox install path.  This is kind
// of a kludge, but it helps us locate the flash player for users that
// already have it for firefox.  Not having to download yet-another-plugin
// is a good thing.
void GetFirefoxDirectory(std::set<FilePath>* plugin_dirs) {
  std::vector<FilePath> paths;
  GetFirefoxInstalledPaths(&paths);
  for (unsigned int i = 0; i < paths.size(); ++i) {
    plugin_dirs->insert(paths[i].Append(L"plugins"));
  }

  FilePath firefox_app_data_plugin_path;
  if (PathService::Get(base::DIR_APP_DATA, &firefox_app_data_plugin_path)) {
    firefox_app_data_plugin_path =
        firefox_app_data_plugin_path.AppendASCII("Mozilla")
                                    .AppendASCII("plugins");
    plugin_dirs->insert(firefox_app_data_plugin_path);
  }
}

// Hardcoded logic to detect Acrobat plugins locations.
void GetAcrobatDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath path;
  if (!GetInstalledPath(kRegistryAcrobatReader, &path) &&
      !GetInstalledPath(kRegistryAcrobat, &path)) {
    return;
  }

  plugin_dirs->insert(path.Append(L"Browser"));
}

// Hardcoded logic to detect QuickTime plugin location.
void GetQuicktimeDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath path;
  if (GetInstalledPath(kRegistryQuickTime, &path))
    plugin_dirs->insert(path.Append(L"plugins"));
}

// Hardcoded logic to detect Windows Media Player plugin location.
void GetWindowsMediaDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath path;
  if (GetInstalledPath(kRegistryWindowsMedia, &path))
    plugin_dirs->insert(path);

  // If the Windows Media Player Firefox plugin is installed before Firefox,
  // the plugin will get written under PFiles\Plugins on one the drives
  // (usually, but not always, the last letter).
  int size = GetLogicalDriveStrings(0, NULL);
  if (size) {
    scoped_array<wchar_t> strings(new wchar_t[size]);
    if (GetLogicalDriveStrings(size, strings.get())) {
      wchar_t* next_drive = strings.get();
      while (*next_drive) {
        if (GetDriveType(next_drive) == DRIVE_FIXED) {
          FilePath pfiles(next_drive);
          pfiles = pfiles.Append(L"PFiles\\Plugins");
          if (file_util::PathExists(pfiles))
            plugin_dirs->insert(pfiles);
        }
        next_drive = &next_drive[wcslen(next_drive) + 1];
      }
    }
  }
}

// Hardcoded logic to detect Java plugin location.
void GetJavaDirectory(std::set<FilePath>* plugin_dirs) {
  // Load the new NPAPI Java plugin
  // 1. Open the main JRE key under HKLM
  RegKey java_key(HKEY_LOCAL_MACHINE, kRegistryJava, KEY_QUERY_VALUE);

  // 2. Read the current Java version
  std::wstring java_version;
  if (!java_key.ReadValue(kRegistryBrowserJavaVersion, &java_version))
    java_key.ReadValue(kRegistryCurrentJavaVersion, &java_version);

  if (!java_version.empty()) {
    java_key.OpenKey(java_version.c_str(), KEY_QUERY_VALUE);

    // 3. Install path of the JRE binaries is specified in "JavaHome"
    //    value under the Java version key.
    std::wstring java_plugin_directory;
    if (java_key.ReadValue(kRegistryJavaHome, &java_plugin_directory)) {
      // 4. The new plugin resides under the 'bin/new_plugin'
      //    subdirectory.
      DCHECK(!java_plugin_directory.empty());
      java_plugin_directory.append(L"\\bin\\new_plugin");

      // 5. We don't know the exact name of the DLL but it's in the form
      //    NP*.dll so just invoke LoadPlugins on this path.
      plugin_dirs->insert(FilePath(java_plugin_directory));
    }
  }
}

}  // anonymous namespace

namespace NPAPI {

void PluginList::PlatformInit() {
  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
  dont_load_new_wmp_ = command_line.HasSwitch(kUseOldWMPPluginSwitch);
}

void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) {
  // We use a set for uniqueness, which we require, over order, which we do not.
  std::set<FilePath> dirs;

  // Load from the application-specific area
  GetAppDirectory(&dirs);

  // Load from the executable area
  GetExeDirectory(&dirs);

  // Load Java
  GetJavaDirectory(&dirs);

  // Load firefox plugins too.  This is mainly to try to locate
  // a pre-installed Flash player.
  GetFirefoxDirectory(&dirs);

  // Firefox hard-codes the paths of some popular plugins to ensure that
  // the plugins are found.  We are going to copy this as well.
  GetAcrobatDirectory(&dirs);
  GetQuicktimeDirectory(&dirs);
  GetWindowsMediaDirectory(&dirs);

  for (std::set<FilePath>::iterator i = dirs.begin(); i != dirs.end(); ++i)
    plugin_dirs->push_back(*i);
}

void PluginList::LoadPluginsFromDir(const FilePath &path,
                                    std::vector<WebPluginInfo>* plugins,
                                    std::set<FilePath>* visited_plugins) {
  WIN32_FIND_DATA find_file_data;
  HANDLE find_handle;

  std::wstring dir = path.value();
  // FindFirstFile requires that you specify a wildcard for directories.
  dir.append(L"\\NP*.DLL");

  find_handle = FindFirstFile(dir.c_str(), &find_file_data);
  if (find_handle == INVALID_HANDLE_VALUE)
    return;

  do {
    if (!(find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
      FilePath filename = path.Append(find_file_data.cFileName);
      LoadPlugin(filename, plugins);
      visited_plugins->insert(filename);
    }
  } while (FindNextFile(find_handle, &find_file_data) != 0);

  DCHECK(GetLastError() == ERROR_NO_MORE_FILES);
  FindClose(find_handle);
}

void PluginList::LoadPluginsFromRegistry(
    std::vector<WebPluginInfo>* plugins,
    std::set<FilePath>* visited_plugins) {
  std::set<FilePath> plugin_dirs;

  GetPluginsInRegistryDirectory(
      HKEY_CURRENT_USER, kRegistryMozillaPlugins, &plugin_dirs);
  GetPluginsInRegistryDirectory(
      HKEY_LOCAL_MACHINE, kRegistryMozillaPlugins, &plugin_dirs);

  for (std::set<FilePath>::iterator i = plugin_dirs.begin();
       i != plugin_dirs.end(); ++i) {
    LoadPlugin(*i, plugins);
    visited_plugins->insert(*i);
  }
}

// Compares Windows style version strings (i.e. 1,2,3,4).  Returns true if b's
// version is newer than a's, or false if it's equal or older.
bool IsNewerVersion(const std::wstring& a, const std::wstring& b) {
  std::vector<std::wstring> a_ver, b_ver;
  SplitString(a, ',', &a_ver);
  SplitString(b, ',', &b_ver);
  if (a_ver.size() != b_ver.size())
    return false;
  for (size_t i = 0; i < a_ver.size(); i++) {
    int cur_a = StringToInt(a_ver[i]);
    int cur_b = StringToInt(b_ver[i]);
    if (cur_a > cur_b)
      return false;
    if (cur_a < cur_b)
      return true;
  }
  return false;
}

bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
                                  std::vector<WebPluginInfo>* plugins) {
  // Version check

  for (size_t i = 0; i < plugins->size(); ++i) {
    if ((*plugins)[i].path.BaseName() == info.path.BaseName() &&
        !IsNewerVersion((*plugins)[i].version, info.version)) {
      return false;  // We already have a loaded plugin whose version is newer.
    }
  }

  // Troublemakers

  std::wstring filename = StringToLowerASCII(info.path.BaseName().value());
  // Depends on XPCOM.
  if (filename == kMozillaActiveXPlugin)
    return false;

  // Disable the Yahoo Application State plugin as it crashes the plugin
  // process on return from NPObjectStub::OnInvoke. Please refer to
  // http://b/issue?id=1372124 for more information.
  if (filename == kYahooApplicationStatePlugin)
    return false;

  // Disable the WangWang protocol handler plugin (npww.dll) as it crashes
  // chrome during shutdown. Firefox also disables this plugin.
  // Please refer to http://code.google.com/p/chromium/issues/detail?id=3953
  // for more information.
  if (filename == kWanWangProtocolHandlerPlugin)
    return false;

  // We only work with newer versions of the Java plugin which use NPAPI only
  // and don't depend on XPCOM.
  if (filename == kJavaPlugin1 || filename == kJavaPlugin2) {
    std::vector<std::wstring> ver;
    SplitString(info.version, '.', &ver);
    int major, minor, update;
    if (ver.size() == 4 &&
        StringToInt(ver[0], &major) &&
        StringToInt(ver[1], &minor) &&
        StringToInt(ver[2], &update)) {
      if (major == 6 && minor == 0 && update < 120)
        return false;  // Java SE6 Update 11 or older.
    }
  }

  // Special WMP handling

  // If both the new and old WMP plugins exist, only load the new one.
  if (filename == kNewWMPPlugin) {
    if (dont_load_new_wmp_)
      return false;

    for (size_t i = 0; i < plugins->size(); ++i) {
      if ((*plugins)[i].path.BaseName().value() == kOldWMPPlugin) {
        plugins->erase(plugins->begin() + i);
        break;
      }
    }
  } else if (filename == kOldWMPPlugin) {
    for (size_t i = 0; i < plugins->size(); ++i) {
      if ((*plugins)[i].path.BaseName().value() == kNewWMPPlugin)
        return false;
    }
  }

  return true;
}

}  // namespace NPAPI
<commit_msg>Don't load the old Java Deployment plugin if a newer one (with a different name) exists. Review URL: http://codereview.chromium.org/1672004<commit_after>// Copyright (c) 2009 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 "webkit/glue/plugins/plugin_list.h"

#include <tchar.h>

#include <set>

#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/registry.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "webkit/glue/plugins/plugin_constants_win.h"
#include "webkit/glue/plugins/plugin_lib.h"
#include "webkit/glue/webkit_glue.h"

namespace {

const TCHAR kRegistryApps[] =
    _T("Software\\Microsoft\\Windows\\CurrentVersion\\App Paths");
const TCHAR kRegistryFirefox[] = _T("firefox.exe");
const TCHAR kRegistryAcrobat[] = _T("Acrobat.exe");
const TCHAR kRegistryAcrobatReader[] = _T("AcroRd32.exe");
const TCHAR kRegistryWindowsMedia[] = _T("wmplayer.exe");
const TCHAR kRegistryQuickTime[] = _T("QuickTimePlayer.exe");
const TCHAR kRegistryPath[] = _T("Path");
const TCHAR kRegistryFirefoxInstalled[] =
    _T("SOFTWARE\\Mozilla\\Mozilla Firefox");
const TCHAR kRegistryJava[] =
    _T("Software\\JavaSoft\\Java Runtime Environment");
const TCHAR kRegistryBrowserJavaVersion[] = _T("BrowserJavaVersion");
const TCHAR kRegistryCurrentJavaVersion[] = _T("CurrentVersion");
const TCHAR kRegistryJavaHome[] = _T("JavaHome");
const TCHAR kJavaDeploy1[] = _T("npdeploytk.dll");
const TCHAR kJavaDeploy2[] = _T("npdeployjava1.dll");

// The application path where we expect to find plugins.
void GetAppDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath app_path;
  if (!webkit_glue::GetApplicationDirectory(&app_path))
    return;

  app_path = app_path.AppendASCII("plugins");
  plugin_dirs->insert(app_path);
}

// The executable path where we expect to find plugins.
void GetExeDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath exe_path;
  if (!webkit_glue::GetExeDirectory(&exe_path))
    return;

  exe_path = exe_path.AppendASCII("plugins");
  plugin_dirs->insert(exe_path);
}

// Gets the installed path for a registered app.
bool GetInstalledPath(const TCHAR* app, FilePath* out) {
  std::wstring reg_path(kRegistryApps);
  reg_path.append(L"\\");
  reg_path.append(app);

  RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str());
  std::wstring path;
  if (key.ReadValue(kRegistryPath, &path)) {
    *out = FilePath(path);
    return true;
  }

  return false;
}

// Search the registry at the given path and detect plugin directories.
void GetPluginsInRegistryDirectory(
    HKEY root_key,
    const std::wstring& registry_folder,
    std::set<FilePath>* plugin_dirs) {
  for (RegistryKeyIterator iter(root_key, registry_folder.c_str());
       iter.Valid(); ++iter) {
    // Use the registry to gather plugin across the file system.
    std::wstring reg_path = registry_folder;
    reg_path.append(L"\\");
    reg_path.append(iter.Name());
    RegKey key(root_key, reg_path.c_str());

    std::wstring path;
    if (key.ReadValue(kRegistryPath, &path))
      plugin_dirs->insert(FilePath(path));
  }
}

// Enumerate through the registry key to find all installed FireFox paths.
// FireFox 3 beta and version 2 can coexist. See bug: 1025003
void GetFirefoxInstalledPaths(std::vector<FilePath>* out) {
  RegistryKeyIterator it(HKEY_LOCAL_MACHINE, kRegistryFirefoxInstalled);
  for (; it.Valid(); ++it) {
    std::wstring full_path = std::wstring(kRegistryFirefoxInstalled) + L"\\" +
                             it.Name() + L"\\Main";
    RegKey key(HKEY_LOCAL_MACHINE, full_path.c_str(), KEY_READ);
    std::wstring install_dir;
    if (!key.ReadValue(L"Install Directory", &install_dir))
      continue;
    out->push_back(FilePath(install_dir));
  }
}

// Get plugin directory locations from the Firefox install path.  This is kind
// of a kludge, but it helps us locate the flash player for users that
// already have it for firefox.  Not having to download yet-another-plugin
// is a good thing.
void GetFirefoxDirectory(std::set<FilePath>* plugin_dirs) {
  std::vector<FilePath> paths;
  GetFirefoxInstalledPaths(&paths);
  for (unsigned int i = 0; i < paths.size(); ++i) {
    plugin_dirs->insert(paths[i].Append(L"plugins"));
  }

  FilePath firefox_app_data_plugin_path;
  if (PathService::Get(base::DIR_APP_DATA, &firefox_app_data_plugin_path)) {
    firefox_app_data_plugin_path =
        firefox_app_data_plugin_path.AppendASCII("Mozilla")
                                    .AppendASCII("plugins");
    plugin_dirs->insert(firefox_app_data_plugin_path);
  }
}

// Hardcoded logic to detect Acrobat plugins locations.
void GetAcrobatDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath path;
  if (!GetInstalledPath(kRegistryAcrobatReader, &path) &&
      !GetInstalledPath(kRegistryAcrobat, &path)) {
    return;
  }

  plugin_dirs->insert(path.Append(L"Browser"));
}

// Hardcoded logic to detect QuickTime plugin location.
void GetQuicktimeDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath path;
  if (GetInstalledPath(kRegistryQuickTime, &path))
    plugin_dirs->insert(path.Append(L"plugins"));
}

// Hardcoded logic to detect Windows Media Player plugin location.
void GetWindowsMediaDirectory(std::set<FilePath>* plugin_dirs) {
  FilePath path;
  if (GetInstalledPath(kRegistryWindowsMedia, &path))
    plugin_dirs->insert(path);

  // If the Windows Media Player Firefox plugin is installed before Firefox,
  // the plugin will get written under PFiles\Plugins on one the drives
  // (usually, but not always, the last letter).
  int size = GetLogicalDriveStrings(0, NULL);
  if (size) {
    scoped_array<wchar_t> strings(new wchar_t[size]);
    if (GetLogicalDriveStrings(size, strings.get())) {
      wchar_t* next_drive = strings.get();
      while (*next_drive) {
        if (GetDriveType(next_drive) == DRIVE_FIXED) {
          FilePath pfiles(next_drive);
          pfiles = pfiles.Append(L"PFiles\\Plugins");
          if (file_util::PathExists(pfiles))
            plugin_dirs->insert(pfiles);
        }
        next_drive = &next_drive[wcslen(next_drive) + 1];
      }
    }
  }
}

// Hardcoded logic to detect Java plugin location.
void GetJavaDirectory(std::set<FilePath>* plugin_dirs) {
  // Load the new NPAPI Java plugin
  // 1. Open the main JRE key under HKLM
  RegKey java_key(HKEY_LOCAL_MACHINE, kRegistryJava, KEY_QUERY_VALUE);

  // 2. Read the current Java version
  std::wstring java_version;
  if (!java_key.ReadValue(kRegistryBrowserJavaVersion, &java_version))
    java_key.ReadValue(kRegistryCurrentJavaVersion, &java_version);

  if (!java_version.empty()) {
    java_key.OpenKey(java_version.c_str(), KEY_QUERY_VALUE);

    // 3. Install path of the JRE binaries is specified in "JavaHome"
    //    value under the Java version key.
    std::wstring java_plugin_directory;
    if (java_key.ReadValue(kRegistryJavaHome, &java_plugin_directory)) {
      // 4. The new plugin resides under the 'bin/new_plugin'
      //    subdirectory.
      DCHECK(!java_plugin_directory.empty());
      java_plugin_directory.append(L"\\bin\\new_plugin");

      // 5. We don't know the exact name of the DLL but it's in the form
      //    NP*.dll so just invoke LoadPlugins on this path.
      plugin_dirs->insert(FilePath(java_plugin_directory));
    }
  }
}

}  // anonymous namespace

namespace NPAPI {

void PluginList::PlatformInit() {
  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
  dont_load_new_wmp_ = command_line.HasSwitch(kUseOldWMPPluginSwitch);
}

void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) {
  // We use a set for uniqueness, which we require, over order, which we do not.
  std::set<FilePath> dirs;

  // Load from the application-specific area
  GetAppDirectory(&dirs);

  // Load from the executable area
  GetExeDirectory(&dirs);

  // Load Java
  GetJavaDirectory(&dirs);

  // Load firefox plugins too.  This is mainly to try to locate
  // a pre-installed Flash player.
  GetFirefoxDirectory(&dirs);

  // Firefox hard-codes the paths of some popular plugins to ensure that
  // the plugins are found.  We are going to copy this as well.
  GetAcrobatDirectory(&dirs);
  GetQuicktimeDirectory(&dirs);
  GetWindowsMediaDirectory(&dirs);

  for (std::set<FilePath>::iterator i = dirs.begin(); i != dirs.end(); ++i)
    plugin_dirs->push_back(*i);
}

void PluginList::LoadPluginsFromDir(const FilePath &path,
                                    std::vector<WebPluginInfo>* plugins,
                                    std::set<FilePath>* visited_plugins) {
  WIN32_FIND_DATA find_file_data;
  HANDLE find_handle;

  std::wstring dir = path.value();
  // FindFirstFile requires that you specify a wildcard for directories.
  dir.append(L"\\NP*.DLL");

  find_handle = FindFirstFile(dir.c_str(), &find_file_data);
  if (find_handle == INVALID_HANDLE_VALUE)
    return;

  do {
    if (!(find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
      FilePath filename = path.Append(find_file_data.cFileName);
      LoadPlugin(filename, plugins);
      visited_plugins->insert(filename);
    }
  } while (FindNextFile(find_handle, &find_file_data) != 0);

  DCHECK(GetLastError() == ERROR_NO_MORE_FILES);
  FindClose(find_handle);
}

void PluginList::LoadPluginsFromRegistry(
    std::vector<WebPluginInfo>* plugins,
    std::set<FilePath>* visited_plugins) {
  std::set<FilePath> plugin_dirs;

  GetPluginsInRegistryDirectory(
      HKEY_CURRENT_USER, kRegistryMozillaPlugins, &plugin_dirs);
  GetPluginsInRegistryDirectory(
      HKEY_LOCAL_MACHINE, kRegistryMozillaPlugins, &plugin_dirs);

  for (std::set<FilePath>::iterator i = plugin_dirs.begin();
       i != plugin_dirs.end(); ++i) {
    LoadPlugin(*i, plugins);
    visited_plugins->insert(*i);
  }
}

// Compares Windows style version strings (i.e. 1,2,3,4).  Returns true if b's
// version is newer than a's, or false if it's equal or older.
bool IsNewerVersion(const std::wstring& a, const std::wstring& b) {
  std::vector<std::wstring> a_ver, b_ver;
  SplitString(a, ',', &a_ver);
  SplitString(b, ',', &b_ver);
  if (a_ver.size() == 1 && b_ver.size() == 1) {
    a_ver.clear();
    b_ver.clear();
    SplitString(a, '.', &a_ver);
    SplitString(b, '.', &b_ver);
  }
  if (a_ver.size() != b_ver.size())
    return false;
  for (size_t i = 0; i < a_ver.size(); i++) {
    int cur_a = StringToInt(a_ver[i]);
    int cur_b = StringToInt(b_ver[i]);
    if (cur_a > cur_b)
      return false;
    if (cur_a < cur_b)
      return true;
  }
  return false;
}

bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
                                  std::vector<WebPluginInfo>* plugins) {
  // Version check

  for (size_t i = 0; i < plugins->size(); ++i) {
    std::wstring plugin1 =
        StringToLowerASCII((*plugins)[i].path.BaseName().ToWStringHack());
    std::wstring plugin2 =
        StringToLowerASCII(info.path.BaseName().ToWStringHack());
    if (plugin1 == plugin2 ||
        (plugin1 == kJavaDeploy1 && plugin2 == kJavaDeploy2) ||
        (plugin1 == kJavaDeploy2 && plugin2 == kJavaDeploy1)) {
      if (!IsNewerVersion((*plugins)[i].version, info.version))
        return false;  // We have loaded a plugin whose version is newer.

      plugins->erase(plugins->begin() + i);
      break;
    }
  }

  // Troublemakers

  std::wstring filename = StringToLowerASCII(info.path.BaseName().value());
  // Depends on XPCOM.
  if (filename == kMozillaActiveXPlugin)
    return false;

  // Disable the Yahoo Application State plugin as it crashes the plugin
  // process on return from NPObjectStub::OnInvoke. Please refer to
  // http://b/issue?id=1372124 for more information.
  if (filename == kYahooApplicationStatePlugin)
    return false;

  // Disable the WangWang protocol handler plugin (npww.dll) as it crashes
  // chrome during shutdown. Firefox also disables this plugin.
  // Please refer to http://code.google.com/p/chromium/issues/detail?id=3953
  // for more information.
  if (filename == kWanWangProtocolHandlerPlugin)
    return false;

  // We only work with newer versions of the Java plugin which use NPAPI only
  // and don't depend on XPCOM.
  if (filename == kJavaPlugin1 || filename == kJavaPlugin2) {
    std::vector<std::wstring> ver;
    SplitString(info.version, '.', &ver);
    int major, minor, update;
    if (ver.size() == 4 &&
        StringToInt(ver[0], &major) &&
        StringToInt(ver[1], &minor) &&
        StringToInt(ver[2], &update)) {
      if (major == 6 && minor == 0 && update < 120)
        return false;  // Java SE6 Update 11 or older.
    }
  }

  // Special WMP handling

  // If both the new and old WMP plugins exist, only load the new one.
  if (filename == kNewWMPPlugin) {
    if (dont_load_new_wmp_)
      return false;

    for (size_t i = 0; i < plugins->size(); ++i) {
      if ((*plugins)[i].path.BaseName().value() == kOldWMPPlugin) {
        plugins->erase(plugins->begin() + i);
        break;
      }
    }
  } else if (filename == kOldWMPPlugin) {
    for (size_t i = 0; i < plugins->size(); ++i) {
      if ((*plugins)[i].path.BaseName().value() == kNewWMPPlugin)
        return false;
    }
  }

  return true;
}

}  // namespace NPAPI
<|endoftext|>


<commit_before>#pragma once

#include "numerics/poisson_series_basis.hpp"

#include <algorithm>

#include "geometry/hilbert.hpp"
#include "quantities/si.hpp"
#include "quantities/traits.hpp"

namespace principia {
namespace numerics {
namespace internal_poisson_series_basis {

using geometry::Hilbert;
using quantities::is_quantity_v;
namespace si = quantities::si;

// A helper to build unit quantities or multivector.  |Coefficient| must be a
// member of a Hilbert space with |dimension| dimensions.
template<typename Coefficient,
         int dimension,
         typename = std::make_index_sequence<dimension>,
         typename = void>
struct CoefficientGenerator;

// Specialization for non-quantities (i.e., Multivector).
template<typename Coefficient, int dimension, std::size_t... ds>
struct CoefficientGenerator<Coefficient,
                            dimension,
                            std::index_sequence<ds...>,
                            std::enable_if_t<!is_quantity_v<Coefficient>>> {
  // Returns a unit multivector in the direction given by |d|, for instance,
  // a multivector with coordinates {1, 0, 0}.
  template<int d>
  static Coefficient Unit();
};

// Specialization for quantities.
template<typename Coefficient, std::size_t... ds>
struct CoefficientGenerator<Coefficient,
                            /*dimension=*/1,
                            std::index_sequence<ds...>,
                            std::enable_if_t<is_quantity_v<Coefficient>>> {
  // Returns a unit quantity.  This function is templated for consistency with
  // the preceeding specialization; |d| must be 0.
  template<int d>
  static Coefficient Unit();
};

template<typename Coefficient, int dimension, std::size_t... ds>
template<int d>
Coefficient
CoefficientGenerator<Coefficient,
                     dimension,
                     std::index_sequence<ds...>,
                     std::enable_if_t<!is_quantity_v<Coefficient>>>::Unit() {
  using Scalar = typename Hilbert<Coefficient>::NormType;
  return Coefficient({(d == ds ? si::Unit<Scalar> : Scalar{})...});
}

template<typename Coefficient, std::size_t... ds>
template<int d>
Coefficient
CoefficientGenerator<Coefficient,
                     /*dimension=*/1,
                     std::index_sequence<ds...>,
                     std::enable_if_t<is_quantity_v<Coefficient>>>::Unit() {
  static_assert(d == 0);
  return si::Unit<Coefficient>;
}

// In the following classes |index| and |indices...| encode the coordinate, the
// degree and the parity (Sin or Cos) of a series.  How this encoding is
// performed determines the order of the series in the basis.

// A helper to build unit polynomials.  |Polynomial| must be a polynomial with
// values in a |dimension|-dimensional Hilbert space.
template<typename Polynomial, int dimension>
struct PolynomialGenerator {
  // Returns a polynomial whose coordinate and degree are encoded in |index|.
  template<int index>
  static Polynomial UnitPolynomial(Instant const& origin);

  // Returns a pair of polynomials (for Sin and Cos) whose parity, coordinate
  // and degree are encoded in |index|.
  template<typename Polynomials, int index>
  static Polynomials UnitPolynomials(Instant const& origin);
};

template<typename Polynomial, int dimension>
template<int index>
Polynomial PolynomialGenerator<Polynomial, dimension>::UnitPolynomial(
    Instant const& origin) {
  // Extract the coordinate and the degree from |index|.  The coordinate varies
  // faster, so terms of the same degree but different coordinates are
  // consecutive when this function is called from a template pack expansion.
  static constexpr int coordinate = index % dimension;
  static constexpr int degree = index / dimension;

  using Coefficients = typename Polynomial::Coefficients;
  using Coefficient = std::tuple_element_t<degree, Coefficients>;
  Coefficients coefficients;
  std::get<degree>(coefficients) =
      CoefficientGenerator<Coefficient, dimension>::template Unit<coordinate>();
  return Polynomial(coefficients, origin);
}

template<typename Polynomial, int dimension>
template<typename Polynomials, int index>
static Polynomials PolynomialGenerator<Polynomial, dimension>::UnitPolynomials(
    Instant const& origin) {
  // Extract the parity, coordinate and the degree from |index|.  The coordinate
  // varies faster, so terms of the same parity and degree but different
  // coordinates are consecutive when this function is called from a template
  // pack expansion.  The parity varies next, so Sin and Cos terms alternate for
  // a given degree.  Finally, the degree increases.
  static constexpr int coordinate = index % dimension;
  static constexpr int parity = (index / dimension) % 2;
  static constexpr int degree = index / (2 * dimension);

  // Reencode the degree and coordinate alone for generating the polynomials.
  static constexpr int degree_and_coordinate = coordinate + dimension * degree;

  static Polynomial const zero{{}, origin};
  if constexpr (parity == 0) {
    return {/*sin=*/zero,
            /*cos=*/PolynomialGenerator<Polynomial, dimension>::UnitPolynomial<
                degree_and_coordinate>(origin)};
  } else {
    return {/*sin=*/PolynomialGenerator<Polynomial, dimension>::UnitPolynomial<
                degree_and_coordinate>(origin),
            /*cos=*/zero};
  }
}

// A helper to generate aperiodic series, i.e., series of the form tⁿ along some
// dimension.  Note how a single index_sequence is generated that covers the
// cross-product of degrees and dimensions.
template<typename Series,
         int degree, int dimension,
         typename = std::make_index_sequence<dimension * (degree + 1)>>
struct AperiodicSeriesGenerator;

template<typename Series, int degree, int dimension, std::size_t... indices>
struct AperiodicSeriesGenerator<Series,
                                degree, dimension,
                                std::index_sequence<indices...>> {
  static std::array<Series, sizeof...(indices)> BasisElements(
      Instant const& origin);
};

template<typename Series, int degree, int dimension, std::size_t... indices>
std::array<Series, sizeof...(indices)> AperiodicSeriesGenerator<
    Series,
    degree, dimension,
    std::index_sequence<indices...>>::BasisElements(Instant const& origin) {
  return {
      (Series(PolynomialGenerator<typename Series::AperiodicPolynomial,
                                  dimension>::UnitPolynomial<indices>(origin),
              {}))...};
}

// A helper to generate periodic series, i.e., series of the form  tⁿ sin ω t
// and tⁿ cos ω t along some dimension.  Note how a single index_sequence is
// generated that covers the cross-product of parities, degrees and dimensions.
template<typename Series,
         int degree, int dimension,
         typename = std::make_index_sequence<2 * dimension * (degree + 1)>>
struct PeriodicSeriesGenerator;

template<typename Series, int degree, int dimension, std::size_t... indices>
struct PeriodicSeriesGenerator<Series,
                        degree, dimension,
                        std::index_sequence<indices...>> {
  static std::array<Series, sizeof...(indices)> BasisElements(
      AngularFrequency const& ω,
      Instant const& origin);
};

template<typename Series, int degree, int dimension, std::size_t... indices>
std::array<Series, sizeof...(indices)> PeriodicSeriesGenerator<
    Series,
    degree, dimension,
    std::index_sequence<indices...>>::BasisElements(AngularFrequency const& ω,
                                                    Instant const& origin) {
  static typename Series::AperiodicPolynomial const aperiodic_zero{{}, origin};
  return {Series(
      aperiodic_zero,
      {{ω,
        PolynomialGenerator<typename Series::PeriodicPolynomial, dimension>::
            template UnitPolynomials<typename Series::Polynomials, indices>(
                origin)}})...};
}

template<typename Series, int degree>
auto PoissonSeriesBasisGenerator<Series, degree>::Basis(Instant const& origin)
    -> std::array<Series, dimension * (degree + 1)> {
  return AperiodicSeriesGenerator<Series, degree, dimension>::
             BasisElements(origin);
}

template<typename Series, int degree>
auto PoissonSeriesBasisGenerator<Series, degree>::Basis(
    AngularFrequency const& ω,
    Instant const& origin) -> std::array<Series, 2 * dimension * (degree + 1)> {
  return PeriodicSeriesGenerator<Series, degree, dimension>::
             BasisElements(ω, origin);
}

}  // namespace internal_poisson_series_basis
}  // namespace numerics
}  // namespace principia
<commit_msg>Fix errors found by Clang.<commit_after>#pragma once

#include "numerics/poisson_series_basis.hpp"

#include <algorithm>

#include "geometry/hilbert.hpp"
#include "quantities/si.hpp"
#include "quantities/traits.hpp"

namespace principia {
namespace numerics {
namespace internal_poisson_series_basis {

using geometry::Hilbert;
using quantities::is_quantity_v;
namespace si = quantities::si;

// A helper to build unit quantities or multivector.  |Coefficient| must be a
// member of a Hilbert space with |dimension| dimensions.
template<typename Coefficient,
         int dimension,
         typename = std::make_index_sequence<dimension>,
         typename = void>
struct CoefficientGenerator;

// Specialization for non-quantities (i.e., Multivector).
template<typename Coefficient, int dimension, std::size_t... ds>
struct CoefficientGenerator<Coefficient,
                            dimension,
                            std::index_sequence<ds...>,
                            std::enable_if_t<!is_quantity_v<Coefficient>>> {
  // Returns a unit multivector in the direction given by |d|, for instance,
  // a multivector with coordinates {1, 0, 0}.
  template<int d>
  static Coefficient Unit();
};

// Specialization for quantities.
template<typename Coefficient, std::size_t... ds>
struct CoefficientGenerator<Coefficient,
                            /*dimension=*/1,
                            std::index_sequence<ds...>,
                            std::enable_if_t<is_quantity_v<Coefficient>>> {
  // Returns a unit quantity.  This function is templated for consistency with
  // the preceeding specialization; |d| must be 0.
  template<int d>
  static Coefficient Unit();
};

template<typename Coefficient, int dimension, std::size_t... ds>
template<int d>
Coefficient
CoefficientGenerator<Coefficient,
                     dimension,
                     std::index_sequence<ds...>,
                     std::enable_if_t<!is_quantity_v<Coefficient>>>::Unit() {
  using Scalar = typename Hilbert<Coefficient>::NormType;
  return Coefficient({(d == ds ? si::Unit<Scalar> : Scalar{})...});
}

template<typename Coefficient, std::size_t... ds>
template<int d>
Coefficient
CoefficientGenerator<Coefficient,
                     /*dimension=*/1,
                     std::index_sequence<ds...>,
                     std::enable_if_t<is_quantity_v<Coefficient>>>::Unit() {
  static_assert(d == 0);
  return si::Unit<Coefficient>;
}

// In the following classes |index| and |indices...| encode the coordinate, the
// degree and the parity (Sin or Cos) of a series.  How this encoding is
// performed determines the order of the series in the basis.

// A helper to build unit polynomials.  |Polynomial| must be a polynomial with
// values in a |dimension|-dimensional Hilbert space.
template<typename Polynomial, int dimension>
struct PolynomialGenerator {
  // Returns a polynomial whose coordinate and degree are encoded in |index|.
  template<int index>
  static Polynomial UnitPolynomial(Instant const& origin);

  // Returns a pair of polynomials (for Sin and Cos) whose parity, coordinate
  // and degree are encoded in |index|.
  template<typename Polynomials, int index>
  static Polynomials UnitPolynomials(Instant const& origin);
};

template<typename Polynomial, int dimension>
template<int index>
Polynomial PolynomialGenerator<Polynomial, dimension>::UnitPolynomial(
    Instant const& origin) {
  // Extract the coordinate and the degree from |index|.  The coordinate varies
  // faster, so terms of the same degree but different coordinates are
  // consecutive when this function is called from a template pack expansion.
  static constexpr int coordinate = index % dimension;
  static constexpr int degree = index / dimension;

  using Coefficients = typename Polynomial::Coefficients;
  using Coefficient = std::tuple_element_t<degree, Coefficients>;
  Coefficients coefficients;
  std::get<degree>(coefficients) =
      CoefficientGenerator<Coefficient, dimension>::template Unit<coordinate>();
  return Polynomial(coefficients, origin);
}

template<typename Polynomial, int dimension>
template<typename Polynomials, int index>
Polynomials PolynomialGenerator<Polynomial, dimension>::UnitPolynomials(
    Instant const& origin) {
  // Extract the parity, coordinate and the degree from |index|.  The coordinate
  // varies faster, so terms of the same parity and degree but different
  // coordinates are consecutive when this function is called from a template
  // pack expansion.  The parity varies next, so Sin and Cos terms alternate for
  // a given degree.  Finally, the degree increases.
  static constexpr int coordinate = index % dimension;
  static constexpr int parity = (index / dimension) % 2;
  static constexpr int degree = index / (2 * dimension);

  // Reencode the degree and coordinate alone for generating the polynomials.
  static constexpr int degree_and_coordinate = coordinate + dimension * degree;

  static Polynomial const zero{{}, origin};
  if constexpr (parity == 0) {
    return {/*sin=*/zero,
            /*cos=*/PolynomialGenerator<Polynomial, dimension>::UnitPolynomial<
                degree_and_coordinate>(origin)};
  } else {
    return {/*sin=*/PolynomialGenerator<Polynomial, dimension>::UnitPolynomial<
                degree_and_coordinate>(origin),
            /*cos=*/zero};
  }
}

// A helper to generate aperiodic series, i.e., series of the form tⁿ along some
// dimension.  Note how a single index_sequence is generated that covers the
// cross-product of degrees and dimensions.
template<typename Series,
         int degree, int dimension,
         typename = std::make_index_sequence<dimension * (degree + 1)>>
struct AperiodicSeriesGenerator;

template<typename Series, int degree, int dimension, std::size_t... indices>
struct AperiodicSeriesGenerator<Series,
                                degree, dimension,
                                std::index_sequence<indices...>> {
  static std::array<Series, sizeof...(indices)> BasisElements(
      Instant const& origin);
};

template<typename Series, int degree, int dimension, std::size_t... indices>
std::array<Series, sizeof...(indices)> AperiodicSeriesGenerator<
    Series,
    degree, dimension,
    std::index_sequence<indices...>>::BasisElements(Instant const& origin) {
  return {(Series(
      PolynomialGenerator<typename Series::AperiodicPolynomial,
                          dimension>::template UnitPolynomial<indices>(origin),
      {}))...};
}

// A helper to generate periodic series, i.e., series of the form  tⁿ sin ω t
// and tⁿ cos ω t along some dimension.  Note how a single index_sequence is
// generated that covers the cross-product of parities, degrees and dimensions.
template<typename Series,
         int degree, int dimension,
         typename = std::make_index_sequence<2 * dimension * (degree + 1)>>
struct PeriodicSeriesGenerator;

template<typename Series, int degree, int dimension, std::size_t... indices>
struct PeriodicSeriesGenerator<Series,
                        degree, dimension,
                        std::index_sequence<indices...>> {
  static std::array<Series, sizeof...(indices)> BasisElements(
      AngularFrequency const& ω,
      Instant const& origin);
};

template<typename Series, int degree, int dimension, std::size_t... indices>
std::array<Series, sizeof...(indices)> PeriodicSeriesGenerator<
    Series,
    degree, dimension,
    std::index_sequence<indices...>>::BasisElements(AngularFrequency const& ω,
                                                    Instant const& origin) {
  static typename Series::AperiodicPolynomial const aperiodic_zero{{}, origin};
  return {Series(
      aperiodic_zero,
      {{ω,
        PolynomialGenerator<typename Series::PeriodicPolynomial, dimension>::
            template UnitPolynomials<typename Series::Polynomials, indices>(
                origin)}})...};
}

template<typename Series, int degree>
auto PoissonSeriesBasisGenerator<Series, degree>::Basis(Instant const& origin)
    -> std::array<Series, dimension * (degree + 1)> {
  return AperiodicSeriesGenerator<Series, degree, dimension>::
             BasisElements(origin);
}

template<typename Series, int degree>
auto PoissonSeriesBasisGenerator<Series, degree>::Basis(
    AngularFrequency const& ω,
    Instant const& origin) -> std::array<Series, 2 * dimension * (degree + 1)> {
  return PeriodicSeriesGenerator<Series, degree, dimension>::
             BasisElements(ω, origin);
}

}  // namespace internal_poisson_series_basis
}  // namespace numerics
}  // namespace principia
<|endoftext|>


<commit_before>//----------------------------------------------------------------------
//  A TIFF for 1-bit ver.1.0.0  Time-stamp: <2016-10-31 00:11:31 kido>
//----------------------------------------------------------------------
#include <cstdio>
#include <cstdarg>
#include <iostream>
using namespace std;

#include <tiff.h>
#include <tiffio.h>

#include "atiff1.h"

inline void OUTMSG(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    char tmp[BUFSIZ];
    vsnprintf(tmp, sizeof(tmp), fmt, args);
    cout << tmp << endl;
    va_end(args);
}

inline void ERRMSG(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    char tmp[BUFSIZ];
    vsnprintf(tmp, sizeof(tmp), fmt, args);
    cerr << tmp << endl;
    va_end(args);
}

//----------------------------------------------------------------------
//  ATIFF : TIFF manipulate class for 1-bit
//----------------------------------------------------------------------
atiff1::atiff1() {
    this->initialize();
}

atiff1::atiff1(int width, int height) {
    this->build(width, height);
}

// atiff1::~atiff1() {
// }
// コピー演算・ムーブ演算の自動生成のために宣言しない

void atiff1::initialize() {
    parent::initialize();
    depth_        = ATIFF_2LEVEL;           // 2階調(白黒2値)
    software_     = "atiff1_powerdby_libtiff";
}

bool atiff1::build(int width, int height) {
    if(width % 8 != 0) {
        ERRMSG("%d: width must be multiples of 8", width);
        return false;
    }
    this->initialize();

    width_   = (uint32)width;
    height_  = (uint32)height;
    ncolors_ = ATIFF_MONO_COLOR;
    depth_   = ATIFF_2LEVEL;
    nx_      =         width;
    ny_      =         height;
    nc_      = ATIFF_MONO_COLOR;

    photometric_  = PHOTOMETRIC_MINISWHITE;
    planarmode_   = PLANARCONFIG_CONTIG;
    ordering_     =  0; //single plane
    if((int)buf_.size() != nx_*ny_*nc_/8) buf_.resize(nx_*ny_*nc_/8, 0);
}

//----------------------------------------------------------------------
//  End Of File
//----------------------------------------------------------------------
<commit_msg>Delete atiff1.cpp<commit_after><|endoftext|>