<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 <EGL/egl.h>

#include "build/build_config.h"
#if defined(OS_LINUX)
#include "app/x11_util.h"
#define EGL_HAS_PBUFFERS 1
#endif
#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "app/gfx/gl/gl_bindings.h"
#include "app/gfx/gl/gl_context_egl.h"

namespace gfx {

namespace {

// The EGL configuration to use.
EGLDisplay g_display;
EGLConfig g_config;

// Returns the last EGL error as a string.
const char* GetLastEGLErrorString() {
  EGLint error = eglGetError();
  switch (error) {
    case EGL_SUCCESS:
      return "EGL_SUCCESS";
    case EGL_BAD_ACCESS:
      return "EGL_BAD_ACCESS";
    case EGL_BAD_ALLOC:
      return "EGL_BAD_ALLOC";
    case EGL_BAD_ATTRIBUTE:
      return "EGL_BAD_ATTRIBUTE";
    case EGL_BAD_CONTEXT:
      return "EGL_BAD_CONTEXT";
    case EGL_BAD_CONFIG:
      return "EGL_BAD_CONFIG";
    case EGL_BAD_CURRENT_SURFACE:
      return "EGL_BAD_CURRENT_SURFACE";
    case EGL_BAD_DISPLAY:
      return "EGL_BAD_DISPLAY";
    case EGL_BAD_SURFACE:
      return "EGL_BAD_SURFACE";
    case EGL_BAD_MATCH:
      return "EGL_BAD_MATCH";
    case EGL_BAD_PARAMETER:
      return "EGL_BAD_PARAMETER";
    case EGL_BAD_NATIVE_PIXMAP:
      return "EGL_BAD_NATIVE_PIXMAP";
    case EGL_BAD_NATIVE_WINDOW:
      return "EGL_BAD_NATIVE_WINDOW";
    default:
      return "UNKNOWN";
  }
}
}  // namespace anonymous

bool BaseEGLContext::InitializeOneOff() {
  static bool initialized = false;
  if (initialized)
    return true;

#ifdef OS_LINUX
  EGLNativeDisplayType native_display = x11_util::GetXDisplay();
#else
  EGLNativeDisplayType native_display = EGL_DEFAULT_DISPLAY;
#endif
  g_display = eglGetDisplay(native_display);
  if (!g_display) {
    LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString();
    return false;
  }

  if (!eglInitialize(g_display, NULL, NULL)) {
    LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString();
    return false;
  }

  // Choose an EGL configuration.
  static const EGLint kConfigAttribs[] = {
    EGL_BUFFER_SIZE, 32,
    EGL_ALPHA_SIZE, 8,
    EGL_BLUE_SIZE, 8,
    EGL_RED_SIZE, 8,
    EGL_DEPTH_SIZE, 16,
    EGL_STENCIL_SIZE, 8,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#ifdef EGL_HAS_PBUFFERS
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
#else
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
#endif
    EGL_NONE
  };

  EGLint num_configs;
  if (!eglChooseConfig(g_display,
                       kConfigAttribs,
                       NULL,
                       0,
                       &num_configs)) {
    LOG(ERROR) << "eglChooseConfig failed failed with error "
               << GetLastEGLErrorString();
    return false;
  }

  if (num_configs == 0) {
    LOG(ERROR) << "No suitable EGL configs found.";
    return false;
  }

  scoped_array<EGLConfig> configs(new EGLConfig[num_configs]);
  if (!eglChooseConfig(g_display,
                       kConfigAttribs,
                       configs.get(),
                       num_configs,
                       &num_configs)) {
    LOG(ERROR) << "eglChooseConfig failed with error "
               << GetLastEGLErrorString();
    return false;
  }

  g_config = configs[0];

  initialized = true;
  return true;
}

EGLDisplay BaseEGLContext::GetDisplay() {
  return g_display;
}

std::string BaseEGLContext::GetExtensions() {
  const char* extensions = eglQueryString(g_display, EGL_EXTENSIONS);
  if (!extensions)
    return GLContext::GetExtensions();

  return GLContext::GetExtensions() + " " + extensions;
}

NativeViewEGLContext::NativeViewEGLContext(void* window)
    : window_(window),
      surface_(NULL),
      context_(NULL)
{
}

NativeViewEGLContext::~NativeViewEGLContext() {
}

bool NativeViewEGLContext::Initialize() {
  DCHECK(!context_);

  // Create a surface for the native window.
  EGLNativeWindowType native_window =
      reinterpret_cast<EGLNativeWindowType>(window_);
  surface_ = eglCreateWindowSurface(g_display, g_config, native_window, NULL);

  if (!surface_) {
    LOG(ERROR) << "eglCreateWindowSurface failed with error "
               << GetLastEGLErrorString();
    Destroy();
    return false;
  }

  // Create a context.
  context_ = eglCreateContext(g_display, g_config, NULL, NULL);
  if (!context_) {
    LOG(ERROR) << "eglCreateContext failed with error "
               << GetLastEGLErrorString();
    Destroy();
    return false;
  }

  if (!MakeCurrent()) {
    LOG(ERROR) << "MakeCurrent failed.";
    Destroy();
    return false;
  }

  if (!InitializeCommon()) {
    LOG(ERROR) << "GLContext::InitializeCommon failed.";
    Destroy();
    return false;
  }

  return true;
}

void NativeViewEGLContext::Destroy() {
  if (context_) {
    if (!eglDestroyContext(g_display, context_)) {
      LOG(ERROR) << "eglDestroyContext failed with error "
                 << GetLastEGLErrorString();
    }

    context_ = NULL;
  }

  if (surface_) {
    if (!eglDestroySurface(g_display, surface_)) {
      LOG(ERROR) << "eglDestroySurface failed with error "
                 << GetLastEGLErrorString();
    }

    surface_ = NULL;
  }
}

bool NativeViewEGLContext::MakeCurrent() {
  DCHECK(context_);
  if (!eglMakeCurrent(g_display,
                      surface_, surface_,
                      context_)) {
    VLOG(1) << "eglMakeCurrent failed with error "
            << GetLastEGLErrorString();
    return false;
  }

  return true;
}

bool NativeViewEGLContext::IsCurrent() {
  DCHECK(context_);
  return context_ == eglGetCurrentContext();
}

bool NativeViewEGLContext::IsOffscreen() {
  return false;
}

bool NativeViewEGLContext::SwapBuffers() {
  if (!eglSwapBuffers(g_display, surface_)) {
    VLOG(1) << "eglSwapBuffers failed with error "
            << GetLastEGLErrorString();
    return false;
  }

  return true;
}

gfx::Size NativeViewEGLContext::GetSize() {
#if defined(OS_WIN)
  RECT rect;
  if (!GetClientRect(static_cast<HWND>(window_), &rect)) {
    DCHECK(false) << "GetClientRect failed.";
    return gfx::Size();
  }

  return gfx::Size(rect.right - rect.left, rect.bottom - rect.top);
#else
  // TODO(piman): This doesn't work correctly on Windows yet, the size doesn't
  // get updated on resize. When it does, we can share the code.
  EGLint width;
  EGLint height;
  if (!eglQuerySurface(g_display, surface_, EGL_WIDTH, &width) ||
      !eglQuerySurface(g_display, surface_, EGL_HEIGHT, &height)) {
    NOTREACHED() << "eglQuerySurface failed with error "
                 << GetLastEGLErrorString();
    return gfx::Size();
  }

  return gfx::Size(width, height);
#endif
}

void* NativeViewEGLContext::GetHandle() {
  return context_;
}

void NativeViewEGLContext::SetSwapInterval(int interval) {
  DCHECK(IsCurrent());
  if (!eglSwapInterval(g_display, interval)) {
    LOG(ERROR) << "eglSwapInterval failed with error "
               << GetLastEGLErrorString();
  }
}

EGLSurface NativeViewEGLContext::GetSurface() {
  return surface_;
}

SecondaryEGLContext::SecondaryEGLContext()
    : surface_(NULL),
      own_surface_(false),
      context_(NULL)
{
}

SecondaryEGLContext::~SecondaryEGLContext() {
}

bool SecondaryEGLContext::Initialize(GLContext* shared_context) {
  DCHECK(!context_);

  static const EGLint kContextAttributes[] = {
    EGL_CONTEXT_CLIENT_VERSION, 2,
    EGL_NONE
  };

  if (shared_context) {
    surface_ = static_cast<BaseEGLContext*>(shared_context)->GetSurface();
    own_surface_ = false;

    // Create a context.
    context_ = eglCreateContext(g_display,
                                g_config,
                                shared_context->GetHandle(),
                                kContextAttributes);
  } else {
#ifdef EGL_HAS_PBUFFERS
    static const EGLint kPbufferAttribs[] = {
      EGL_WIDTH, 1,
      EGL_HEIGHT, 1,
      EGL_NONE
    };

    surface_ = eglCreatePbufferSurface(g_display, g_config, kPbufferAttribs);
    if (!surface_) {
      LOG(ERROR) << "eglCreatePbufferSurface failed with error "
                 << GetLastEGLErrorString();
      return false;
    }
    own_surface_ = true;

    context_ = eglCreateContext(g_display, g_config, NULL, kContextAttributes);
#else
    NOTIMPLEMENTED() << "Offscreen non-shared GLES context";
    return false;
#endif
  }

  if (!context_) {
    LOG(ERROR) << "eglCreateContext failed with error "
               << GetLastEGLErrorString();
    Destroy();
    return false;
  }

  return true;
}

void SecondaryEGLContext::Destroy() {
  if (own_surface_) {
    if (!eglDestroySurface(g_display, surface_)) {
      LOG(ERROR) << "eglDestroySurface failed with error "
                 << GetLastEGLErrorString();
    }

    own_surface_ = false;
  }
  surface_ = NULL;

  if (context_) {
    if (!eglDestroyContext(g_display, context_)) {
      LOG(ERROR) << "eglDestroyContext failed with error "
                 << GetLastEGLErrorString();
    }

    context_ = NULL;
  }
}

bool SecondaryEGLContext::MakeCurrent() {
  DCHECK(context_);
  if (!eglMakeCurrent(g_display,
                      surface_, surface_,
                      context_)) {
    VLOG(1) << "eglMakeCurrent failed with error "
            << GetLastEGLErrorString();
    return false;
  }

  return true;
}

bool SecondaryEGLContext::IsCurrent() {
  DCHECK(context_);
  return context_ == eglGetCurrentContext();
}

bool SecondaryEGLContext::IsOffscreen() {
  return true;
}

bool SecondaryEGLContext::SwapBuffers() {
  NOTREACHED() << "Attempted to call SwapBuffers on a SecondaryEGLContext.";
  return false;
}

gfx::Size SecondaryEGLContext::GetSize() {
  NOTREACHED() << "Should not be requesting size of this SecondaryEGLContext.";
  return gfx::Size(1, 1);
}

void* SecondaryEGLContext::GetHandle() {
  return context_;
}

void SecondaryEGLContext::SetSwapInterval(int interval) {
  DCHECK(IsCurrent());
  NOTREACHED() << "Attempt to call SetSwapInterval on a SecondaryEGLContext.";
}

EGLSurface SecondaryEGLContext::GetSurface() {
  return surface_;
}

}  // namespace gfx
<commit_msg>Specify client version 2 when creating EGL contexts.<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 <EGL/egl.h>

