<commit_before>// Copyright (c) 2015, Matthew Malensek.
// Distributed under the BSD 2-Clause License (see LICENSE.txt for details)

#include "3RVX.h"

#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "Wtsapi32.lib")

#include <Windows.h>
#include <ctime>
#include <gdiplus.h>
#include <iostream>
#include <Wtsapi32.h>

#include "DisplayManager.h"
#include "HotkeyManager.h"
#include "Logger.h"
#include "OSD/BrightnessOSD.h"
#include "OSD/EjectOSD.h"
#include "OSD/VolumeOSD.h"
#include "Settings.h"
#include "Skin/SkinManager.h"

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR lpCmdLine, _In_ int nShowCmd) {

    Logger::Start();

    QCLOG(L"  _____ ______     ____  _______ ");
    QCLOG(L" |___ /|  _ \\ \\   / /\\ \\/ /___ / ");
    QCLOG(L"   |_ \\| |_) \\ \\ / /  \\  /  |_ \\ ");
    QCLOG(L"  ___) |  _ < \\ V /   /  \\ ___) |");
    QCLOG(L" |____/|_| \\_\\ \\_/   /_/\\_\\____/ ");
    QCLOG(L"");

    QCLOG(L"Starting up...");

    HANDLE mutex;
    mutex = CreateMutex(NULL, FALSE, L"Local\\3RVX");
    if (GetLastError() == ERROR_ALREADY_EXISTS) {
        if (mutex) {
            ReleaseMutex(mutex);
        }

        CLOG(L"A previous instance of the program is already running.\n"
            L"Requesting Settings dialog.");
        _3RVX::Message(_3RVX::MSG_SETTINGS, NULL);

#if defined(ENABLE_3RVX_LOG) && (defined(ENABLE_3RVX_LOGTOFILE) == FALSE)
        CLOG(L"Press [enter] to terminate");
        std::cin.get();
#endif

        return EXIT_SUCCESS;
    }

    CLOG(L"App directory: %s", Settings::AppDir().c_str());

    using namespace Gdiplus;
    ULONG_PTR gdiplusToken;
    GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    _3RVX mainWnd(hInstance);

    HRESULT hr = CoInitializeEx(NULL,
        COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    if (hr != S_OK) {
        CLOG(L"Failed to initialize the COM library.");
        return EXIT_FAILURE;
    }

    /* Tell the program to initialize */
    PostMessage(mainWnd.Handle(), _3RVX::WM_3RVX_CTRL, _3RVX::MSG_LOAD, NULL);

    /* Register for session change notifications */
    WTSRegisterSessionNotification(mainWnd.Handle(), NOTIFY_FOR_THIS_SESSION);

    /* Start the event loop */
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    GdiplusShutdown(gdiplusToken);
    CoUninitialize();

    Logger::Stop();

    return (int) msg.wParam;
}

_3RVX::_3RVX(HINSTANCE hInstance) :
Window(_3RVX::CLASS_3RVX, _3RVX::CLASS_3RVX, hInstance) {
}

void _3RVX::Initialize() {
    CLOG(L"Initializing...");

    delete _vOSD;
    delete _eOSD;
    delete _bOSD;

    Settings *settings = Settings::Instance();
    settings->Load();

    KillTimer(Window::Handle(), TIMER_FIRSTUPDATE);
    KillTimer(Window::Handle(), TIMER_UPDATE);
    if (settings->AutomaticUpdates()) {
        SetTimer(
            Window::Handle(),
            TIMER_FIRSTUPDATE,
            FIRSTUPDATE_INTERVAL,
            NULL);
    }

    SkinManager::Instance()->LoadSkin(settings->SkinXML());

    /* TODO: Detect monitor changes, update this map, and reload/reorg OSDs */
    DisplayManager::UpdateMonitorMap();

    /* OSDs */
    _eOSD = new EjectOSD();
    _vOSD = new VolumeOSD();
    _bOSD = new BrightnessOSD();

    /* Hotkey setup */
    if (_hkManager != NULL) {
        _hkManager->Shutdown();
    }
    _hkManager = HotkeyManager::Instance(Handle());

    _hotkeys = Settings::Instance()->Hotkeys();
    for (auto it = _hotkeys.begin(); it != _hotkeys.end(); ++it) {
        /* Enable arg caching */
        it->second.EnableArgCache();

        int combination = it->first;
        _hkManager->Register(combination);
    }

}

void _3RVX::ProcessHotkeys(HotkeyInfo &hki) {
    switch (hki.action) {
    case HotkeyInfo::IncreaseVolume:
    case HotkeyInfo::DecreaseVolume:
    case HotkeyInfo::SetVolume:
    case HotkeyInfo::Mute:
    case HotkeyInfo::VolumeSlider:
        if (_vOSD) {
            _vOSD->ProcessHotkeys(hki);
        }
        break;

    case HotkeyInfo::EjectDrive:
    case HotkeyInfo::EjectLastDisk:
        if (_eOSD) {
            _eOSD->ProcessHotkeys(hki);
        }
        break;

    case HotkeyInfo::IncreaseBrightness:
    case HotkeyInfo::DecreaseBrightness:
    case HotkeyInfo::SetBrightness:
        if (_bOSD) {
            _bOSD->ProcessHotkeys(hki);
        }
        break;

    case HotkeyInfo::MediaKey:
    case HotkeyInfo::VirtualKey:
        _kbHotkeyProcessor.ProcessHotkeys(hki);
        break;

    case HotkeyInfo::Run:
        if (hki.HasArgs()) {
            ShellExecute(NULL, L"open", hki.args[0].c_str(),
                NULL, NULL, SW_SHOWNORMAL);
        }
        break;

    case HotkeyInfo::DisableOSD:
        ToggleOSDs();
        break;

    case HotkeyInfo::Settings:
        ShellExecute(NULL, L"open", Settings::SettingsApp().c_str(),
            NULL, NULL, SW_SHOWNORMAL);
        break;

    case HotkeyInfo::Exit:
        SendMessage(Handle(), WM_CLOSE, NULL, NULL);
        break;
    }
}

void _3RVX::ToggleOSDs() {
    _eOSD->Enabled(!(_eOSD->Enabled()));
    _vOSD->Enabled(!(_vOSD->Enabled()));
    _bOSD->Enabled(!(_bOSD->Enabled()));
}

LRESULT _3RVX::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
    case WM_HOTKEY: {
        CLOG(L"Hotkey: %d", (int) wParam);
        HotkeyInfo hki = _hotkeys[(int) wParam];
        ProcessHotkeys(hki);
        break;
    }

    case WM_WTSSESSION_CHANGE: {
        CLOG(L"Detected session change");
        break;
    }

    case WM_CLOSE: {
        CLOG(L"Shutting down");
        HotkeyManager::Instance()->Shutdown();
        _vOSD->HideIcon();
        break;
    }

    case WM_DESTROY: {
        PostQuitMessage(0);
        break;
    }

    case WM_TIMER:
        if (wParam == TIMER_FIRSTUPDATE || wParam == TIMER_UPDATE) {
            CLOG(L"Received updater timer notification");
            Settings *settings = Settings::Instance();
            long long checkTime = settings->LastUpdateCheck();
            if ((std::time(nullptr) - checkTime) > (UPDATE_INTERVAL / 1000)) {
                /* Enough time has elapsed since the last update check */
                std::wstring settingsApp = Settings::SettingsApp();
                CLOG(L"Launching update task: %s %s",
                    settingsApp.c_str(), L"-update");
                ShellExecute(NULL, L"open",
                    Settings::SettingsApp().c_str(), L"-update", NULL, SW_HIDE);
            }

            if (wParam == TIMER_FIRSTUPDATE) {
                CLOG(L"Starting long-term update timer");
                /* If this was the first update check (30 min after launch),
                 * then kill the first update timer and start the main timer
                 * (checks on 24-hour intervals) */
                KillTimer(Window::Handle(), TIMER_FIRSTUPDATE);
                SetTimer(Window::Handle(), TIMER_UPDATE,
                    UPDATE_INTERVAL, NULL);
            }
        }
        break;
    }

    if (message == _3RVX::WM_3RVX_CTRL) {
        switch (wParam) {
        case _3RVX::MSG_LOAD:
            Initialize();
            break;

        case _3RVX::MSG_SETTINGS:
            Settings::LaunchSettingsApp();
            break;

        case _3RVX::MSG_HIDEOSD:
            int except = (OSDType) lParam;
            switch (except) {
            case Volume:
                if (_eOSD) { _eOSD->Hide(); }
                if (_bOSD) { _bOSD->Hide(); }
                break;

            case Eject:
                if (_vOSD) { _vOSD->Hide(); }
                if (_bOSD) { _bOSD->Hide(); }
                break;

            case Brightness:
                if (_vOSD) { _vOSD->Hide(); }
                if (_eOSD) { _eOSD->Hide(); }
            }

            break;
        }
    }

    return Window::WndProc(hWnd, message, wParam, lParam);
}
<commit_msg>Remove TODO re: display changes<commit_after>// Copyright (c) 2015, Matthew Malensek.
// Distributed under the BSD 2-Clause License (see LICENSE.txt for details)

#include "3RVX.h"

#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "Wtsapi32.lib")

#include <Windows.h>
#include <ctime>
#include <gdiplus.h>
#include <iostream>
#include <Wtsapi32.h>

