<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.
 *
 ************************************************************************/

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

#include <tchar.h>

#ifdef _MSC_VER
#pragma warning(push,1) // disable warnings within system headers
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>

#ifndef SIGNULL
#define SIGNULL 0
#endif

#ifndef SIGKILL
#define SIGKILL 9
#endif

#include <signal.h>

#define MAX_MODULES 1024

/////////////////////////////////////////////////////////////////////////////
// Determines if a returned handle value is valid
/////////////////////////////////////////////////////////////////////////////

static inline bool IsValidHandle( HANDLE handle )
{
    return INVALID_HANDLE_VALUE != handle && NULL != handle;
}

#define elementsof( a ) (sizeof(a) / sizeof( (a)[0] ))

/////////////////////////////////////////////////////////////////////////////
// Retrieves function adress in another process
/////////////////////////////////////////////////////////////////////////////

#if 1
#define GetProcAddressEx( hProcess, hModule, lpProcName ) GetProcAddress( hModule, lpProcName )
#else
FARPROC WINAPI GetProcAddressEx( HANDLE hProcess, HMODULE hModule, LPCSTR lpProcName )
{
    FARPROC lpfnProcAddress = GetProcAddress( hModule, lpProcName );

    if ( lpfnProcAddress )
    {
        DWORD   dwProcessId = GetProcessId( hProcess );

        if ( GetCurrentProcessId() != dwProcessId )
        {
            FARPROC lpfnRemoteProcAddress = NULL;
            TCHAR   szBaseName[MAX_PATH];

            if ( GetModuleBaseName( GetCurrentProcess(), hModule, szBaseName, elementsof(szBaseName) ) )
            {
                HMODULE ahModules[MAX_MODULES];
                DWORD   cbNeeded = 0;

                if ( EnumProcessModules( hProcess, ahModules, sizeof(ahModules), &cbNeeded ) )
                {
                    ULONG   nModules = cbNeeded / sizeof(ahModules[0]);

                    for ( ULONG n = 0; n < nModules; n++ )
                    {
                        TCHAR   szRemoteBaseName[MAX_PATH];

                        if ( GetModuleBaseName(
                            hProcess, ahModules[n], szRemoteBaseName, elementsof(szRemoteBaseName) ) &&
                            0 == lstrcmpi( szRemoteBaseName, szBaseName )
                            )
                        {
                            lpfnRemoteProcAddress = lpfnProcAddress;

                            if ( ahModules[n] != hModule )
                                *(LPBYTE*)&lpfnRemoteProcAddress += (LPBYTE)ahModules[n] - (LPBYTE)hModule;
                            break;
                        }
                    }
                }
            }

            lpfnProcAddress = lpfnRemoteProcAddress;
        }
    }

    return lpfnProcAddress;
}
#endif

/////////////////////////////////////////////////////////////////////////////
// Raises a signal in an other process
/////////////////////////////////////////////////////////////////////////////

static DWORD SignalToExceptionCode( int signal )
{
    switch ( signal )
    {
    case SIGSEGV:
        return EXCEPTION_ACCESS_VIOLATION;
    case SIGFPE:
        return EXCEPTION_FLT_INVALID_OPERATION;
    case SIGILL:
        return EXCEPTION_ILLEGAL_INSTRUCTION;
    case SIGINT:
        return CONTROL_C_EXIT;
    case SIGBREAK:
        return CONTROL_C_EXIT;
    default:
        return 0;
    }
}