#include "build/build_config.h"
#if defined(OS_LINUX)
#include "app/x11_util.h"
#define EGL_HAS_PBUFFERS 1
#endif
#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "app/gfx/gl/gl_bindings.h"
#include "app/gfx/gl/gl_context_egl.h"

namespace gfx {

namespace {

// The EGL configuration to use.
EGLDisplay g_display;
EGLConfig g_config;

// Returns the last EGL error as a string.
const char* GetLastEGLErrorString() {
  EGLint error = eglGetError();
  switch (error) {
    case EGL_SUCCESS:
      return "EGL_SUCCESS";
    case EGL_BAD_ACCESS:
      return "EGL_BAD_ACCESS";
    case EGL_BAD_ALLOC:
      return "EGL_BAD_ALLOC";
    case EGL_BAD_ATTRIBUTE:
      return "EGL_BAD_ATTRIBUTE";
    case EGL_BAD_CONTEXT:
      return "EGL_BAD_CONTEXT";
    case EGL_BAD_CONFIG:
      return "EGL_BAD_CONFIG";
    case EGL_BAD_CURRENT_SURFACE:
      return "EGL_BAD_CURRENT_SURFACE";
    case EGL_BAD_DISPLAY:
      return "EGL_BAD_DISPLAY";
    case EGL_BAD_SURFACE:
      return "EGL_BAD_SURFACE";
    case EGL_BAD_MATCH:
      return "EGL_BAD_MATCH";
    case EGL_BAD_PARAMETER:
      return "EGL_BAD_PARAMETER";
    case EGL_BAD_NATIVE_PIXMAP:
      return "EGL_BAD_NATIVE_PIXMAP";
    case EGL_BAD_NATIVE_WINDOW:
      return "EGL_BAD_NATIVE_WINDOW";
    default:
      return "UNKNOWN";
  }
}
}  // namespace anonymous

bool BaseEGLContext::InitializeOneOff() {
  static bool initialized = false;
  if (initialized)
    return true;

#ifdef OS_LINUX
  EGLNativeDisplayType native_display = x11_util::GetXDisplay();
#else
  EGLNativeDisplayType native_display = EGL_DEFAULT_DISPLAY;
#endif
  g_display = eglGetDisplay(native_display);
  if (!g_display) {
    LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString();
    return false;
  }

  if (!eglInitialize(g_display, NULL, NULL)) {
    LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString();
    return false;
  }

  // Choose an EGL configuration.
  static const EGLint kConfigAttribs[] = {
    EGL_BUFFER_SIZE, 32,
    EGL_ALPHA_SIZE, 8,
    EGL_BLUE_SIZE, 8,
    EGL_RED_SIZE, 8,
    EGL_DEPTH_SIZE, 16,
    EGL_STENCIL_SIZE, 8,
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
#ifdef EGL_HAS_PBUFFERS
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
#else
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
#endif
    EGL_NONE
  };

  EGLint num_configs;
  if (!eglChooseConfig(g_display,
                       kConfigAttribs,
                       NULL,
                       0,
                       &num_configs)) {
    LOG(ERROR) << "eglChooseConfig failed failed with error "
               << GetLastEGLErrorString();
    return false;
  }

  if (num_configs == 0) {
    LOG(ERROR) << "No suitable EGL configs found.";
    return false;
  }

  scoped_array<EGLConfig> configs(new EGLConfig[num_configs]);
  if (!eglChooseConfig(g_display,
                       kConfigAttribs,
                       configs.get(),
                       num_configs,
                       &num_configs)) {
    LOG(ERROR) << "eglChooseConfig failed with error "
               << GetLastEGLErrorString();
    return false;
  }

  g_config = configs[0];

  initialized = true;
  return true;
}

EGLDisplay BaseEGLContext::GetDisplay() {
  return g_display;
}

std::string BaseEGLContext::GetExtensions() {
  const char* extensions = eglQueryString(g_display, EGL_EXTENSIONS);
  if (!extensions)
    return GLContext::GetExtensions();

  return GLContext::GetExtensions() + " " + extensions;
}

NativeViewEGLContext::NativeViewEGLContext(void* window)
    : window_(window),
      surface_(NULL),
      context_(NULL)
{
}

NativeViewEGLContext::~NativeViewEGLContext() {
}

bool NativeViewEGLContext::Initialize() {
  DCHECK(!context_);

  // Create a surface for the native window.
  EGLNativeWindowType native_window =
      reinterpret_cast<EGLNativeWindowType>(window_);
  surface_ = eglCreateWindowSurface(g_display, g_config, native_window, NULL);

  if (!surface_) {
    LOG(ERROR) << "eglCreateWindowSurface failed with error "
               << GetLastEGLErrorString();
    Destroy();
    return false;
  }

  static const EGLint kContextAttributes[] = {
    EGL_CONTEXT_CLIENT_VERSION, 2,
    EGL_NONE
  };

  context_ = eglCreateContext(g_display, g_config, NULL, kContextAttributes);
  if (!context_) {
    LOG(ERROR) << "eglCreateContext failed with error "
               << GetLastEGLErrorString();
    Destroy();
    return false;
  }

  if (!MakeCurrent()) {
    LOG(ERROR) << "MakeCurrent failed.";
    Destroy();
    return false;
  }

  if (!InitializeCommon()) {
    LOG(ERROR) << "GLContext::InitializeCommon failed.";
    Destroy();
    return false;
  }

  return true;
}

void NativeViewEGLContext::Destroy() {
  if (context_) {
    if (!eglDestroyContext(g_display, context_)) {
      LOG(ERROR) << "eglDestroyContext failed with error "
                 << GetLastEGLErrorString();
    }

    context_ = NULL;
  }

  if (surface_) {
    if (!eglDestroySurface(g_display, surface_)) {
      LOG(ERROR) << "eglDestroySurface failed with error "
                 << GetLastEGLErrorString();
    }

    surface_ = NULL;
  }
}

bool NativeViewEGLContext::MakeCurrent() {
  DCHECK(context_);
  if (!eglMakeCurrent(g_display,
                      surface_, surface_,
                      context_)) {
    VLOG(1) << "eglMakeCurrent failed with error "
            << GetLastEGLErrorString();
    return false;
  }

  return true;
}

bool NativeViewEGLContext::IsCurrent() {
  DCHECK(context_);
  return context_ == eglGetCurrentContext();
}

bool NativeViewEGLContext::IsOffscreen() {
  return false;
}

bool NativeViewEGLContext::SwapBuffers() {
  if (!eglSwapBuffers(g_display, surface_)) {
    VLOG(1) << "eglSwapBuffers failed with error "
            << GetLastEGLErrorString();
    return false;
  }

  return true;
}

gfx::Size NativeViewEGLContext::GetSize() {
#if defined(OS_WIN)
  RECT rect;
  if (!GetClientRect(static_cast<HWND>(window_), &rect)) {
    DCHECK(false) << "GetClientRect failed.";
    return gfx::Size();
  }

  return gfx::Size(rect.right - rect.left, rect.bottom - rect.top);
#else
  // TODO(piman): This doesn't work correctly on Windows yet, the size doesn't
  // get updated on resize. When it does, we can share the code.
  EGLint width;
  EGLint height;
  if (!eglQuerySurface(g_display, surface_, EGL_WIDTH, &width) ||
      !eglQuerySurface(g_display, surface_, EGL_HEIGHT, &height)) {
    NOTREACHED() << "eglQuerySurface failed with error "
                 << GetLastEGLErrorString();
    return gfx::Size();
  }

  return gfx::Size(width, height);
#endif
}

void* NativeViewEGLContext::GetHandle() {
  return context_;
}

void NativeViewEGLContext::SetSwapInterval(int interval) {
  DCHECK(IsCurrent());
  if (!eglSwapInterval(g_display, interval)) {
    LOG(ERROR) << "eglSwapInterval failed with error "
               << GetLastEGLErrorString();
  }
}

EGLSurface NativeViewEGLContext::GetSurface() {
  return surface_;
}

SecondaryEGLContext::SecondaryEGLContext()
    : surface_(NULL),
      own_surface_(false),
      context_(NULL)
{
}

SecondaryEGLContext::~SecondaryEGLContext() {
}

bool SecondaryEGLContext::Initialize(GLContext* shared_context) {
  DCHECK(!context_);

  static const EGLint kContextAttributes[] = {
    EGL_CONTEXT_CLIENT_VERSION, 2,
    EGL_NONE
  };

  if (shared_context) {
    surface_ = static_cast<BaseEGLContext*>(shared_context)->GetSurface();
    own_surface_ = false;

    // Create a context.
    context_ = eglCreateContext(g_display,
                                g_config,
                                shared_context->GetHandle(),
                                kContextAttributes);
  } else {
#ifdef EGL_HAS_PBUFFERS
    static const EGLint kPbufferAttribs[] = {
      EGL_WIDTH, 1,
      EGL_HEIGHT, 1,
      EGL_NONE
    };

    surface_ = eglCreatePbufferSurface(g_display, g_config, kPbufferAttribs);
    if (!surface_) {
      LOG(ERROR) << "eglCreatePbufferSurface failed with error "
                 << GetLastEGLErrorString();
      return false;
    }
    own_surface_ = true;

    context_ = eglCreateContext(g_display, g_config, NULL, kContextAttributes);
#else
    NOTIMPLEMENTED() << "Offscreen non-shared GLES context";
    return false;
#endif
  }

  if (!context_) {
    LOG(ERROR) << "eglCreateContext failed with error "
               << GetLastEGLErrorString();
    Destroy();
    return false;
  }

  return true;
}

void SecondaryEGLContext::Destroy() {
  if (own_surface_) {
    if (!eglDestroySurface(g_display, surface_)) {
      LOG(ERROR) << "eglDestroySurface failed with error "
                 << GetLastEGLErrorString();
    }

    own_surface_ = false;
  }
  surface_ = NULL;

  if (context_) {
    if (!eglDestroyContext(g_display, context_)) {
      LOG(ERROR) << "eglDestroyContext failed with error "
                 << GetLastEGLErrorString();
    }

    context_ = NULL;
  }
}

bool SecondaryEGLContext::MakeCurrent() {
  DCHECK(context_);
  if (!eglMakeCurrent(g_display,
                      surface_, surface_,
                      context_)) {
    VLOG(1) << "eglMakeCurrent failed with error "
            << GetLastEGLErrorString();
    return false;
  }

  return true;
}

bool SecondaryEGLContext::IsCurrent() {
  DCHECK(context_);
  return context_ == eglGetCurrentContext();
}

bool SecondaryEGLContext::IsOffscreen() {
  return true;
}

bool SecondaryEGLContext::SwapBuffers() {
  NOTREACHED() << "Attempted to call SwapBuffers on a SecondaryEGLContext.";
  return false;
}

gfx::Size SecondaryEGLContext::GetSize() {
  NOTREACHED() << "Should not be requesting size of this SecondaryEGLContext.";
  return gfx::Size(1, 1);
}

void* SecondaryEGLContext::GetHandle() {
  return context_;
}

void SecondaryEGLContext::SetSwapInterval(int interval) {
  DCHECK(IsCurrent());
  NOTREACHED() << "Attempt to call SetSwapInterval on a SecondaryEGLContext.";
}

EGLSurface SecondaryEGLContext::GetSurface() {
  return surface_;
}

}  // namespace gfx
<|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 "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/autocomplete/autocomplete_edit.h"
#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/location_bar.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