#include "DisplayManager.h"
#include "HotkeyManager.h"
#include "Logger.h"
#include "OSD/BrightnessOSD.h"
#include "OSD/EjectOSD.h"
#include "OSD/VolumeOSD.h"
#include "Settings.h"
#include "Skin/SkinManager.h"

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR lpCmdLine, _In_ int nShowCmd) {

    Logger::Start();

    QCLOG(L"  _____ ______     ____  _______ ");
    QCLOG(L" |___ /|  _ \\ \\   / /\\ \\/ /___ / ");
    QCLOG(L"   |_ \\| |_) \\ \\ / /  \\  /  |_ \\ ");
    QCLOG(L"  ___) |  _ < \\ V /   /  \\ ___) |");
    QCLOG(L" |____/|_| \\_\\ \\_/   /_/\\_\\____/ ");
    QCLOG(L"");

    QCLOG(L"Starting up...");

    HANDLE mutex;
    mutex = CreateMutex(NULL, FALSE, L"Local\\3RVX");
    if (GetLastError() == ERROR_ALREADY_EXISTS) {
        if (mutex) {
            ReleaseMutex(mutex);
        }

        CLOG(L"A previous instance of the program is already running.\n"
            L"Requesting Settings dialog.");
        _3RVX::Message(_3RVX::MSG_SETTINGS, NULL);

#if defined(ENABLE_3RVX_LOG) && (defined(ENABLE_3RVX_LOGTOFILE) == FALSE)
        CLOG(L"Press [enter] to terminate");
        std::cin.get();
#endif

        return EXIT_SUCCESS;
    }

    CLOG(L"App directory: %s", Settings::AppDir().c_str());

    using namespace Gdiplus;
    ULONG_PTR gdiplusToken;
    GdiplusStartupInput gdiplusStartupInput;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    _3RVX mainWnd(hInstance);

    HRESULT hr = CoInitializeEx(NULL,
        COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    if (hr != S_OK) {
        CLOG(L"Failed to initialize the COM library.");
        return EXIT_FAILURE;
    }

    /* Tell the program to initialize */
    PostMessage(mainWnd.Handle(), _3RVX::WM_3RVX_CTRL, _3RVX::MSG_LOAD, NULL);

    /* Register for session change notifications */
    WTSRegisterSessionNotification(mainWnd.Handle(), NOTIFY_FOR_THIS_SESSION);

    /* Start the event loop */
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    GdiplusShutdown(gdiplusToken);
    CoUninitialize();

    Logger::Stop();

    return (int) msg.wParam;
}

_3RVX::_3RVX(HINSTANCE hInstance) :
Window(_3RVX::CLASS_3RVX, _3RVX::CLASS_3RVX, hInstance) {
}

void _3RVX::Initialize() {
    CLOG(L"Initializing...");

    delete _vOSD;
    delete _eOSD;
    delete _bOSD;

    Settings *settings = Settings::Instance();
    settings->Load();

    KillTimer(Window::Handle(), TIMER_FIRSTUPDATE);
    KillTimer(Window::Handle(), TIMER_UPDATE);
    if (settings->AutomaticUpdates()) {
        SetTimer(
            Window::Handle(),
            TIMER_FIRSTUPDATE,
            FIRSTUPDATE_INTERVAL,
            NULL);
    }

    SkinManager::Instance()->LoadSkin(settings->SkinXML());

    DisplayManager::UpdateMonitorMap();

    /* OSDs */
    _eOSD = new EjectOSD();
    _vOSD = new VolumeOSD();
    _bOSD = new BrightnessOSD();

    /* Hotkey setup */
    if (_hkManager != NULL) {
        _hkManager->Shutdown();
    }
    _hkManager = HotkeyManager::Instance(Handle());

    _hotkeys = Settings::Instance()->Hotkeys();
    for (auto it = _hotkeys.begin(); it != _hotkeys.end(); ++it) {
        /* Enable arg caching */
        it->second.EnableArgCache();

        int combination = it->first;
        _hkManager->Register(combination);
    }

}

void _3RVX::ProcessHotkeys(HotkeyInfo &hki) {
    switch (hki.action) {
    case HotkeyInfo::IncreaseVolume:
    case HotkeyInfo::DecreaseVolume:
    case HotkeyInfo::SetVolume:
    case HotkeyInfo::Mute:
    case HotkeyInfo::VolumeSlider:
        if (_vOSD) {
            _vOSD->ProcessHotkeys(hki);
        }
        break;

    case HotkeyInfo::EjectDrive:
    case HotkeyInfo::EjectLastDisk:
        if (_eOSD) {
            _eOSD->ProcessHotkeys(hki);
        }
        break;

    case HotkeyInfo::IncreaseBrightness:
    case HotkeyInfo::DecreaseBrightness:
    case HotkeyInfo::SetBrightness:
        if (_bOSD) {
            _bOSD->ProcessHotkeys(hki);
        }
        break;

    case HotkeyInfo::MediaKey:
    case HotkeyInfo::VirtualKey:
        _kbHotkeyProcessor.ProcessHotkeys(hki);
        break;

    case HotkeyInfo::Run:
        if (hki.HasArgs()) {
            ShellExecute(NULL, L"open", hki.args[0].c_str(),
                NULL, NULL, SW_SHOWNORMAL);
        }
        break;

    case HotkeyInfo::DisableOSD:
        ToggleOSDs();
        break;

    case HotkeyInfo::Settings:
        ShellExecute(NULL, L"open", Settings::SettingsApp().c_str(),
            NULL, NULL, SW_SHOWNORMAL);
        break;

    case HotkeyInfo::Exit:
        SendMessage(Handle(), WM_CLOSE, NULL, NULL);
        break;
    }
}

void _3RVX::ToggleOSDs() {
    _eOSD->Enabled(!(_eOSD->Enabled()));
    _vOSD->Enabled(!(_vOSD->Enabled()));
    _bOSD->Enabled(!(_bOSD->Enabled()));
}

LRESULT _3RVX::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
    case WM_HOTKEY: {
        CLOG(L"Hotkey: %d", (int) wParam);
        HotkeyInfo hki = _hotkeys[(int) wParam];
        ProcessHotkeys(hki);
        break;
    }

    case WM_WTSSESSION_CHANGE: {
        CLOG(L"Detected session change");
        break;
    }

    case WM_CLOSE: {
        CLOG(L"Shutting down");
        HotkeyManager::Instance()->Shutdown();
        _vOSD->HideIcon();
        break;
    }

    case WM_DESTROY: {
        PostQuitMessage(0);
        break;
    }

    case WM_TIMER:
        if (wParam == TIMER_FIRSTUPDATE || wParam == TIMER_UPDATE) {
            CLOG(L"Received updater timer notification");
            Settings *settings = Settings::Instance();
            long long checkTime = settings->LastUpdateCheck();
            if ((std::time(nullptr) - checkTime) > (UPDATE_INTERVAL / 1000)) {
                /* Enough time has elapsed since the last update check */
                std::wstring settingsApp = Settings::SettingsApp();
                CLOG(L"Launching update task: %s %s",
                    settingsApp.c_str(), L"-update");
                ShellExecute(NULL, L"open",
                    Settings::SettingsApp().c_str(), L"-update", NULL, SW_HIDE);
            }

            if (wParam == TIMER_FIRSTUPDATE) {
                CLOG(L"Starting long-term update timer");
                /* If this was the first update check (30 min after launch),
                 * then kill the first update timer and start the main timer
                 * (checks on 24-hour intervals) */
                KillTimer(Window::Handle(), TIMER_FIRSTUPDATE);
                SetTimer(Window::Handle(), TIMER_UPDATE,
                    UPDATE_INTERVAL, NULL);
            }
        }
        break;
    }

    if (message == _3RVX::WM_3RVX_CTRL) {
        switch (wParam) {
        case _3RVX::MSG_LOAD:
            Initialize();
            break;

        case _3RVX::MSG_SETTINGS:
            Settings::LaunchSettingsApp();
            break;

        case _3RVX::MSG_HIDEOSD:
            int except = (OSDType) lParam;
            switch (except) {
            case Volume:
                if (_eOSD) { _eOSD->Hide(); }
                if (_bOSD) { _bOSD->Hide(); }
                break;

            case Eject:
                if (_vOSD) { _vOSD->Hide(); }
                if (_bOSD) { _bOSD->Hide(); }
                break;

            case Brightness:
                if (_vOSD) { _vOSD->Hide(); }
                if (_eOSD) { _eOSD->Hide(); }
            }

            break;
        }
    }

    return Window::WndProc(hWnd, message, wParam, lParam);
}
<|endoftext|>


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

#include "webkit/glue/plugins/pepper_file_chooser.h"

#include <string>
#include <vector>

#include "base/logging.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCString.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileChooserCompletion.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileChooserParams.h"
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
#include "third_party/WebKit/WebKit/chromium/public/WebVector.h"
#include "webkit/glue/plugins/pepper_common.h"
#include "webkit/glue/plugins/pepper_file_ref.h"
#include "webkit/glue/plugins/pepper_plugin_delegate.h"
#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_resource_tracker.h"
#include "webkit/glue/webkit_glue.h"

using WebKit::WebCString;
using WebKit::WebFileChooserCompletion;
using WebKit::WebFileChooserParams;
using WebKit::WebString;
using WebKit::WebVector;

namespace pepper {

namespace {

PP_Resource Create(PP_Instance instance_id,
                   const PP_FileChooserOptions_Dev* options) {
  PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
  if (!instance)
    return 0;

  FileChooser* chooser = new FileChooser(instance, options);
  return chooser->GetReference();
}

PP_Bool IsFileChooser(PP_Resource resource) {
  return BoolToPPBool(!!Resource::GetAs<FileChooser>(resource));
}

int32_t Show(PP_Resource chooser_id, PP_CompletionCallback callback) {
  scoped_refptr<FileChooser> chooser(
      Resource::GetAs<FileChooser>(chooser_id));
  if (!chooser)
    return PP_ERROR_BADRESOURCE;

  return chooser->Show(callback);
}

PP_Resource GetNextChosenFile(PP_Resource chooser_id) {
  scoped_refptr<FileChooser> chooser(
      Resource::GetAs<FileChooser>(chooser_id));
  if (!chooser)
    return 0;

  scoped_refptr<FileRef> file_ref(chooser->GetNextChosenFile());
  if (!file_ref)
    return 0;

  return file_ref->GetReference();
}

const PPB_FileChooser_Dev ppb_filechooser = {
  &Create,
  &IsFileChooser,
  &Show,
  &GetNextChosenFile
};

class FileChooserCompletionImpl : public WebFileChooserCompletion {
 public:
  FileChooserCompletionImpl(pepper::FileChooser* file_chooser)
      : file_chooser_(file_chooser) {
    DCHECK(file_chooser_);
  }

  virtual ~FileChooserCompletionImpl() {}

  virtual void didChooseFile(const WebVector<WebString>& file_names) {
    std::vector<std::string> files;
    for (size_t i = 0; i < file_names.size(); i++)
      files.push_back(file_names[i].utf8().data());

    file_chooser_->StoreChosenFiles(files);
  }

 private:
  FileChooser* file_chooser_;
};

}  // namespace

FileChooser::FileChooser(PluginInstance* instance,
                         const PP_FileChooserOptions_Dev* options)
    : Resource(instance->module()),
      delegate_(instance->delegate()),
      mode_(options->mode),
      accept_mime_types_(options->accept_mime_types),
      completion_callback_() {
}

FileChooser::~FileChooser() {
}

// static
const PPB_FileChooser_Dev* FileChooser::GetInterface() {
  return &ppb_filechooser;
}

void FileChooser::StoreChosenFiles(const std::vector<std::string>& files) {
  next_chosen_file_index_ = 0;
  std::vector<std::string>::const_iterator end_it = files.end();
  for (std::vector<std::string>::const_iterator it = files.begin();
       it != end_it; it++) {
    chosen_files_.push_back(make_scoped_refptr(
        new FileRef(module(), FilePath().AppendASCII(*it))));
  }

  if (!completion_callback_.func)
    return;

  PP_CompletionCallback callback = {0};
  std::swap(callback, completion_callback_);
  PP_RunCompletionCallback(&callback, 0);
}

int32_t FileChooser::Show(PP_CompletionCallback callback) {
  DCHECK((mode_ == PP_FILECHOOSERMODE_OPEN) ||
         (mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE));
  DCHECK(!completion_callback_.func);
  completion_callback_ = callback;

  WebFileChooserParams params;
  params.multiSelect = (mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE);
  params.acceptTypes = WebString::fromUTF8(accept_mime_types_);
  params.directory = false;

  return delegate_->RunFileChooser(
      params, new FileChooserCompletionImpl(this));
}

scoped_refptr<FileRef> FileChooser::GetNextChosenFile() {
  if (next_chosen_file_index_ >= chosen_files_.size())
    return NULL;

  return chosen_files_[next_chosen_file_index_++];
}

}  // namespace pepper
<commit_msg>Make sure we create a FileChooser instance only if the selection mode is "single file" or "multiple files".<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "webkit/glue/plugins/pepper_file_chooser.h"