static BOOL RaiseSignalEx( HANDLE hProcess, int sig )
{
    DWORD   dwProcessId = GetProcessId( hProcess );

    HANDLE  hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
    HANDLE  hThread = 0;
    BOOL fSuccess = FALSE;

    if ( IsValidHandle(hSnapshot) )
    {
        THREADENTRY32   te;

        te.dwSize = sizeof(te);
        fSuccess = Thread32First( hSnapshot, &te );
        while ( fSuccess )
        {
            if ( te.th32OwnerProcessID == dwProcessId )
            {
                hThread = OpenThread(
                    THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION |
                    THREAD_GET_CONTEXT | THREAD_SET_CONTEXT,
                    FALSE, te.th32ThreadID );
                if ( IsValidHandle(hThread) )
                    break;
            }

            fSuccess = Thread32Next( hSnapshot, &te );
        }

        CloseHandle( hSnapshot );
    }

    if ( fSuccess )
    {
        CONTEXT aContext;

        if ( SuspendThread( hThread ) != (DWORD)-1 )
        {
            ZeroMemory( &aContext, sizeof(aContext) );
            aContext.ContextFlags = CONTEXT_FULL;

            fSuccess = GetThreadContext( hThread, &aContext );

            if ( fSuccess )
            {
                if ( sig )
                {
                    DWORD   dwStackBuffer[] =
                    {
                        aContext.Eip,
                        SignalToExceptionCode( sig ),
                        EXCEPTION_NONCONTINUABLE,
                        0,
                        0
                    };

                    aContext.Esp -= sizeof(dwStackBuffer);
                    WriteProcessMemory( hProcess, (LPVOID)aContext.Esp, dwStackBuffer, sizeof(dwStackBuffer), NULL );
                    aContext.Eip = (DWORD)GetProcAddressEx( hProcess, GetModuleHandleA("KERNEL32"), "RaiseException" );
                }
                else
                {
                    aContext.Ecx = aContext.Eax = aContext.Ebx = aContext.Edx = aContext.Esi = aContext.Edi = 0;
                }

                fSuccess = SetThreadContext( hThread, &aContext );
            }

            fSuccess = ResumeThread( hThread ) && fSuccess;

            DWORD   dwLastError = GetLastError();
            CloseHandle( hThread );
            SetLastError( dwLastError );

            return fSuccess;
        }
    }

    return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// Command line parameter parsing
/////////////////////////////////////////////////////////////////////////////

static void ParseCommandArgs( LPDWORD lpProcesses, LPDWORD lpdwNumProcesses, int *pSig )
{
    typedef struct _SignalEntry
    {
        LPCTSTR lpSignalName;
        int iSignalValue;
    } SignalEntry;

    #define SIG_ENTRY( signal ) { TEXT(#signal), SIG##signal }

    static SignalEntry SupportedSignals[] =
    {
        SIG_ENTRY( NULL ),
        SIG_ENTRY( SEGV ),
        SIG_ENTRY( ILL ),
        SIG_ENTRY( FPE ),
        SIG_ENTRY( INT ),
        SIG_ENTRY( BREAK ),
        SIG_ENTRY( TERM ),
        SIG_ENTRY( ABRT ),
        SIG_ENTRY( KILL )
    };

    const int NumSupportedSignals = elementsof(SupportedSignals);

    DWORD   dwMaxProcesses = *lpdwNumProcesses;
    int     argc = __argc;
    TCHAR   **argv = __targv;

    *lpdwNumProcesses = 0;

    for ( int argn = 1; argn < argc; argn++ )
    {
        if ( 0 == lstrcmpi( argv[argn], TEXT("-l") ) ||
             0 == lstrcmpi( argv[argn], TEXT("/l") ) )

        {
            for ( int n = 0; n < NumSupportedSignals; n++ )
            {
                _tprintf( _T("%s "), SupportedSignals[n] );
            }
            _tprintf( _T("\n") );
            ExitProcess( 0 );
        }
        else if ( 0 == lstrcmpi( argv[argn], TEXT("-?") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("/?") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("-h") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("/h") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("--help") ) )
        {
            _tprintf(
                _T("Terminates a process by sending a signal.\n\n")
                _T("Usage: kill [ -l ] [ -signal ] pid ...\n\n")
                _T("-l        Lists supported signals\n")
                _T("-signal   Sends the specified signal to the given processes.\n")
                _T("          signal can be a numeric value specifying the signal number\n")
                _T("          or a string listed by the -l parameter. If no signal is\n")
                _T("          given SIGTERM (-TERM) is used.\n")
                _T("pid       Process id(s) or executables names(s) of processes to \n")
                _T("          signal or terminate.\n\n")
                );
            ExitProcess( 0 );
        }
        else if ( argv[argn] && ( *argv[argn] == '-' || *argv[argn] == '/' ) )
        {
            LPCTSTR argsig = CharNext( argv[argn] );

            int n;
            for ( n = 0; n < NumSupportedSignals; n++ )
            {
                _TCHAR *endptr = NULL;

                if ( 0 == lstrcmpi( SupportedSignals[n].lpSignalName, argsig ) ||
                     _tcstoul( argsig, &endptr, 0 ) == static_cast< unsigned >(SupportedSignals[n].iSignalValue) && (!endptr || !*endptr) )
                {
                    *pSig = SupportedSignals[n].iSignalValue;
                    break;
                }
            }

            if ( n >= NumSupportedSignals )
            {
                _ftprintf( stderr,
                    _T("kill: Illegal argument %s\n")
                    _T("Type 'kill --help' to show allowed syntax.\n")
                    _T("Type 'kill -l' to show supported signals.\n"),
                    argv[argn] );
                ExitProcess( 0 );
            }
        }
        else
        {
            unsigned long value = 0;
            _TCHAR  *endptr = NULL;

            value = _tcstoul( argv[argn], &endptr, 0 );

            if ( !endptr || !*endptr )
            {
                if ( *lpdwNumProcesses < dwMaxProcesses )
                {
                    *(lpProcesses++) = value;
                    (*lpdwNumProcesses)++;
                }
            }
            else
            {
                HANDLE  hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

                if ( IsValidHandle( hSnapshot ) )
                {
                    PROCESSENTRY32  pe;

                    pe.dwSize = sizeof(pe);
                    BOOL fSuccess = Process32First( hSnapshot, &pe );

                    while ( fSuccess )
                    {
                        if ( 0 == lstrcmpi( argv[argn], pe.szExeFile ) )
                        {
                            if ( *lpdwNumProcesses < dwMaxProcesses )
                            {
                                *(lpProcesses++) = pe.th32ProcessID;
                                (*lpdwNumProcesses)++;
                            }
                        }
                        fSuccess = Process32Next( hSnapshot, &pe );
                    }

                    CloseHandle( hSnapshot );
                }
            }
        }
    }

    if ( !*lpdwNumProcesses )
    {
        _ftprintf( stderr,
            _T("kill: No process specified.\n")
            _T("Use kill --help to show allowed syntax.\n")
            );
        ExitProcess( 0 );
    }

}

void OutputSystemMessage( DWORD dwErrorCode )
{
    LPVOID lpMsgBuf;
    FormatMessageA(
                    FORMAT_MESSAGE_ALLOCATE_BUFFER |
                    FORMAT_MESSAGE_FROM_SYSTEM |
                    FORMAT_MESSAGE_IGNORE_INSERTS,
                    NULL,
                    dwErrorCode,
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                    (LPSTR)&lpMsgBuf,
                    0,
                    NULL
                );

    printf( (LPSTR)lpMsgBuf );
    LocalFree( lpMsgBuf );
}

int _tmain()
{
    DWORD   dwProcessIds[1024];
    DWORD   nProcesses = elementsof(dwProcessIds);
    int     sig = SIGTERM;

    ParseCommandArgs( dwProcessIds, &nProcesses, &sig );

    for ( ULONG n = 0; n < nProcesses; n++ )
    {
        HANDLE  hProcess;

        _tprintf( _T("Sending signal to process id %d..."), dwProcessIds[n] );
        hProcess = OpenProcess( PROCESS_TERMINATE | PROCESS_CREATE_THREAD | SYNCHRONIZE |
            PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
            FALSE, dwProcessIds[n] );

        if ( IsValidHandle( hProcess ) )
        {
            if ( SIGKILL == sig )
                TerminateProcess( hProcess, 255 );
            else
            {
                if ( RaiseSignalEx( hProcess, sig ) )
                    _tprintf( _T("OK\n") );
                else
                {
                    OutputSystemMessage( GetLastError() );
                }
            }

            CloseHandle( hProcess );
        }
        else
        {
            OutputSystemMessage( GetLastError() );
        }
    }

    return 0;
}

<commit_msg>sb132: #i113211# correctly pass char* to %s<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.
 *
 ************************************************************************/

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

#include <tchar.h>

#ifdef _MSC_VER
#pragma warning(push,1) // disable warnings within system headers
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>

#ifndef SIGNULL
#define SIGNULL 0
#endif

#ifndef SIGKILL
#define SIGKILL 9
#endif

#include <signal.h>

#define MAX_MODULES 1024

/////////////////////////////////////////////////////////////////////////////
// Determines if a returned handle value is valid
/////////////////////////////////////////////////////////////////////////////

static inline bool IsValidHandle( HANDLE handle )
{
    return INVALID_HANDLE_VALUE != handle && NULL != handle;
}

#define elementsof( a ) (sizeof(a) / sizeof( (a)[0] ))

/////////////////////////////////////////////////////////////////////////////
// Retrieves function adress in another process
/////////////////////////////////////////////////////////////////////////////

#if 1
#define GetProcAddressEx( hProcess, hModule, lpProcName ) GetProcAddress( hModule, lpProcName )
#else
FARPROC WINAPI GetProcAddressEx( HANDLE hProcess, HMODULE hModule, LPCSTR lpProcName )
{
    FARPROC lpfnProcAddress = GetProcAddress( hModule, lpProcName );

    if ( lpfnProcAddress )
    {
        DWORD   dwProcessId = GetProcessId( hProcess );

        if ( GetCurrentProcessId() != dwProcessId )
        {
            FARPROC lpfnRemoteProcAddress = NULL;
            TCHAR   szBaseName[MAX_PATH];

            if ( GetModuleBaseName( GetCurrentProcess(), hModule, szBaseName, elementsof(szBaseName) ) )
            {
                HMODULE ahModules[MAX_MODULES];
                DWORD   cbNeeded = 0;

                if ( EnumProcessModules( hProcess, ahModules, sizeof(ahModules), &cbNeeded ) )
                {
                    ULONG   nModules = cbNeeded / sizeof(ahModules[0]);

                    for ( ULONG n = 0; n < nModules; n++ )
                    {
                        TCHAR   szRemoteBaseName[MAX_PATH];

                        if ( GetModuleBaseName(
                            hProcess, ahModules[n], szRemoteBaseName, elementsof(szRemoteBaseName) ) &&
                            0 == lstrcmpi( szRemoteBaseName, szBaseName )
                            )
                        {
                            lpfnRemoteProcAddress = lpfnProcAddress;

                            if ( ahModules[n] != hModule )
                                *(LPBYTE*)&lpfnRemoteProcAddress += (LPBYTE)ahModules[n] - (LPBYTE)hModule;
                            break;
                        }
                    }
                }
            }

            lpfnProcAddress = lpfnRemoteProcAddress;
        }
    }

    return lpfnProcAddress;
}
#endif

/////////////////////////////////////////////////////////////////////////////
// Raises a signal in an other process
/////////////////////////////////////////////////////////////////////////////

static DWORD SignalToExceptionCode( int signal )
{
    switch ( signal )
    {
    case SIGSEGV:
        return EXCEPTION_ACCESS_VIOLATION;
    case SIGFPE:
        return EXCEPTION_FLT_INVALID_OPERATION;
    case SIGILL:
        return EXCEPTION_ILLEGAL_INSTRUCTION;
    case SIGINT:
        return CONTROL_C_EXIT;
    case SIGBREAK:
        return CONTROL_C_EXIT;
    default:
        return 0;
    }
}

static BOOL RaiseSignalEx( HANDLE hProcess, int sig )
{
    DWORD   dwProcessId = GetProcessId( hProcess );

    HANDLE  hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
    HANDLE  hThread = 0;
    BOOL fSuccess = FALSE;

    if ( IsValidHandle(hSnapshot) )
    {
        THREADENTRY32   te;

        te.dwSize = sizeof(te);
        fSuccess = Thread32First( hSnapshot, &te );
        while ( fSuccess )
        {
            if ( te.th32OwnerProcessID == dwProcessId )
            {
                hThread = OpenThread(
                    THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION |
                    THREAD_GET_CONTEXT | THREAD_SET_CONTEXT,
                    FALSE, te.th32ThreadID );
                if ( IsValidHandle(hThread) )
                    break;
            }

            fSuccess = Thread32Next( hSnapshot, &te );
        }

        CloseHandle( hSnapshot );
    }

    if ( fSuccess )
    {
        CONTEXT aContext;

        if ( SuspendThread( hThread ) != (DWORD)-1 )
        {
            ZeroMemory( &aContext, sizeof(aContext) );
            aContext.ContextFlags = CONTEXT_FULL;

            fSuccess = GetThreadContext( hThread, &aContext );

            if ( fSuccess )
            {
                if ( sig )
                {
                    DWORD   dwStackBuffer[] =
                    {
                        aContext.Eip,
                        SignalToExceptionCode( sig ),
                        EXCEPTION_NONCONTINUABLE,
                        0,
                        0
                    };

                    aContext.Esp -= sizeof(dwStackBuffer);
                    WriteProcessMemory( hProcess, (LPVOID)aContext.Esp, dwStackBuffer, sizeof(dwStackBuffer), NULL );
                    aContext.Eip = (DWORD)GetProcAddressEx( hProcess, GetModuleHandleA("KERNEL32"), "RaiseException" );
                }
                else
                {
                    aContext.Ecx = aContext.Eax = aContext.Ebx = aContext.Edx = aContext.Esi = aContext.Edi = 0;
                }

                fSuccess = SetThreadContext( hThread, &aContext );
            }

            fSuccess = ResumeThread( hThread ) && fSuccess;

            DWORD   dwLastError = GetLastError();
            CloseHandle( hThread );
            SetLastError( dwLastError );

            return fSuccess;
        }
    }

    return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// Command line parameter parsing
/////////////////////////////////////////////////////////////////////////////

static void ParseCommandArgs( LPDWORD lpProcesses, LPDWORD lpdwNumProcesses, int *pSig )
{
    typedef struct _SignalEntry
    {
        LPCTSTR lpSignalName;
        int iSignalValue;
    } SignalEntry;

    #define SIG_ENTRY( signal ) { TEXT(#signal), SIG##signal }

    static SignalEntry SupportedSignals[] =
    {
        SIG_ENTRY( NULL ),
        SIG_ENTRY( SEGV ),
        SIG_ENTRY( ILL ),
        SIG_ENTRY( FPE ),
        SIG_ENTRY( INT ),
        SIG_ENTRY( BREAK ),
        SIG_ENTRY( TERM ),
        SIG_ENTRY( ABRT ),
        SIG_ENTRY( KILL )
    };

    const int NumSupportedSignals = elementsof(SupportedSignals);

    DWORD   dwMaxProcesses = *lpdwNumProcesses;
    int     argc = __argc;
    TCHAR   **argv = __targv;

    *lpdwNumProcesses = 0;

    for ( int argn = 1; argn < argc; argn++ )
    {
        if ( 0 == lstrcmpi( argv[argn], TEXT("-l") ) ||
             0 == lstrcmpi( argv[argn], TEXT("/l") ) )

        {
            for ( int n = 0; n < NumSupportedSignals; n++ )
            {
                _tprintf( _T("%s "), SupportedSignals[n].lpSignalName );
            }
            _tprintf( _T("\n") );
            ExitProcess( 0 );
        }
        else if ( 0 == lstrcmpi( argv[argn], TEXT("-?") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("/?") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("-h") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("/h") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("--help") ) )
        {
            _tprintf(
                _T("Terminates a process by sending a signal.\n\n")
                _T("Usage: kill [ -l ] [ -signal ] pid ...\n\n")
                _T("-l        Lists supported signals\n")
                _T("-signal   Sends the specified signal to the given processes.\n")
                _T("          signal can be a numeric value specifying the signal number\n")
                _T("          or a string listed by the -l parameter. If no signal is\n")
                _T("          given SIGTERM (-TERM) is used.\n")
                _T("pid       Process id(s) or executables names(s) of processes to \n")
                _T("          signal or terminate.\n\n")
                );
            ExitProcess( 0 );
        }
        else if ( argv[argn] && ( *argv[argn] == '-' || *argv[argn] == '/' ) )
        {
            LPCTSTR argsig = CharNext( argv[argn] );

            int n;
            for ( n = 0; n < NumSupportedSignals; n++ )
            {
                _TCHAR *endptr = NULL;

                if ( 0 == lstrcmpi( SupportedSignals[n].lpSignalName, argsig ) ||
                     _tcstoul( argsig, &endptr, 0 ) == static_cast< unsigned >(SupportedSignals[n].iSignalValue) && (!endptr || !*endptr) )
                {
                    *pSig = SupportedSignals[n].iSignalValue;
                    break;
                }
            }

            if ( n >= NumSupportedSignals )
            {
                _ftprintf( stderr,
                    _T("kill: Illegal argument %s\n")
                    _T("Type 'kill --help' to show allowed syntax.\n")
                    _T("Type 'kill -l' to show supported signals.\n"),
                    argv[argn] );
                ExitProcess( 0 );
            }
        }
        else
        {
            unsigned long value = 0;
            _TCHAR  *endptr = NULL;

            value = _tcstoul( argv[argn], &endptr, 0 );

            if ( !endptr || !*endptr )
            {
                if ( *lpdwNumProcesses < dwMaxProcesses )
                {
                    *(lpProcesses++) = value;
                    (*lpdwNumProcesses)++;
                }
            }
            else
            {
                HANDLE  hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

                if ( IsValidHandle( hSnapshot ) )
                {
                    PROCESSENTRY32  pe;

                    pe.dwSize = sizeof(pe);
                    BOOL fSuccess = Process32First( hSnapshot, &pe );

                    while ( fSuccess )
                    {
                        if ( 0 == lstrcmpi( argv[argn], pe.szExeFile ) )
                        {
                            if ( *lpdwNumProcesses < dwMaxProcesses )
                            {
                                *(lpProcesses++) = pe.th32ProcessID;
                                (*lpdwNumProcesses)++;
                            }
                        }
                        fSuccess = Process32Next( hSnapshot, &pe );
                    }

                    CloseHandle( hSnapshot );
                }
            }
        }
    }

    if ( !*lpdwNumProcesses )
    {
        _ftprintf( stderr,
            _T("kill: No process specified.\n")
            _T("Use kill --help to show allowed syntax.\n")
            );
        ExitProcess( 0 );
    }

}

void OutputSystemMessage( DWORD dwErrorCode )
{
    LPVOID lpMsgBuf;
    FormatMessageA(
                    FORMAT_MESSAGE_ALLOCATE_BUFFER |
                    FORMAT_MESSAGE_FROM_SYSTEM |
                    FORMAT_MESSAGE_IGNORE_INSERTS,
                    NULL,
                    dwErrorCode,
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                    (LPSTR)&lpMsgBuf,
                    0,
                    NULL
                );

    printf( (LPSTR)lpMsgBuf );
    LocalFree( lpMsgBuf );
}

int _tmain()
{
    DWORD   dwProcessIds[1024];
    DWORD   nProcesses = elementsof(dwProcessIds);
    int     sig = SIGTERM;

    ParseCommandArgs( dwProcessIds, &nProcesses, &sig );

    for ( ULONG n = 0; n < nProcesses; n++ )
    {
        HANDLE  hProcess;

        _tprintf( _T("Sending signal to process id %d..."), dwProcessIds[n] );
        hProcess = OpenProcess( PROCESS_TERMINATE | PROCESS_CREATE_THREAD | SYNCHRONIZE |
            PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
            FALSE, dwProcessIds[n] );

        if ( IsValidHandle( hProcess ) )
        {
            if ( SIGKILL == sig )
                TerminateProcess( hProcess, 255 );
            else
            {
                if ( RaiseSignalEx( hProcess, sig ) )
                    _tprintf( _T("OK\n") );
                else
                {
                    OutputSystemMessage( GetLastError() );
                }
            }

            CloseHandle( hProcess );
        }
        else
        {
            OutputSystemMessage( GetLastError() );
        }
    }

    return 0;
}

<|endoftext|>


<commit_before>#ifndef TD_CLIENT_HPP
#define TD_CLIENT_HPP

#include <string>
#include <sstream>
#include <vector>

#include "ConnectionSubsys.hpp"

class TrainDirClient {
public:
  TrainDirClient() {}
  ~TrainDirClient() {}

  bool create_connection(int port, std::string host = "localhost");
  void close_connection();

  void click(int x, int y);
  void run();

private:
  Connection conn;
};

#endif
<commit_msg>added defaults.<commit_after>#ifndef TD_CLIENT_HPP
#define TD_CLIENT_HPP

#include <string>
#include <sstream>
#include <vector>

#include "ConnectionSubsys.hpp"

class TrainDirClient {
public:
  TrainDirClient() {}
  ~TrainDirClient() {}

  bool create_connection(int port = 8900, std::string host = "127.0.0.1");
  void close_connection();

  void click(int x, int y);
  void run();

private:
  Connection conn;
};

#endif
<|endoftext|>


<commit_before>#ifndef INCLUDED_KONTSEVICH_GRAPH_SUM_H_
#define INCLUDED_KONTSEVICH_GRAPH_SUM_H_

#include <vector>
#include <utility>
#include <ostream>
#include <kontsevich_graph.hpp>

template<class T> class KontsevichGraphSum;
template<class T> std::ostream& operator<<(std::ostream&, const KontsevichGraphSum<T>&);

template<class T>
class KontsevichGraphSum : public std::vector< std::pair<T, KontsevichGraph> >
{
    using std::vector< std::pair<T, KontsevichGraph> >::vector; // inherit constructors
    public:
    void reduce();

    friend std::ostream& operator<< <>(std::ostream& os, const KontsevichGraphSum<T>& gs);
};

#endif
<commit_msg>Add handy typedef Term (value_type) in KontsevichGraphSum.<commit_after>#ifndef INCLUDED_KONTSEVICH_GRAPH_SUM_H_
#define INCLUDED_KONTSEVICH_GRAPH_SUM_H_

#include <vector>
#include <utility>
#include <ostream>
#include <kontsevich_graph.hpp>

template<class T> class KontsevichGraphSum;
template<class T> std::ostream& operator<<(std::ostream&, const KontsevichGraphSum<T>&);

template<class T>
class KontsevichGraphSum : public std::vector< std::pair<T, KontsevichGraph> >
{
    typedef std::pair<T, KontsevichGraph> Term;
    using std::vector<Term>::vector; // inherit constructors
    public:
    void reduce();

    friend std::ostream& operator<< <>(std::ostream& os, const KontsevichGraphSum<T>& gs);
};

#endif
<|endoftext|>


<commit_before>#include <QtGui>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    app.setApplicationName("QMH Remote Control");
    app.setOrganizationName("Nokia");

    MainWindow mainWindow;
#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO5)
    mainWindow.showMaximized();
#else
    mainWindow.show();
#endif

    return app.exec();
}

<commit_msg>remotecontrol: set org domain<commit_after>#include <QtGui>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    app.setApplicationName("QMH Remote Control");
    app.setOrganizationDomain("nokia.com");
    app.setOrganizationName("Nokia");

    MainWindow mainWindow;
#if defined(Q_OS_SYMBIAN) || defined(Q_WS_MAEMO5)
    mainWindow.showMaximized();
#else
    mainWindow.show();
#endif

    return app.exec();
}