// Basic test is crashy on Mac
// http://crbug.com/49324
#if defined(OS_MAC)
#define MAYBE_Basic DISABLED_Basic
#else
#define MAYBE_Basic Basic
#endif

// Autocomplete test is flaky on ChromeOS.
// http://crbug.com/52928
#if defined(OS_CHROMEOS)
#define MAYBE_Autocomplete FLAKY_Autocomplete
#else
#define MAYBE_Autocomplete Autocomplete
#endif

namespace {

std::wstring AutocompleteResultAsString(const AutocompleteResult& result) {
  std::wstring output(StringPrintf(L"{%d} ", result.size()));
  for (size_t i = 0; i < result.size(); ++i) {
    AutocompleteMatch match = result.match_at(i);
    std::wstring provider_name(ASCIIToWide(match.provider->name()));
    output.append(StringPrintf(L"[\"%ls\" by \"%ls\"] ",
                               match.contents.c_str(),
                               provider_name.c_str()));
  }
  return output;
}

}  // namespace

class AutocompleteBrowserTest : public InProcessBrowserTest {
 protected:
  LocationBar* GetLocationBar() const {
    return browser()->window()->GetLocationBar();
  }

  AutocompleteController* GetAutocompleteController() const {
    return GetLocationBar()->location_entry()->model()->popup_model()->
        autocomplete_controller();
  }
};

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, MAYBE_Basic) {
  LocationBar* location_bar = GetLocationBar();

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  // TODO(phajdan.jr): check state of IsSelectAll when it's consistent across
  // platforms.

  location_bar->FocusLocation(true);

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->SetUserText(L"chrome");

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(L"chrome", location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->RevertAll();

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->SetUserText(L"chrome");
  location_bar->Revert();

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, MAYBE_Autocomplete) {
  // The results depend on the history backend being loaded. Make sure it is
  // loaded so that the autocomplete results are consistent.
  ui_test_utils::WaitForHistoryToLoad(browser());

  LocationBar* location_bar = GetLocationBar();
  AutocompleteController* autocomplete_controller = GetAutocompleteController();

  {
    autocomplete_controller->Start(L"chrome", std::wstring(),
                                   true, false, true);

    EXPECT_TRUE(autocomplete_controller->done());
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(std::wstring(), location_bar->location_entry()->GetText());
    EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    ASSERT_EQ(1U, result.size()) << AutocompleteResultAsString(result);
    AutocompleteMatch match = result.match_at(0);
    EXPECT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, match.type);
    EXPECT_FALSE(match.deletable);
  }

  {
    location_bar->Revert();

    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
              location_bar->location_entry()->GetText());
    EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    EXPECT_TRUE(result.empty()) << AutocompleteResultAsString(result);
  }
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, TabAwayRevertSelect) {
  // http://code.google.com/p/chromium/issues/detail?id=38385
  // Make sure that tabbing away from an empty omnibar causes a revert
  // and select all.
  LocationBar* location_bar = GetLocationBar();
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  location_bar->location_entry()->SetUserText(L"");
  Browser::AddTabWithURLParams params(GURL(chrome::kAboutBlankURL),
                                      PageTransition::START_PAGE);
  browser()->AddTabWithURL(&params);
  EXPECT_EQ(browser(), params.target);
  ui_test_utils::WaitForNavigation(
      &browser()->GetSelectedTabContents()->controller());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  browser()->CloseTab();
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, FocusSearch) {
  LocationBar* location_bar = GetLocationBar();

  // Focus search when omnibox is blank
  {
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
              location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"?", location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, selection_start);
    EXPECT_EQ(1U, selection_end);
  }

  // Focus search when omnibox is _not_ alread in forced query mode.
  {
    location_bar->location_entry()->SetUserText(L"foo");
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"foo", location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"?", location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, selection_start);
    EXPECT_EQ(1U, selection_end);
  }

  // Focus search when omnibox _is_ already in forced query mode, but no query
  // has been typed.
  {
    location_bar->location_entry()->SetUserText(L"?");
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"?", location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"?", location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, selection_start);
    EXPECT_EQ(1U, selection_end);
  }

  // Focus search when omnibox _is_ already in forced query mode, and some query
  // has been typed.
  {
    location_bar->location_entry()->SetUserText(L"?foo");
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"?foo", location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"?foo", location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, std::min(selection_start, selection_end));
    EXPECT_EQ(4U, std::max(selection_start, selection_end));
  }

  // Focus search when omnibox is in forced query mode with leading whitespace.
  {
    location_bar->location_entry()->SetUserText(L"   ?foo");
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"   ?foo", location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"   ?foo", location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(4U, std::min(selection_start, selection_end));
    EXPECT_EQ(7U, std::max(selection_start, selection_end));
  }
}
<commit_msg>Re-enable AutocompleteBrowserTest.Basic<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 "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/autocomplete/autocomplete_edit.h"
#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/history/history.h"
#include "chrome/browser/location_bar.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

// Autocomplete test is flaky on ChromeOS.
// http://crbug.com/52928
#if defined(OS_CHROMEOS)
#define MAYBE_Autocomplete FLAKY_Autocomplete
#else
#define MAYBE_Autocomplete Autocomplete
#endif

namespace {

std::wstring AutocompleteResultAsString(const AutocompleteResult& result) {
  std::wstring output(StringPrintf(L"{%d} ", result.size()));
  for (size_t i = 0; i < result.size(); ++i) {
    AutocompleteMatch match = result.match_at(i);
    std::wstring provider_name(ASCIIToWide(match.provider->name()));
    output.append(StringPrintf(L"[\"%ls\" by \"%ls\"] ",
                               match.contents.c_str(),
                               provider_name.c_str()));
  }
  return output;
}

}  // namespace

class AutocompleteBrowserTest : public InProcessBrowserTest {
 protected:
  LocationBar* GetLocationBar() const {
    return browser()->window()->GetLocationBar();
  }

  AutocompleteController* GetAutocompleteController() const {
    return GetLocationBar()->location_entry()->model()->popup_model()->
        autocomplete_controller();
  }
};

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, Basic) {
  LocationBar* location_bar = GetLocationBar();

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  // TODO(phajdan.jr): check state of IsSelectAll when it's consistent across
  // platforms.

  location_bar->FocusLocation(true);

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->SetUserText(L"chrome");

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(L"chrome", location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->RevertAll();

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());

  location_bar->location_entry()->SetUserText(L"chrome");
  location_bar->Revert();

  EXPECT_EQ(std::wstring(), location_bar->GetInputString());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, MAYBE_Autocomplete) {
  // The results depend on the history backend being loaded. Make sure it is
  // loaded so that the autocomplete results are consistent.
  ui_test_utils::WaitForHistoryToLoad(browser());

  LocationBar* location_bar = GetLocationBar();
  AutocompleteController* autocomplete_controller = GetAutocompleteController();

  {
    autocomplete_controller->Start(L"chrome", std::wstring(),
                                   true, false, true);

    EXPECT_TRUE(autocomplete_controller->done());
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(std::wstring(), location_bar->location_entry()->GetText());
    EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    ASSERT_EQ(1U, result.size()) << AutocompleteResultAsString(result);
    AutocompleteMatch match = result.match_at(0);
    EXPECT_EQ(AutocompleteMatch::SEARCH_WHAT_YOU_TYPED, match.type);
    EXPECT_FALSE(match.deletable);
  }

  {
    location_bar->Revert();

    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
              location_bar->location_entry()->GetText());
    EXPECT_FALSE(location_bar->location_entry()->IsSelectAll());
    const AutocompleteResult& result = autocomplete_controller->result();
    EXPECT_TRUE(result.empty()) << AutocompleteResultAsString(result);
  }
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, TabAwayRevertSelect) {
  // http://code.google.com/p/chromium/issues/detail?id=38385
  // Make sure that tabbing away from an empty omnibar causes a revert
  // and select all.
  LocationBar* location_bar = GetLocationBar();
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  location_bar->location_entry()->SetUserText(L"");
  Browser::AddTabWithURLParams params(GURL(chrome::kAboutBlankURL),
                                      PageTransition::START_PAGE);
  browser()->AddTabWithURL(&params);
  EXPECT_EQ(browser(), params.target);
  ui_test_utils::WaitForNavigation(
      &browser()->GetSelectedTabContents()->controller());
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  browser()->CloseTab();
  EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
            location_bar->location_entry()->GetText());
  EXPECT_TRUE(location_bar->location_entry()->IsSelectAll());
}

IN_PROC_BROWSER_TEST_F(AutocompleteBrowserTest, FocusSearch) {
  LocationBar* location_bar = GetLocationBar();

  // Focus search when omnibox is blank
  {
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(UTF8ToWide(chrome::kAboutBlankURL),
              location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"?", location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, selection_start);
    EXPECT_EQ(1U, selection_end);
  }

  // Focus search when omnibox is _not_ alread in forced query mode.
  {
    location_bar->location_entry()->SetUserText(L"foo");
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"foo", location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"?", location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, selection_start);
    EXPECT_EQ(1U, selection_end);
  }

  // Focus search when omnibox _is_ already in forced query mode, but no query
  // has been typed.
  {
    location_bar->location_entry()->SetUserText(L"?");
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"?", location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"?", location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, selection_start);
    EXPECT_EQ(1U, selection_end);
  }

  // Focus search when omnibox _is_ already in forced query mode, and some query
  // has been typed.
  {
    location_bar->location_entry()->SetUserText(L"?foo");
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"?foo", location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"?foo", location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(1U, std::min(selection_start, selection_end));
    EXPECT_EQ(4U, std::max(selection_start, selection_end));
  }

  // Focus search when omnibox is in forced query mode with leading whitespace.
  {
    location_bar->location_entry()->SetUserText(L"   ?foo");
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"   ?foo", location_bar->location_entry()->GetText());

    location_bar->FocusSearch();
    EXPECT_EQ(std::wstring(), location_bar->GetInputString());
    EXPECT_EQ(L"   ?foo", location_bar->location_entry()->GetText());

    size_t selection_start, selection_end;
    location_bar->location_entry()->GetSelectionBounds(&selection_start,
                                                       &selection_end);
    EXPECT_EQ(4U, std::min(selection_start, selection_end));
    EXPECT_EQ(7U, std::max(selection_start, selection_end));
  }
}
<|endoftext|>


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

#include "chrome/browser/automation/url_request_automation_job.h"

#include "base/message_loop.h"
#include "base/time.h"
#include "chrome/browser/automation/automation_resource_message_filter.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
#include "chrome/test/automation/automation_messages.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"

using base::Time;
using base::TimeDelta;

// The list of filtered headers that are removed from requests sent via
// StartAsync(). These must be lower case.
static const char* kFilteredHeaderStrings[] = {
  "accept",
  "authorization",
  "cache-control",
  "connection",
  "cookie",
  "expect",
  "if-match",
  "if-modified-since",
  "if-none-match",
  "if-range",
  "if-unmodified-since",
  "max-forwards",
  "proxy-authorization",
  "te",
  "upgrade",
  "via"
};