#include <string>
#include <vector>

#include "base/logging.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCString.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileChooserCompletion.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileChooserParams.h"
#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
#include "third_party/WebKit/WebKit/chromium/public/WebVector.h"
#include "webkit/glue/plugins/pepper_common.h"
#include "webkit/glue/plugins/pepper_file_ref.h"
#include "webkit/glue/plugins/pepper_plugin_delegate.h"
#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_resource_tracker.h"
#include "webkit/glue/webkit_glue.h"

using WebKit::WebCString;
using WebKit::WebFileChooserCompletion;
using WebKit::WebFileChooserParams;
using WebKit::WebString;
using WebKit::WebVector;

namespace pepper {

namespace {

PP_Resource Create(PP_Instance instance_id,
                   const PP_FileChooserOptions_Dev* options) {
  PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
  if (!instance)
    return 0;

  if ((options->mode != PP_FILECHOOSERMODE_OPEN) &&
      (options->mode != PP_FILECHOOSERMODE_OPENMULTIPLE))
    return 0;

  FileChooser* chooser = new FileChooser(instance, options);
  return chooser->GetReference();
}

PP_Bool IsFileChooser(PP_Resource resource) {
  return BoolToPPBool(!!Resource::GetAs<FileChooser>(resource));
}

int32_t Show(PP_Resource chooser_id, PP_CompletionCallback callback) {
  scoped_refptr<FileChooser> chooser(
      Resource::GetAs<FileChooser>(chooser_id));
  if (!chooser)
    return PP_ERROR_BADRESOURCE;

  return chooser->Show(callback);
}

PP_Resource GetNextChosenFile(PP_Resource chooser_id) {
  scoped_refptr<FileChooser> chooser(
      Resource::GetAs<FileChooser>(chooser_id));
  if (!chooser)
    return 0;

  scoped_refptr<FileRef> file_ref(chooser->GetNextChosenFile());
  if (!file_ref)
    return 0;

  return file_ref->GetReference();
}

const PPB_FileChooser_Dev ppb_filechooser = {
  &Create,
  &IsFileChooser,
  &Show,
  &GetNextChosenFile
};

class FileChooserCompletionImpl : public WebFileChooserCompletion {
 public:
  FileChooserCompletionImpl(pepper::FileChooser* file_chooser)
      : file_chooser_(file_chooser) {
    DCHECK(file_chooser_);
  }

  virtual ~FileChooserCompletionImpl() {}

  virtual void didChooseFile(const WebVector<WebString>& file_names) {
    std::vector<std::string> files;
    for (size_t i = 0; i < file_names.size(); i++)
      files.push_back(file_names[i].utf8().data());

    file_chooser_->StoreChosenFiles(files);
  }

 private:
  FileChooser* file_chooser_;
};

}  // namespace

FileChooser::FileChooser(PluginInstance* instance,
                         const PP_FileChooserOptions_Dev* options)
    : Resource(instance->module()),
      delegate_(instance->delegate()),
      mode_(options->mode),
      accept_mime_types_(options->accept_mime_types),
      completion_callback_() {
}

FileChooser::~FileChooser() {
}

// static
const PPB_FileChooser_Dev* FileChooser::GetInterface() {
  return &ppb_filechooser;
}

void FileChooser::StoreChosenFiles(const std::vector<std::string>& files) {
  next_chosen_file_index_ = 0;
  std::vector<std::string>::const_iterator end_it = files.end();
  for (std::vector<std::string>::const_iterator it = files.begin();
       it != end_it; it++) {
    chosen_files_.push_back(make_scoped_refptr(
        new FileRef(module(), FilePath().AppendASCII(*it))));
  }

  if (!completion_callback_.func)
    return;

  PP_CompletionCallback callback = {0};
  std::swap(callback, completion_callback_);
  PP_RunCompletionCallback(&callback, 0);
}

int32_t FileChooser::Show(PP_CompletionCallback callback) {
  DCHECK((mode_ == PP_FILECHOOSERMODE_OPEN) ||
         (mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE));
  DCHECK(!completion_callback_.func);
  completion_callback_ = callback;

  WebFileChooserParams params;
  params.multiSelect = (mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE);
  params.acceptTypes = WebString::fromUTF8(accept_mime_types_);
  params.directory = false;

  return delegate_->RunFileChooser(
      params, new FileChooserCompletionImpl(this));
}

scoped_refptr<FileRef> FileChooser::GetNextChosenFile() {
  if (next_chosen_file_index_ >= chosen_files_.size())
    return NULL;

  return chosen_files_[next_chosen_file_index_++];
}

}  // namespace pepper
<|endoftext|>


<commit_before>#include "cspersonservice.h"

#include<iostream>
using namespace std;
CSPersonService::CSPersonService()
{
    _fileKeeper = _data.readFromFile();
    searchByName("Gol");
}

void CSPersonService::newPerson(string name, string gender, int birthYear, int deathYear, string comment)
{
    CSPerson newP = CSPerson (name, gender, birthYear, deathYear, comment);
}

int CSPersonService::getIndexOfValueByName(const string name)
{
    for(size_t i = 0; i < _fileKeeper.size(); i++)
    {
        if(name == _fileKeeper[i].getName())
        {
            return i;
        }
    }
    return -1;
}
void CSPersonService::removeNodeFromList(const int index)
{
    _fileKeeper.erase(_fileKeeper.begin() + index +1); //+1 = off by one
    _data.writeToFile(_fileKeeper);
}

vector<CSPerson> CSPersonService::searchByName(const string searchString)
{
    vector<CSPerson> tempVector;
    for(size_t i = 0; i < _fileKeeper.size(); i++)
    {
        if(checkIfStringSameIgnoreUpper(_fileKeeper[i].getName(), searchString))
        {
            tempVector.push_back(_fileKeeper[i]);
        }
    }
    return tempVector;
}

bool CSPersonService::checkIfStringSameIgnoreUpper(string orginalString, string searchFor)
{
    std::transform(orginalString.begin(), orginalString.end(),orginalString.begin(), ::tolower);
    std::transform(searchFor.begin(), searchFor.end(),searchFor.begin(), ::tolower);
    if(orginalString.find(searchFor) != string::npos)
    {
        return true;
    }
    else
    {
        return false;
    }
}
<commit_msg>Comments added the search feature<commit_after>#include "cspersonservice.h"

#include<iostream>
using namespace std;
CSPersonService::CSPersonService()
{
    _fileKeeper = _data.readFromFile();
    searchByName("Gol");
}

void CSPersonService::newPerson(string name, string gender, int birthYear, int deathYear, string comment)
{
    CSPerson newP = CSPerson (name, gender, birthYear, deathYear, comment);
}

int CSPersonService::getIndexOfValueByName(const string name)
{
    for(size_t i = 0; i < _fileKeeper.size(); i++)
    {
        if(name == _fileKeeper[i].getName())
        {
            return i;
        }
    }
    return -1;
}
void CSPersonService::removeNodeFromList(const int index)
{
    _fileKeeper.erase(_fileKeeper.begin() + index +1); //+1 = off by one
    _data.writeToFile(_fileKeeper);
}
//Search by name, find every value that we find and return all of those values in a vector
vector<CSPerson> CSPersonService::searchByName(const string searchString)
{
    vector<CSPerson> tempVector;
    for(size_t i = 0; i < _fileKeeper.size(); i++)
    {
        if(checkIfStringSameIgnoreUpper(_fileKeeper[i].getName(), searchString))
        {
            tempVector.push_back(_fileKeeper[i]);
        }
    }
    return tempVector;
}

//Returns true/false if the string2 is in string1, no matter upper or lower case.
bool CSPersonService::checkIfStringSameIgnoreUpper(string orginalString, string searchFor)
{
    std::transform(orginalString.begin(), orginalString.end(),orginalString.begin(), ::tolower);
    std::transform(searchFor.begin(), searchFor.end(),searchFor.begin(), ::tolower);
    if(orginalString.find(searchFor) != string::npos)//If string.find is not size_t max size
    {
        return true;
    }
    else
    {
        return false;
    }
}
<|endoftext|>


<commit_before>// Filename: 	main.cpp
// Author: 		Christopher Goes
// Course: 		CS 404 Machine Learning and Data Mining
// Semester: 	Spring 2016
// Description:	Assignments 1 and 2 main program logic

#include <iostream>
#include <cstdlib>
#include <cmath>

#include "matrix.h"

using namespace std;

int main() {

	// Initialization
	int inputs = 0;
	int rows = 0;
	int cols = 0;
	int temp = -99;

	// *******************
	// ** Training Data Input **

	cin >> inputs;
	cin >> rows;
	cin >> cols;
	Matrix* train = new Matrix(rows, cols);

	cout << "Inputs: " << inputs << "\nRows: " << rows << "\nCols: " << cols << endl;
	//return(0);
	// Fill the matrix
	for(int r = 0; r < rows; r++) {
		for(int c = 0; c < cols; c++) {
			cin >> temp;
			train->setValue( r, c, temp);
		}
	}

	cout << "Training matrix..." << endl;
	train->printAll();

	// *******************
	// Training

	Matrix* w = new Matrix(rows, cols);

	// *******************
	// ** Test Data Input **

	temp = -99; // paranoia
	cin >> rows;
	cin >> cols;
	Matrix* test = new Matrix(rows, cols);

	// Fill the matrix
	for(int r = 0; r < rows; r++) {
		for(int c = 0; c < cols; c++) {
			cin >> temp;
			test->setValue(r, c, temp);
		}
	}

	cout << "Testing matrix..." << endl;
	test->printAll();

	// Cleanup
	delete train;
	delete test;
	return(0);
}<commit_msg>inputs and outputs into their own matricies. works on iris data with doubles<commit_after>// Filename: 	main.cpp
// Author: 		Christopher Goes
// Course: 		CS 404 Machine Learning and Data Mining
// Semester: 	Spring 2016
// Description:	Assignments 1 and 2 main program logic

#include <iostream>
#include <cstdlib>
#include <cmath>
#include "matrix.h"

#define DEBUG 1

using namespace std;