<|endoftext|>


<commit_before>/* KPilot
**
** Copyright (C) 2000-2001 by Adriaan de Groot
**
** This file defines a specialization of KListView that can
** be used to sort some fixed set of object into some fixed
** set of categories.
*/

/*
** This program 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 2 of the License, or
** (at your option) any later version.
**
** This program 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 this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/

static const char *listCat_id =
	"$Id$";

#include "options.h"

#include <qpainter.h>
#include <klocale.h>

#include "listCat.moc"

ListCategorizer::ListCategorizer(QWidget * parent,
	const char *name) :
	KListView(parent, name),
	fStartOpen(false)
{
	FUNCTIONSETUP;
	setupWidget();
	(void) listCat_id;
}

ListCategorizer::ListCategorizer(const QStringList & i,
	bool startOpen,
	QWidget * parent,
	const char *name) :
	KListView(parent, name),
	fStartOpen(startOpen)
{
	FUNCTIONSETUP;
	addCategories(i);
}

void ListCategorizer::addCategories(const QStringList & l)
{
	FUNCTIONSETUP;
	QStringList::ConstIterator i;

	for (i = l.begin(); i != l.end(); ++i)
	{
		(void) addCategory(*i);
	}
}

QListViewItem *ListCategorizer::addCategory(const QString & name,
	const QString & desc)
{
	FUNCTIONSETUP;
	QListViewItem *m = new QListViewItem(this, name, desc);

	m->setSelectable(false);
	m->setOpen(fStartOpen);
	return m;
}

void ListCategorizer::setupWidget()
{
	FUNCTIONSETUP;
	addColumn(i18n("Category"));
	addColumn(i18n("Description"));
	setItemsMovable(false);
	setDragEnabled(true);
	setAcceptDrops(true);
	setDropVisualizer(true);
	setRootIsDecorated(true);
}

/* virtual */ bool ListCategorizer::acceptDrag(QDropEvent * event) const
{
	FUNCTIONSETUP;
	if (!(event->source()))
		return false;
	QListViewItem *p = itemAt(event->pos());

	if (!p)
		return false;

	return true;
}

