<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (<EMAIL>)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#define _WIN32_WINNT 0x0501 /* WinXP, needed for DebugActiveProcessStop() */

#include <windows.h>
#include <shellapi.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <direct.h>

static FILE *qtcFd;
static wchar_t *sleepMsg;

enum RunMode { Run, Debug, Suspend };

/* Print some "press enter" message, wait for that, exit. */
static void doExit(int code)
{
    char buf[2];
    _putws(sleepMsg);
    fgets(buf, 2, stdin); /* Minimal size to make it wait */
    exit(code);
}

/* Print an error message for unexpected Windows system errors, wait, exit. */
static void systemError(const char *str)
{
    fprintf(stderr, str, GetLastError());
    doExit(3);
}

/* Send a message to the master. */
static void sendMsg(const char *msg, int num)
{
    int pidStrLen;
    char pidStr[64];

    pidStrLen = sprintf(pidStr, msg, num);
    if (fwrite(pidStr, pidStrLen, 1, qtcFd) != 1 || fflush(qtcFd)) {
        fprintf(stderr, "Cannot write to creator comm socket: %s\n",
                strerror(errno));
        doExit(3);
    }
}

/* Ignore the first ctrl-c/break within a second. */
static BOOL WINAPI ctrlHandler(DWORD dwCtrlType)
{
    static ULARGE_INTEGER lastTime;
    ULARGE_INTEGER thisTime;
    SYSTEMTIME sysTime;
    FILETIME fileTime;

    if (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT) {
        GetSystemTime(&sysTime);
        SystemTimeToFileTime(&sysTime, &fileTime);
        thisTime.LowPart = fileTime.dwLowDateTime;
        thisTime.HighPart = fileTime.dwHighDateTime;
        if (lastTime.QuadPart + 10000000 < thisTime.QuadPart) {
            lastTime.QuadPart = thisTime.QuadPart;
            return TRUE;
        }
    }
    return FALSE;
}

enum {
    ArgCmd = 0,
    ArgAction,
    ArgSocket,
    ArgDir,
    ArgEnv,
    ArgCmdLine,
    ArgMsg,
    ArgCount
};