int main() {

	// Initialization
	int inputs = 0;
	int rows = 0;
	int cols = 0;
	double temp = -99;

	// *******************
	// ** Training Data Input **

	cin >> inputs;
	cin >> rows;
	cin >> cols;
	int outputs = cols - inputs;
	Matrix* tinput = new Matrix(rows, inputs);
	Matrix* toutput = new Matrix(rows, outputs);

	if(DEBUG) {
		cout << "Inputs: " << inputs << "\nRows: " << rows << "\nCols: " << cols << endl;
	}

	// Fill the matrix
	for(int r = 0; r < rows; r++) {
		for(int c = 0; c < inputs; c++) {
			cin >> temp;
			tinput->setValue( r, c, temp);
		}

		for(int c = 0; c < outputs; c++ ) {
			cin >> temp;
			toutput->setValue( r, c, temp);
		}
	}

	if(DEBUG) {
		cout << "Training Inputs..." << endl;
		tinput->printAll();
		cout << "Training Outputs..." << endl;
		toutput->printAll();
	}

	// *******************
	// Training

	Matrix* w = new Matrix(rows, cols);

	// *******************
	// ** Test Data Input **

	temp = -99; // paranoia
	cin >> rows;
	cin >> cols;
	Matrix* test = new Matrix(rows, cols);

	// Fill the matrix
	for(int r = 0; r < rows; r++) {
		for(int c = 0; c < cols; c++) {
			cin >> temp;
			test->setValue(r, c, temp);
		}
	}

	if(DEBUG) {
		cout << "Test inputs matrix" << endl;
		test->printAll();
	}

	// Cleanup
	delete tinput;
	delete toutput;
	delete test;
	return(0);
}<|endoftext|>


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

#include "base/at_exit.h"
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/event_recorder.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/icu_util.h"
#include "base/memory_debug.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/rand_util.h"
#include "base/stats_table.h"
#include "base/string_util.h"
#include "base/sys_info.h"
#include "base/trace_event.h"
#include "net/base/cookie_monster.h"
#include "net/base/net_module.h"
#include "net/base/net_util.h"
#include "net/http/http_cache.h"
#include "net/socket/ssl_test_util.h"
#include "net/url_request/url_request_context.h"
#include "webkit/api/public/WebKit.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/window_open_disposition.h"
#include "webkit/extensions/v8/gc_extension.h"
#include "webkit/extensions/v8/playback_extension.h"
#include "webkit/extensions/v8/profiler_extension.h"
#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
#include "webkit/tools/test_shell/test_shell.h"
#include "webkit/tools/test_shell/test_shell_platform_delegate.h"
#include "webkit/tools/test_shell/test_shell_request_context.h"
#include "webkit/tools/test_shell/test_shell_switches.h"
#include "webkit/tools/test_shell/test_shell_webkit_init.h"

static const size_t kPathBufSize = 2048;

namespace {

// StatsTable initialization parameters.
static const char* kStatsFilePrefix = "testshell_";
static int kStatsFileThreads = 20;
static int kStatsFileCounters = 200;

}  // namespace

int main(int argc, char* argv[]) {
  base::EnableTerminationOnHeapCorruption();

  // Some tests may use base::Singleton<>, thus we need to instanciate
  // the AtExitManager or else we will leak objects.
  base::AtExitManager at_exit_manager;

  TestShellPlatformDelegate::PreflightArgs(&argc, &argv);
  CommandLine::Init(argc, argv);
  const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();

  TestShellPlatformDelegate platform(parsed_command_line);

  if (parsed_command_line.HasSwitch(test_shell::kStartupDialog))
    TestShell::ShowStartupDebuggingDialog();

  if (parsed_command_line.HasSwitch(test_shell::kCheckLayoutTestSystemDeps)) {
    exit(platform.CheckLayoutTestSystemDependencies() ? 0 : 1);
  }

  // Allocate a message loop for this thread.  Although it is not used
  // directly, its constructor sets up some necessary state.
  MessageLoopForUI main_message_loop;

  bool suppress_error_dialogs = (
       base::SysInfo::HasEnvVar(L"CHROME_HEADLESS") ||
       parsed_command_line.HasSwitch(test_shell::kNoErrorDialogs) ||
       parsed_command_line.HasSwitch(test_shell::kLayoutTests));
  bool layout_test_mode =
      parsed_command_line.HasSwitch(test_shell::kLayoutTests);
  bool ux_theme = parsed_command_line.HasSwitch(test_shell::kUxTheme);
  bool classic_theme =
      parsed_command_line.HasSwitch(test_shell::kClassicTheme);
#if defined(OS_WIN)
  bool generic_theme = (layout_test_mode && !ux_theme && !classic_theme) ||
      parsed_command_line.HasSwitch(test_shell::kGenericTheme);
#endif

  bool enable_gp_fault_error_box = false;
  enable_gp_fault_error_box =
      parsed_command_line.HasSwitch(test_shell::kGPFaultErrorBox);
  TestShell::InitLogging(suppress_error_dialogs,
                         layout_test_mode,
                         enable_gp_fault_error_box);

  // Initialize WebKit for this scope.
  TestShellWebKitInit test_shell_webkit_init(layout_test_mode);

  // Suppress abort message in v8 library in debugging mode (but not
  // actually under a debugger).  V8 calls abort() when it hits
  // assertion errors.
  if (suppress_error_dialogs) {
    platform.SuppressErrorReporting();
  }

  if (parsed_command_line.HasSwitch(test_shell::kEnableTracing))
    base::TraceLog::StartTracing();

  net::HttpCache::Mode cache_mode = net::HttpCache::NORMAL;

  // This is a special mode where JS helps the browser implement
  // playback/record mode.  Generally, in this mode, some functions
  // of client-side randomness are removed.  For example, in
  // this mode Math.random() and Date.getTime() may not return
  // values which vary.
  bool playback_mode =
    parsed_command_line.HasSwitch(test_shell::kPlaybackMode);
  bool record_mode =
    parsed_command_line.HasSwitch(test_shell::kRecordMode);

  if (playback_mode)
    cache_mode = net::HttpCache::PLAYBACK;
  else if (record_mode)
    cache_mode = net::HttpCache::RECORD;

  if (layout_test_mode ||
      parsed_command_line.HasSwitch(test_shell::kEnableFileCookies))
    net::CookieMonster::EnableFileScheme();

  FilePath cache_path = FilePath::FromWStringHack(
      parsed_command_line.GetSwitchValue(test_shell::kCacheDir));
  // If the cache_path is empty and it's layout_test_mode, leave it empty
  // so we use an in-memory cache. This makes running multiple test_shells
  // in parallel less flaky.
  if (cache_path.empty() && !layout_test_mode) {
    PathService::Get(base::DIR_EXE, &cache_path);
    cache_path = cache_path.AppendASCII("cache");
  }

  // Initializing with a default context, which means no on-disk cookie DB,
  // and no support for directory listings.
  SimpleResourceLoaderBridge::Init(
      new TestShellRequestContext(cache_path.ToWStringHack(),
                                  cache_mode, layout_test_mode));

  // Load ICU data tables
  icu_util::Initialize();

  // Config the network module so it has access to a limited set of resources.
  net::NetModule::SetResourceProvider(TestShell::NetResourceProvider);

  // On Linux, load the test root certificate.
  net::TestServerLauncher ssl_util;
  ssl_util.LoadTestRootCert();

  platform.InitializeGUI();

  TestShell::InitializeTestShell(layout_test_mode);

  if (parsed_command_line.HasSwitch(test_shell::kAllowScriptsToCloseWindows))
    TestShell::SetAllowScriptsToCloseWindows();

  // Disable user themes for layout tests so pixel tests are consistent.
#if defined(OS_WIN)
  TestShellWebTheme::Engine engine;
#endif
  if (classic_theme)
    platform.SelectUnifiedTheme();
#if defined(OS_WIN)
  if (generic_theme)
    test_shell_webkit_init.setThemeEngine(&engine);
#endif

  if (parsed_command_line.HasSwitch(test_shell::kTestShellTimeOut)) {
    const std::wstring timeout_str = parsed_command_line.GetSwitchValue(
        test_shell::kTestShellTimeOut);
    int timeout_ms =
        static_cast<int>(StringToInt64(WideToUTF16Hack(timeout_str.c_str())));
    if (timeout_ms > 0)
      TestShell::SetFileTestTimeout(timeout_ms);
  }

  // Treat the first loose value as the initial URL to open.
  GURL starting_url;

  // Default to a homepage if we're interactive.
  if (!layout_test_mode) {
    FilePath path;
    PathService::Get(base::DIR_SOURCE_ROOT, &path);
    path = path.AppendASCII("webkit");
    path = path.AppendASCII("data");
    path = path.AppendASCII("test_shell");
    path = path.AppendASCII("index.html");
    starting_url = net::FilePathToFileURL(path);
  }

  std::vector<std::wstring> loose_values = parsed_command_line.GetLooseValues();
  if (loose_values.size() > 0) {
    GURL url(WideToUTF16Hack(loose_values[0]));
    if (url.is_valid()) {
      starting_url = url;
    } else {
      // Treat as a file path
      starting_url =
          net::FilePathToFileURL(FilePath::FromWStringHack(loose_values[0]));
    }
  }

  std::wstring js_flags =
    parsed_command_line.GetSwitchValue(test_shell::kJavaScriptFlags);
  // Test shell always exposes the GC.
  js_flags += L" --expose-gc";
  webkit_glue::SetJavaScriptFlags(js_flags);
  // Expose GCController to JavaScript.
  WebKit::registerExtension(extensions_v8::GCExtension::Get());

  if (parsed_command_line.HasSwitch(test_shell::kProfiler)) {
    WebKit::registerExtension(extensions_v8::ProfilerExtension::Get());
  }

  // Load and initialize the stats table.  Attempt to construct a somewhat
  // unique name to isolate separate instances from each other.
  StatsTable *table = new StatsTable(
      // truncate the random # to 32 bits for the benefit of Mac OS X, to
      // avoid tripping over its maximum shared memory segment name length
      kStatsFilePrefix + Uint64ToString(base::RandUint64() & 0xFFFFFFFFL),
      kStatsFileThreads,
      kStatsFileCounters);
  StatsTable::set_current(table);

  TestShell* shell;
  if (TestShell::CreateNewWindow(starting_url, &shell)) {
    if (record_mode || playback_mode) {
      platform.SetWindowPositionForRecording(shell);
      WebKit::registerExtension(extensions_v8::PlaybackExtension::Get());
    }

    shell->Show(WebKit::WebNavigationPolicyNewWindow);

    if (parsed_command_line.HasSwitch(test_shell::kDumpStatsTable))
      shell->DumpStatsTableOnExit();

    bool no_events = parsed_command_line.HasSwitch(test_shell::kNoEvents);
    if ((record_mode || playback_mode) && !no_events) {
      FilePath script_path = cache_path;
      // Create the cache directory in case it doesn't exist.
      file_util::CreateDirectory(cache_path);
      script_path = script_path.AppendASCII("script.log");
      if (record_mode)
        base::EventRecorder::current()->StartRecording(script_path);
      if (playback_mode)
        base::EventRecorder::current()->StartPlayback(script_path);
    }

    if (parsed_command_line.HasSwitch(test_shell::kDebugMemoryInUse)) {
      base::MemoryDebug::SetMemoryInUseEnabled(true);
      // Dump all in use memory at startup
      base::MemoryDebug::DumpAllMemoryInUse();
    }

    // See if we need to run the tests.
    if (layout_test_mode) {
      // Set up for the kind of test requested.
      TestShell::TestParams params;
      if (parsed_command_line.HasSwitch(test_shell::kDumpPixels)) {
        // The pixel test flag also gives the image file name to use.
        params.dump_pixels = true;
        params.pixel_file_name = parsed_command_line.GetSwitchValue(
            test_shell::kDumpPixels);
        if (params.pixel_file_name.size() == 0) {
          fprintf(stderr, "No file specified for pixel tests");
          exit(1);
        }
      }
      if (parsed_command_line.HasSwitch(test_shell::kNoTree)) {
          params.dump_tree = false;
      }

      if (!starting_url.is_valid()) {
        // Watch stdin for URLs.
        char filenameBuffer[kPathBufSize];
        while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
          // When running layout tests we pass new line separated
          // tests to TestShell. Each line is a space separated list
          // of filename, timeout and expected pixel hash. The timeout
          // and the pixel hash are optional.
          char* newLine = strchr(filenameBuffer, '\n');
          if (newLine)
            *newLine = '\0';
          if (!*filenameBuffer)
            continue;

          params.test_url = strtok(filenameBuffer, " ");

          // Set the current path to the directory that contains the test
          // files. This is because certain test file may use the relative
          // path.
          GURL test_url(params.test_url);
          FilePath test_file_path;
          net::FileURLToFilePath(test_url, &test_file_path);
          file_util::SetCurrentDirectory(test_file_path.DirName());

          int old_timeout_ms = TestShell::GetLayoutTestTimeout();

          char* timeout = strtok(NULL, " ");
          if (timeout) {
            TestShell::SetFileTestTimeout(atoi(timeout));
            char* pixel_hash = strtok(NULL, " ");
            if (pixel_hash)
              params.pixel_hash = pixel_hash;
          }

          if (!TestShell::RunFileTest(params))
            break;

          TestShell::SetFileTestTimeout(old_timeout_ms);
        }
      } else {
        // TODO(ojan): Provide a way for run-singly tests to pass
        // in a hash and then set params.pixel_hash here.
        params.test_url = starting_url.spec();
        TestShell::RunFileTest(params);
      }

      shell->CallJSGC();
      shell->CallJSGC();

      // When we finish the last test, cleanup the LayoutTestController.
      // It may have references to not-yet-cleaned up windows.  By
      // cleaning up here we help purify reports.
      shell->ResetTestController();

      // Flush any remaining messages before we kill ourselves.
      // http://code.google.com/p/chromium/issues/detail?id=9500
      MessageLoop::current()->RunAllPending();

      delete shell;
    } else {
      MessageLoop::current()->Run();
    }

    // Flush any remaining messages.  This ensures that any accumulated
    // Task objects get destroyed before we exit, which avoids noise in
    // purify leak-test results.
    MessageLoop::current()->RunAllPending();

    if (record_mode)
      base::EventRecorder::current()->StopRecording();
    if (playback_mode)
      base::EventRecorder::current()->StopPlayback();
  }

  TestShell::ShutdownTestShell();
  TestShell::CleanupLogging();

  // Tear down shared StatsTable; prevents unit_tests from leaking it.
  StatsTable::set_current(NULL);
  delete table;

  return 0;
}
<commit_msg>try again to fix compile w/ unused variables ...<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/at_exit.h"
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/event_recorder.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/icu_util.h"
#include "base/memory_debug.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/rand_util.h"
#include "base/stats_table.h"
#include "base/string_util.h"
#include "base/sys_info.h"
#include "base/trace_event.h"
#include "net/base/cookie_monster.h"
#include "net/base/net_module.h"
#include "net/base/net_util.h"
#include "net/http/http_cache.h"
#include "net/socket/ssl_test_util.h"
#include "net/url_request/url_request_context.h"
#include "webkit/api/public/WebKit.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/window_open_disposition.h"
#include "webkit/extensions/v8/gc_extension.h"
#include "webkit/extensions/v8/playback_extension.h"
#include "webkit/extensions/v8/profiler_extension.h"
#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
#include "webkit/tools/test_shell/test_shell.h"
#include "webkit/tools/test_shell/test_shell_platform_delegate.h"
#include "webkit/tools/test_shell/test_shell_request_context.h"
#include "webkit/tools/test_shell/test_shell_switches.h"
#include "webkit/tools/test_shell/test_shell_webkit_init.h"