/* virtual */ void ListCategorizer::contentsDropEvent(QDropEvent * e)
{
	FUNCTIONSETUP;
	cleanDropVisualizer();

	if (!acceptDrag(e))
		return;
	e->accept();

	QListViewItem *p = itemAt(e->pos());
	QListViewItem *selection = currentItem();

	if (!p)
	{
		kdWarning() << "Drop without a category!" << endl;
		return;
	}

	QListViewItem *category = p->parent();

	if (!category)
	{
		category = p;
	}

	moveItem(selection, category, 0L);
}

/* virtual */ void ListCategorizer::startDrag()
{
	FUNCTIONSETUP;
	QListViewItem *p = currentItem();

	if (!p || !p->parent())
		return;

	KListView::startDrag();
}

QStringList ListCategorizer::listSiblings(const QListViewItem * p, int column) const
{
	FUNCTIONSETUP;
	QStringList l;

	while (p)
	{
		l.append(p->text(column));
		p = p->nextSibling();
	}

	return l;
}

QListViewItem *ListCategorizer::findCategory(const QString & category) const
{
	FUNCTIONSETUP;
	QListViewItem *p = firstChild();

	while (p)
	{
		if (p->text(0) == category)
			return p;
		p = p->nextSibling();
	}

	return 0L;
}

QListViewItem *ListCategorizer::addItem(const QString & category,
	const QString & name, const QString & description)
{
	FUNCTIONSETUP;
	QListViewItem *p = findCategory(category);

	if (!p)
		return 0L;

	return new QListViewItem(p, name, description);
}

#define RVPAD	(4)

RichListViewItem::RichListViewItem(QListViewItem *p,
	QString l,
	int c) :
	QListViewItem(p,l)
{
	FUNCTIONSETUP;

	fColumns=c;
	fIsRich = new bool[c];
	fRect = new QRect[c];

	for (int i=0; i<c; i++)
	{
		fIsRich[i]=false;
	}
}

RichListViewItem::~RichListViewItem()
{
	FUNCTIONSETUP;

	delete[] fIsRich;
	delete[] fRect;
}

void RichListViewItem::computeHeight(int c)
{
	FUNCTIONSETUP;

	if (!fIsRich[c]) return;

	QListView *v = listView();

	fRect[c] = v->fontMetrics().boundingRect(v->itemMargin()+RVPAD,0+RVPAD,
		v->columnWidth(c)-v->itemMargin()-RVPAD,300,
		AlignLeft | AlignTop | WordBreak,
		text(c));
}

/* virtual */ void RichListViewItem::setup()
{
	FUNCTIONSETUP;

	QListViewItem::setup();

	int h = height();

	for (int i=0; i<fColumns; i++)
	{
		computeHeight(i);
		h = QMAX(h,fRect[i].height()+2*RVPAD);
	}

	setHeight(h);
}

/* virtual */ void RichListViewItem::paintCell(QPainter *p,
	const QColorGroup &gc,
	int column,
	int width,
	int alignment)
{
	FUNCTIONSETUP;

	if ((!column) || (!fIsRich[column]))
	{
		QListViewItem::paintCell(p,gc,column,width,alignment);
		return;
	}

	QListView *v = listView();

	p->eraseRect(0,0,width,height());
	p->setBackgroundColor(gc.background());
	p->eraseRect(RVPAD,RVPAD,width-RVPAD,height()-RVPAD);
	p->setPen(gc.text());
	p->drawText(v->itemMargin()+RVPAD,0+RVPAD,
		width-v->itemMargin()-RVPAD,height()-RVPAD,
		AlignTop | AlignLeft | WordBreak,
		text(column),
		-1,
		&fRect[column]);
}
<commit_msg>QMAX -> qMax<commit_after>/* KPilot
**
** Copyright (C) 2000-2001 by Adriaan de Groot
**
** This file defines a specialization of KListView that can
** be used to sort some fixed set of object into some fixed
** set of categories.
*/

/*
** This program 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 2 of the License, or
** (at your option) any later version.
**
** This program 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 this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to kde-pim@kde.org
*/

static const char *listCat_id =
	"$Id$";

#include "options.h"

#include <qpainter.h>
#include <klocale.h>

#include "listCat.moc"

ListCategorizer::ListCategorizer(QWidget * parent,
	const char *name) :
	KListView(parent, name),
	fStartOpen(false)
{
	FUNCTIONSETUP;
	setupWidget();
	(void) listCat_id;
}

ListCategorizer::ListCategorizer(const QStringList & i,
	bool startOpen,
	QWidget * parent,
	const char *name) :
	KListView(parent, name),
	fStartOpen(startOpen)
{
	FUNCTIONSETUP;
	addCategories(i);
}

void ListCategorizer::addCategories(const QStringList & l)
{
	FUNCTIONSETUP;
	QStringList::ConstIterator i;

	for (i = l.begin(); i != l.end(); ++i)
	{
		(void) addCategory(*i);
	}
}

QListViewItem *ListCategorizer::addCategory(const QString & name,
	const QString & desc)
{
	FUNCTIONSETUP;
	QListViewItem *m = new QListViewItem(this, name, desc);

	m->setSelectable(false);
	m->setOpen(fStartOpen);
	return m;
}

void ListCategorizer::setupWidget()
{
	FUNCTIONSETUP;
	addColumn(i18n("Category"));
	addColumn(i18n("Description"));
	setItemsMovable(false);
	setDragEnabled(true);
	setAcceptDrops(true);
	setDropVisualizer(true);
	setRootIsDecorated(true);
}

/* virtual */ bool ListCategorizer::acceptDrag(QDropEvent * event) const
{
	FUNCTIONSETUP;
	if (!(event->source()))
		return false;
	QListViewItem *p = itemAt(event->pos());

	if (!p)
		return false;

	return true;
}

/* virtual */ void ListCategorizer::contentsDropEvent(QDropEvent * e)
{
	FUNCTIONSETUP;
	cleanDropVisualizer();

	if (!acceptDrag(e))
		return;
	e->accept();

	QListViewItem *p = itemAt(e->pos());
	QListViewItem *selection = currentItem();

	if (!p)
	{
		kdWarning() << "Drop without a category!" << endl;
		return;
	}

	QListViewItem *category = p->parent();

	if (!category)
	{
		category = p;
	}

	moveItem(selection, category, 0L);
}

/* virtual */ void ListCategorizer::startDrag()
{
	FUNCTIONSETUP;
	QListViewItem *p = currentItem();

	if (!p || !p->parent())
		return;

	KListView::startDrag();
}

QStringList ListCategorizer::listSiblings(const QListViewItem * p, int column) const
{
	FUNCTIONSETUP;
	QStringList l;

	while (p)
	{
		l.append(p->text(column));
		p = p->nextSibling();
	}

	return l;
}

QListViewItem *ListCategorizer::findCategory(const QString & category) const
{
	FUNCTIONSETUP;
	QListViewItem *p = firstChild();

	while (p)
	{
		if (p->text(0) == category)
			return p;
		p = p->nextSibling();
	}

	return 0L;
}

QListViewItem *ListCategorizer::addItem(const QString & category,
	const QString & name, const QString & description)
{
	FUNCTIONSETUP;
	QListViewItem *p = findCategory(category);

	if (!p)
		return 0L;

	return new QListViewItem(p, name, description);
}

#define RVPAD	(4)

RichListViewItem::RichListViewItem(QListViewItem *p,
	QString l,
	int c) :
	QListViewItem(p,l)
{
	FUNCTIONSETUP;

	fColumns=c;
	fIsRich = new bool[c];
	fRect = new QRect[c];

	for (int i=0; i<c; i++)
	{
		fIsRich[i]=false;
	}
}

RichListViewItem::~RichListViewItem()
{
	FUNCTIONSETUP;

	delete[] fIsRich;
	delete[] fRect;
}

void RichListViewItem::computeHeight(int c)
{
	FUNCTIONSETUP;

	if (!fIsRich[c]) return;

	QListView *v = listView();

	fRect[c] = v->fontMetrics().boundingRect(v->itemMargin()+RVPAD,0+RVPAD,
		v->columnWidth(c)-v->itemMargin()-RVPAD,300,
		AlignLeft | AlignTop | WordBreak,
		text(c));
}

/* virtual */ void RichListViewItem::setup()
{
	FUNCTIONSETUP;

	QListViewItem::setup();

	int h = height();

	for (int i=0; i<fColumns; i++)
	{
		computeHeight(i);
		h = qMax(h,fRect[i].height()+2*RVPAD);
	}

	setHeight(h);
}