// This class manages the interception of network requests for automation.
// It looks at the request, and creates an intercept job if it indicates
// that it should use automation channel.
// NOTE: All methods must be called on the IO thread.
class AutomationRequestInterceptor : public URLRequest::Interceptor {
 public:
  AutomationRequestInterceptor() {
    URLRequest::RegisterRequestInterceptor(this);
  }

  virtual ~AutomationRequestInterceptor() {
    URLRequest::UnregisterRequestInterceptor(this);
  }

  // URLRequest::Interceptor
  virtual URLRequestJob* MaybeIntercept(URLRequest* request);

 private:
  DISALLOW_COPY_AND_ASSIGN(AutomationRequestInterceptor);
};

URLRequestJob* AutomationRequestInterceptor::MaybeIntercept(
    URLRequest* request) {
  if (request->url().SchemeIs("http") || request->url().SchemeIs("https")) {
    ResourceDispatcherHostRequestInfo* request_info =
        ResourceDispatcherHost::InfoForRequest(request);
    if (request_info) {
      AutomationResourceMessageFilter::AutomationDetails details;
      if (AutomationResourceMessageFilter::LookupRegisteredRenderView(
              request_info->child_id(), request_info->route_id(), &details)) {
        URLRequestAutomationJob* job = new URLRequestAutomationJob(request,
            details.tab_handle, details.filter);
        return job;
      }
    }
  }

  return NULL;
}

static URLRequest::Interceptor* GetAutomationRequestInterceptor() {
  return Singleton<AutomationRequestInterceptor>::get();
}

int URLRequestAutomationJob::instance_count_ = 0;

URLRequestAutomationJob::URLRequestAutomationJob(
    URLRequest* request, int tab, AutomationResourceMessageFilter* filter)
    : URLRequestJob(request), id_(0), tab_(tab), message_filter_(filter),
      pending_buf_size_(0), redirect_status_(0) {
  DLOG(INFO) << "URLRequestAutomationJob create. Count: " << ++instance_count_;
  if (message_filter_) {
    id_ = message_filter_->NewRequestId();
    DCHECK(id_);
  } else {
    NOTREACHED();
  }
}

URLRequestAutomationJob::~URLRequestAutomationJob() {
  DLOG(INFO) << "URLRequestAutomationJob delete. Count: " << --instance_count_;
  Cleanup();
}

bool URLRequestAutomationJob::InitializeInterceptor() {
  // AutomationRequestInterceptor will register itself when it
  // is first created.
  URLRequest::Interceptor* interceptor = GetAutomationRequestInterceptor();
  return (interceptor != NULL);
}

// URLRequestJob Implementation.
void URLRequestAutomationJob::Start() {
  // Start reading asynchronously so that all error reporting and data
  // callbacks happen as they would for network requests.
  MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
      this, &URLRequestAutomationJob::StartAsync));
}

void URLRequestAutomationJob::Kill() {
  if (message_filter_.get()) {
    message_filter_->Send(new AutomationMsg_RequestEnd(0, tab_, id_,
        URLRequestStatus(URLRequestStatus::CANCELED, 0)));
  }
  DisconnectFromMessageFilter();
  URLRequestJob::Kill();
}

bool URLRequestAutomationJob::ReadRawData(
    net::IOBuffer* buf, int buf_size, int* bytes_read) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - read pending: " << buf_size;
  pending_buf_ = buf;
  pending_buf_size_ = buf_size;

  message_filter_->Send(new AutomationMsg_RequestRead(0, tab_, id_,
      buf_size));
  SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
  return false;
}

bool URLRequestAutomationJob::GetMimeType(std::string* mime_type) const {
  if (!mime_type_.empty()) {
    *mime_type = mime_type_;
  } else if (headers_) {
    headers_->GetMimeType(mime_type);
  }

  return (!mime_type->empty());
}

bool URLRequestAutomationJob::GetCharset(std::string* charset) {
  if (headers_)
    return headers_->GetCharset(charset);
  return false;
}

void URLRequestAutomationJob::GetResponseInfo(net::HttpResponseInfo* info) {
  if (headers_)
    info->headers = headers_;
  if (request_->url().SchemeIsSecure()) {
    // Make up a fake certificate for this response since we don't have
    // access to the real SSL info.
    const char* kCertIssuer = "Chrome Internal";
    const int kLifetimeDays = 100;

    info->ssl_info.cert =
        new net::X509Certificate(request_->url().GetWithEmptyPath().spec(),
                                 kCertIssuer,
                                 Time::Now(),
                                 Time::Now() +
                                     TimeDelta::FromDays(kLifetimeDays));
    info->ssl_info.cert_status = 0;
    info->ssl_info.security_bits = 0;
  }
}

int URLRequestAutomationJob::GetResponseCode() const {
  if (headers_)
    return headers_->response_code();

  static const int kDefaultResponseCode = 200;
  return kDefaultResponseCode;
}

bool URLRequestAutomationJob::IsRedirectResponse(
    GURL* location, int* http_status_code) {
  static const int kDefaultHttpRedirectResponseCode = 301;

  if (!redirect_url_.empty()) {
    DLOG_IF(ERROR, redirect_status_ == 0) << "Missing redirect status?";
    *http_status_code = redirect_status_ ? redirect_status_ :
                                           kDefaultHttpRedirectResponseCode;
    *location = GURL(redirect_url_);
    return true;
  } else {
    DCHECK(redirect_status_ == 0)
        << "Unexpectedly have redirect status but no URL";
  }

  return false;
}

int URLRequestAutomationJob::MayFilterMessage(const IPC::Message& message) {
  switch (message.type()) {
    case AutomationMsg_RequestStarted::ID:
    case AutomationMsg_RequestData::ID:
    case AutomationMsg_RequestEnd::ID: {
      void* iter = NULL;
      int tab = 0;
      int id = 0;
      if (message.ReadInt(&iter, &tab) && message.ReadInt(&iter, &id)) {
        DCHECK(id);
        return id;
      }
      break;
    }
  }

  return 0;
}

void URLRequestAutomationJob::OnMessage(const IPC::Message& message) {
  IPC_BEGIN_MESSAGE_MAP(URLRequestAutomationJob, message)
    IPC_MESSAGE_HANDLER(AutomationMsg_RequestStarted, OnRequestStarted)
    IPC_MESSAGE_HANDLER(AutomationMsg_RequestData, OnDataAvailable)
    IPC_MESSAGE_HANDLER(AutomationMsg_RequestEnd, OnRequestEnd)
  IPC_END_MESSAGE_MAP()
}

void URLRequestAutomationJob::OnRequestStarted(
    int tab, int id, const IPC::AutomationURLResponse& response) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - response started.";
  set_expected_content_size(response.content_length);
  mime_type_ = response.mime_type;

  redirect_url_ = response.redirect_url;
  redirect_status_ = response.redirect_status;
  DCHECK(redirect_status_ == 0 || redirect_status_ == 200 ||
         (redirect_status_ >= 300 && redirect_status_ < 400));

  GURL url_for_cookies =
      GURL(redirect_url_.empty() ? request_->url().spec().c_str() :
          redirect_url_.c_str());

  URLRequestContext* ctx = request_->context();

  if (!response.headers.empty()) {
    headers_ = new net::HttpResponseHeaders(
        net::HttpUtil::AssembleRawHeaders(response.headers.data(),
                                          response.headers.size()));
    // Parse and set HTTP cookies.
    const std::string name = "Set-Cookie";
    std::string value;
    std::vector<std::string> response_cookies;

    void* iter = NULL;
    while (headers_->EnumerateHeader(&iter, name, &value)) {
      if (request_->context()->InterceptCookie(request_, &value))
        response_cookies.push_back(value);
    }

    if (response_cookies.size()) {
      if (ctx && ctx->cookie_store() &&
          ctx->cookie_policy()->CanSetCookie(
              url_for_cookies, request_->first_party_for_cookies())) {
        net::CookieOptions options;
        options.set_include_httponly();
        ctx->cookie_store()->SetCookiesWithOptions(url_for_cookies,
                                                   response_cookies,
                                                   options);
      }
    }
  }

  if (ctx && ctx->cookie_store() && !response.persistent_cookies.empty() &&
      ctx->cookie_policy()->CanSetCookie(
          url_for_cookies, request_->first_party_for_cookies())) {
    StringTokenizer cookie_parser(response.persistent_cookies, ";");

    while (cookie_parser.GetNext()) {
      net::CookieOptions options;
      ctx->cookie_store()->SetCookieWithOptions(url_for_cookies,
                                                cookie_parser.token(),
                                                options);
    }
  }

  NotifyHeadersComplete();
}

void URLRequestAutomationJob::OnDataAvailable(
    int tab, int id, const std::string& bytes) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - data available, Size: " << bytes.size();
  DCHECK(!bytes.empty());

  // The request completed, and we have all the data.
  // Clear any IO pending status.
  SetStatus(URLRequestStatus());

  if (pending_buf_ && pending_buf_->data()) {
    DCHECK_GE(pending_buf_size_, bytes.size());
    const int bytes_to_copy = std::min(bytes.size(), pending_buf_size_);
    memcpy(pending_buf_->data(), &bytes[0], bytes_to_copy);

    pending_buf_ = NULL;
    pending_buf_size_ = 0;

    NotifyReadComplete(bytes_to_copy);
  }
}

void URLRequestAutomationJob::OnRequestEnd(
    int tab, int id, const URLRequestStatus& status) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - request end. Status: " << status.status();

  // TODO(tommi): When we hit certificate errors, notify the delegate via
  // OnSSLCertificateError().  Right now we don't have the certificate
  // so we don't.  We could possibly call OnSSLCertificateError with a NULL
  // certificate, but I'm not sure if all implementations expect it.
  // if (status.status() == URLRequestStatus::FAILED &&
  //    net::IsCertificateError(status.os_error()) && request_->delegate()) {
  //  request_->delegate()->OnSSLCertificateError(request_, status.os_error(),
  //                                              NULL);
  // }

  DisconnectFromMessageFilter();
  NotifyDone(status);

  // Reset any pending reads.
  if (pending_buf_) {
    pending_buf_ = NULL;
    pending_buf_size_ = 0;
    NotifyReadComplete(0);
  }
}

void URLRequestAutomationJob::Cleanup() {
  headers_ = NULL;
  mime_type_.erase();

  id_ = 0;
  tab_ = 0;

  DCHECK(message_filter_ == NULL);
  DisconnectFromMessageFilter();

  pending_buf_ = NULL;
  pending_buf_size_ = 0;
}

void URLRequestAutomationJob::StartAsync() {
  DLOG(INFO) << "URLRequestAutomationJob: start request: " <<
      (request_ ? request_->url().spec() : "NULL request");

  // If the job is cancelled before we got a chance to start it
  // we have nothing much to do here.
  if (is_done())
    return;

  if (!request_) {
    NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED,
        net::ERR_FAILED));
    return;
  }

  // Register this request with automation message filter.
  message_filter_->RegisterRequest(this);

  // Strip unwanted headers.
  std::string new_request_headers(
      net::HttpUtil::StripHeaders(request_->extra_request_headers(),
                                  kFilteredHeaderStrings,
                                  arraysize(kFilteredHeaderStrings)));

  // Ensure that we do not send username and password fields in the referrer.
  GURL referrer(request_->GetSanitizedReferrer());

  // The referrer header must be suppressed if the preceding URL was
  // a secure one and the new one is not.
  if (referrer.SchemeIsSecure() && !request_->url().SchemeIsSecure()) {
    DLOG(INFO) <<
        "Suppressing referrer header since going from secure to non-secure";
    referrer = GURL();
  }

  // Ask automation to start this request.
  IPC::AutomationURLRequest automation_request = {
    request_->url().spec(),
    request_->method(),
    referrer.spec(),
    new_request_headers,
    request_->get_upload()
  };

  DCHECK(message_filter_);
  message_filter_->Send(new AutomationMsg_RequestStart(0, tab_, id_,
      automation_request));
}