static const size_t kPathBufSize = 2048;

namespace {

// StatsTable initialization parameters.
static const char* kStatsFilePrefix = "testshell_";
static int kStatsFileThreads = 20;
static int kStatsFileCounters = 200;

}  // namespace

int main(int argc, char* argv[]) {
  base::EnableTerminationOnHeapCorruption();

  // Some tests may use base::Singleton<>, thus we need to instanciate
  // the AtExitManager or else we will leak objects.
  base::AtExitManager at_exit_manager;

  TestShellPlatformDelegate::PreflightArgs(&argc, &argv);
  CommandLine::Init(argc, argv);
  const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();

  TestShellPlatformDelegate platform(parsed_command_line);

  if (parsed_command_line.HasSwitch(test_shell::kStartupDialog))
    TestShell::ShowStartupDebuggingDialog();

  if (parsed_command_line.HasSwitch(test_shell::kCheckLayoutTestSystemDeps)) {
    exit(platform.CheckLayoutTestSystemDependencies() ? 0 : 1);
  }

  // Allocate a message loop for this thread.  Although it is not used
  // directly, its constructor sets up some necessary state.
  MessageLoopForUI main_message_loop;

  bool suppress_error_dialogs = (
       base::SysInfo::HasEnvVar(L"CHROME_HEADLESS") ||
       parsed_command_line.HasSwitch(test_shell::kNoErrorDialogs) ||
       parsed_command_line.HasSwitch(test_shell::kLayoutTests));
  bool layout_test_mode =
      parsed_command_line.HasSwitch(test_shell::kLayoutTests);
  bool ux_theme = parsed_command_line.HasSwitch(test_shell::kUxTheme);
  bool classic_theme =
      parsed_command_line.HasSwitch(test_shell::kClassicTheme);
#if defined(OS_WIN)
  bool generic_theme = (layout_test_mode && !ux_theme && !classic_theme) ||
      parsed_command_line.HasSwitch(test_shell::kGenericTheme);
#else
  // Stop compiler warnings about unused variables.
  ux_theme = ux_theme;
#endif

  bool enable_gp_fault_error_box = false;
  enable_gp_fault_error_box =
      parsed_command_line.HasSwitch(test_shell::kGPFaultErrorBox);
  TestShell::InitLogging(suppress_error_dialogs,
                         layout_test_mode,
                         enable_gp_fault_error_box);

  // Initialize WebKit for this scope.
  TestShellWebKitInit test_shell_webkit_init(layout_test_mode);

  // Suppress abort message in v8 library in debugging mode (but not
  // actually under a debugger).  V8 calls abort() when it hits
  // assertion errors.
  if (suppress_error_dialogs) {
    platform.SuppressErrorReporting();
  }

  if (parsed_command_line.HasSwitch(test_shell::kEnableTracing))
    base::TraceLog::StartTracing();

  net::HttpCache::Mode cache_mode = net::HttpCache::NORMAL;

  // This is a special mode where JS helps the browser implement
  // playback/record mode.  Generally, in this mode, some functions
  // of client-side randomness are removed.  For example, in
  // this mode Math.random() and Date.getTime() may not return
  // values which vary.
  bool playback_mode =
    parsed_command_line.HasSwitch(test_shell::kPlaybackMode);
  bool record_mode =
    parsed_command_line.HasSwitch(test_shell::kRecordMode);

  if (playback_mode)
    cache_mode = net::HttpCache::PLAYBACK;
  else if (record_mode)
    cache_mode = net::HttpCache::RECORD;

  if (layout_test_mode ||
      parsed_command_line.HasSwitch(test_shell::kEnableFileCookies))
    net::CookieMonster::EnableFileScheme();

  FilePath cache_path = FilePath::FromWStringHack(
      parsed_command_line.GetSwitchValue(test_shell::kCacheDir));
  // If the cache_path is empty and it's layout_test_mode, leave it empty
  // so we use an in-memory cache. This makes running multiple test_shells
  // in parallel less flaky.
  if (cache_path.empty() && !layout_test_mode) {
    PathService::Get(base::DIR_EXE, &cache_path);
    cache_path = cache_path.AppendASCII("cache");
  }

  // Initializing with a default context, which means no on-disk cookie DB,
  // and no support for directory listings.
  SimpleResourceLoaderBridge::Init(
      new TestShellRequestContext(cache_path.ToWStringHack(),
                                  cache_mode, layout_test_mode));

  // Load ICU data tables
  icu_util::Initialize();

  // Config the network module so it has access to a limited set of resources.
  net::NetModule::SetResourceProvider(TestShell::NetResourceProvider);

  // On Linux, load the test root certificate.
  net::TestServerLauncher ssl_util;
  ssl_util.LoadTestRootCert();

  platform.InitializeGUI();

  TestShell::InitializeTestShell(layout_test_mode);

  if (parsed_command_line.HasSwitch(test_shell::kAllowScriptsToCloseWindows))
    TestShell::SetAllowScriptsToCloseWindows();

  // Disable user themes for layout tests so pixel tests are consistent.
#if defined(OS_WIN)
  TestShellWebTheme::Engine engine;
#endif
  if (classic_theme)
    platform.SelectUnifiedTheme();
#if defined(OS_WIN)
  if (generic_theme)
    test_shell_webkit_init.setThemeEngine(&engine);
#endif

  if (parsed_command_line.HasSwitch(test_shell::kTestShellTimeOut)) {
    const std::wstring timeout_str = parsed_command_line.GetSwitchValue(
        test_shell::kTestShellTimeOut);
    int timeout_ms =
        static_cast<int>(StringToInt64(WideToUTF16Hack(timeout_str.c_str())));
    if (timeout_ms > 0)
      TestShell::SetFileTestTimeout(timeout_ms);
  }

  // Treat the first loose value as the initial URL to open.
  GURL starting_url;

  // Default to a homepage if we're interactive.
  if (!layout_test_mode) {
    FilePath path;
    PathService::Get(base::DIR_SOURCE_ROOT, &path);
    path = path.AppendASCII("webkit");
    path = path.AppendASCII("data");
    path = path.AppendASCII("test_shell");
    path = path.AppendASCII("index.html");
    starting_url = net::FilePathToFileURL(path);
  }

  std::vector<std::wstring> loose_values = parsed_command_line.GetLooseValues();
  if (loose_values.size() > 0) {
    GURL url(WideToUTF16Hack(loose_values[0]));
    if (url.is_valid()) {
      starting_url = url;
    } else {
      // Treat as a file path
      starting_url =
          net::FilePathToFileURL(FilePath::FromWStringHack(loose_values[0]));
    }
  }

  std::wstring js_flags =
    parsed_command_line.GetSwitchValue(test_shell::kJavaScriptFlags);
  // Test shell always exposes the GC.
  js_flags += L" --expose-gc";
  webkit_glue::SetJavaScriptFlags(js_flags);
  // Expose GCController to JavaScript.
  WebKit::registerExtension(extensions_v8::GCExtension::Get());

  if (parsed_command_line.HasSwitch(test_shell::kProfiler)) {
    WebKit::registerExtension(extensions_v8::ProfilerExtension::Get());
  }

  // Load and initialize the stats table.  Attempt to construct a somewhat
  // unique name to isolate separate instances from each other.
  StatsTable *table = new StatsTable(
      // truncate the random # to 32 bits for the benefit of Mac OS X, to
      // avoid tripping over its maximum shared memory segment name length
      kStatsFilePrefix + Uint64ToString(base::RandUint64() & 0xFFFFFFFFL),
      kStatsFileThreads,
      kStatsFileCounters);
  StatsTable::set_current(table);

  TestShell* shell;
  if (TestShell::CreateNewWindow(starting_url, &shell)) {
    if (record_mode || playback_mode) {
      platform.SetWindowPositionForRecording(shell);
      WebKit::registerExtension(extensions_v8::PlaybackExtension::Get());
    }

    shell->Show(WebKit::WebNavigationPolicyNewWindow);

    if (parsed_command_line.HasSwitch(test_shell::kDumpStatsTable))
      shell->DumpStatsTableOnExit();

    bool no_events = parsed_command_line.HasSwitch(test_shell::kNoEvents);
    if ((record_mode || playback_mode) && !no_events) {
      FilePath script_path = cache_path;
      // Create the cache directory in case it doesn't exist.
      file_util::CreateDirectory(cache_path);
      script_path = script_path.AppendASCII("script.log");
      if (record_mode)
        base::EventRecorder::current()->StartRecording(script_path);
      if (playback_mode)
        base::EventRecorder::current()->StartPlayback(script_path);
    }

    if (parsed_command_line.HasSwitch(test_shell::kDebugMemoryInUse)) {
      base::MemoryDebug::SetMemoryInUseEnabled(true);
      // Dump all in use memory at startup
      base::MemoryDebug::DumpAllMemoryInUse();
    }

    // See if we need to run the tests.
    if (layout_test_mode) {
      // Set up for the kind of test requested.
      TestShell::TestParams params;
      if (parsed_command_line.HasSwitch(test_shell::kDumpPixels)) {
        // The pixel test flag also gives the image file name to use.
        params.dump_pixels = true;
        params.pixel_file_name = parsed_command_line.GetSwitchValue(
            test_shell::kDumpPixels);
        if (params.pixel_file_name.size() == 0) {
          fprintf(stderr, "No file specified for pixel tests");
          exit(1);
        }
      }
      if (parsed_command_line.HasSwitch(test_shell::kNoTree)) {
          params.dump_tree = false;
      }

      if (!starting_url.is_valid()) {
        // Watch stdin for URLs.
        char filenameBuffer[kPathBufSize];
        while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
          // When running layout tests we pass new line separated
          // tests to TestShell. Each line is a space separated list
          // of filename, timeout and expected pixel hash. The timeout
          // and the pixel hash are optional.
          char* newLine = strchr(filenameBuffer, '\n');
          if (newLine)
            *newLine = '\0';
          if (!*filenameBuffer)
            continue;

          params.test_url = strtok(filenameBuffer, " ");

          // Set the current path to the directory that contains the test
          // files. This is because certain test file may use the relative
          // path.
          GURL test_url(params.test_url);
          FilePath test_file_path;
          net::FileURLToFilePath(test_url, &test_file_path);
          file_util::SetCurrentDirectory(test_file_path.DirName());

          int old_timeout_ms = TestShell::GetLayoutTestTimeout();

          char* timeout = strtok(NULL, " ");
          if (timeout) {
            TestShell::SetFileTestTimeout(atoi(timeout));
            char* pixel_hash = strtok(NULL, " ");
            if (pixel_hash)
              params.pixel_hash = pixel_hash;
          }

          if (!TestShell::RunFileTest(params))
            break;

          TestShell::SetFileTestTimeout(old_timeout_ms);
        }
      } else {
        // TODO(ojan): Provide a way for run-singly tests to pass
        // in a hash and then set params.pixel_hash here.
        params.test_url = starting_url.spec();
        TestShell::RunFileTest(params);
      }

      shell->CallJSGC();
      shell->CallJSGC();

      // When we finish the last test, cleanup the LayoutTestController.
      // It may have references to not-yet-cleaned up windows.  By
      // cleaning up here we help purify reports.
      shell->ResetTestController();

      // Flush any remaining messages before we kill ourselves.
      // http://code.google.com/p/chromium/issues/detail?id=9500
      MessageLoop::current()->RunAllPending();

      delete shell;
    } else {
      MessageLoop::current()->Run();
    }

    // Flush any remaining messages.  This ensures that any accumulated
    // Task objects get destroyed before we exit, which avoids noise in
    // purify leak-test results.
    MessageLoop::current()->RunAllPending();

    if (record_mode)
      base::EventRecorder::current()->StopRecording();
    if (playback_mode)
      base::EventRecorder::current()->StopPlayback();
  }

  TestShell::ShutdownTestShell();
  TestShell::CleanupLogging();

  // Tear down shared StatsTable; prevents unit_tests from leaking it.
  StatsTable::set_current(NULL);
  delete table;

  return 0;
}
<|endoftext|>


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