/* virtual */ void RichListViewItem::paintCell(QPainter *p,
	const QColorGroup &gc,
	int column,
	int width,
	int alignment)
{
	FUNCTIONSETUP;

	if ((!column) || (!fIsRich[column]))
	{
		QListViewItem::paintCell(p,gc,column,width,alignment);
		return;
	}

	QListView *v = listView();

	p->eraseRect(0,0,width,height());
	p->setBackgroundColor(gc.background());
	p->eraseRect(RVPAD,RVPAD,width-RVPAD,height()-RVPAD);
	p->setPen(gc.text());
	p->drawText(v->itemMargin()+RVPAD,0+RVPAD,
		width-v->itemMargin()-RVPAD,height()-RVPAD,
		AlignTop | AlignLeft | WordBreak,
		text(column),
		-1,
		&fRect[column]);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2013-2014 Daniel Nicoletti <dantti12@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB. If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "engineuwsgi.h"
#include "plugin.h"

#include <Cutelyst/application.h>
#include <Cutelyst/context.h>
#include <Cutelyst/response.h>
#include <Cutelyst/request.h>

#include <QPluginLoader>
#include <QFile>
#include <QUrl>
#include <QDebug>

extern struct uwsgi_server uwsgi;

using namespace Cutelyst;

EngineUwsgi::EngineUwsgi(QObject *parent) :
    Engine(parent),
    m_loader(0)
{
}

bool EngineUwsgi::loadApplication(const QString &path)
{
    if (m_loader) {
        delete m_loader->instance();
        delete m_loader;
    }

    m_loader = new QPluginLoader(path);
    if (m_loader->load()) {
        QObject *instance = m_loader->instance();
        if (instance) {
            Application *app = qobject_cast<Application *>(instance);
            if (app) {
                qDebug() << "Application"
                         << app->applicationName()
                         << "loaded.";
                return setupApplication(app);
            } else {
                qCritical() << "Could not create an instance of the application:" << instance;
            }
        } else {
            qCritical() << "Could not create an instance:" << path;
        }
    } else {
        qWarning() << "Failed to open app:" << m_loader->errorString();
    }
    return false;
}

void EngineUwsgi::finalizeBody(Context *ctx)
{
    Response *res = ctx->res();
    struct wsgi_request *wsgi_req = static_cast<wsgi_request*>(requestPtr(ctx->req()));

    uwsgi_response_write_body_do(wsgi_req, res->body().data(), res->body().size());
}

void EngineUwsgi::processRequest(struct wsgi_request *wsgi_req)
{
    Request *request;
    QByteArray host(wsgi_req->host, wsgi_req->host_len);
    QByteArray path(wsgi_req->path_info, wsgi_req->path_info_len);
    QUrlQuery queryString(QByteArray(wsgi_req->query_string, wsgi_req->query_string_len));
    request = newRequest(wsgi_req,
                         wsgi_req->https_len ? "http" : "https",
                         host,
                         path,
                         queryString);

    QByteArray remote(wsgi_req->remote_addr, wsgi_req->remote_addr_len);

    QByteArray method(wsgi_req->method, wsgi_req->method_len);

    QByteArray protocol(wsgi_req->protocol, wsgi_req->protocol_len);

    QHash<QByteArray, QByteArray> headers;
    for (int i = 0; i < wsgi_req->var_cnt; i += 2) {
        if (wsgi_req->hvec[i].iov_len < 6) {
            continue;
        }

        if (!uwsgi_startswith((char *) wsgi_req->hvec[i].iov_base,
                              const_cast<char *>("HTTP_"), 5)) {
            QByteArray key((char *) wsgi_req->hvec[i].iov_base+5, wsgi_req->hvec[i].iov_len-5);
            QByteArray value((char *) wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
            headers.insert(httpCase(key), value);
        }
    }

    QByteArray contentType(wsgi_req->content_type, wsgi_req->content_type_len);
    if (!contentType.isNull()) {
        headers.insert("Content-Type", contentType);
    }

    QByteArray contentEncoding(wsgi_req->encoding, wsgi_req->encoding_len);
    if (!contentEncoding.isNull()) {
        headers.insert("Content-Encoding", contentEncoding);
    }

    QByteArray remoteUser(wsgi_req->remote_user, wsgi_req->remote_user_len);

    QByteArray bodyArray;
    size_t remains = wsgi_req->post_cl;
    while(remains > 0) {
        ssize_t body_len = 0;
        char *body =  uwsgi_request_body_read(wsgi_req, UMIN(remains, 32768) , &body_len);
        if (!body || body == uwsgi.empty) {
            break;
        }

        bodyArray.append(body, body_len);
    }

    uint16_t remote_port_len;
    char *remote_port = uwsgi_get_var(wsgi_req, (char *) "REMOTE_PORT", 11, &remote_port_len);
    QByteArray remotePort(remote_port, remote_port_len);

    QFile *upload = new QFile;
    if (wsgi_req->post_file && !upload->open(wsgi_req->post_file, QIODevice::ReadOnly)) {
        qDebug() << "Could not open upload file";
    }

    setupRequest(request,
                 method,
                 protocol,
                 headers,
                 bodyArray,
                 remoteUser,
                 QHostAddress(remote.data()),
                 remotePort.toUInt(),
                 upload);

    handleRequest(request, new Response);
}

QByteArray EngineUwsgi::httpCase(const QByteArray &headerKey) const
{
    QByteArray ret;

    bool lastWasUnderscore = false;

    for (int i = 0 ; i < headerKey.size() ; ++i) {
        QChar buf = headerKey[i];
        if(i == 0 || lastWasUnderscore) {
            ret += buf.toUpper();
            lastWasUnderscore = false;
        } else  if (buf == '_') {
            ret += '-';
            lastWasUnderscore = true;
        } else {
            ret += buf.toLower();
            lastWasUnderscore = false;
        }
    }

    return ret;
}

void EngineUwsgi::finalizeHeaders(Context *ctx)
{
    Response *res = ctx->res();
    struct wsgi_request *wsgi_req = static_cast<wsgi_request*>(requestPtr(ctx->req()));

    if (uwsgi_response_prepare_headers(wsgi_req,
                                       res->statusCode().data(),
                                       res->statusCode().size())) {
        return;
    }

    QMap<QByteArray, QByteArray> headers = ctx->res()->headers();
    QMap<QByteArray, QByteArray>::Iterator it = headers.begin();
    while (it != headers.end()) {
        QByteArray key = it.key();
        if (uwsgi_response_add_header(wsgi_req,
                                      key.data(),
                                      key.size(),
                                      it.value().data(),
                                      it.value().size())) {
            return;
        }
        ++it;
    }
}

bool EngineUwsgi::init()
{
    return true;
}

EngineUwsgi *engine;

extern "C" int uwsgi_cutelyst_init()
{
    uwsgi_log("Initializing Cutelyst plugin\n");

    engine = new EngineUwsgi;

    return 0;
}

extern "C" int uwsgi_cutelyst_request(struct wsgi_request *wsgi_req)
{
    // empty request ?
    if (!wsgi_req->uh->pktsize) {
        uwsgi_log( "Invalid request. skip.\n");
        goto clear;
    }

    // get uwsgi variables
    if (uwsgi_parse_vars(wsgi_req)) {
        uwsgi_log("Invalid request. skip.\n");
        goto clear;
    }

    engine->processRequest(wsgi_req);

clear:
    return UWSGI_OK;
}

extern "C" void uwsgi_cutelyst_init_apps()
{
    uwsgi_log("Cutelyst Init App\n");

    QString path(options.app);
    if (path.isEmpty()) {
        qCritical() << "Cytelyst Application was not set";
        return;
    }

    qDebug()  << "Loading" << path;
    if (!engine->loadApplication(path)) {
        qCritical() << "Could not load application:" << path;
        return;
    }

    // get the current app id
    int id = uwsgi_apps_cnt;

    // register a new app under a specific "mountpoint"
    uwsgi_add_app(id, CUTELYST_MODIFIER1, NULL, 0, NULL, NULL);
}
<commit_msg>Creating a QCoreApplication on uwsgi plugin init allows for some async stuff to work, namely QTimers aren't working (maybe due the lack of QThread).<commit_after>/*
 * Copyright (C) 2013-2014 Daniel Nicoletti <dantti12@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB. If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "engineuwsgi.h"
#include "plugin.h"

#include <Cutelyst/application.h>
#include <Cutelyst/context.h>
#include <Cutelyst/response.h>
#include <Cutelyst/request.h>

#include <QPluginLoader>
#include <QFile>
#include <QUrl>
#include <QDebug>

extern struct uwsgi_server uwsgi;

using namespace Cutelyst;

EngineUwsgi::EngineUwsgi(QObject *parent) :
    Engine(parent),
    m_loader(0)
{
}

bool EngineUwsgi::loadApplication(const QString &path)
{
    if (m_loader) {
        delete m_loader->instance();
        delete m_loader;
    }

    m_loader = new QPluginLoader(path);
    if (m_loader->load()) {
        QObject *instance = m_loader->instance();
        if (instance) {
            Application *app = qobject_cast<Application *>(instance);
            if (app) {
                qDebug() << "Application"
                         << app->applicationName()
                         << "loaded.";
                return setupApplication(app);
            } else {
                qCritical() << "Could not create an instance of the application:" << instance;
            }
        } else {
            qCritical() << "Could not create an instance:" << path;
        }
    } else {
        qWarning() << "Failed to open app:" << m_loader->errorString();
    }
    return false;
}

void EngineUwsgi::finalizeBody(Context *ctx)
{
    Response *res = ctx->res();
    struct wsgi_request *wsgi_req = static_cast<wsgi_request*>(requestPtr(ctx->req()));

    uwsgi_response_write_body_do(wsgi_req, res->body().data(), res->body().size());
}

void EngineUwsgi::processRequest(struct wsgi_request *wsgi_req)
{
    Request *request;
    QByteArray host(wsgi_req->host, wsgi_req->host_len);
    QByteArray path(wsgi_req->path_info, wsgi_req->path_info_len);
    QUrlQuery queryString(QByteArray(wsgi_req->query_string, wsgi_req->query_string_len));
    request = newRequest(wsgi_req,
                         wsgi_req->https_len ? "http" : "https",
                         host,
                         path,
                         queryString);

    QByteArray remote(wsgi_req->remote_addr, wsgi_req->remote_addr_len);

    QByteArray method(wsgi_req->method, wsgi_req->method_len);

    QByteArray protocol(wsgi_req->protocol, wsgi_req->protocol_len);

    QHash<QByteArray, QByteArray> headers;
    for (int i = 0; i < wsgi_req->var_cnt; i += 2) {
        if (wsgi_req->hvec[i].iov_len < 6) {
            continue;
        }

        if (!uwsgi_startswith((char *) wsgi_req->hvec[i].iov_base,
                              const_cast<char *>("HTTP_"), 5)) {
            QByteArray key((char *) wsgi_req->hvec[i].iov_base+5, wsgi_req->hvec[i].iov_len-5);
            QByteArray value((char *) wsgi_req->hvec[i + 1].iov_base, wsgi_req->hvec[i + 1].iov_len);
            headers.insert(httpCase(key), value);
        }
    }

    QByteArray contentType(wsgi_req->content_type, wsgi_req->content_type_len);
    if (!contentType.isNull()) {
        headers.insert("Content-Type", contentType);
    }

    QByteArray contentEncoding(wsgi_req->encoding, wsgi_req->encoding_len);
    if (!contentEncoding.isNull()) {
        headers.insert("Content-Encoding", contentEncoding);
    }

    QByteArray remoteUser(wsgi_req->remote_user, wsgi_req->remote_user_len);

    QByteArray bodyArray;
    size_t remains = wsgi_req->post_cl;
    while(remains > 0) {
        ssize_t body_len = 0;
        char *body =  uwsgi_request_body_read(wsgi_req, UMIN(remains, 32768) , &body_len);
        if (!body || body == uwsgi.empty) {
            break;
        }

        bodyArray.append(body, body_len);
    }

    uint16_t remote_port_len;
    char *remote_port = uwsgi_get_var(wsgi_req, (char *) "REMOTE_PORT", 11, &remote_port_len);
    QByteArray remotePort(remote_port, remote_port_len);

    QFile *upload = new QFile;
    if (wsgi_req->post_file && !upload->open(wsgi_req->post_file, QIODevice::ReadOnly)) {
        qDebug() << "Could not open upload file";
    }

    setupRequest(request,
                 method,
                 protocol,
                 headers,
                 bodyArray,
                 remoteUser,
                 QHostAddress(remote.data()),
                 remotePort.toUInt(),
                 upload);

    handleRequest(request, new Response);
}

QByteArray EngineUwsgi::httpCase(const QByteArray &headerKey) const
{
    QByteArray ret;

    bool lastWasUnderscore = false;

    for (int i = 0 ; i < headerKey.size() ; ++i) {
        QChar buf = headerKey[i];
        if(i == 0 || lastWasUnderscore) {
            ret += buf.toUpper();
            lastWasUnderscore = false;
        } else  if (buf == '_') {
            ret += '-';
            lastWasUnderscore = true;
        } else {
            ret += buf.toLower();
            lastWasUnderscore = false;
        }
    }

    return ret;
}

void EngineUwsgi::finalizeHeaders(Context *ctx)
{
    Response *res = ctx->res();
    struct wsgi_request *wsgi_req = static_cast<wsgi_request*>(requestPtr(ctx->req()));

    if (uwsgi_response_prepare_headers(wsgi_req,
                                       res->statusCode().data(),
                                       res->statusCode().size())) {
        return;
    }

    QMap<QByteArray, QByteArray> headers = ctx->res()->headers();
    QMap<QByteArray, QByteArray>::Iterator it = headers.begin();
    while (it != headers.end()) {
        QByteArray key = it.key();
        if (uwsgi_response_add_header(wsgi_req,
                                      key.data(),
                                      key.size(),
                                      it.value().data(),
                                      it.value().size())) {
            return;
        }
        ++it;
    }
}

bool EngineUwsgi::init()
{
    return true;
}

EngineUwsgi *engine;

extern "C" int uwsgi_cutelyst_init()
{
    uwsgi_log("Initializing Cutelyst plugin\n");

    // This allows for some stuff to run event loops
    (void) new QCoreApplication(uwsgi.argc, uwsgi.argv);

    engine = new EngineUwsgi;

    return 0;
}

extern "C" int uwsgi_cutelyst_request(struct wsgi_request *wsgi_req)
{
    // empty request ?
    if (!wsgi_req->uh->pktsize) {
        uwsgi_log( "Invalid request. skip.\n");
        goto clear;
    }

    // get uwsgi variables
    if (uwsgi_parse_vars(wsgi_req)) {
        uwsgi_log("Invalid request. skip.\n");
        goto clear;
    }

    engine->processRequest(wsgi_req);

clear:
    return UWSGI_OK;
}

extern "C" void uwsgi_cutelyst_init_apps()
{
    uwsgi_log("Cutelyst Init App\n");

    QString path(options.app);
    if (path.isEmpty()) {
        qCritical() << "Cytelyst Application was not set";
        return;
    }

    qDebug()  << "Loading" << path;
    if (!engine->loadApplication(path)) {
        qCritical() << "Could not load application:" << path;
        return;
    }

    // get the current app id
    int id = uwsgi_apps_cnt;

    // register a new app under a specific "mountpoint"
    uwsgi_add_app(id, CUTELYST_MODIFIER1, NULL, 0, NULL, NULL);
}
<|endoftext|>


<commit_before>/** Implementation of canonpy.
 */

#include <canonpy.h>

#include <Python.h>

#include <algorithm>
#include <string>

#include <libcanon/perm.h>

using libcanon::Simple_perm;

//
// Perm class
// ==========
//
// Internal functions
// ------------------
//
// These functions are not directly set to Python types but are used
// internally.  They are also used by other parts of this extension.
//

/** Builds a tuple object for a permutation.
 *
 * This function creates a pair, where the first field is a list of integers
 * for the preimage array, and the second field is the accompanied action,
 * which is also encoded as an integer.
 */

static PyObject* build_perm_to_tuple(const Simple_perm& perm)
{

    PyObject* pre_images = NULL;
    PyObject* res = NULL;
    PyObject* acc = NULL;
    size_t size = perm.size();

    pre_images = PyList_New(size);
    if (!pre_images)
        goto error;
    for (size_t i = 0; i < size; ++i) {
        PyObject* curr = Py_BuildValue('n', perm >> i);
        if (curr) {
            PyList_SetItem(pre_images, i, curr);
        } else {
            goto error;
        }
    }

    acc = Py_BuildValue('b', perm.acc());
    if (!acc)
        goto error;

    res = PyTuple_New(2);
    if (!res)
        goto error;

    PyTuple_SET_ITEM(res, 0, pre_images);
    PyTuple_SET_ITEM(res, 1, acc);

    return (PyObject*)res;

error:
    Py_XDECREF(pre_images);
    Py_XDECREF(res);
    Py_XDECREF(acc);
    return NULL;
}

/** Builds a permutation from its construction arguments.
 *
 * An iterable of positive integers for the pre-image array needs to be given
 * as the first argument.  The accompanied action can be optionally given as
 * another integral argument, or by the keyword ``acc``.
 *
 * If the arguments are not valid, a Perm of size zero is going to be returned.
 *
 * This function is designed to be compatible with the result from the function
 * `build_perm_to_tuple`.  However, more general input format is accepted.
 */

static Simple_perm make_perm_from_args(PyObject* args, PyObject* kwargs);

//
// Interface functions
// -------------------
//

const static char* perm_getnewargs_doc
    = "Get the arguments for new to construct the Perm.";

static PyObject* perm_getnewargs(Perm_object* self)
{
    // Here we directly use the tuple format of a perm.

    return build_perm_to_tuple(self->perm);
}

/** Gets the size of the permutation domain of a Perm.
 */

static Py_ssize_t perm_length(Perm_object* self)
{
    // The type should be the same, size_t and Py_ssize_t.

    return self->perm.size();
}

/** Gets the pre-image of a point.
 *
 * A new integer object will be built by this function.
 */

static PyObject* perm_item(Perm_object* self, Py_ssize_t i)
{
    if (i < 0 || i >= self->perm.size()) {
        PyErr_SetString(PyExc_IndexError, "Point outside permutation domain");
        return NULL;
    }

    return Py_BuildValue("n", self->perm >> i);
}

/** Gets the accompanied action of a Perm.
 */

static PyObject* perm_get_acc(Perm_object* self, void* closure)
{
    // Note that the accompanied action is a byte in simple perm.

    return Py_BuildValue("b", self->perm.acc());
}

/** Deallocates a perm instance.
 */

static void perm_dealloc(Perm_object* self)
{
    perm.perm.~Simple_perm();

    // For subclassing.
    Py_TYPE(self)->tp_free((PyObject*)self);
}

/** Forms the string representation of a Perm object.
 */

static PyObject* perm_repr(Perm_object* self)
{
    const Simple_perm& perm = self->perm;

    std::wstring repr("Perm(");

    size_t size = perm.size();

    if (size > 0) {
        for (size_t i = 0; i < size; ++i) {
            if (i == 0) {
                repr.append('[');
            } else {
                repr.append(", ");
            }
            repr.append(std::to_wstring(perm >> i));
        }
        repr.append(']');

        // Add the accompanied action only when we need.
        char acc = perm.acc();
        if (acc != 0) {
            repr.append(", ");
            repr.append(std::to_wstring(acc));
        }
    }

    // This is used for empty or non-empty permutation.
    repr.append(')');

    return PyUnicode_FromUnicode(repr.data(), repr.size());
}

/** Gets the hash of a perm.
 */

static Py_hash_t perm_hash(Perm_object* self)
{
    // Py_hash_t should be compatible with size_t.

    return self->perm.hash();
}

/** Creates a new Perm object.
 *
 * The actual work is delegated to the Python/Perm interface function.
 */

static PyObject* perm_new(PyTypeObject* type, PyObject* args, PyObject* kwargs)
{
    Perm_object* self;

    // Pay attention to subclassing.
    self = (Perm_object*)type->tp_alloc(type, 0);

    if (!self)
        return NULL;

    Simple_perm perm = get_perm_from_args(args, kwargs);

    if (perm.size() > 0) {
        new (&self->perm) Simple_perm(std::move(perm));
        return (PyObject*)self;
    } else {
        return NULL;
    }
}

//
// Class definition
// ----------------
//

/** Methods for Perm objects.
 */

static PyMethodDef perm_methods[] = {
    { "__getnewargs__", (PyCFunction)perm_getnewargs, METH_NOARGS,
        perm_getnewargs_doc },
    { NULL, NULL } /* sentinel */
};

/** Sequence operations for Perm objects.
 *
 * Here we only support size and pre-image query.
 */

// clang-format off
static PySequenceMethods perm_as_sequence = {
    (lenfunc)perm_length,                       /* sq_length */
    0,                                          /* sq_concat */
    0,                                          /* sq_repeat */
    (ssizeargfunc)perm_item,                    /* sq_item */
    0,                                          /* sq_slice */
    0,                                          /* sq_ass_item */
    0,                                          /* sq_ass_slice */
    0                                           /* sq_contains */
};
// clang-format on

/** Accessors for Perms.
 *
 * The accompanied action query is made here.
 */

// clang-format off
static PyGetSetDef perm_getsets[] = {
    { "acc", (getter)perm_get_acc, NULL, "The accompanied action.", NULL },
    { NULL }
};
// clang-format on

/** Perm type doc string.
  */

static char* perm_doc =
    R"__doc__(Permutation of points with accompanied action.

Permutations can be constructed from an iterable giving the pre-image of the
points and an optional integral value for the accompanied action.  The
accompanied action can be given positionally or by the keyword ``acc``, and it
will be manipulated according to the convention in libcanon.

Querying the length of a Perm object gives the size of the permutation domain,
while indexing it gives the pre-image of the given integral point.  The
accompanied action can be obtained by getting the attribute ``acc``.
Otherwise, this data type is mostly opaque.

)__doc__"

/** Type definition for Perm class.
 */

// clang-format off
static PyTypeObject perm_type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "drudge.canonpy.Perm",
    sizeof(Perm_object),
    0,
    (destructor) perm_dealloc,                  /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    (reprfunc) perm_repr,                       /* tp_repr */
    0,                                          /* tp_as_number */
    &perm_as_sequence,                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    (hashfunc) perm_hash,                       /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0, /* In main. */                           /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
    perm_doc,                                   /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    perm_methods,                               /* tp_methods */
    0,                                          /* tp_members */
    perm_getsets,                               /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    perm_new,                                   /* tp_new */
    0,                                          /* tp_free */
};
// clang-format on