void URLRequestAutomationJob::DisconnectFromMessageFilter() {
  if (message_filter_) {
    message_filter_->UnRegisterRequest(this);
    message_filter_ = NULL;
  }
}
<commit_msg>Retry that check for nullness in url request automation job.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/automation/url_request_automation_job.h"

#include "base/message_loop.h"
#include "base/time.h"
#include "chrome/browser/automation/automation_resource_message_filter.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
#include "chrome/test/automation/automation_messages.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"

using base::Time;
using base::TimeDelta;

// The list of filtered headers that are removed from requests sent via
// StartAsync(). These must be lower case.
static const char* kFilteredHeaderStrings[] = {
  "accept",
  "authorization",
  "cache-control",
  "connection",
  "cookie",
  "expect",
  "if-match",
  "if-modified-since",
  "if-none-match",
  "if-range",
  "if-unmodified-since",
  "max-forwards",
  "proxy-authorization",
  "te",
  "upgrade",
  "via"
};

// This class manages the interception of network requests for automation.
// It looks at the request, and creates an intercept job if it indicates
// that it should use automation channel.
// NOTE: All methods must be called on the IO thread.
class AutomationRequestInterceptor : public URLRequest::Interceptor {
 public:
  AutomationRequestInterceptor() {
    URLRequest::RegisterRequestInterceptor(this);
  }

  virtual ~AutomationRequestInterceptor() {
    URLRequest::UnregisterRequestInterceptor(this);
  }

  // URLRequest::Interceptor
  virtual URLRequestJob* MaybeIntercept(URLRequest* request);

 private:
  DISALLOW_COPY_AND_ASSIGN(AutomationRequestInterceptor);
};

URLRequestJob* AutomationRequestInterceptor::MaybeIntercept(
    URLRequest* request) {
  if (request->url().SchemeIs("http") || request->url().SchemeIs("https")) {
    ResourceDispatcherHostRequestInfo* request_info =
        ResourceDispatcherHost::InfoForRequest(request);
    if (request_info) {
      AutomationResourceMessageFilter::AutomationDetails details;
      if (AutomationResourceMessageFilter::LookupRegisteredRenderView(
              request_info->child_id(), request_info->route_id(), &details)) {
        URLRequestAutomationJob* job = new URLRequestAutomationJob(request,
            details.tab_handle, details.filter);
        return job;
      }
    }
  }

  return NULL;
}

static URLRequest::Interceptor* GetAutomationRequestInterceptor() {
  return Singleton<AutomationRequestInterceptor>::get();
}

int URLRequestAutomationJob::instance_count_ = 0;

URLRequestAutomationJob::URLRequestAutomationJob(
    URLRequest* request, int tab, AutomationResourceMessageFilter* filter)
    : URLRequestJob(request), id_(0), tab_(tab), message_filter_(filter),
      pending_buf_size_(0), redirect_status_(0) {
  DLOG(INFO) << "URLRequestAutomationJob create. Count: " << ++instance_count_;
  if (message_filter_) {
    id_ = message_filter_->NewRequestId();
    DCHECK(id_);
  } else {
    NOTREACHED();
  }
}

URLRequestAutomationJob::~URLRequestAutomationJob() {
  DLOG(INFO) << "URLRequestAutomationJob delete. Count: " << --instance_count_;
  Cleanup();
}

bool URLRequestAutomationJob::InitializeInterceptor() {
  // AutomationRequestInterceptor will register itself when it
  // is first created.
  URLRequest::Interceptor* interceptor = GetAutomationRequestInterceptor();
  return (interceptor != NULL);
}

// URLRequestJob Implementation.
void URLRequestAutomationJob::Start() {
  // Start reading asynchronously so that all error reporting and data
  // callbacks happen as they would for network requests.
  MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
      this, &URLRequestAutomationJob::StartAsync));
}

void URLRequestAutomationJob::Kill() {
  if (message_filter_.get()) {
    message_filter_->Send(new AutomationMsg_RequestEnd(0, tab_, id_,
        URLRequestStatus(URLRequestStatus::CANCELED, 0)));
  }
  DisconnectFromMessageFilter();
  URLRequestJob::Kill();
}

bool URLRequestAutomationJob::ReadRawData(
    net::IOBuffer* buf, int buf_size, int* bytes_read) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - read pending: " << buf_size;
  pending_buf_ = buf;
  pending_buf_size_ = buf_size;

  message_filter_->Send(new AutomationMsg_RequestRead(0, tab_, id_,
      buf_size));
  SetStatus(URLRequestStatus(URLRequestStatus::IO_PENDING, 0));
  return false;
}

bool URLRequestAutomationJob::GetMimeType(std::string* mime_type) const {
  if (!mime_type_.empty()) {
    *mime_type = mime_type_;
  } else if (headers_) {
    headers_->GetMimeType(mime_type);
  }

  return (!mime_type->empty());
}

bool URLRequestAutomationJob::GetCharset(std::string* charset) {
  if (headers_)
    return headers_->GetCharset(charset);
  return false;
}

void URLRequestAutomationJob::GetResponseInfo(net::HttpResponseInfo* info) {
  if (headers_)
    info->headers = headers_;
  if (request_->url().SchemeIsSecure()) {
    // Make up a fake certificate for this response since we don't have
    // access to the real SSL info.
    const char* kCertIssuer = "Chrome Internal";
    const int kLifetimeDays = 100;

    info->ssl_info.cert =
        new net::X509Certificate(request_->url().GetWithEmptyPath().spec(),
                                 kCertIssuer,
                                 Time::Now(),
                                 Time::Now() +
                                     TimeDelta::FromDays(kLifetimeDays));
    info->ssl_info.cert_status = 0;
    info->ssl_info.security_bits = 0;
  }
}

int URLRequestAutomationJob::GetResponseCode() const {
  if (headers_)
    return headers_->response_code();

  static const int kDefaultResponseCode = 200;
  return kDefaultResponseCode;
}

bool URLRequestAutomationJob::IsRedirectResponse(
    GURL* location, int* http_status_code) {
  static const int kDefaultHttpRedirectResponseCode = 301;

  if (!redirect_url_.empty()) {
    DLOG_IF(ERROR, redirect_status_ == 0) << "Missing redirect status?";
    *http_status_code = redirect_status_ ? redirect_status_ :
                                           kDefaultHttpRedirectResponseCode;
    *location = GURL(redirect_url_);
    return true;
  } else {
    DCHECK(redirect_status_ == 0)
        << "Unexpectedly have redirect status but no URL";
  }

  return false;
}

int URLRequestAutomationJob::MayFilterMessage(const IPC::Message& message) {
  switch (message.type()) {
    case AutomationMsg_RequestStarted::ID:
    case AutomationMsg_RequestData::ID:
    case AutomationMsg_RequestEnd::ID: {
      void* iter = NULL;
      int tab = 0;
      int id = 0;
      if (message.ReadInt(&iter, &tab) && message.ReadInt(&iter, &id)) {
        DCHECK(id);
        return id;
      }
      break;
    }
  }

  return 0;
}

void URLRequestAutomationJob::OnMessage(const IPC::Message& message) {
  IPC_BEGIN_MESSAGE_MAP(URLRequestAutomationJob, message)
    IPC_MESSAGE_HANDLER(AutomationMsg_RequestStarted, OnRequestStarted)
    IPC_MESSAGE_HANDLER(AutomationMsg_RequestData, OnDataAvailable)
    IPC_MESSAGE_HANDLER(AutomationMsg_RequestEnd, OnRequestEnd)
  IPC_END_MESSAGE_MAP()
}

void URLRequestAutomationJob::OnRequestStarted(
    int tab, int id, const IPC::AutomationURLResponse& response) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - response started.";
  set_expected_content_size(response.content_length);
  mime_type_ = response.mime_type;

  redirect_url_ = response.redirect_url;
  redirect_status_ = response.redirect_status;
  DCHECK(redirect_status_ == 0 || redirect_status_ == 200 ||
         (redirect_status_ >= 300 && redirect_status_ < 400));

  GURL url_for_cookies =
      GURL(redirect_url_.empty() ? request_->url().spec().c_str() :
          redirect_url_.c_str());

  URLRequestContext* ctx = request_->context();

  if (!response.headers.empty()) {
    headers_ = new net::HttpResponseHeaders(
        net::HttpUtil::AssembleRawHeaders(response.headers.data(),
                                          response.headers.size()));
    // Parse and set HTTP cookies.
    const std::string name = "Set-Cookie";
    std::string value;
    std::vector<std::string> response_cookies;

    void* iter = NULL;
    while (headers_->EnumerateHeader(&iter, name, &value)) {
      if (request_->context()->InterceptCookie(request_, &value))
        response_cookies.push_back(value);
    }

    if (response_cookies.size()) {
      if (ctx && ctx->cookie_store() &&
          ctx->cookie_policy()->CanSetCookie(
              url_for_cookies, request_->first_party_for_cookies())) {
        net::CookieOptions options;
        options.set_include_httponly();
        ctx->cookie_store()->SetCookiesWithOptions(url_for_cookies,
                                                   response_cookies,
                                                   options);
      }
    }
  }

  if (ctx && ctx->cookie_store() && !response.persistent_cookies.empty() &&
      ctx->cookie_policy()->CanSetCookie(
          url_for_cookies, request_->first_party_for_cookies())) {
    StringTokenizer cookie_parser(response.persistent_cookies, ";");

    while (cookie_parser.GetNext()) {
      net::CookieOptions options;
      ctx->cookie_store()->SetCookieWithOptions(url_for_cookies,
                                                cookie_parser.token(),
                                                options);
    }
  }

  NotifyHeadersComplete();
}

void URLRequestAutomationJob::OnDataAvailable(
    int tab, int id, const std::string& bytes) {
  DLOG(INFO) << "URLRequestAutomationJob: " <<
      request_->url().spec() << " - data available, Size: " << bytes.size();
  DCHECK(!bytes.empty());

  // The request completed, and we have all the data.
  // Clear any IO pending status.
  SetStatus(URLRequestStatus());

  if (pending_buf_ && pending_buf_->data()) {
    DCHECK_GE(pending_buf_size_, bytes.size());
    const int bytes_to_copy = std::min(bytes.size(), pending_buf_size_);
    memcpy(pending_buf_->data(), &bytes[0], bytes_to_copy);

    pending_buf_ = NULL;
    pending_buf_size_ = 0;

    NotifyReadComplete(bytes_to_copy);
  }
}