// Creates an instance of the test_shell.
#include "build/build_config.h"

#include <stdlib.h>  // required by _set_abort_behavior

#if defined(OS_WIN)
#include <windows.h>
#include <commctrl.h>
#include "base/event_recorder.h"
#include "base/gfx/native_theme.h"
#include "base/resource_util.h"
#include "breakpad/src/client/windows/handler/exception_handler.h"
#include "webkit/tools/test_shell/foreground_helper.h"
#endif

#if defined(OS_LINUX)
#include <gtk/gtk.h>
#endif

#include "base/at_exit.h"
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/icu_util.h"
#include "base/memory_debug.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/stack_container.h"
#include "base/stats_table.h"
#include "base/string_util.h"
#include "base/trace_event.h"
#include "net/base/cookie_monster.h"
#include "net/base/net_module.h"
#include "net/http/http_cache.h"
#include "net/http/http_network_layer.h"
#include "net/url_request/url_request_context.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/window_open_disposition.h"
#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
#include "webkit/tools/test_shell/test_shell.h"
#include "webkit/tools/test_shell/test_shell_request_context.h"
#include "webkit/tools/test_shell/test_shell_switches.h"

#include <iostream>
using namespace std;

#if defined(OS_WIN)
// This is only set for layout tests.
static wchar_t g_currentTestName[MAX_PATH];
#endif

namespace {

// StatsTable initialization parameters.
static const wchar_t* kStatsFile = L"testshell";
static int kStatsFileThreads = 20;
static int kStatsFileCounters = 200;

#if defined(OS_WIN)
std::string GetDataResource(HMODULE module, int resource_id) {
  void* data_ptr;
  size_t data_size;
  return base::GetDataResourceFromModule(module, resource_id, &data_ptr,
                                         &data_size) ?
      std::string(static_cast<char*>(data_ptr), data_size) : std::string();
}

// This is called indirectly by the network layer to access resources.
std::string NetResourceProvider(int key) {
  return GetDataResource(::GetModuleHandle(NULL), key);
}

void SetCurrentTestName(char* path)
{
    char* lastSlash = strrchr(path, '/');
    if (lastSlash) {
        ++lastSlash;
    } else {
        lastSlash = path;
    }

    wcscpy_s(g_currentTestName, arraysize(g_currentTestName),
             UTF8ToWide(lastSlash).c_str());
}

bool MinidumpCallback(const wchar_t *dumpPath,
                             const wchar_t *minidumpID,
                             void *context,
                             EXCEPTION_POINTERS *exinfo,
                             MDRawAssertionInfo *assertion,
                             bool succeeded)
{
    // Warning: Don't use the heap in this function.  It may be corrupted.
    if (!g_currentTestName[0])
        return false;

    // Try to rename the minidump file to include the crashed test's name.
    // StackString uses the stack but overflows onto the heap.  But we don't
    // care too much about being completely correct here, since most crashes
    // will be happening on developers' machines where they have debuggers.
    StackWString<MAX_PATH*2> origPath;
    origPath->append(dumpPath);
    origPath->push_back(file_util::kPathSeparator);
    origPath->append(minidumpID);
    origPath->append(L".dmp");

    StackWString<MAX_PATH*2>  newPath;
    newPath->append(dumpPath);
    newPath->push_back(file_util::kPathSeparator);
    newPath->append(g_currentTestName);
    newPath->append(L"-");
    newPath->append(minidumpID);
    newPath->append(L".dmp");

    // May use the heap, but oh well.  If this fails, we'll just have the
    // original dump file lying around.
    _wrename(origPath->c_str(), newPath->c_str());

    return false;
}
#endif

}  // namespace