//
// Python module definition
// ========================
//

/** Docstring for the canonpy module.
 */

static const char* canonpy_docstring
    = R"__doc__(Canonpy, simple wrapper over libcanon for Python.

This wrapper of libcanon is directly targeted towards usage using drudge.
Here, we have a class `Perm`, which wraps over the `Simple_perm` class in
libcanon, another class `SimsTransv`, which wraps over the `Sims_trasv` class
for `Simple_perm`.  And we also have the function `canon_eldag` to canonicalize
an Eldag.

)__doc__";

/** Methods in the canonpy module.
 */

static PyMethodDef canonpy_methods[] = { { NULL, NULL, 0, NULL } };

/** Executes the initialization of the canonpy module.
 */

static int canopy_exec(PyObject* m)
{
    //
    // Add the class for Perm.
    //

    perm_type.tp_getattro = PyObject_GenericGetAttr;
    if (PyType_Ready(&perm_type) < 0)
        return NULL;
    Py_INCREF(&perm_type);
    PyModule_AddObject(m, "Perm", (PyObject*)&perm_type);

    return 0;
}

/** Slots for for canonpy module definition.
 */

static struct PyModuleDef_Slot canonpy_slots[] = {
    { Py_mod_exec, canonpy_exec }, { 0, NULL },
};