/* syntax: $0 {"run"|"debug"} <pid-socket> <workdir> <env-file> <cmdline> <continuation-msg> */
/* exit codes: 0 = ok, 1 = invocation error, 3 = internal error */
int main()
{
    int argc;
    int creationFlags;
    wchar_t **argv;
    wchar_t *env = 0;
    STARTUPINFOW si;
    PROCESS_INFORMATION pi;
    DEBUG_EVENT dbev;
    enum RunMode mode = Run;

    argv = CommandLineToArgvW(GetCommandLine(), &argc);

    if (argc != ArgCount) {
        fprintf(stderr, "This is an internal helper of Qt Creator. Do not run it manually.\n");
        return 1;
    }
    sleepMsg = argv[ArgMsg];

    /* Connect to the master, i.e. Creator. */
    if (!(qtcFd = _wfopen(argv[ArgSocket], L"w"))) {
        fprintf(stderr, "Cannot connect creator comm pipe %S: %s\n",
                argv[ArgSocket], strerror(errno));
        doExit(1);
    }

    if (*argv[ArgDir] && !SetCurrentDirectoryW(argv[ArgDir])) {
        /* Only expected error: no such file or direcotry */
        sendMsg("err:chdir %d\n", GetLastError());
        return 1;
    }

    if (*argv[ArgEnv]) {
        FILE *envFd;
        long size;
        if (!(envFd = _wfopen(argv[ArgEnv], L"r"))) {
            fprintf(stderr, "Cannot read creator env file %S: %s\n",
                    argv[ArgEnv], strerror(errno));
            doExit(1);
        }
        fseek(envFd, 0, SEEK_END);
        size = ftell(envFd);
        rewind(envFd);
        env = malloc(size + sizeof(wchar_t));
        env[size] = 0;
        if (fread(env, 1, size, envFd) != size) {<commit_msg>Debugger: Fix crash in console stub on Windows<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (<EMAIL>)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#define _WIN32_WINNT 0x0501 /* WinXP, needed for DebugActiveProcessStop() */

#include <windows.h>
#include <shellapi.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <direct.h>

static FILE *qtcFd;
static wchar_t *sleepMsg;

enum RunMode { Run, Debug, Suspend };

/* Print some "press enter" message, wait for that, exit. */
static void doExit(int code)
{
    char buf[2];
    _putws(sleepMsg);
    fgets(buf, 2, stdin); /* Minimal size to make it wait */
    exit(code);
}

/* Print an error message for unexpected Windows system errors, wait, exit. */
static void systemError(const char *str)
{
    fprintf(stderr, str, GetLastError());
    doExit(3);
}

/* Send a message to the master. */
static void sendMsg(const char *msg, int num)
{
    int pidStrLen;
    char pidStr[64];

    pidStrLen = sprintf(pidStr, msg, num);
    if (fwrite(pidStr, pidStrLen, 1, qtcFd) != 1 || fflush(qtcFd)) {
        fprintf(stderr, "Cannot write to creator comm socket: %s\n",
                strerror(errno));
        doExit(3);
    }
}

/* Ignore the first ctrl-c/break within a second. */
static BOOL WINAPI ctrlHandler(DWORD dwCtrlType)
{
    static ULARGE_INTEGER lastTime;
    ULARGE_INTEGER thisTime;
    SYSTEMTIME sysTime;
    FILETIME fileTime;

    if (dwCtrlType == CTRL_C_EVENT || dwCtrlType == CTRL_BREAK_EVENT) {
        GetSystemTime(&sysTime);
        SystemTimeToFileTime(&sysTime, &fileTime);
        thisTime.LowPart = fileTime.dwLowDateTime;
        thisTime.HighPart = fileTime.dwHighDateTime;
        if (lastTime.QuadPart + 10000000 < thisTime.QuadPart) {
            lastTime.QuadPart = thisTime.QuadPart;
            return TRUE;
        }
    }
    return FALSE;
}

enum {
    ArgCmd = 0,
    ArgAction,
    ArgSocket,
    ArgDir,
    ArgEnv,
    ArgCmdLine,
    ArgMsg,
    ArgCount
};

/* syntax: $0 {"run"|"debug"} <pid-socket> <workdir> <env-file> <cmdline> <continuation-msg> */
/* exit codes: 0 = ok, 1 = invocation error, 3 = internal error */
int main()
{
    int argc;
    int creationFlags;
    wchar_t **argv;
    wchar_t *env = 0;
    STARTUPINFOW si;
    PROCESS_INFORMATION pi;
    DEBUG_EVENT dbev;
    enum RunMode mode = Run;

    argv = CommandLineToArgvW(GetCommandLine(), &argc);

    if (argc != ArgCount) {
        fprintf(stderr, "This is an internal helper of Qt Creator. Do not run it manually.\n");
        return 1;
    }
    sleepMsg = argv[ArgMsg];

    /* Connect to the master, i.e. Creator. */
    if (!(qtcFd = _wfopen(argv[ArgSocket], L"w"))) {
        fprintf(stderr, "Cannot connect creator comm pipe %S: %s\n",
                argv[ArgSocket], strerror(errno));
        doExit(1);
    }

    if (*argv[ArgDir] && !SetCurrentDirectoryW(argv[ArgDir])) {
        /* Only expected error: no such file or direcotry */
        sendMsg("err:chdir %d\n", GetLastError());
        return 1;
    }

    if (*argv[ArgEnv]) {
        FILE *envFd;
        long size;
        if (!(envFd = _wfopen(argv[ArgEnv], L"r"))) {
            fprintf(stderr, "Cannot read creator env file %S: %s\n",
                    argv[ArgEnv], strerror(errno));
            doExit(1);
        }
        fseek(envFd, 0, SEEK_END);
        size = ftell(envFd);
        rewind(envFd);
        env = malloc(size);
        if (fread(env, 1, size, envFd) != size) {
{'fraction_non_alphanumeric': 0.14984709480122324, 'fraction_numerical': 0.009938837920489297, 'mean_word_length': 3.0788418708240535, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3290681', 'n_tokens_mistral': 2952, 'n_tokens_neox': 2799, 'n_words': 904}