int main(int argc, char* argv[]) {
  base::EnableTerminationOnHeapCorruption();
#ifdef _CRTDBG_MAP_ALLOC
  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
#endif
  // Some tests may use base::Singleton<>, thus we need to instanciate
  // the AtExitManager or else we will leak objects.
  base::AtExitManager at_exit_manager;

#if defined(OS_LINUX)
  gtk_init(&argc, &argv);
  // Only parse the command line after GTK's had a crack at it.
  CommandLine::SetArgcArgv(argc, argv);
#endif

  CommandLine parsed_command_line;
#if defined(OS_WIN)
  if (parsed_command_line.HasSwitch(test_shell::kStartupDialog))
      MessageBox(NULL, L"attach to me?", L"test_shell", MB_OK);
#endif

  // Allocate a message loop for this thread.  Although it is not used
  // directly, its constructor sets up some necessary state.
  MessageLoopForUI main_message_loop;

  bool suppress_error_dialogs = (
#if defined(OS_WIN)
       GetEnvironmentVariable(L"CHROME_HEADLESS", NULL, 0) ||
#endif
       parsed_command_line.HasSwitch(test_shell::kNoErrorDialogs) ||
       parsed_command_line.HasSwitch(test_shell::kLayoutTests));
  bool layout_test_mode =
      parsed_command_line.HasSwitch(test_shell::kLayoutTests);

  TestShell::InitLogging(suppress_error_dialogs, layout_test_mode);

  // Set this early before we start using WebCore.
  webkit_glue::SetLayoutTestMode(layout_test_mode);

  // Suppress abort message in v8 library in debugging mode.
  // V8 calls abort() when it hits assertion errors.
#if defined(OS_WIN)
  if (suppress_error_dialogs) {
    _set_abort_behavior(0, _WRITE_ABORT_MSG);
  }
#endif

  if (parsed_command_line.HasSwitch(test_shell::kEnableTracing))
    base::TraceLog::StartTracing();

#if defined(OS_WIN)
  // Make the selection of network stacks early on before any consumers try to
  // issue HTTP requests.
  if (parsed_command_line.HasSwitch(test_shell::kUseWinHttp))
    net::HttpNetworkLayer::UseWinHttp(true);
#endif

  net::HttpCache::Mode cache_mode = net::HttpCache::NORMAL;
  bool playback_mode =
    parsed_command_line.HasSwitch(test_shell::kPlaybackMode);
  bool record_mode =
    parsed_command_line.HasSwitch(test_shell::kRecordMode);

  if (playback_mode)
    cache_mode = net::HttpCache::PLAYBACK;
  else if (record_mode)
    cache_mode = net::HttpCache::RECORD;

  if (layout_test_mode ||
      parsed_command_line.HasSwitch(test_shell::kEnableFileCookies))
    net::CookieMonster::EnableFileScheme();

  std::wstring cache_path =
      parsed_command_line.GetSwitchValue(test_shell::kCacheDir);
  if (cache_path.empty()) {
    PathService::Get(base::DIR_EXE, &cache_path);
    file_util::AppendToPath(&cache_path, L"cache");
  }

  // Initializing with a default context, which means no on-disk cookie DB,
  // and no support for directory listings.
  SimpleResourceLoaderBridge::Init(
      new TestShellRequestContext(cache_path, cache_mode));

  // Load ICU data tables
  icu_util::Initialize();

#if defined(OS_WIN)
  // Config the network module so it has access to a limited set of resources.
  net::NetModule::SetResourceProvider(NetResourceProvider);

  INITCOMMONCONTROLSEX InitCtrlEx;

  InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
  InitCtrlEx.dwICC  = ICC_STANDARD_CLASSES;
  InitCommonControlsEx(&InitCtrlEx);

  // Register the Ahem font used by layout tests.
  DWORD num_fonts = 1;
  void* font_ptr;
  size_t font_size;
  if (base::GetDataResourceFromModule(::GetModuleHandle(NULL), IDR_AHEM_FONT,
                                      &font_ptr, &font_size)) {
    HANDLE rc = AddFontMemResourceEx(font_ptr, font_size, 0, &num_fonts);
    DCHECK(rc != 0);
  }
#endif

  bool interactive = !layout_test_mode;
  TestShell::InitializeTestShell(interactive);

  if (parsed_command_line.HasSwitch(test_shell::kAllowScriptsToCloseWindows))
    TestShell::SetAllowScriptsToCloseWindows();

  // Disable user themes for layout tests so pixel tests are consistent.
#if defined(OS_WIN)
  if (!interactive)
    gfx::NativeTheme::instance()->DisableTheming();
#endif

  if (parsed_command_line.HasSwitch(test_shell::kTestShellTimeOut)) {
    const std::wstring timeout_str = parsed_command_line.GetSwitchValue(
        test_shell::kTestShellTimeOut);
    int timeout_ms = static_cast<int>(StringToInt64(timeout_str.c_str()));
    if (timeout_ms > 0)
      TestShell::SetFileTestTimeout(timeout_ms);
  }

#if defined(OS_WIN)
  // Initialize global strings
  TestShell::RegisterWindowClass();
#endif

  // Treat the first loose value as the initial URL to open.
  std::wstring uri;

  // Default to a homepage if we're interactive.
  if (interactive) {
    PathService::Get(base::DIR_SOURCE_ROOT, &uri);
    file_util::AppendToPath(&uri, L"webkit");
    file_util::AppendToPath(&uri, L"data");
    file_util::AppendToPath(&uri, L"test_shell");
    file_util::AppendToPath(&uri, L"index.html");
  }

  if (parsed_command_line.GetLooseValueCount() > 0) {
    CommandLine::LooseValueIterator iter(
        parsed_command_line.GetLooseValuesBegin());
    uri = *iter;
  }

#if defined(OS_WIN)
  if (parsed_command_line.HasSwitch(test_shell::kCrashDumps)) {
    std::wstring dir(
        parsed_command_line.GetSwitchValue(test_shell::kCrashDumps));
    new google_breakpad::ExceptionHandler(dir, 0, &MinidumpCallback, 0, true);
  }
#endif

  std::wstring js_flags =
    parsed_command_line.GetSwitchValue(test_shell::kJavaScriptFlags);
  // Test shell always exposes the GC.
  CommandLine::AppendSwitch(&js_flags, L"expose-gc");
  webkit_glue::SetJavaScriptFlags(js_flags);
  // Also expose GCController to JavaScript.
  webkit_glue::SetShouldExposeGCController(true);

  // load and initialize the stats table.
  StatsTable *table = new StatsTable(kStatsFile, kStatsFileThreads, kStatsFileCounters);
  StatsTable::set_current(table);

  TestShell* shell;
  if (TestShell::CreateNewWindow(uri, &shell)) {
#if defined(OS_WIN)
    if (record_mode || playback_mode) {
      // Move the window to the upper left corner for consistent
      // record/playback mode.  For automation, we want this to work
      // on build systems where the script invoking us is a background
      // process.  So for this case, make our window the topmost window
      // as well.
      ForegroundHelper::SetForeground(shell->mainWnd());
      ::SetWindowPos(shell->mainWnd(), HWND_TOP, 0, 0, 600, 800, 0);
      // Tell webkit as well.
      webkit_glue::SetRecordPlaybackMode(true);
    }
#endif

    shell->Show(shell->webView(), NEW_WINDOW);

    if (parsed_command_line.HasSwitch(test_shell::kDumpStatsTable))
      shell->DumpStatsTableOnExit();

#if defined(OS_WIN)
    bool no_events = parsed_command_line.HasSwitch(test_shell::kNoEvents);
    if ((record_mode || playback_mode) && !no_events) {
      std::wstring script_path = cache_path;
      // Create the cache directory in case it doesn't exist.
      file_util::CreateDirectory(cache_path);
      file_util::AppendToPath(&script_path, L"script.log");
      if (record_mode)
        base::EventRecorder::current()->StartRecording(script_path);
      if (playback_mode)
        base::EventRecorder::current()->StartPlayback(script_path);
    }
#endif

    if (parsed_command_line.HasSwitch(test_shell::kDebugMemoryInUse)) {
      base::MemoryDebug::SetMemoryInUseEnabled(true);
      // Dump all in use memory at startup
      base::MemoryDebug::DumpAllMemoryInUse();
    }

    // See if we need to run the tests.
    if (layout_test_mode) {
      // Set up for the kind of test requested.
      TestShell::TestParams params;
      if (parsed_command_line.HasSwitch(test_shell::kDumpPixels)) {
        // The pixel test flag also gives the image file name to use.
        params.dump_pixels = true;
        params.pixel_file_name = parsed_command_line.GetSwitchValue(
            test_shell::kDumpPixels);
        if (params.pixel_file_name.size() == 0) {
          fprintf(stderr, "No file specified for pixel tests");
          exit(1);
        }
      }
      if (parsed_command_line.HasSwitch(test_shell::kNoTree)) {
          params.dump_tree = false;
      }

      if (uri.length() == 0) {
        // Watch stdin for URLs.
        char filenameBuffer[2048];
        while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
          char *newLine = strchr(filenameBuffer, '\n');
          if (newLine)
            *newLine = '\0';
          if (!*filenameBuffer)
            continue;

#if defined(OS_WIN)
          SetCurrentTestName(filenameBuffer);
#endif

          if (!TestShell::RunFileTest(filenameBuffer, params))
            break;
        }
      } else {
        TestShell::RunFileTest(WideToUTF8(uri).c_str(), params);
      }

      shell->CallJSGC();
      shell->CallJSGC();
      if (shell) delete shell;
    } else {
      MessageLoop::current()->Run();
    }

    // Flush any remaining messages.  This ensures that any accumulated
    // Task objects get destroyed before we exit, which avoids noise in
    // purify leak-test results.
    MessageLoop::current()->RunAllPending();

#if defined(OS_WIN)
    if (record_mode)
      base::EventRecorder::current()->StopRecording();
    if (playback_mode)
      base::EventRecorder::current()->StopPlayback();
#endif
  }

  TestShell::ShutdownTestShell();
  TestShell::CleanupLogging();

  // Tear down shared StatsTable; prevents unit_tests from leaking it.
  StatsTable::set_current(NULL);
  delete table;

#ifdef _CRTDBG_MAP_ALLOC
  _CrtDumpMemoryLeaks();
#endif
  return 0;
}
<commit_msg>Make test_shell stats table names unique. On Linux, our shared memory name can conflict across users.  For now, just try to make the name unique.  Eventually we should work towards improving our stats table implementation.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Creates an instance of the test_shell.
#include "build/build_config.h"

#include <stdlib.h>  // required by _set_abort_behavior

#if defined(OS_WIN)
#include <windows.h>
#include <commctrl.h>
#include "base/event_recorder.h"
#include "base/gfx/native_theme.h"
#include "base/resource_util.h"
#include "breakpad/src/client/windows/handler/exception_handler.h"
#include "webkit/tools/test_shell/foreground_helper.h"
#endif

#if defined(OS_LINUX)
#include <gtk/gtk.h>
#endif

#include "base/at_exit.h"
#include "base/basictypes.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/icu_util.h"
#include "base/memory_debug.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/rand_util.h"
#include "base/stack_container.h"
#include "base/stats_table.h"
#include "base/string_util.h"
#include "base/trace_event.h"
#include "net/base/cookie_monster.h"
#include "net/base/net_module.h"
#include "net/http/http_cache.h"
#include "net/http/http_network_layer.h"
#include "net/url_request/url_request_context.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/window_open_disposition.h"
#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
#include "webkit/tools/test_shell/test_shell.h"
#include "webkit/tools/test_shell/test_shell_request_context.h"
#include "webkit/tools/test_shell/test_shell_switches.h"

#include <iostream>
using namespace std;

#if defined(OS_WIN)
// This is only set for layout tests.
static wchar_t g_currentTestName[MAX_PATH];
#endif

namespace {

// StatsTable initialization parameters.
static const wchar_t* kStatsFilePrefix = L"testshell_";
static int kStatsFileThreads = 20;
static int kStatsFileCounters = 200;

#if defined(OS_WIN)
std::string GetDataResource(HMODULE module, int resource_id) {
  void* data_ptr;
  size_t data_size;
  return base::GetDataResourceFromModule(module, resource_id, &data_ptr,
                                         &data_size) ?
      std::string(static_cast<char*>(data_ptr), data_size) : std::string();
}

// This is called indirectly by the network layer to access resources.
std::string NetResourceProvider(int key) {
  return GetDataResource(::GetModuleHandle(NULL), key);
}

void SetCurrentTestName(char* path)
{
    char* lastSlash = strrchr(path, '/');
    if (lastSlash) {
        ++lastSlash;
    } else {
        lastSlash = path;
    }

    wcscpy_s(g_currentTestName, arraysize(g_currentTestName),
             UTF8ToWide(lastSlash).c_str());
}

bool MinidumpCallback(const wchar_t *dumpPath,
                             const wchar_t *minidumpID,
                             void *context,
                             EXCEPTION_POINTERS *exinfo,
                             MDRawAssertionInfo *assertion,
                             bool succeeded)
{
    // Warning: Don't use the heap in this function.  It may be corrupted.
    if (!g_currentTestName[0])
        return false;

    // Try to rename the minidump file to include the crashed test's name.
    // StackString uses the stack but overflows onto the heap.  But we don't
    // care too much about being completely correct here, since most crashes
    // will be happening on developers' machines where they have debuggers.
    StackWString<MAX_PATH*2> origPath;
    origPath->append(dumpPath);
    origPath->push_back(file_util::kPathSeparator);
    origPath->append(minidumpID);
    origPath->append(L".dmp");

    StackWString<MAX_PATH*2>  newPath;
    newPath->append(dumpPath);
    newPath->push_back(file_util::kPathSeparator);
    newPath->append(g_currentTestName);
    newPath->append(L"-");
    newPath->append(minidumpID);
    newPath->append(L".dmp");

    // May use the heap, but oh well.  If this fails, we'll just have the
    // original dump file lying around.
    _wrename(origPath->c_str(), newPath->c_str());

    return false;
}
#endif

}  // namespace