/** Canonpy module definition.
 */

// clang-format off

static struct PyModuleDef canonpy_module = {
    PyModuleDef_HEAD_INIT,
    "drudge.canonpy",
    canonpy_docstring,
    0, // m-size
    canonpy_methods,
    canonpy_slots,
    NULL, // Transverse
    NULL, // Clear
    NULL  // Free
};

// clang-format on

/** The published canonpy function.
 */

PyMODINIT_FUNC PyInit_canonpy(void)
{
    return PyModuleDef_Init(&canonpy_module);
}
<commit_msg>Fix ending of docstring<commit_after>/** Implementation of canonpy.
 */

#include <canonpy.h>

#include <Python.h>

#include <algorithm>
#include <string>

#include <libcanon/perm.h>

using libcanon::Simple_perm;

//
// Perm class
// ==========
//
// Internal functions
// ------------------
//
// These functions are not directly set to Python types but are used
// internally.  They are also used by other parts of this extension.
//

/** Builds a tuple object for a permutation.
 *
 * This function creates a pair, where the first field is a list of integers
 * for the preimage array, and the second field is the accompanied action,
 * which is also encoded as an integer.
 */

static PyObject* build_perm_to_tuple(const Simple_perm& perm)
{

    PyObject* pre_images = NULL;
    PyObject* res = NULL;
    PyObject* acc = NULL;
    size_t size = perm.size();

    pre_images = PyList_New(size);
    if (!pre_images)
        goto error;
    for (size_t i = 0; i < size; ++i) {
        PyObject* curr = Py_BuildValue('n', perm >> i);
        if (curr) {
            PyList_SetItem(pre_images, i, curr);
        } else {
            goto error;
        }
    }

    acc = Py_BuildValue('b', perm.acc());
    if (!acc)
        goto error;

    res = PyTuple_New(2);
    if (!res)
        goto error;

    PyTuple_SET_ITEM(res, 0, pre_images);
    PyTuple_SET_ITEM(res, 1, acc);

    return (PyObject*)res;

error:
    Py_XDECREF(pre_images);
    Py_XDECREF(res);
    Py_XDECREF(acc);
    return NULL;
}

/** Builds a permutation from its construction arguments.
 *
 * An iterable of positive integers for the pre-image array needs to be given
 * as the first argument.  The accompanied action can be optionally given as
 * another integral argument, or by the keyword ``acc``.
 *
 * If the arguments are not valid, a Perm of size zero is going to be returned.
 *
 * This function is designed to be compatible with the result from the function
 * `build_perm_to_tuple`.  However, more general input format is accepted.
 */

static Simple_perm make_perm_from_args(PyObject* args, PyObject* kwargs);

//
// Interface functions
// -------------------
//

const static char* perm_getnewargs_doc
    = "Get the arguments for new to construct the Perm.";

static PyObject* perm_getnewargs(Perm_object* self)
{
    // Here we directly use the tuple format of a perm.

    return build_perm_to_tuple(self->perm);
}

/** Gets the size of the permutation domain of a Perm.
 */

static Py_ssize_t perm_length(Perm_object* self)
{
    // The type should be the same, size_t and Py_ssize_t.

    return self->perm.size();
}

/** Gets the pre-image of a point.
 *
 * A new integer object will be built by this function.
 */

static PyObject* perm_item(Perm_object* self, Py_ssize_t i)
{
    if (i < 0 || i >= self->perm.size()) {
        PyErr_SetString(PyExc_IndexError, "Point outside permutation domain");
        return NULL;
    }

    return Py_BuildValue("n", self->perm >> i);
}

/** Gets the accompanied action of a Perm.
 */

static PyObject* perm_get_acc(Perm_object* self, void* closure)
{
    // Note that the accompanied action is a byte in simple perm.

    return Py_BuildValue("b", self->perm.acc());
}

/** Deallocates a perm instance.
 */

static void perm_dealloc(Perm_object* self)
{
    perm.perm.~Simple_perm();

    // For subclassing.
    Py_TYPE(self)->tp_free((PyObject*)self);
}

/** Forms the string representation of a Perm object.
 */

static PyObject* perm_repr(Perm_object* self)
{
    const Simple_perm& perm = self->perm;

    std::wstring repr("Perm(");

    size_t size = perm.size();

    if (size > 0) {
        for (size_t i = 0; i < size; ++i) {
            if (i == 0) {
                repr.append('[');
            } else {
                repr.append(", ");
            }
            repr.append(std::to_wstring(perm >> i));
        }
        repr.append(']');

        // Add the accompanied action only when we need.
        char acc = perm.acc();
        if (acc != 0) {
            repr.append(", ");
            repr.append(std::to_wstring(acc));
        }
    }

    // This is used for empty or non-empty permutation.
    repr.append(')');

    return PyUnicode_FromUnicode(repr.data(), repr.size());
}

/** Gets the hash of a perm.
 */

static Py_hash_t perm_hash(Perm_object* self)
{
    // Py_hash_t should be compatible with size_t.

    return self->perm.hash();
}

/** Creates a new Perm object.
 *
 * The actual work is delegated to the Python/Perm interface function.
 */

static PyObject* perm_new(PyTypeObject* type, PyObject* args, PyObject* kwargs)
{
    Perm_object* self;

    // Pay attention to subclassing.
    self = (Perm_object*)type->tp_alloc(type, 0);

    if (!self)
        return NULL;

    Simple_perm perm = get_perm_from_args(args, kwargs);

    if (perm.size() > 0) {
        new (&self->perm) Simple_perm(std::move(perm));
        return (PyObject*)self;
    } else {
        return NULL;
    }
}

//
// Class definition
// ----------------
//

/** Methods for Perm objects.
 */

static PyMethodDef perm_methods[] = {
    { "__getnewargs__", (PyCFunction)perm_getnewargs, METH_NOARGS,
        perm_getnewargs_doc },
    { NULL, NULL } /* sentinel */
};

/** Sequence operations for Perm objects.
 *
 * Here we only support size and pre-image query.
 */

// clang-format off
static PySequenceMethods perm_as_sequence = {
    (lenfunc)perm_length,                       /* sq_length */
    0,                                          /* sq_concat */
    0,                                          /* sq_repeat */
    (ssizeargfunc)perm_item,                    /* sq_item */
    0,                                          /* sq_slice */
    0,                                          /* sq_ass_item */
    0,                                          /* sq_ass_slice */
    0                                           /* sq_contains */
};
// clang-format on

/** Accessors for Perms.
 *
 * The accompanied action query is made here.
 */

// clang-format off
static PyGetSetDef perm_getsets[] = {
    { "acc", (getter)perm_get_acc, NULL, "The accompanied action.", NULL },
    { NULL }
};
// clang-format on

/** Perm type doc string.
  */