void URLRequestAutomationJob::OnRequestEnd(
    int tab, int id, const URLRequestStatus& status) {
#ifndef NDEBUG
  std::string url;
  if (request_)
    url = request_->url().spec();
  DLOG(INFO) << "URLRequestAutomationJob: "
      << url << " - request end. Status: " << status.status();
#endif

  // TODO(tommi): When we hit certificate errors, notify the delegate via
  // OnSSLCertificateError().  Right now we don't have the certificate
  // so we don't.  We could possibly call OnSSLCertificateError with a NULL
  // certificate, but I'm not sure if all implementations expect it.
  // if (status.status() == URLRequestStatus::FAILED &&
  //    net::IsCertificateError(status.os_error()) && request_->delegate()) {
  //  request_->delegate()->OnSSLCertificateError(request_, status.os_error(),
  //                                              NULL);
  // }

  DisconnectFromMessageFilter();
  NotifyDone(status);

  // Reset any pending reads.
  if (pending_buf_) {
    pending_buf_ = NULL;
    pending_buf_size_ = 0;
    NotifyReadComplete(0);
  }
}

void URLRequestAutomationJob::Cleanup() {
  headers_ = NULL;
  mime_type_.erase();

  id_ = 0;
  tab_ = 0;

  DCHECK(message_filter_ == NULL);
  DisconnectFromMessageFilter();

  pending_buf_ = NULL;
  pending_buf_size_ = 0;
}

void URLRequestAutomationJob::StartAsync() {
  DLOG(INFO) << "URLRequestAutomationJob: start request: " <<
      (request_ ? request_->url().spec() : "NULL request");

  // If the job is cancelled before we got a chance to start it
  // we have nothing much to do here.
  if (is_done())
    return;

  if (!request_) {
    NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED,
        net::ERR_FAILED));
    return;
  }

  // Register this request with automation message filter.
  message_filter_->RegisterRequest(this);

  // Strip unwanted headers.
  std::string new_request_headers(
      net::HttpUtil::StripHeaders(request_->extra_request_headers(),
                                  kFilteredHeaderStrings,
                                  arraysize(kFilteredHeaderStrings)));

  // Ensure that we do not send username and password fields in the referrer.
  GURL referrer(request_->GetSanitizedReferrer());

  // The referrer header must be suppressed if the preceding URL was
  // a secure one and the new one is not.
  if (referrer.SchemeIsSecure() && !request_->url().SchemeIsSecure()) {
    DLOG(INFO) <<
        "Suppressing referrer header since going from secure to non-secure";
    referrer = GURL();
  }

  // Ask automation to start this request.
  IPC::AutomationURLRequest automation_request = {
    request_->url().spec(),
    request_->method(),
    referrer.spec(),
    new_request_headers,
    request_->get_upload()
  };

  DCHECK(message_filter_);
  message_filter_->Send(new AutomationMsg_RequestStart(0, tab_, id_,
      automation_request));
}

void URLRequestAutomationJob::DisconnectFromMessageFilter() {
  if (message_filter_) {
    message_filter_->UnRegisterRequest(this);
    message_filter_ = NULL;
  }
}
<|endoftext|>


<commit_before>#include "IfNode.h"
#include "../Parser.h"

#include <assert.h>

namespace Language {
    IfNode* IfNode::parse(Parser& parser) {
        IfNode* node = new IfNode();

        node->setStatement(true);

        assert(parser.next().type() == Token::Type::KeywordIf);

        // parse the condition
        node->_conditionNode = parser.parseExpression();

        parser.parseNewline();

        // and now, parse the body
        while (true) {
            Token t = parser.peek();

            if (t.type() == Token::Type::KeywordEnd || t.type() == Token::Type::KeywordElse) {
                break;
            }

            node->addChild(parser.parseStatement());
        }

        if (parser.peek().type() == Token::Type::KeywordElse) {
            node->_elseNode = ElseNode::parse(parser);
        } else {
            assert(parser.next().type() == Token::Type::KeywordEnd);
        }

        return node;
    }

    ASTNode* IfNode::parseTailing(Parser& parser, ASTNode* node) {
        if (parser.peek().type() != Token::Type::KeywordIf) {
            return node;
        }

        assert(parser.next().type() == Token::Type::KeywordIf);

        IfNode* ifNode = new IfNode();

        ifNode->addChild(node);

        ifNode->setCondition(parser.parseExpression());

        return ifNode;
    }

    IfNode::IfNode() : _elseNode(NULL) {
    }

    std::string IfNode::name() const {
        return "If";
    }

    ASTNode* IfNode::condition() const {
        return _conditionNode;
    }

    void IfNode::setCondition(ASTNode* node) {
        _conditionNode = node;
    }

    ElseNode* IfNode::elseStatement() const {
        return _elseNode;
    }

    void IfNode::codeGenCSource(CSourceContext& context) {
        context.current()->print("if (");

        this->condition()->codeGenCSource(context);

        context.current()->printLineAndIndent(") {");

        this->codeGenCSourceForChildren(context);

        if (this->elseStatement()) {
            context.current()->outdentAndPrintLine("} else {");
            context.current()->increaseIndentation();

            this->elseStatement()->codeGenCSourceForChildren(context);
        }

        context.current()->outdentAndPrintLine("}");
    }
}
<commit_msg>Hack to if codegen to remove compiler warning<commit_after>#include "IfNode.h"
#include "../Parser.h"

#include <assert.h>

namespace Language {
    IfNode* IfNode::parse(Parser& parser) {
        IfNode* node = new IfNode();

        node->setStatement(true);

        assert(parser.next().type() == Token::Type::KeywordIf);

        // parse the condition
        node->_conditionNode = parser.parseExpression();

        parser.parseNewline();

        // and now, parse the body
        while (true) {
            Token t = parser.peek();

            if (t.type() == Token::Type::KeywordEnd || t.type() == Token::Type::KeywordElse) {
                break;
            }

            node->addChild(parser.parseStatement());
        }

        if (parser.peek().type() == Token::Type::KeywordElse) {
            node->_elseNode = ElseNode::parse(parser);
        } else {
            assert(parser.next().type() == Token::Type::KeywordEnd);
        }

        return node;
    }

    ASTNode* IfNode::parseTailing(Parser& parser, ASTNode* node) {
        if (parser.peek().type() != Token::Type::KeywordIf) {
            return node;
        }

        assert(parser.next().type() == Token::Type::KeywordIf);

        IfNode* ifNode = new IfNode();

        ifNode->addChild(node);

        ifNode->setCondition(parser.parseExpression());

        return ifNode;
    }

    IfNode::IfNode() : _elseNode(NULL) {
    }

    std::string IfNode::name() const {
        return "If";
    }

    ASTNode* IfNode::condition() const {
        return _conditionNode;
    }

    void IfNode::setCondition(ASTNode* node) {
        _conditionNode = node;
    }

    ElseNode* IfNode::elseStatement() const {
        return _elseNode;
    }

    void IfNode::codeGenCSource(CSourceContext& context) {
        context.current()->print("if ");

        // TODO: this is a messy hack to avoid duplicating parenthesis around
        // operators
        if (this->condition()->nodeName() != "Operator") {
            context.current()->print("(");
        }

        this->condition()->codeGenCSource(context);

        if (this->condition()->nodeName() != "Operator") {
            context.current()->print(")");
        }

        context.current()->printLineAndIndent(" {");

        this->codeGenCSourceForChildren(context);

        if (this->elseStatement()) {
            context.current()->outdentAndPrintLine("} else {");
            context.current()->increaseIndentation();

            this->elseStatement()->codeGenCSourceForChildren(context);
        }

        context.current()->outdentAndPrintLine("}");
    }
}
<|endoftext|>