int main(int argc, char* argv[]) {
  base::EnableTerminationOnHeapCorruption();
#ifdef _CRTDBG_MAP_ALLOC
  _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
#endif
  // Some tests may use base::Singleton<>, thus we need to instanciate
  // the AtExitManager or else we will leak objects.
  base::AtExitManager at_exit_manager;

#if defined(OS_LINUX)
  gtk_init(&argc, &argv);
  // Only parse the command line after GTK's had a crack at it.
  CommandLine::SetArgcArgv(argc, argv);
#endif

  CommandLine parsed_command_line;
#if defined(OS_WIN)
  if (parsed_command_line.HasSwitch(test_shell::kStartupDialog))
      MessageBox(NULL, L"attach to me?", L"test_shell", MB_OK);
#endif

  // Allocate a message loop for this thread.  Although it is not used
  // directly, its constructor sets up some necessary state.
  MessageLoopForUI main_message_loop;

  bool suppress_error_dialogs = (
#if defined(OS_WIN)
       GetEnvironmentVariable(L"CHROME_HEADLESS", NULL, 0) ||
#endif
       parsed_command_line.HasSwitch(test_shell::kNoErrorDialogs) ||
       parsed_command_line.HasSwitch(test_shell::kLayoutTests));
  bool layout_test_mode =
      parsed_command_line.HasSwitch(test_shell::kLayoutTests);

  TestShell::InitLogging(suppress_error_dialogs, layout_test_mode);

  // Set this early before we start using WebCore.
  webkit_glue::SetLayoutTestMode(layout_test_mode);

  // Suppress abort message in v8 library in debugging mode.
  // V8 calls abort() when it hits assertion errors.
#if defined(OS_WIN)
  if (suppress_error_dialogs) {
    _set_abort_behavior(0, _WRITE_ABORT_MSG);
  }
#endif

  if (parsed_command_line.HasSwitch(test_shell::kEnableTracing))
    base::TraceLog::StartTracing();

#if defined(OS_WIN)
  // Make the selection of network stacks early on before any consumers try to
  // issue HTTP requests.
  if (parsed_command_line.HasSwitch(test_shell::kUseWinHttp))
    net::HttpNetworkLayer::UseWinHttp(true);
#endif

  net::HttpCache::Mode cache_mode = net::HttpCache::NORMAL;
  bool playback_mode =
    parsed_command_line.HasSwitch(test_shell::kPlaybackMode);
  bool record_mode =
    parsed_command_line.HasSwitch(test_shell::kRecordMode);

  if (playback_mode)
    cache_mode = net::HttpCache::PLAYBACK;
  else if (record_mode)
    cache_mode = net::HttpCache::RECORD;

  if (layout_test_mode ||
      parsed_command_line.HasSwitch(test_shell::kEnableFileCookies))
    net::CookieMonster::EnableFileScheme();

  std::wstring cache_path =
      parsed_command_line.GetSwitchValue(test_shell::kCacheDir);
  if (cache_path.empty()) {
    PathService::Get(base::DIR_EXE, &cache_path);
    file_util::AppendToPath(&cache_path, L"cache");
  }

  // Initializing with a default context, which means no on-disk cookie DB,
  // and no support for directory listings.
  SimpleResourceLoaderBridge::Init(
      new TestShellRequestContext(cache_path, cache_mode));

  // Load ICU data tables
  icu_util::Initialize();

#if defined(OS_WIN)
  // Config the network module so it has access to a limited set of resources.
  net::NetModule::SetResourceProvider(NetResourceProvider);

  INITCOMMONCONTROLSEX InitCtrlEx;

  InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
  InitCtrlEx.dwICC  = ICC_STANDARD_CLASSES;
  InitCommonControlsEx(&InitCtrlEx);

  // Register the Ahem font used by layout tests.
  DWORD num_fonts = 1;
  void* font_ptr;
  size_t font_size;
  if (base::GetDataResourceFromModule(::GetModuleHandle(NULL), IDR_AHEM_FONT,
                                      &font_ptr, &font_size)) {
    HANDLE rc = AddFontMemResourceEx(font_ptr, font_size, 0, &num_fonts);
    DCHECK(rc != 0);
  }
#endif

  bool interactive = !layout_test_mode;
  TestShell::InitializeTestShell(interactive);

  if (parsed_command_line.HasSwitch(test_shell::kAllowScriptsToCloseWindows))
    TestShell::SetAllowScriptsToCloseWindows();

  // Disable user themes for layout tests so pixel tests are consistent.
#if defined(OS_WIN)
  if (!interactive)
    gfx::NativeTheme::instance()->DisableTheming();
#endif

  if (parsed_command_line.HasSwitch(test_shell::kTestShellTimeOut)) {
    const std::wstring timeout_str = parsed_command_line.GetSwitchValue(
        test_shell::kTestShellTimeOut);
    int timeout_ms = static_cast<int>(StringToInt64(timeout_str.c_str()));
    if (timeout_ms > 0)
      TestShell::SetFileTestTimeout(timeout_ms);
  }

#if defined(OS_WIN)
  // Initialize global strings
  TestShell::RegisterWindowClass();
#endif

  // Treat the first loose value as the initial URL to open.
  std::wstring uri;

  // Default to a homepage if we're interactive.
  if (interactive) {
    PathService::Get(base::DIR_SOURCE_ROOT, &uri);
    file_util::AppendToPath(&uri, L"webkit");
    file_util::AppendToPath(&uri, L"data");
    file_util::AppendToPath(&uri, L"test_shell");
    file_util::AppendToPath(&uri, L"index.html");
  }

  if (parsed_command_line.GetLooseValueCount() > 0) {
    CommandLine::LooseValueIterator iter(
        parsed_command_line.GetLooseValuesBegin());
    uri = *iter;
  }

#if defined(OS_WIN)
  if (parsed_command_line.HasSwitch(test_shell::kCrashDumps)) {
    std::wstring dir(
        parsed_command_line.GetSwitchValue(test_shell::kCrashDumps));
    new google_breakpad::ExceptionHandler(dir, 0, &MinidumpCallback, 0, true);
  }
#endif

  std::wstring js_flags =
    parsed_command_line.GetSwitchValue(test_shell::kJavaScriptFlags);
  // Test shell always exposes the GC.
  CommandLine::AppendSwitch(&js_flags, L"expose-gc");
  webkit_glue::SetJavaScriptFlags(js_flags);
  // Also expose GCController to JavaScript.
  webkit_glue::SetShouldExposeGCController(true);

  // Load and initialize the stats table.  Attempt to construct a somewhat
  // unique name to isolate separate instances from each other.
  StatsTable *table = new StatsTable(
      kStatsFilePrefix + Uint64ToWString(base::RandUint64()),
      kStatsFileThreads,
      kStatsFileCounters);
  StatsTable::set_current(table);

  TestShell* shell;
  if (TestShell::CreateNewWindow(uri, &shell)) {
#if defined(OS_WIN)
    if (record_mode || playback_mode) {
      // Move the window to the upper left corner for consistent
      // record/playback mode.  For automation, we want this to work
      // on build systems where the script invoking us is a background
      // process.  So for this case, make our window the topmost window
      // as well.
      ForegroundHelper::SetForeground(shell->mainWnd());
      ::SetWindowPos(shell->mainWnd(), HWND_TOP, 0, 0, 600, 800, 0);
      // Tell webkit as well.
      webkit_glue::SetRecordPlaybackMode(true);
    }
#endif

    shell->Show(shell->webView(), NEW_WINDOW);

    if (parsed_command_line.HasSwitch(test_shell::kDumpStatsTable))
      shell->DumpStatsTableOnExit();

#if defined(OS_WIN)
    bool no_events = parsed_command_line.HasSwitch(test_shell::kNoEvents);
    if ((record_mode || playback_mode) && !no_events) {
      std::wstring script_path = cache_path;
      // Create the cache directory in case it doesn't exist.
      file_util::CreateDirectory(cache_path);
      file_util::AppendToPath(&script_path, L"script.log");
      if (record_mode)
        base::EventRecorder::current()->StartRecording(script_path);
      if (playback_mode)
        base::EventRecorder::current()->StartPlayback(script_path);
    }
#endif

    if (parsed_command_line.HasSwitch(test_shell::kDebugMemoryInUse)) {
      base::MemoryDebug::SetMemoryInUseEnabled(true);
      // Dump all in use memory at startup
      base::MemoryDebug::DumpAllMemoryInUse();
    }

    // See if we need to run the tests.
    if (layout_test_mode) {
      // Set up for the kind of test requested.
      TestShell::TestParams params;
      if (parsed_command_line.HasSwitch(test_shell::kDumpPixels)) {
        // The pixel test flag also gives the image file name to use.
        params.dump_pixels = true;
        params.pixel_file_name = parsed_command_line.GetSwitchValue(
            test_shell::kDumpPixels);
        if (params.pixel_file_name.size() == 0) {
          fprintf(stderr, "No file specified for pixel tests");
          exit(1);
        }
      }
      if (parsed_command_line.HasSwitch(test_shell::kNoTree)) {
          params.dump_tree = false;
      }

      if (uri.length() == 0) {
        // Watch stdin for URLs.
        char filenameBuffer[2048];
        while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
          char *newLine = strchr(filenameBuffer, '\n');
          if (newLine)
            *newLine = '\0';
          if (!*filenameBuffer)
            continue;

#if defined(OS_WIN)
          SetCurrentTestName(filenameBuffer);
#endif

          if (!TestShell::RunFileTest(filenameBuffer, params))
            break;
        }
      } else {
        TestShell::RunFileTest(WideToUTF8(uri).c_str(), params);
      }

      shell->CallJSGC();
      shell->CallJSGC();
      if (shell) delete shell;
    } else {
      MessageLoop::current()->Run();
    }

    // Flush any remaining messages.  This ensures that any accumulated
    // Task objects get destroyed before we exit, which avoids noise in
    // purify leak-test results.
    MessageLoop::current()->RunAllPending();

#if defined(OS_WIN)
    if (record_mode)
      base::EventRecorder::current()->StopRecording();
    if (playback_mode)
      base::EventRecorder::current()->StopPlayback();
#endif
  }

  TestShell::ShutdownTestShell();
  TestShell::CleanupLogging();

  // Tear down shared StatsTable; prevents unit_tests from leaking it.
  StatsTable::set_current(NULL);
  delete table;

#ifdef _CRTDBG_MAP_ALLOC
  _CrtDumpMemoryLeaks();
#endif
  return 0;
}
<|endoftext|>