static char* perm_doc =
    R"__doc__(Permutation of points with accompanied action.

Permutations can be constructed from an iterable giving the pre-image of the
points and an optional integral value for the accompanied action.  The
accompanied action can be given positionally or by the keyword ``acc``, and it
will be manipulated according to the convention in libcanon.

Querying the length of a Perm object gives the size of the permutation domain,
while indexing it gives the pre-image of the given integral point.  The
accompanied action can be obtained by getting the attribute ``acc``.
Otherwise, this data type is mostly opaque.

)__doc__";

/** Type definition for Perm class.
 */

// clang-format off
static PyTypeObject perm_type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "drudge.canonpy.Perm",
    sizeof(Perm_object),
    0,
    (destructor) perm_dealloc,                  /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    (reprfunc) perm_repr,                       /* tp_repr */
    0,                                          /* tp_as_number */
    &perm_as_sequence,                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    (hashfunc) perm_hash,                       /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    0, /* In main. */                           /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
    perm_doc,                                   /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    perm_methods,                               /* tp_methods */
    0,                                          /* tp_members */
    perm_getsets,                               /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    perm_new,                                   /* tp_new */
    0,                                          /* tp_free */
};
// clang-format on

//
// Python module definition
// ========================
//

/** Docstring for the canonpy module.
 */

static const char* canonpy_docstring
    = R"__doc__(Canonpy, simple wrapper over libcanon for Python.

This wrapper of libcanon is directly targeted towards usage using drudge.
Here, we have a class `Perm`, which wraps over the `Simple_perm` class in
libcanon, another class `SimsTransv`, which wraps over the `Sims_trasv` class
for `Simple_perm`.  And we also have the function `canon_eldag` to canonicalize
an Eldag.

)__doc__";

/** Methods in the canonpy module.
 */

static PyMethodDef canonpy_methods[] = { { NULL, NULL, 0, NULL } };

/** Executes the initialization of the canonpy module.
 */

static int canopy_exec(PyObject* m)
{
    //
    // Add the class for Perm.
    //

    perm_type.tp_getattro = PyObject_GenericGetAttr;
    if (PyType_Ready(&perm_type) < 0)
        return NULL;
    Py_INCREF(&perm_type);
    PyModule_AddObject(m, "Perm", (PyObject*)&perm_type);

    return 0;
}

/** Slots for for canonpy module definition.
 */

static struct PyModuleDef_Slot canonpy_slots[] = {
    { Py_mod_exec, canonpy_exec }, { 0, NULL },
};

/** Canonpy module definition.
 */

// clang-format off

static struct PyModuleDef canonpy_module = {
    PyModuleDef_HEAD_INIT,
    "drudge.canonpy",
    canonpy_docstring,
    0, // m-size
    canonpy_methods,
    canonpy_slots,
    NULL, // Transverse
    NULL, // Clear
    NULL  // Free
};

// clang-format on

/** The published canonpy function.
 */

PyMODINIT_FUNC PyInit_canonpy(void)
{
    return PyModuleDef_Init(&canonpy_module);
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2004 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <iostream>

#include "base/misc.hh"
#include "dev/etherpkt.hh"
#include "sim/serialize.hh"

using namespace std;

void
PacketData::serialize(const string &base, ostream &os)
{
    paramOut(os, base + ".length", length);
    arrayParamOut(os, base + ".data", data, length);
}

void
PacketData::unserialize(const string &base, Checkpoint *cp,
                        const string &section)
{
    paramIn(cp, section, base + ".length", length);
    arrayParamIn(cp, section, base + ".data", data, length);
}
<commit_msg>Improve checkpointing of ethernet packets a bit.<commit_after>/*
 * Copyright (c) 2004 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <iostream>

#include "base/misc.hh"
#include "dev/etherpkt.hh"
#include "sim/serialize.hh"

using namespace std;

void
PacketData::serialize(const string &base, ostream &os)
{
    paramOut(os, base + ".length", length);
    arrayParamOut(os, base + ".data", data, length);
}

void
PacketData::unserialize(const string &base, Checkpoint *cp,
                        const string &section)
{
    paramIn(cp, section, base + ".length", length);
    if (length)
        arrayParamIn(cp, section, base + ".data", data, length);
}
<|endoftext|>


<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2015 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/base/filesystem.h"

#include <algorithm>

namespace xe {
namespace filesystem {

std::string CanonicalizePath(const std::string& original_path) {
  char path_sep(xe::kPathSeparator);
  std::string path(xe::fix_path_separators(original_path, path_sep));

  std::vector<std::string::size_type> path_breaks;

  std::string::size_type pos(path.find_first_of(path_sep));
  std::string::size_type pos_n(std::string::npos);

  while (pos != std::string::npos) {
    if ((pos_n = path.find_first_of(path_sep, pos + 1)) == std::string::npos) {
      pos_n = path.size();
    }

    auto diff(pos_n - pos);
    switch (diff) {
      case 0:
        pos_n = std::string::npos;
        break;
      case 1:
        // Duplicate separators.
        path.erase(pos, 1);
        pos_n -= 1;
        break;
      case 2:
        // Potential marker for current directory.
        if (path[pos + 1] == '.') {
          path.erase(pos, 2);
          pos_n -= 2;
        } else {
          path_breaks.push_back(pos);
        }
        break;
      case 3:
        // Potential marker for parent directory.
        if (path[pos + 1] == '.' && path[pos + 2] == '.') {
          if (path_breaks.empty()) {
            // Ensure we don't override the device name.
            std::string::size_type loc(path.find_first_of(':'));
            auto req(pos + 3);
            if (loc == std::string::npos || loc > req) {
              path.erase(0, req);
              pos_n -= req;
            } else {
              path.erase(loc + 1, req - (loc + 1));
              pos_n -= req - (loc + 1);
            }
          } else {
            auto last(path_breaks.back());
            auto last_diff((pos + 3) - last);
            path.erase(last, last_diff);
            pos_n = last;
            // Also remove path reference.
            path_breaks.erase(path_breaks.end() - 1);
          }
        } else {
          path_breaks.push_back(pos);
        }
        break;

      default:
        path_breaks.push_back(pos);
        break;
    }

    pos = pos_n;
  }

  // Remove trailing seperator.
  if (!path.empty() && path.back() == path_sep) {
    path.erase(path.size() - 1);
  }

  // Final sanity check for dead paths.
  if ((path.size() == 1 && (path[0] == '.' || path[0] == path_sep)) ||
      (path.size() == 2 && path[0] == '.' && path[1] == '.')) {
    return "";
  }

  return path;
}

bool CreateParentFolder(const std::wstring& path) {
  auto fixed_path = xe::fix_path_separators(path, xe::kWPathSeparator);
  auto base_path = xe::find_base_path(fixed_path, xe::kWPathSeparator);
  if (!PathExists(base_path)) {
    return CreateFolder(base_path);
  } else {
    return true;
  }
}

}  // namespace filesystem
}  // namespace xe
<commit_msg>[Base] Only attempt to create non-empty base paths in CreateParentFolder.<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2015 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/base/filesystem.h"

#include <algorithm>

namespace xe {
namespace filesystem {

std::string CanonicalizePath(const std::string& original_path) {
  char path_sep(xe::kPathSeparator);
  std::string path(xe::fix_path_separators(original_path, path_sep));

  std::vector<std::string::size_type> path_breaks;

  std::string::size_type pos(path.find_first_of(path_sep));
  std::string::size_type pos_n(std::string::npos);

  while (pos != std::string::npos) {
    if ((pos_n = path.find_first_of(path_sep, pos + 1)) == std::string::npos) {
      pos_n = path.size();
    }

    auto diff(pos_n - pos);
    switch (diff) {
      case 0:
        pos_n = std::string::npos;
        break;
      case 1:
        // Duplicate separators.
        path.erase(pos, 1);
        pos_n -= 1;
        break;
      case 2:
        // Potential marker for current directory.
        if (path[pos + 1] == '.') {
          path.erase(pos, 2);
          pos_n -= 2;
        } else {
          path_breaks.push_back(pos);
        }
        break;
      case 3:
        // Potential marker for parent directory.
        if (path[pos + 1] == '.' && path[pos + 2] == '.') {
          if (path_breaks.empty()) {
            // Ensure we don't override the device name.
            std::string::size_type loc(path.find_first_of(':'));
            auto req(pos + 3);
            if (loc == std::string::npos || loc > req) {
              path.erase(0, req);
              pos_n -= req;
            } else {
              path.erase(loc + 1, req - (loc + 1));
              pos_n -= req - (loc + 1);
            }
          } else {
            auto last(path_breaks.back());
            auto last_diff((pos + 3) - last);
            path.erase(last, last_diff);
            pos_n = last;
            // Also remove path reference.
            path_breaks.erase(path_breaks.end() - 1);
          }
        } else {
          path_breaks.push_back(pos);
        }
        break;

      default:
        path_breaks.push_back(pos);
        break;
    }

    pos = pos_n;
  }

  // Remove trailing seperator.
  if (!path.empty() && path.back() == path_sep) {
    path.erase(path.size() - 1);
  }

  // Final sanity check for dead paths.
  if ((path.size() == 1 && (path[0] == '.' || path[0] == path_sep)) ||
      (path.size() == 2 && path[0] == '.' && path[1] == '.')) {
    return "";
  }

  return path;
}

bool CreateParentFolder(const std::wstring& path) {
  auto fixed_path = xe::fix_path_separators(path, xe::kWPathSeparator);
  auto base_path = xe::find_base_path(fixed_path, xe::kWPathSeparator);
  if (base_path.size() && !PathExists(base_path)) {
    return CreateFolder(base_path);
  } else {
    return true;
  }
}

}  // namespace filesystem
}  // namespace xe
<|endoftext|>


<commit_before><commit_msg>fixed map::at out_of_range exception when bfd could not be opened<commit_after><|endoftext|>