<commit_before>/******************************************************************************

  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/

#include "ViewMenuManager.h"

#include "pqCoreUtilities.h"
#include "pqView.h"
#include "vtkCommand.h"
#include "vtkSMPropertyHelper.h"
#include "vtkSMViewProxy.h"

#include <QAction>
#include <QActionGroup>
#include <QDialog>
#include <QHBoxLayout>
#include <QMainWindow>
#include <QMenu>

#include "ActiveObjects.h"
#include "Utilities.h"
#include "ViewPropertiesPanel.h"

namespace tomviz
{

ViewMenuManager::ViewMenuManager(QMainWindow* mainWindow, QMenu* menu)
  : pqViewMenuManager(mainWindow, menu)
{
  this->viewPropertiesDialog = new QDialog(mainWindow);
  this->viewPropertiesDialog->setWindowTitle("View Properties");
  ViewPropertiesPanel* panel = new ViewPropertiesPanel(this->viewPropertiesDialog);
  QHBoxLayout *layout = new QHBoxLayout;
  layout->addWidget(panel);
  this->viewPropertiesDialog->setLayout(layout);
  this->connect(this->viewPropertiesDialog, SIGNAL(finished(int)),
                    SLOT(viewPropertiesDialogHidden()));

  this->showViewPropertiesAction = new QAction("View Properties", this->Menu);
  this->showViewPropertiesAction->setCheckable(true);
  this->connect(this->showViewPropertiesAction, SIGNAL(triggered(bool)),
                    SLOT(showViewPropertiesDialog(bool)));
  this->View = ActiveObjects::instance().activeView();
  if (this->View)
  {
    this->ViewObserverId = pqCoreUtilities::connect(
        this->View, vtkCommand::PropertyModifiedEvent,
        this, SLOT(onViewPropertyChanged()));
  }
  this->connect(&ActiveObjects::instance(), SIGNAL(viewChanged(vtkSMViewProxy*)),
                SLOT(onViewChanged()));
}

void ViewMenuManager::buildMenu()
{
  bool showViewPropertiesChecked = this->showViewPropertiesAction->isChecked();
  bool perspectiveProjectionChecked = true;
  if (this->perspectiveProjectionAction)
  {
    perspectiveProjectionChecked = this->perspectiveProjectionAction->isChecked();
  }
  bool axisGridIsShowing = false;
  if (this->showAxisGridAction)
  {
    axisGridIsShowing = this->showAxisGridAction->isChecked();
  }
  this->showViewPropertiesAction = nullptr; // The object is about to be deleted
  this->perspectiveProjectionAction = nullptr;
  this->orthographicProjectionAction = nullptr;
  pqViewMenuManager::buildMenu(); // deletes all prior menu items and repopulates menu

  this->Menu->addSeparator();
  // Projection modes
  QMenu *projectionMenu = this->Menu->addMenu("Projection Mode");
  QActionGroup *projectionGroup = new QActionGroup(this);

  this->perspectiveProjectionAction = projectionMenu->addAction("Perspective");
  this->perspectiveProjectionAction->setCheckable(true);
  this->perspectiveProjectionAction->setActionGroup(projectionGroup);
  this->perspectiveProjectionAction->setChecked(perspectiveProjectionChecked);
  this->connect(this->perspectiveProjectionAction, SIGNAL(triggered()),
                SLOT(setProjectionModeToPerspective()));
  this->orthographicProjectionAction = projectionMenu->addAction("Orthographic");
  this->orthographicProjectionAction->setCheckable(true);
  this->orthographicProjectionAction->setActionGroup(projectionGroup);
  this->orthographicProjectionAction->setChecked(!perspectiveProjectionChecked);
  this->connect(this->orthographicProjectionAction, SIGNAL(triggered()),
                SLOT(setProjectionModeToOrthographic()));

  this->showAxisGridAction = this->Menu->addAction("Show Axis Grid");
  this->showAxisGridAction->setCheckable(true);
  this->showAxisGridAction->setChecked(axisGridIsShowing);
  this->connect(this->showAxisGridAction, SIGNAL(triggered(bool)),
                SLOT(setShowAxisGrid(bool)));

  // Show view properties
  this->showViewPropertiesAction = new QAction("View Properties", this->Menu);
  this->showViewPropertiesAction->setCheckable(true);
  this->showViewPropertiesAction->setChecked(showViewPropertiesChecked);
  this->connect(this->showViewPropertiesAction, SIGNAL(triggered(bool)),
                    SLOT(showViewPropertiesDialog(bool)));
  this->Menu->addSeparator();
  this->Menu->addAction(this->showViewPropertiesAction);
}

void ViewMenuManager::showViewPropertiesDialog(bool show)
{
  if (show)
  {
    this->viewPropertiesDialog->show();
  }
  else
  {
    this->viewPropertiesDialog->accept();
  }
}

void ViewMenuManager::viewPropertiesDialogHidden()
{
  this->showViewPropertiesAction->setChecked(false);
}

void ViewMenuManager::setProjectionModeToPerspective()
{
  int parallel = vtkSMPropertyHelper(this->View, "CameraParallelProjection").GetAsInt();
  if (parallel)
  {
    vtkSMPropertyHelper(this->View, "CameraParallelProjection").Set(0);
    this->View->UpdateVTKObjects();
    pqView* view = tomviz::convert<pqView*>(this->View);
    if (view)
    {
      view->render();
    }
  }
}

void ViewMenuManager::setProjectionModeToOrthographic()
{
  int parallel = vtkSMPropertyHelper(this->View, "CameraParallelProjection").GetAsInt();
  if (!parallel)
  {
    vtkSMPropertyHelper(this->View, "CameraParallelProjection").Set(1);
    this->View->UpdateVTKObjects();
    pqView* view = tomviz::convert<pqView*>(this->View);
    if (view)
    {
      view->render();
    }
  }
}

void ViewMenuManager::onViewPropertyChanged()
{
  int parallel = vtkSMPropertyHelper(this->View, "CameraParallelProjection").GetAsInt();
  if (!this->perspectiveProjectionAction)
  {
    return;
  }
  if (parallel && this->perspectiveProjectionAction->isChecked())
  {
    this->orthographicProjectionAction->setChecked(true);
  }
  else if (!parallel && this->orthographicProjectionAction->isChecked())
  {
    this->perspectiveProjectionAction->setChecked(true);
  }
}

void ViewMenuManager::onViewChanged()
{
  if (this->View)
  {
    vtkSMPropertyHelper(this->View, "AxesGrid").GetAsProxy()
      ->RemoveObserver(this->AxesGridObserverId);
    this->View->RemoveObserver(this->ViewObserverId);
  }
  this->View = ActiveObjects::instance().activeView();
  if (this->View)
  {
    this->ViewObserverId = pqCoreUtilities::connect(
        this->View, vtkCommand::PropertyModifiedEvent,
        this, SLOT(onViewPropertyChanged()));
    this->AxesGridObserverId = pqCoreUtilities::connect(
        vtkSMPropertyHelper(this->View, "AxesGrid").GetAsProxy(),
        vtkCommand::PropertyModifiedEvent, this, SLOT(onAxesGridChanged()));
  }
}

void ViewMenuManager::setShowAxisGrid(bool show)
{
  vtkSMProxy *axesGrid = vtkSMPropertyHelper(this->View, "AxesGrid").GetAsProxy();
  int showing = vtkSMPropertyHelper(axesGrid, "Visibility").GetAsInt();
  if (showing && !show)
  {
    vtkSMPropertyHelper(axesGrid, "Visibility").Set(0);
  }
  else if (!showing && show)
  {
    vtkSMPropertyHelper(axesGrid, "Visibility").Set(1);
  }
  axesGrid->UpdateVTKObjects();
  pqView* view = tomviz::convert<pqView*>(this->View);
  if (view)
  {
    view->render();
  }
}

void ViewMenuManager::onAxesGridChanged()
{
  vtkSMProxy *axesGrid = vtkSMPropertyHelper(this->View, "AxesGrid").GetAsProxy();
  int showing = vtkSMPropertyHelper(axesGrid, "Visibility").GetAsInt();
  if (showing && !this->showAxisGridAction->isChecked())
  {
    this->showAxisGridAction->setChecked(true);
  }
  else if (!showing && this->showAxisGridAction->isChecked())
  {
    this->showAxisGridAction->setChecked(false);
  }
}

}
<commit_msg>Added missing initialization of member variables<commit_after>/******************************************************************************

  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/

#include "ViewMenuManager.h"

#include "pqCoreUtilities.h"
#include "pqView.h"
#include "vtkCommand.h"
#include "vtkSMPropertyHelper.h"
#include "vtkSMViewProxy.h"

#include <QAction>
#include <QActionGroup>
#include <QDialog>
#include <QHBoxLayout>
#include <QMainWindow>
#include <QMenu>

#include "ActiveObjects.h"
#include "Utilities.h"
#include "ViewPropertiesPanel.h"

namespace tomviz
{

ViewMenuManager::ViewMenuManager(QMainWindow* mainWindow, QMenu* menu)
  : pqViewMenuManager(mainWindow, menu), perspectiveProjectionAction(nullptr),
    orthographicProjectionAction(nullptr), showAxisGridAction(nullptr)
{
  this->viewPropertiesDialog = new QDialog(mainWindow);
  this->viewPropertiesDialog->setWindowTitle("View Properties");
  ViewPropertiesPanel* panel = new ViewPropertiesPanel(this->viewPropertiesDialog);
  QHBoxLayout *layout = new QHBoxLayout;
  layout->addWidget(panel);
  this->viewPropertiesDialog->setLayout(layout);
  this->connect(this->viewPropertiesDialog, SIGNAL(finished(int)),
                    SLOT(viewPropertiesDialogHidden()));

  this->showViewPropertiesAction = new QAction("View Properties", this->Menu);
  this->showViewPropertiesAction->setCheckable(true);
  this->connect(this->showViewPropertiesAction, SIGNAL(triggered(bool)),
                    SLOT(showViewPropertiesDialog(bool)));
  this->View = ActiveObjects::instance().activeView();
  if (this->View)
  {
    this->ViewObserverId = pqCoreUtilities::connect(
        this->View, vtkCommand::PropertyModifiedEvent,
        this, SLOT(onViewPropertyChanged()));
  }
  this->connect(&ActiveObjects::instance(), SIGNAL(viewChanged(vtkSMViewProxy*)),
                SLOT(onViewChanged()));
}

void ViewMenuManager::buildMenu()
{
  bool showViewPropertiesChecked = this->showViewPropertiesAction->isChecked();
  bool perspectiveProjectionChecked = true;
  if (this->perspectiveProjectionAction)
  {
    perspectiveProjectionChecked = this->perspectiveProjectionAction->isChecked();
  }
  bool axisGridIsShowing = false;
  if (this->showAxisGridAction)
  {
    axisGridIsShowing = this->showAxisGridAction->isChecked();
  }
  this->showViewPropertiesAction = nullptr; // The object is about to be deleted
  this->perspectiveProjectionAction = nullptr;
  this->orthographicProjectionAction = nullptr;
  pqViewMenuManager::buildMenu(); // deletes all prior menu items and repopulates menu

  this->Menu->addSeparator();
  // Projection modes
  QMenu *projectionMenu = this->Menu->addMenu("Projection Mode");
  QActionGroup *projectionGroup = new QActionGroup(this);

  this->perspectiveProjectionAction = projectionMenu->addAction("Perspective");
  this->perspectiveProjectionAction->setCheckable(true);
  this->perspectiveProjectionAction->setActionGroup(projectionGroup);
  this->perspectiveProjectionAction->setChecked(perspectiveProjectionChecked);
  this->connect(this->perspectiveProjectionAction, SIGNAL(triggered()),
                SLOT(setProjectionModeToPerspective()));
  this->orthographicProjectionAction = projectionMenu->addAction("Orthographic");
  this->orthographicProjectionAction->setCheckable(true);
  this->orthographicProjectionAction->setActionGroup(projectionGroup);
  this->orthographicProjectionAction->setChecked(!perspectiveProjectionChecked);
  this->connect(this->orthographicProjectionAction, SIGNAL(triggered()),
                SLOT(setProjectionModeToOrthographic()));

  this->showAxisGridAction = this->Menu->addAction("Show Axis Grid");
  this->showAxisGridAction->setCheckable(true);
  this->showAxisGridAction->setChecked(axisGridIsShowing);
  this->connect(this->showAxisGridAction, SIGNAL(triggered(bool)),
                SLOT(setShowAxisGrid(bool)));

  // Show view properties
  this->showViewPropertiesAction = new QAction("View Properties", this->Menu);
  this->showViewPropertiesAction->setCheckable(true);
  this->showViewPropertiesAction->setChecked(showViewPropertiesChecked);
  this->connect(this->showViewPropertiesAction, SIGNAL(triggered(bool)),
                    SLOT(showViewPropertiesDialog(bool)));
  this->Menu->addSeparator();
  this->Menu->addAction(this->showViewPropertiesAction);
}

void ViewMenuManager::showViewPropertiesDialog(bool show)
{
  if (show)
  {
    this->viewPropertiesDialog->show();
  }
  else
  {
    this->viewPropertiesDialog->accept();
  }
}

void ViewMenuManager::viewPropertiesDialogHidden()
{
  this->showViewPropertiesAction->setChecked(false);
}

void ViewMenuManager::setProjectionModeToPerspective()
{
  int parallel = vtkSMPropertyHelper(this->View, "CameraParallelProjection").GetAsInt();
  if (parallel)
  {
    vtkSMPropertyHelper(this->View, "CameraParallelProjection").Set(0);
    this->View->UpdateVTKObjects();
    pqView* view = tomviz::convert<pqView*>(this->View);
    if (view)
    {
      view->render();
    }
  }
}

void ViewMenuManager::setProjectionModeToOrthographic()
{
  int parallel = vtkSMPropertyHelper(this->View, "CameraParallelProjection").GetAsInt();
  if (!parallel)
  {
    vtkSMPropertyHelper(this->View, "CameraParallelProjection").Set(1);
    this->View->UpdateVTKObjects();
    pqView* view = tomviz::convert<pqView*>(this->View);
    if (view)
    {
      view->render();
    }
  }
}

void ViewMenuManager::onViewPropertyChanged()
{
  if (!this->perspectiveProjectionAction || !this->orthographicProjectionAction)
  {
    return;
  }
  int parallel = vtkSMPropertyHelper(this->View, "CameraParallelProjection").GetAsInt();
  if (parallel && this->perspectiveProjectionAction->isChecked())
  {
    this->orthographicProjectionAction->setChecked(true);
  }
  else if (!parallel && this->orthographicProjectionAction->isChecked())
  {
    this->perspectiveProjectionAction->setChecked(true);
  }
}

void ViewMenuManager::onViewChanged()
{
  if (this->View)
  {
    vtkSMPropertyHelper(this->View, "AxesGrid").GetAsProxy()
      ->RemoveObserver(this->AxesGridObserverId);
    this->View->RemoveObserver(this->ViewObserverId);
  }
  this->View = ActiveObjects::instance().activeView();
  if (this->View)
  {
    this->ViewObserverId = pqCoreUtilities::connect(
        this->View, vtkCommand::PropertyModifiedEvent,
        this, SLOT(onViewPropertyChanged()));
    this->AxesGridObserverId = pqCoreUtilities::connect(
        vtkSMPropertyHelper(this->View, "AxesGrid").GetAsProxy(),
        vtkCommand::PropertyModifiedEvent, this, SLOT(onAxesGridChanged()));
  }
}

void ViewMenuManager::setShowAxisGrid(bool show)
{
  vtkSMProxy *axesGrid = vtkSMPropertyHelper(this->View, "AxesGrid").GetAsProxy();
  int showing = vtkSMPropertyHelper(axesGrid, "Visibility").GetAsInt();
  if (showing && !show)
  {
    vtkSMPropertyHelper(axesGrid, "Visibility").Set(0);
  }
  else if (!showing && show)
  {
    vtkSMPropertyHelper(axesGrid, "Visibility").Set(1);
  }
  axesGrid->UpdateVTKObjects();
  pqView* view = tomviz::convert<pqView*>(this->View);
  if (view)
  {
    view->render();
  }
}

void ViewMenuManager::onAxesGridChanged()
{
  vtkSMProxy *axesGrid = vtkSMPropertyHelper(this->View, "AxesGrid").GetAsProxy();
  int showing = vtkSMPropertyHelper(axesGrid, "Visibility").GetAsInt();
  if (showing && !this->showAxisGridAction->isChecked())
  {
    this->showAxisGridAction->setChecked(true);
  }
  else if (!showing && this->showAxisGridAction->isChecked())
  {
    this->showAxisGridAction->setChecked(false);
  }
}

}
<|endoftext|>


<commit_before>#!/usr/bin/env c-script

struct BP{
  Matrix<double> X;
  Matrix<double> D;
  Matrix<double> S;
  Matrix<double> W;
  Matrix<double> dW;
  Matrix<double> Y;
  Matrix<double> Hd;
  double d;
  void forward(){
    S=W*Y;
    mat_for(Hd)
      X(r,c)=sigm(S(r,c));
  }
  void update(){

    mat_for(Hd)
      Hd(r,c)=sigm(S(r,c))*(1-sigm(S(r,c)));
    dW=-2*ary_mul(ary_mul((D-X),Hd),Y);
  }
  void update(Matrix<double>& hW,Matrix<double>& hY){
    mat_for(Hd)
      Hd(r,c)=sigm(S(r,c))*(1-sigm(S(r,c)));
    dW=-2*ary_mul(ary_mul(t(hY*hW),Hd),Y);
  }
};

int
main(){
  SVM svm;
  svm.init(9,2);
  svm.set();
  int n=100000;
  for(int i=0;i<100000;i++){
    svm.update(i,n);
  }

  printf("L:\n");
  svm.L.write(stdout,"%2.2f");
  printf("w:\n");
  svm.w.write(stdout,"%2.2f");
  printf("LY:%f\n",dot(svm.L,svm.Y));
  printf("cost:%f\n",svm.cost());

  return 0;
}
<commit_msg>update<commit_after>#!/usr/bin/env c-script

double
sigm(double v){
  return 1.0/(1.0+exp(-v));
}
const Matrix<double>&
sigm(const Matrix<double>& X){
  Matrix<double> a(X.nr,X.nc);
  mat_for(a)
    a(r,c)=sigm(X(r,c));
  return a;
}

template<int N>
struct BP{
  Matrix<double> X[N+1];
  Matrix<double> D[N];
  Matrix<double> S[N];
  Matrix<double> W[N];
  double d;
  void init(){

  }
  //X[i+1]=sigm(S[i]=W[i]*X[i])
  const Matrix<double>&
  forward(const Matrix<double>& Y){
    X[0]=Y;
    for(int i=0;i<N;i++){
      S[i]=W[i]*X[i];
      X[i+1]=sigm(S);
    }
    return X[N];
  }
  void back(const Matrix<double>& D){
  }

};

int
main(){
  BP<1>  bp;

  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2020 The Orbit 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 "FrameTrackOnlineProcessor.h"

#include <absl/container/flat_hash_map.h>
#include <absl/container/flat_hash_set.h>

#include <limits>
#include <utility>

#include "OrbitClientData/FunctionInfoSet.h"
#include "OrbitClientData/UserDefinedCaptureData.h"
#include "OrbitClientModel/CaptureData.h"
#include "TimeGraph.h"

FrameTrackOnlineProcessor::FrameTrackOnlineProcessor(const CaptureData& capture_data,
                                                     TimeGraph* time_graph)
    : time_graph_(time_graph) {
  const auto& frame_track_function_ids = capture_data.frame_track_function_ids();
  for (const auto& function_id : frame_track_function_ids) {
    current_frame_track_function_ids_.insert(function_id);
    function_id_to_previous_timestamp_ns_.insert(
        std::make_pair(function_id, std::numeric_limits<uint64_t>::max()));
  }
}

void FrameTrackOnlineProcessor::ProcessTimer(const orbit_client_protos::TimerInfo& timer_info,
                                             const orbit_client_protos::FunctionInfo& function) {
  uint64_t function_id = timer_info.function_id();
  if (!current_frame_track_function_ids_.contains(function_id)) {
    return;
  }
  uint64_t previous_timestamp_ns = function_id_to_previous_timestamp_ns_.at(function_id);
  if (previous_timestamp_ns == std::numeric_limits<uint64_t>::max()) {
    function_id_to_previous_timestamp_ns_[function_id] = timer_info.start();
    return;
  }

  if (previous_timestamp_ns < timer_info.start()) {
    orbit_client_protos::TimerInfo frame_timer;

    // TID is meaningless for this timer (start and end can be on two different threads).
    constexpr const int32_t kUnusedThreadId = -1;
    frame_timer.set_thread_id(kUnusedThreadId);
    frame_timer.set_start(previous_timestamp_ns);
    frame_timer.set_end(timer_info.start());
    // We use user_data_key to keep track of the frame number.
    frame_timer.set_user_data_key(current_frame_index_++);
    frame_timer.set_type(orbit_client_protos::TimerInfo::kFrame);

    time_graph_->ProcessTimer(frame_timer, &function);

    function_id_to_previous_timestamp_ns_[function_id] = timer_info.start();
  }
}

void FrameTrackOnlineProcessor::AddFrameTrack(uint64_t function_id) {
  current_frame_track_function_ids_.insert(function_id);
  function_id_to_previous_timestamp_ns_.insert(
      std::make_pair(function_id, std::numeric_limits<uint64_t>::max()));
}

void FrameTrackOnlineProcessor::RemoveFrameTrack(uint64_t function_id) {
  current_frame_track_function_ids_.erase(function_id);
  function_id_to_previous_timestamp_ns_.erase(function_id);
}
<commit_msg>Solve the twice frame-track issue (regression)<commit_after>// Copyright (c) 2020 The Orbit 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 "FrameTrackOnlineProcessor.h"

#include <absl/container/flat_hash_map.h>
#include <absl/container/flat_hash_set.h>

#include <limits>
#include <utility>

#include "OrbitClientData/FunctionInfoSet.h"
#include "OrbitClientData/UserDefinedCaptureData.h"
#include "OrbitClientModel/CaptureData.h"
#include "TimeGraph.h"

FrameTrackOnlineProcessor::FrameTrackOnlineProcessor(const CaptureData& capture_data,
                                                     TimeGraph* time_graph)
    : time_graph_(time_graph) {
  const auto& frame_track_function_ids = capture_data.frame_track_function_ids();
  for (const auto& function_id : frame_track_function_ids) {
    current_frame_track_function_ids_.insert(function_id);
    function_id_to_previous_timestamp_ns_.insert(
        std::make_pair(function_id, std::numeric_limits<uint64_t>::max()));
  }
}

void FrameTrackOnlineProcessor::ProcessTimer(const orbit_client_protos::TimerInfo& timer_info,
                                             const orbit_client_protos::FunctionInfo& function) {
  uint64_t function_id = timer_info.function_id();
  if (!current_frame_track_function_ids_.contains(function_id)) {
    return;
  }
  uint64_t previous_timestamp_ns = function_id_to_previous_timestamp_ns_.at(function_id);
  if (previous_timestamp_ns == std::numeric_limits<uint64_t>::max()) {
    function_id_to_previous_timestamp_ns_[function_id] = timer_info.start();
    return;
  }

  if (previous_timestamp_ns < timer_info.start()) {
    orbit_client_protos::TimerInfo frame_timer;

    // TID is meaningless for this timer (start and end can be on two different threads).
    constexpr const int32_t kUnusedThreadId = -1;
    frame_timer.set_thread_id(kUnusedThreadId);
    frame_timer.set_function_id(function_id);
    frame_timer.set_start(previous_timestamp_ns);
    frame_timer.set_end(timer_info.start());
    // We use user_data_key to keep track of the frame number.
    frame_timer.set_user_data_key(current_frame_index_++);
    frame_timer.set_type(orbit_client_protos::TimerInfo::kFrame);

    time_graph_->ProcessTimer(frame_timer, &function);

    function_id_to_previous_timestamp_ns_[function_id] = timer_info.start();
  }
}

void FrameTrackOnlineProcessor::AddFrameTrack(uint64_t function_id) {
  current_frame_track_function_ids_.insert(function_id);
  function_id_to_previous_timestamp_ns_.insert(
      std::make_pair(function_id, std::numeric_limits<uint64_t>::max()));
}

void FrameTrackOnlineProcessor::RemoveFrameTrack(uint64_t function_id) {
  current_frame_track_function_ids_.erase(function_id);
  function_id_to_previous_timestamp_ns_.erase(function_id);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <vector>
//-----------------------------------------------------------------------------
#include <SDL2/SDL.h>
//-----------------------------------------------------------------------------
#include "../parser_yaml/parser_yaml.h"
#include "../log/logger.h"
#include "../model/game.h"
#include "../gfx/game_window.h"
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
int main(int argc, char* args[]) {

	auto & logger = *Logger::getInstance();
	logger.writeInformation("Start game");

	{
		Game game;
		ParserYAML parser(CONFIG_FILE_PATH);
		parser.parse();
		game.setBoard(make_shared<Board>(parser));
		game.addClient(make_shared<GameWindow>(game, *(game.getAvailablePlayer()), parser));
		game.start();
	}

	logger.getInstance()->writeInformation("Closing down");

	exit(0);
}
//-----------------------------------------------------------------------------
<commit_msg>Recupero restart en standalone<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <vector>
//-----------------------------------------------------------------------------
#include <SDL2/SDL.h>
//-----------------------------------------------------------------------------
#include "../parser_yaml/parser_yaml.h"
#include "../log/logger.h"
#include "../model/game.h"
#include "../gfx/game_window.h"
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
int main(int argc, char* args[]) {

	auto & logger = *Logger::getInstance();
	logger.writeInformation("Start game");

	{
		bool restart = true;
		do {
			Game game;
			ParserYAML parser(CONFIG_FILE_PATH);
			parser.parse();
			game.setBoard(make_shared<Board>(parser));
			game.addClient(make_shared<GameWindow>(game, *(game.getAvailablePlayer()), parser));
			game.start();
			restart = game.willRestart();
		} while (restart);
	}

	logger.getInstance()->writeInformation("Closing down");

	exit(0);
}
//-----------------------------------------------------------------------------
<|endoftext|>