<commit_before>// Copyright (c) 2011 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 <algorithm>
#include <list>
#include <map>

#include "chrome/browser/browser_thread.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/login/login_prompt.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/notification_service.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "net/base/auth.h"

namespace {

class LoginPromptBrowserTest : public InProcessBrowserTest {
 public:
  LoginPromptBrowserTest()
      : bad_password_(L"incorrect"), bad_username_(L"nouser") {
    set_show_window(true);

    auth_map_[L"foo"] = AuthInfo(L"testuser", L"foopassword");
    auth_map_[L"bar"] = AuthInfo(L"testuser", L"barpassword");
  }

 protected:
  void SetAuthFor(LoginHandler* handler);

  struct AuthInfo {
    std::wstring username_;
    std::wstring password_;

    AuthInfo() {}

    AuthInfo(const std::wstring username,
             const std::wstring password)
        : username_(username), password_(password) {}
  };

  std::map<std::wstring, AuthInfo> auth_map_;
  std::wstring bad_password_;
  std::wstring bad_username_;
};

void LoginPromptBrowserTest::SetAuthFor(LoginHandler* handler) {
  const net::AuthChallengeInfo* challenge = handler->auth_info();

  ASSERT_TRUE(challenge);
  std::map<std::wstring, AuthInfo>::iterator i =
      auth_map_.find(challenge->realm);
  EXPECT_TRUE(auth_map_.end() != i);
  if (i != auth_map_.end()) {
    const AuthInfo& info = i->second;
    handler->SetAuth(info.username_, info.password_);
  }
}

// Maintains a set of LoginHandlers that are currently active and
// keeps a count of the notifications that were observed.
class LoginPromptBrowserTestObserver : public NotificationObserver {
 public:
  LoginPromptBrowserTestObserver()
      : auth_needed_count_(0),
        auth_supplied_count_(0),
        auth_cancelled_count_(0) {}

  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details);

  void AddHandler(LoginHandler* handler);

  void RemoveHandler(LoginHandler* handler);

  void Register(const NotificationSource& source);

  std::list<LoginHandler*> handlers_;

  // The exact number of notifications we receive is depedent on the
  // number of requests that were dispatched and is subject to a
  // number of factors that we don't directly control here.  The
  // values below should only be used qualitatively.
  int auth_needed_count_;
  int auth_supplied_count_;
  int auth_cancelled_count_;

 private:
  NotificationRegistrar registrar_;

  DISALLOW_COPY_AND_ASSIGN(LoginPromptBrowserTestObserver);
};

void LoginPromptBrowserTestObserver::Observe(
    NotificationType type,
    const NotificationSource& source,
    const NotificationDetails& details) {
  if (type == NotificationType::AUTH_NEEDED) {
    LoginNotificationDetails* login_details =
        Details<LoginNotificationDetails>(details).ptr();
    AddHandler(login_details->handler());
    auth_needed_count_++;
  } else if (type == NotificationType::AUTH_SUPPLIED) {
    AuthSuppliedLoginNotificationDetails* login_details =
        Details<AuthSuppliedLoginNotificationDetails>(details).ptr();
    RemoveHandler(login_details->handler());
    auth_supplied_count_++;
  } else if (type == NotificationType::AUTH_CANCELLED) {
    LoginNotificationDetails* login_details =
        Details<LoginNotificationDetails>(details).ptr();
    RemoveHandler(login_details->handler());
    auth_cancelled_count_++;
  }
}

void LoginPromptBrowserTestObserver::AddHandler(LoginHandler* handler) {
  std::list<LoginHandler*>::iterator i = std::find(handlers_.begin(),
                                                   handlers_.end(),
                                                   handler);
  EXPECT_TRUE(i == handlers_.end());
  if (i == handlers_.end())
    handlers_.push_back(handler);
}

void LoginPromptBrowserTestObserver::RemoveHandler(LoginHandler* handler) {
  std::list<LoginHandler*>::iterator i = std::find(handlers_.begin(),
                                                   handlers_.end(),
                                                   handler);
  EXPECT_TRUE(i != handlers_.end());
  if (i != handlers_.end())
    handlers_.erase(i);
}

void LoginPromptBrowserTestObserver::Register(
    const NotificationSource& source) {
  registrar_.Add(this, NotificationType::AUTH_NEEDED, source);
  registrar_.Add(this, NotificationType::AUTH_SUPPLIED, source);
  registrar_.Add(this, NotificationType::AUTH_CANCELLED, source);
}

template <NotificationType::Type T>
class WindowedNavigationObserver
    : public ui_test_utils::WindowedNotificationObserver {
 public:
  explicit WindowedNavigationObserver(NavigationController* controller)
      : ui_test_utils::WindowedNotificationObserver(
          T, Source<NavigationController>(controller)) {}
};

typedef WindowedNavigationObserver<NotificationType::LOAD_STOP>
    WindowedLoadStopObserver;

typedef WindowedNavigationObserver<NotificationType::AUTH_NEEDED>
    WindowedAuthNeededObserver;

typedef WindowedNavigationObserver<NotificationType::AUTH_CANCELLED>
    WindowedAuthCancelledObserver;

typedef WindowedNavigationObserver<NotificationType::AUTH_SUPPLIED>
    WindowedAuthSuppliedObserver;

const char* kPrefetchAuthPage = "files/login/prefetch.html";

const char* kMultiRealmTestPage = "files/login/multi_realm.html";
const int   kMultiRealmTestRealmCount = 2;
const int   kMultiRealmTestResourceCount = 4;

const char* kSingleRealmTestPage = "files/login/single_realm.html";
const int   kSingleRealmTestResourceCount = 6;

// Confirm that <link rel="prefetch"> targetting an auth required
// resource does not provide a login dialog.  These types of requests
// should instead just cancel the auth.

// Unfortunately, this test doesn't assert on anything for its
// correctness.  Instead, it relies on the auth dialog blocking the
// browser, and triggering a timeout to cause failure when the
// prefetch resource requires authorization.
IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, PrefetchAuthCancels) {
  ASSERT_TRUE(test_server()->Start());

  GURL test_page = test_server()->GetURL(kPrefetchAuthPage);

  class SetPrefetchForTest {
   public:
    explicit SetPrefetchForTest(bool prefetch)
        : old_prefetch_state_(ResourceDispatcherHost::is_prefetch_enabled()) {
      ResourceDispatcherHost::set_is_prefetch_enabled(prefetch);
    }

    ~SetPrefetchForTest() {
      ResourceDispatcherHost::set_is_prefetch_enabled(old_prefetch_state_);
    }
   private:
    bool old_prefetch_state_;
  } set_prefetch_for_test(true);

  TabContentsWrapper* contents =
      browser()->GetSelectedTabContentsWrapper();
  ASSERT_TRUE(contents);
  NavigationController* controller = &contents->controller();
  LoginPromptBrowserTestObserver observer;

  observer.Register(Source<NavigationController>(controller));

  WindowedLoadStopObserver load_stop_waiter(controller);
  browser()->OpenURL(test_page, GURL(), CURRENT_TAB, PageTransition::TYPED);

  load_stop_waiter.Wait();
  EXPECT_TRUE(observer.handlers_.empty());
  EXPECT_TRUE(test_server()->Stop());
}

// Test handling of resources that require authentication even though
// the page they are included on doesn't.  In this case we should only
// present the minimal number of prompts necessary for successfully
// displaying the page.  First we check whether cancelling works as
// expected.
IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, MultipleRealmCancellation) {
  ASSERT_TRUE(test_server()->Start());
  GURL test_page = test_server()->GetURL(kMultiRealmTestPage);

  TabContentsWrapper* contents =
      browser()->GetSelectedTabContentsWrapper();
  ASSERT_TRUE(contents);

  NavigationController* controller = &contents->controller();
  LoginPromptBrowserTestObserver observer;

  observer.Register(Source<NavigationController>(controller));

  WindowedLoadStopObserver load_stop_waiter(controller);

  {
    WindowedAuthNeededObserver auth_needed_waiter(controller);
    browser()->OpenURL(test_page, GURL(), CURRENT_TAB, PageTransition::TYPED);
    auth_needed_waiter.Wait();
  }

  int n_handlers = 0;

  while (n_handlers < kMultiRealmTestRealmCount) {
    WindowedAuthNeededObserver auth_needed_waiter(controller);

    while (!observer.handlers_.empty()) {
      WindowedAuthCancelledObserver auth_cancelled_waiter(controller);
      LoginHandler* handler = *observer.handlers_.begin();

      ASSERT_TRUE(handler);
      n_handlers++;
      handler->CancelAuth();
      auth_cancelled_waiter.Wait();
    }

    if (n_handlers < kMultiRealmTestRealmCount)
      auth_needed_waiter.Wait();
  }

  load_stop_waiter.Wait();

  EXPECT_EQ(kMultiRealmTestRealmCount, n_handlers);
  EXPECT_EQ(0, observer.auth_supplied_count_);
  EXPECT_LT(0, observer.auth_needed_count_);
  EXPECT_LT(0, observer.auth_cancelled_count_);
  EXPECT_TRUE(test_server()->Stop());
}

// Similar to the MultipleRealmCancellation test above, but tests
// whether supplying credentials work as exepcted.
#if defined(OS_WIN)
// See http://crbug.com/70960
#define MAYBE_MultipleRealmConfirmation DISABLED_MultipleRealmConfirmation
#else
#define MAYBE_MultipleRealmConfirmation MultipleRealmConfirmation
#endif
IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest,
                       MAYBE_MultipleRealmConfirmation) {
  ASSERT_TRUE(test_server()->Start());
  GURL test_page = test_server()->GetURL(kMultiRealmTestPage);

  TabContentsWrapper* contents =
      browser()->GetSelectedTabContentsWrapper();
  ASSERT_TRUE(contents);

  NavigationController* controller = &contents->controller();
  LoginPromptBrowserTestObserver observer;

  observer.Register(Source<NavigationController>(controller));

  WindowedLoadStopObserver load_stop_waiter(controller);
  int n_handlers = 0;

  {
    WindowedAuthNeededObserver auth_needed_waiter(controller);

    browser()->OpenURL(test_page, GURL(), CURRENT_TAB, PageTransition::TYPED);
    auth_needed_waiter.Wait();
  }

  while (n_handlers < kMultiRealmTestRealmCount) {
    WindowedAuthNeededObserver auth_needed_waiter(controller);

    while (!observer.handlers_.empty()) {
      WindowedAuthSuppliedObserver auth_supplied_waiter(controller);
      LoginHandler* handler = *observer.handlers_.begin();

      ASSERT_TRUE(handler);
      n_handlers++;
      SetAuthFor(handler);
      auth_supplied_waiter.Wait();
    }

    if (n_handlers < kMultiRealmTestRealmCount)
      auth_needed_waiter.Wait();
  }

  load_stop_waiter.Wait();

  EXPECT_EQ(kMultiRealmTestRealmCount, n_handlers);
  EXPECT_LT(0, observer.auth_needed_count_);
  EXPECT_LT(0, observer.auth_supplied_count_);
  EXPECT_EQ(0, observer.auth_cancelled_count_);
  EXPECT_TRUE(test_server()->Stop());
}

// Testing for recovery from an incorrect password for the case where
// there are multiple authenticated resources.
// Marked as flaky.  See http://crbug.com/69266 and http://crbug.com/68860
// TODO(asanka): Remove logging when timeout issues are resolved.
IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, FLAKY_IncorrectConfirmation) {
  ASSERT_TRUE(test_server()->Start());
  GURL test_page = test_server()->GetURL(kSingleRealmTestPage);

  TabContentsWrapper* contents =
      browser()->GetSelectedTabContentsWrapper();
  ASSERT_TRUE(contents);

  NavigationController* controller = &contents->controller();
  LoginPromptBrowserTestObserver observer;

  observer.Register(Source<NavigationController>(controller));

  WindowedLoadStopObserver load_stop_waiter(controller);

  LOG(INFO) <<
      "Begin test run "
      "(tracing for potential hang. crbug.com/69266)";
  {
    WindowedAuthNeededObserver auth_needed_waiter(controller);
    browser()->OpenURL(test_page, GURL(), CURRENT_TAB, PageTransition::TYPED);
    LOG(INFO) << "Waiting for initial AUTH_NEEDED";
    auth_needed_waiter.Wait();
  }

  EXPECT_FALSE(observer.handlers_.empty());

  if (!observer.handlers_.empty()) {
    WindowedAuthNeededObserver auth_needed_waiter(controller);
    WindowedAuthSuppliedObserver auth_supplied_waiter(controller);
    LoginHandler* handler = *observer.handlers_.begin();

    ASSERT_TRUE(handler);
    handler->SetAuth(bad_username_, bad_password_);
    LOG(INFO) << "Waiting for initial AUTH_SUPPLIED";
    auth_supplied_waiter.Wait();

    // The request should be retried after the incorrect password is
    // supplied.  This should result in a new AUTH_NEEDED notification
    // for the same realm.
    LOG(INFO) << "Waiting for secondary AUTH_NEEDED";
    auth_needed_waiter.Wait();
  }

  int n_handlers = 0;

  while (n_handlers < 1) {
    WindowedAuthNeededObserver auth_needed_waiter(controller);

    while (!observer.handlers_.empty()) {
      WindowedAuthSuppliedObserver auth_supplied_waiter(controller);
      LoginHandler* handler = *observer.handlers_.begin();

      ASSERT_TRUE(handler);
      n_handlers++;
      SetAuthFor(handler);
      LOG(INFO) << "Waiting for secondary AUTH_SUPPLIED";
      auth_supplied_waiter.Wait();
    }

    if (n_handlers < 1) {
      LOG(INFO) << "Waiting for additional AUTH_NEEDED";
      auth_needed_waiter.Wait();
    }
  }

  // The single realm test has only one realm, and thus only one login
  // prompt.
  EXPECT_EQ(1, n_handlers);
  EXPECT_LT(0, observer.auth_needed_count_);
  EXPECT_EQ(0, observer.auth_cancelled_count_);
  EXPECT_EQ(observer.auth_needed_count_, observer.auth_supplied_count_);
  LOG(INFO) << "Waiting for LOAD_STOP";
  load_stop_waiter.Wait();
  EXPECT_TRUE(test_server()->Stop());
  LOG(INFO) << "Done with test";
}
}  // namespace
<commit_msg>Disable LoginPromptBrowserTest.IncorrectConfirmation<commit_after>// Copyright (c) 2011 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 <algorithm>
#include <list>
#include <map>

#include "chrome/browser/browser_thread.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/login/login_prompt.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/notification_service.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "net/base/auth.h"

namespace {

class LoginPromptBrowserTest : public InProcessBrowserTest {
 public:
  LoginPromptBrowserTest()
      : bad_password_(L"incorrect"), bad_username_(L"nouser") {
    set_show_window(true);

    auth_map_[L"foo"] = AuthInfo(L"testuser", L"foopassword");
    auth_map_[L"bar"] = AuthInfo(L"testuser", L"barpassword");
  }

 protected:
  void SetAuthFor(LoginHandler* handler);

  struct AuthInfo {
    std::wstring username_;
    std::wstring password_;

    AuthInfo() {}

    AuthInfo(const std::wstring username,
             const std::wstring password)
        : username_(username), password_(password) {}
  };

  std::map<std::wstring, AuthInfo> auth_map_;
  std::wstring bad_password_;
  std::wstring bad_username_;
};

void LoginPromptBrowserTest::SetAuthFor(LoginHandler* handler) {
  const net::AuthChallengeInfo* challenge = handler->auth_info();

  ASSERT_TRUE(challenge);
  std::map<std::wstring, AuthInfo>::iterator i =
      auth_map_.find(challenge->realm);
  EXPECT_TRUE(auth_map_.end() != i);
  if (i != auth_map_.end()) {
    const AuthInfo& info = i->second;
    handler->SetAuth(info.username_, info.password_);
  }
}

// Maintains a set of LoginHandlers that are currently active and
// keeps a count of the notifications that were observed.
class LoginPromptBrowserTestObserver : public NotificationObserver {
 public:
  LoginPromptBrowserTestObserver()
      : auth_needed_count_(0),
        auth_supplied_count_(0),
        auth_cancelled_count_(0) {}

  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details);

  void AddHandler(LoginHandler* handler);

  void RemoveHandler(LoginHandler* handler);

  void Register(const NotificationSource& source);

  std::list<LoginHandler*> handlers_;

  // The exact number of notifications we receive is depedent on the
  // number of requests that were dispatched and is subject to a
  // number of factors that we don't directly control here.  The
  // values below should only be used qualitatively.
  int auth_needed_count_;
  int auth_supplied_count_;
  int auth_cancelled_count_;

 private:
  NotificationRegistrar registrar_;

  DISALLOW_COPY_AND_ASSIGN(LoginPromptBrowserTestObserver);
};

void LoginPromptBrowserTestObserver::Observe(
    NotificationType type,
    const NotificationSource& source,
    const NotificationDetails& details) {
  if (type == NotificationType::AUTH_NEEDED) {
    LoginNotificationDetails* login_details =
        Details<LoginNotificationDetails>(details).ptr();
    AddHandler(login_details->handler());
    auth_needed_count_++;
  } else if (type == NotificationType::AUTH_SUPPLIED) {
    AuthSuppliedLoginNotificationDetails* login_details =
        Details<AuthSuppliedLoginNotificationDetails>(details).ptr();
    RemoveHandler(login_details->handler());
    auth_supplied_count_++;
  } else if (type == NotificationType::AUTH_CANCELLED) {
    LoginNotificationDetails* login_details =
        Details<LoginNotificationDetails>(details).ptr();
    RemoveHandler(login_details->handler());
    auth_cancelled_count_++;
  }
}

void LoginPromptBrowserTestObserver::AddHandler(LoginHandler* handler) {
  std::list<LoginHandler*>::iterator i = std::find(handlers_.begin(),
                                                   handlers_.end(),
                                                   handler);
  EXPECT_TRUE(i == handlers_.end());
  if (i == handlers_.end())
    handlers_.push_back(handler);
}

void LoginPromptBrowserTestObserver::RemoveHandler(LoginHandler* handler) {
  std::list<LoginHandler*>::iterator i = std::find(handlers_.begin(),
                                                   handlers_.end(),
                                                   handler);
  EXPECT_TRUE(i != handlers_.end());
  if (i != handlers_.end())
    handlers_.erase(i);
}

void LoginPromptBrowserTestObserver::Register(
    const NotificationSource& source) {
  registrar_.Add(this, NotificationType::AUTH_NEEDED, source);
  registrar_.Add(this, NotificationType::AUTH_SUPPLIED, source);
  registrar_.Add(this, NotificationType::AUTH_CANCELLED, source);
}

template <NotificationType::Type T>
class WindowedNavigationObserver
    : public ui_test_utils::WindowedNotificationObserver {
 public:
  explicit WindowedNavigationObserver(NavigationController* controller)
      : ui_test_utils::WindowedNotificationObserver(
          T, Source<NavigationController>(controller)) {}
};

typedef WindowedNavigationObserver<NotificationType::LOAD_STOP>
    WindowedLoadStopObserver;

typedef WindowedNavigationObserver<NotificationType::AUTH_NEEDED>
    WindowedAuthNeededObserver;

typedef WindowedNavigationObserver<NotificationType::AUTH_CANCELLED>
    WindowedAuthCancelledObserver;

typedef WindowedNavigationObserver<NotificationType::AUTH_SUPPLIED>
    WindowedAuthSuppliedObserver;

const char* kPrefetchAuthPage = "files/login/prefetch.html";

const char* kMultiRealmTestPage = "files/login/multi_realm.html";
const int   kMultiRealmTestRealmCount = 2;
const int   kMultiRealmTestResourceCount = 4;

const char* kSingleRealmTestPage = "files/login/single_realm.html";
const int   kSingleRealmTestResourceCount = 6;

// Confirm that <link rel="prefetch"> targetting an auth required
// resource does not provide a login dialog.  These types of requests
// should instead just cancel the auth.

// Unfortunately, this test doesn't assert on anything for its
// correctness.  Instead, it relies on the auth dialog blocking the
// browser, and triggering a timeout to cause failure when the
// prefetch resource requires authorization.
IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, PrefetchAuthCancels) {
  ASSERT_TRUE(test_server()->Start());

  GURL test_page = test_server()->GetURL(kPrefetchAuthPage);

  class SetPrefetchForTest {
   public:
    explicit SetPrefetchForTest(bool prefetch)
        : old_prefetch_state_(ResourceDispatcherHost::is_prefetch_enabled()) {
      ResourceDispatcherHost::set_is_prefetch_enabled(prefetch);
    }

    ~SetPrefetchForTest() {
      ResourceDispatcherHost::set_is_prefetch_enabled(old_prefetch_state_);
    }
   private:
    bool old_prefetch_state_;
  } set_prefetch_for_test(true);

  TabContentsWrapper* contents =
      browser()->GetSelectedTabContentsWrapper();
  ASSERT_TRUE(contents);
  NavigationController* controller = &contents->controller();
  LoginPromptBrowserTestObserver observer;

  observer.Register(Source<NavigationController>(controller));

  WindowedLoadStopObserver load_stop_waiter(controller);
  browser()->OpenURL(test_page, GURL(), CURRENT_TAB, PageTransition::TYPED);

  load_stop_waiter.Wait();
  EXPECT_TRUE(observer.handlers_.empty());
  EXPECT_TRUE(test_server()->Stop());
}

// Test handling of resources that require authentication even though
// the page they are included on doesn't.  In this case we should only
// present the minimal number of prompts necessary for successfully
// displaying the page.  First we check whether cancelling works as
// expected.
IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, MultipleRealmCancellation) {
  ASSERT_TRUE(test_server()->Start());
  GURL test_page = test_server()->GetURL(kMultiRealmTestPage);

  TabContentsWrapper* contents =
      browser()->GetSelectedTabContentsWrapper();
  ASSERT_TRUE(contents);

  NavigationController* controller = &contents->controller();
  LoginPromptBrowserTestObserver observer;

  observer.Register(Source<NavigationController>(controller));

  WindowedLoadStopObserver load_stop_waiter(controller);

  {
    WindowedAuthNeededObserver auth_needed_waiter(controller);
    browser()->OpenURL(test_page, GURL(), CURRENT_TAB, PageTransition::TYPED);
    auth_needed_waiter.Wait();
  }

  int n_handlers = 0;

  while (n_handlers < kMultiRealmTestRealmCount) {
    WindowedAuthNeededObserver auth_needed_waiter(controller);

    while (!observer.handlers_.empty()) {
      WindowedAuthCancelledObserver auth_cancelled_waiter(controller);
      LoginHandler* handler = *observer.handlers_.begin();

      ASSERT_TRUE(handler);
      n_handlers++;
      handler->CancelAuth();
      auth_cancelled_waiter.Wait();
    }

    if (n_handlers < kMultiRealmTestRealmCount)
      auth_needed_waiter.Wait();
  }

  load_stop_waiter.Wait();

  EXPECT_EQ(kMultiRealmTestRealmCount, n_handlers);
  EXPECT_EQ(0, observer.auth_supplied_count_);
  EXPECT_LT(0, observer.auth_needed_count_);
  EXPECT_LT(0, observer.auth_cancelled_count_);
  EXPECT_TRUE(test_server()->Stop());
}

// Similar to the MultipleRealmCancellation test above, but tests
// whether supplying credentials work as exepcted.
#if defined(OS_WIN)
// See http://crbug.com/70960
#define MAYBE_MultipleRealmConfirmation DISABLED_MultipleRealmConfirmation
#else
#define MAYBE_MultipleRealmConfirmation MultipleRealmConfirmation
#endif
IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest,
                       MAYBE_MultipleRealmConfirmation) {
  ASSERT_TRUE(test_server()->Start());
  GURL test_page = test_server()->GetURL(kMultiRealmTestPage);

  TabContentsWrapper* contents =
      browser()->GetSelectedTabContentsWrapper();
  ASSERT_TRUE(contents);

  NavigationController* controller = &contents->controller();
  LoginPromptBrowserTestObserver observer;

  observer.Register(Source<NavigationController>(controller));

  WindowedLoadStopObserver load_stop_waiter(controller);
  int n_handlers = 0;

  {
    WindowedAuthNeededObserver auth_needed_waiter(controller);

    browser()->OpenURL(test_page, GURL(), CURRENT_TAB, PageTransition::TYPED);
    auth_needed_waiter.Wait();
  }

  while (n_handlers < kMultiRealmTestRealmCount) {
    WindowedAuthNeededObserver auth_needed_waiter(controller);

    while (!observer.handlers_.empty()) {
      WindowedAuthSuppliedObserver auth_supplied_waiter(controller);
      LoginHandler* handler = *observer.handlers_.begin();

      ASSERT_TRUE(handler);
      n_handlers++;
      SetAuthFor(handler);
      auth_supplied_waiter.Wait();
    }

    if (n_handlers < kMultiRealmTestRealmCount)
      auth_needed_waiter.Wait();
  }

  load_stop_waiter.Wait();

  EXPECT_EQ(kMultiRealmTestRealmCount, n_handlers);
  EXPECT_LT(0, observer.auth_needed_count_);
  EXPECT_LT(0, observer.auth_supplied_count_);
  EXPECT_EQ(0, observer.auth_cancelled_count_);
  EXPECT_TRUE(test_server()->Stop());
}

// Testing for recovery from an incorrect password for the case where
// there are multiple authenticated resources.
// Marked as flaky.  See http://crbug.com/69266 and http://crbug.com/68860
// TODO(asanka): Remove logging when timeout issues are resolved.
IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, DISABLED_IncorrectConfirmation) {
  ASSERT_TRUE(test_server()->Start());
  GURL test_page = test_server()->GetURL(kSingleRealmTestPage);

  TabContentsWrapper* contents =
      browser()->GetSelectedTabContentsWrapper();
  ASSERT_TRUE(contents);

  NavigationController* controller = &contents->controller();
  LoginPromptBrowserTestObserver observer;

  observer.Register(Source<NavigationController>(controller));

  WindowedLoadStopObserver load_stop_waiter(controller);

  LOG(INFO) <<
      "Begin test run "
      "(tracing for potential hang. crbug.com/69266)";
  {
    WindowedAuthNeededObserver auth_needed_waiter(controller);
    browser()->OpenURL(test_page, GURL(), CURRENT_TAB, PageTransition::TYPED);
    LOG(INFO) << "Waiting for initial AUTH_NEEDED";
    auth_needed_waiter.Wait();
  }

  EXPECT_FALSE(observer.handlers_.empty());

  if (!observer.handlers_.empty()) {
    WindowedAuthNeededObserver auth_needed_waiter(controller);
    WindowedAuthSuppliedObserver auth_supplied_waiter(controller);
    LoginHandler* handler = *observer.handlers_.begin();

    ASSERT_TRUE(handler);
    handler->SetAuth(bad_username_, bad_password_);
    LOG(INFO) << "Waiting for initial AUTH_SUPPLIED";
    auth_supplied_waiter.Wait();

    // The request should be retried after the incorrect password is
    // supplied.  This should result in a new AUTH_NEEDED notification
    // for the same realm.
    LOG(INFO) << "Waiting for secondary AUTH_NEEDED";
    auth_needed_waiter.Wait();
  }

  int n_handlers = 0;

  while (n_handlers < 1) {
    WindowedAuthNeededObserver auth_needed_waiter(controller);

    while (!observer.handlers_.empty()) {
      WindowedAuthSuppliedObserver auth_supplied_waiter(controller);
      LoginHandler* handler = *observer.handlers_.begin();

      ASSERT_TRUE(handler);
      n_handlers++;
      SetAuthFor(handler);
      LOG(INFO) << "Waiting for secondary AUTH_SUPPLIED";
      auth_supplied_waiter.Wait();
    }

    if (n_handlers < 1) {
      LOG(INFO) << "Waiting for additional AUTH_NEEDED";
      auth_needed_waiter.Wait();
    }
  }

  // The single realm test has only one realm, and thus only one login
  // prompt.
  EXPECT_EQ(1, n_handlers);
  EXPECT_LT(0, observer.auth_needed_count_);
  EXPECT_EQ(0, observer.auth_cancelled_count_);
  EXPECT_EQ(observer.auth_needed_count_, observer.auth_supplied_count_);
  LOG(INFO) << "Waiting for LOAD_STOP";
  load_stop_waiter.Wait();
  EXPECT_TRUE(test_server()->Stop());
  LOG(INFO) << "Done with test";
}
}  // namespace
<|endoftext|>


<commit_before>#include "SceneLights.h"
#include "IEUtility/IEVector3.h"
#include "GPUBuffer.h"
#include "DrawBuffer.h"
#include "Globals.h"
#include "FrameTransformBuffer.h"
#include "IEUtility/IEQuaternion.h"
#include "IEUtility/IEMath.h"

const GLsizei SceneLights::shadowMapW = 512;
const GLsizei SceneLights::shadowMapH = 512;

const IEVector3 SceneLights::pLightDir[6] =
{
	IEVector3::Xaxis,
	-IEVector3::Xaxis,
	IEVector3::Yaxis,
	-IEVector3::Yaxis,
	IEVector3::Zaxis,
	-IEVector3::Zaxis
};

const IEVector3 SceneLights::pLightUp[6] =
{
	IEVector3::Yaxis,
	IEVector3::Yaxis,
	-IEVector3::Zaxis,
	IEVector3::Zaxis,
	IEVector3::Yaxis,
	IEVector3::Yaxis
};

const IEVector3 SceneLights::aLightDir[6] =
{
	IEQuaternion(IEMath::ToRadians(45.0f), -IEVector3::Zaxis).ApplyRotation(IEVector3::Xaxis),
	IEQuaternion(IEMath::ToRadians(45.0f), IEVector3::Zaxis).ApplyRotation(-IEVector3::Xaxis),
	IEVector3::ZeroVector,	// Unused
	-IEVector3::Yaxis,
	IEQuaternion(IEMath::ToRadians(45.0f), IEVector3::Xaxis).ApplyRotation(IEVector3::Zaxis),
	IEQuaternion(IEMath::ToRadians(45.0f), -IEVector3::Xaxis).ApplyRotation(-IEVector3::Zaxis)
};

const IEVector3 SceneLights::aLightUp[6] =
{
	IEQuaternion(IEMath::ToRadians(45.0f), -IEVector3::Zaxis).ApplyRotation(IEVector3::Yaxis),
	IEQuaternion(IEMath::ToRadians(45.0f), IEVector3::Zaxis).ApplyRotation(IEVector3::Yaxis),
	IEVector3::ZeroVector,	// Unused
	IEVector3::Zaxis,
	IEQuaternion(IEMath::ToRadians(45.0f), IEVector3::Xaxis).ApplyRotation(IEVector3::Yaxis),
	IEQuaternion(IEMath::ToRadians(45.0f), -IEVector3::Xaxis).ApplyRotation(IEVector3::Yaxis)
};

SceneLights::SceneLights(const Array32<Light>& lights)
	: lightsGPU(lights.length)
	, lightShadowMaps(0)
	, viewMatrices(6)
	, fragShadowMap(ShaderType::FRAGMENT, "Shaders/ShadowMap.frag")
	, vertShadowMap(ShaderType::VERTEX, "Shaders/ShadowMap.vert")
	, geomAreaShadowMap(ShaderType::GEOMETRY, "Shaders/ShadowMapA.geom")
	, geomDirShadowMap(ShaderType::GEOMETRY, "Shaders/ShadowMapD.geom")
	, geomPointShadowMap(ShaderType::GEOMETRY, "Shaders/ShadowMapP.geom")
{

	glGenTextures(1, &lightShadowMaps);
	glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, lightShadowMaps);
	glTextureStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_DEPTH_COMPONENT32F, shadowMapW, shadowMapH, lights.length);
	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);

	shadowMapFBOs.resize(lights.length);
	glGenFramebuffers(lights.length, shadowMapFBOs.data());

	for(unsigned int i = 0; i < lights.length; i++)
	{
		lightsGPU.AddData(lights.arr[i]);
		glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBOs[i]);
		glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, lightShadowMaps, i);
		assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
	}
	lightsGPU.SendData();
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

SceneLights::~SceneLights()
{
	glDeleteTextures(1, &lightShadowMaps);
}

void SceneLights::GenerateShadowMaps(DrawBuffer& drawBuffer, GPUBuffer& gpuBuffer,
									 FrameTransformBuffer& fTransform,
									 unsigned int drawCount,
									 IEVector3 frustumMin,
	 								 IEVector3 frustumMax)
{
	fragShadowMap.Bind();
	vertShadowMap.Bind();

	// State
	glColorMask(false, false, false, false);
	glDepthMask(true);
	glEnable(GL_DEPTH_TEST);
	glDisable(GL_MULTISAMPLE);
	glDisable(GL_CULL_FACE);
	glViewport(0, 0, shadowMapW, shadowMapH);

	gpuBuffer.Bind();
	fTransform.Bind();
	drawBuffer.getDrawParamBuffer().BindAsDrawIndirectBuffer();
	viewMatrices.BindAsUniformBuffer(U_SHADOW_VIEW);

	// Render From Dir of the light	with proper view params
	IEMatrix4x4 viewTransform = IEMatrix4x4::IdentityMatrix;
	IEMatrix4x4 projection;
	for(int i = 0; i < lightsGPU.CPUData().size(); i++)
	{
		const Light& currentLight = lightsGPU.CPUData()[i];
		// Determine light type
		LightType t = static_cast<LightType>(static_cast<uint32_t>(currentLight.position.getW()));
		switch(t)
		{
			case LightType::POINT:
			{
				// Render to Cubemap
				geomPointShadowMap.Bind();

				// Each Side will have 90 degree FOV
				// Geom shader will render for each layer
				for(unsigned int i = 0; i < 6; i++)
				{
					viewMatrices.CPUData()[i] = IEMatrix4x4::LookAt(currentLight.position,
																	currentLight.position + pLightDir[i],
																	pLightUp[i]);
				}
				viewMatrices.SendData();
				projection = IEMatrix4x4::Perspective(90.0f, 1.0f,
													  0.1f, currentLight.color.getW() + 10.0f);
				break;
			}
			case LightType::DIRECTIONAL:
			{
				// Render to one sheet
				// Camera Direction should be
				viewTransform = IEMatrix4x4::LookAt(currentLight.position,
													currentLight.position + currentLight.direction,
													IEVector3::Yaxis);
				projection = IEMatrix4x4::Ortogonal(frustumMin.getX(), frustumMax.getX(),
													frustumMax.getY(), frustumMin.getY(),
													frustumMin.getZ(), frustumMax.getZ());
				break;
			}
			case LightType::AREA:
			{
				// Render to cube but only 5 sides (6th side is not illuminated)
				geomAreaShadowMap.Bind();
				// we'll use 5 sides but each will comply different ares that a point light
				for(unsigned int i = 0; i < 5; i++)
				{
					viewMatrices.CPUData()[i] = IEMatrix4x4::LookAt(currentLight.position,
																	currentLight.position + aLightDir[i],
																	aLightUp[i]);
				}
				viewMatrices.SendData();

				// Put a 45 degree frustum projection matrix to the viewTransform part of the
				// FrameTransformUniform Buffer it'll be required on area light omni directional frustum
				viewTransform = IEMatrix4x4::Perspective(45.0f, 1.0f,
														 0.1f, currentLight.color.getW() + 10.0f);
				projection = IEMatrix4x4::Perspective(90.0f, 1.0f,
													  0.1f, currentLight.color.getW() + 10.0f);
				break;
			}
		}

		// Determine projection params
		// Do not waste objects that are out of the current view frustum
		fTransform.Update
		(
			FrameTransformBufferData
			{
				viewTransform,
				projection,
				IEMatrix4x4::IdentityMatrix
			}
		);

		// FBO Bind and render calls
		glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBOs[i]);
		for(unsigned int i = 0; i < drawCount; i++)
		{
			drawBuffer.getModelTransformBuffer().BindAsUniformBuffer(U_MTRANSFORM, i, 1);
			glDrawElementsIndirect(GL_TRIANGLES,
								   GL_UNSIGNED_INT,
								   (void *) (i * sizeof(DrawPointIndexed)));
		}
	}
}

void SceneLights::ChangeLightPos(uint32_t index, IEVector3 position)
{
	Light l = lightsGPU.GetData(index);
	l.position.setX(position.getX());
	l.position.setY(position.getY());
	l.position.setZ(position.getZ());
	lightsGPU.ChangeData(index, l);
}

void SceneLights::ChangeLightType(uint32_t index, LightType type)
{
	Light l = lightsGPU.GetData(index);
	l.position.setW(static_cast<float>(type));
	lightsGPU.ChangeData(index, l);
}

void SceneLights::ChangeLightDir(uint32_t index, IEVector3 direction)
{
	Light l = lightsGPU.GetData(index);
	l.direction.setX(direction.getX());
	l.direction.setY(direction.getY());
	l.direction.setZ(direction.getZ());
	lightsGPU.ChangeData(index, l);
}

void SceneLights::ChangeLightColor(uint32_t index, IEVector3 color)
{
	Light l = lightsGPU.GetData(index);
	l.color.setX(color.getX());
	l.color.setY(color.getY());
	l.color.setZ(color.getZ());
	lightsGPU.ChangeData(index, l);
}

void SceneLights::ChangeLightRadius(uint32_t index, float radius)
{
	Light l = lightsGPU.GetData(index);
	l.color.setW(radius);
	lightsGPU.ChangeData(index, l);
}
<commit_msg>Added geom shader bind for directional light<commit_after>#include "SceneLights.h"
#include "IEUtility/IEVector3.h"
#include "GPUBuffer.h"
#include "DrawBuffer.h"
#include "Globals.h"
#include "FrameTransformBuffer.h"
#include "IEUtility/IEQuaternion.h"
#include "IEUtility/IEMath.h"

const GLsizei SceneLights::shadowMapW = 512;
const GLsizei SceneLights::shadowMapH = 512;

const IEVector3 SceneLights::pLightDir[6] =
{
	IEVector3::Xaxis,
	-IEVector3::Xaxis,
	IEVector3::Yaxis,
	-IEVector3::Yaxis,
	IEVector3::Zaxis,
	-IEVector3::Zaxis
};

const IEVector3 SceneLights::pLightUp[6] =
{
	IEVector3::Yaxis,
	IEVector3::Yaxis,
	-IEVector3::Zaxis,
	IEVector3::Zaxis,
	IEVector3::Yaxis,
	IEVector3::Yaxis
};

const IEVector3 SceneLights::aLightDir[6] =
{
	IEQuaternion(IEMath::ToRadians(45.0f), -IEVector3::Zaxis).ApplyRotation(IEVector3::Xaxis),
	IEQuaternion(IEMath::ToRadians(45.0f), IEVector3::Zaxis).ApplyRotation(-IEVector3::Xaxis),
	IEVector3::ZeroVector,	// Unused
	-IEVector3::Yaxis,
	IEQuaternion(IEMath::ToRadians(45.0f), IEVector3::Xaxis).ApplyRotation(IEVector3::Zaxis),
	IEQuaternion(IEMath::ToRadians(45.0f), -IEVector3::Xaxis).ApplyRotation(-IEVector3::Zaxis)
};

const IEVector3 SceneLights::aLightUp[6] =
{
	IEQuaternion(IEMath::ToRadians(45.0f), -IEVector3::Zaxis).ApplyRotation(IEVector3::Yaxis),
	IEQuaternion(IEMath::ToRadians(45.0f), IEVector3::Zaxis).ApplyRotation(IEVector3::Yaxis),
	IEVector3::ZeroVector,	// Unused
	IEVector3::Zaxis,
	IEQuaternion(IEMath::ToRadians(45.0f), IEVector3::Xaxis).ApplyRotation(IEVector3::Yaxis),
	IEQuaternion(IEMath::ToRadians(45.0f), -IEVector3::Xaxis).ApplyRotation(IEVector3::Yaxis)
};

SceneLights::SceneLights(const Array32<Light>& lights)
	: lightsGPU(lights.length)
	, lightShadowMaps(0)
	, viewMatrices(6)
	, fragShadowMap(ShaderType::FRAGMENT, "Shaders/ShadowMap.frag")
	, vertShadowMap(ShaderType::VERTEX, "Shaders/ShadowMap.vert")
	, geomAreaShadowMap(ShaderType::GEOMETRY, "Shaders/ShadowMapA.geom")
	, geomDirShadowMap(ShaderType::GEOMETRY, "Shaders/ShadowMapD.geom")
	, geomPointShadowMap(ShaderType::GEOMETRY, "Shaders/ShadowMapP.geom")
{

	glGenTextures(1, &lightShadowMaps);
	glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, lightShadowMaps);
	glTextureStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_DEPTH_COMPONENT32F, shadowMapW, shadowMapH, lights.length);
	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_GREATER);

	shadowMapFBOs.resize(lights.length);
	glGenFramebuffers(lights.length, shadowMapFBOs.data());

	for(unsigned int i = 0; i < lights.length; i++)
	{
		lightsGPU.AddData(lights.arr[i]);
		glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBOs[i]);
		glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, lightShadowMaps, i);
		assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
	}
	lightsGPU.SendData();
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

SceneLights::~SceneLights()
{
	glDeleteTextures(1, &lightShadowMaps);
}

void SceneLights::GenerateShadowMaps(DrawBuffer& drawBuffer, GPUBuffer& gpuBuffer,
									 FrameTransformBuffer& fTransform,
									 unsigned int drawCount,
									 IEVector3 frustumMin,
	 								 IEVector3 frustumMax)
{
	fragShadowMap.Bind();
	vertShadowMap.Bind();

	// State
	glColorMask(false, false, false, false);
	glDepthMask(true);
	glEnable(GL_DEPTH_TEST);
	glDisable(GL_MULTISAMPLE);
	glDisable(GL_CULL_FACE);
	glViewport(0, 0, shadowMapW, shadowMapH);

	gpuBuffer.Bind();
	fTransform.Bind();
	drawBuffer.getDrawParamBuffer().BindAsDrawIndirectBuffer();
	viewMatrices.BindAsUniformBuffer(U_SHADOW_VIEW);

	// Render From Dir of the light	with proper view params
	IEMatrix4x4 viewTransform = IEMatrix4x4::IdentityMatrix;
	IEMatrix4x4 projection;
	for(int i = 0; i < lightsGPU.CPUData().size(); i++)
	{
		const Light& currentLight = lightsGPU.CPUData()[i];
		// Determine light type
		LightType t = static_cast<LightType>(static_cast<uint32_t>(currentLight.position.getW()));
		switch(t)
		{
			case LightType::POINT:
			{
				// Render to Cubemap
				geomPointShadowMap.Bind();

				// Each Side will have 90 degree FOV
				// Geom shader will render for each layer
				for(unsigned int i = 0; i < 6; i++)
				{
					viewMatrices.CPUData()[i] = IEMatrix4x4::LookAt(currentLight.position,
																	currentLight.position + pLightDir[i],
																	pLightUp[i]);
				}
				viewMatrices.SendData();
				projection = IEMatrix4x4::Perspective(90.0f, 1.0f,
													  0.1f, currentLight.color.getW() + 10.0f);
				break;
			}
			case LightType::DIRECTIONAL:
			{
				// Render to one sheet
				geomDirShadowMap.Bind();

				// Camera Direction should be
				viewTransform = IEMatrix4x4::LookAt(currentLight.position,
													currentLight.position + currentLight.direction,
													IEVector3::Yaxis);
				projection = IEMatrix4x4::Ortogonal(frustumMin.getX(), frustumMax.getX(),
													frustumMax.getY(), frustumMin.getY(),
													frustumMin.getZ(), frustumMax.getZ());
				break;
			}
			case LightType::AREA:
			{
				// Render to cube but only 5 sides (6th side is not illuminated)
				geomAreaShadowMap.Bind();
				// we'll use 5 sides but each will comply different ares that a point light
				for(unsigned int i = 0; i < 5; i++)
				{
					viewMatrices.CPUData()[i] = IEMatrix4x4::LookAt(currentLight.position,
																	currentLight.position + aLightDir[i],
																	aLightUp[i]);
				}
				viewMatrices.SendData();

				// Put a 45 degree frustum projection matrix to the viewTransform part of the
				// FrameTransformUniform Buffer it'll be required on area light omni directional frustum
				viewTransform = IEMatrix4x4::Perspective(45.0f, 1.0f,
														 0.1f, currentLight.color.getW() + 10.0f);
				projection = IEMatrix4x4::Perspective(90.0f, 1.0f,
													  0.1f, currentLight.color.getW() + 10.0f);
				break;
			}
		}

		// Determine projection params
		// Do not waste objects that are out of the current view frustum
		fTransform.Update
		(
			FrameTransformBufferData
			{
				viewTransform,
				projection,
				IEMatrix4x4::IdentityMatrix
			}
		);

		// FBO Bind and render calls
		glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBOs[i]);
		for(unsigned int i = 0; i < drawCount; i++)
		{
			drawBuffer.getModelTransformBuffer().BindAsUniformBuffer(U_MTRANSFORM, i, 1);
			glDrawElementsIndirect(GL_TRIANGLES,
								   GL_UNSIGNED_INT,
								   (void *) (i * sizeof(DrawPointIndexed)));
		}
	}
}

void SceneLights::ChangeLightPos(uint32_t index, IEVector3 position)
{
	Light l = lightsGPU.GetData(index);
	l.position.setX(position.getX());
	l.position.setY(position.getY());
	l.position.setZ(position.getZ());
	lightsGPU.ChangeData(index, l);
}

void SceneLights::ChangeLightType(uint32_t index, LightType type)
{
	Light l = lightsGPU.GetData(index);
	l.position.setW(static_cast<float>(type));
	lightsGPU.ChangeData(index, l);
}

void SceneLights::ChangeLightDir(uint32_t index, IEVector3 direction)
{
	Light l = lightsGPU.GetData(index);
	l.direction.setX(direction.getX());
	l.direction.setY(direction.getY());
	l.direction.setZ(direction.getZ());
	lightsGPU.ChangeData(index, l);
}

void SceneLights::ChangeLightColor(uint32_t index, IEVector3 color)
{
	Light l = lightsGPU.GetData(index);
	l.color.setX(color.getX());
	l.color.setY(color.getY());
	l.color.setZ(color.getZ());
	lightsGPU.ChangeData(index, l);
}

void SceneLights::ChangeLightRadius(uint32_t index, float radius)
{
	Light l = lightsGPU.GetData(index);
	l.color.setW(radius);
	lightsGPU.ChangeData(index, l);
}
<|endoftext|>


<commit_before>//== Environment.cpp - Map from Stmt* to Locations/Values -------*- C++ -*--==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defined the Environment and EnvironmentManager classes.
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/Compiler.h"

using namespace clang;

SVal Environment::GetSVal(Stmt* E, BasicValueFactory& BasicVals) const {

  for (;;) {

    switch (E->getStmtClass()) {

      case Stmt::AddrLabelExprClass:
        return Loc::MakeVal(cast<AddrLabelExpr>(E));

        // ParenExprs are no-ops.

      case Stmt::ParenExprClass:
        E = cast<ParenExpr>(E)->getSubExpr();
        continue;

      case Stmt::CharacterLiteralClass: {
        CharacterLiteral* C = cast<CharacterLiteral>(E);
        return NonLoc::MakeVal(BasicVals, C->getValue(), C->getType());
      }

      case Stmt::IntegerLiteralClass: {
        return NonLoc::MakeVal(BasicVals, cast<IntegerLiteral>(E));
      }

      // Casts where the source and target type are the same
      // are no-ops.  We blast through these to get the descendant
      // subexpression that has a value.

      case Stmt::ImplicitCastExprClass:
      case Stmt::CStyleCastExprClass: {
        CastExpr* C = cast<CastExpr>(E);
        QualType CT = C->getType();

        if (CT->isVoidType())
          return UnknownVal();

        break;
      }

        // Handle all other Stmt* using a lookup.

      default:
        break;
    };

    break;
  }

  return LookupExpr(E);
}

SVal Environment::GetBlkExprSVal(Stmt* E, BasicValueFactory& BasicVals) const {

  while (1) {
    switch (E->getStmtClass()) {
      case Stmt::ParenExprClass:
        E = cast<ParenExpr>(E)->getSubExpr();
        continue;

      case Stmt::CharacterLiteralClass: {
        CharacterLiteral* C = cast<CharacterLiteral>(E);
        return NonLoc::MakeVal(BasicVals, C->getValue(), C->getType());
      }

      case Stmt::IntegerLiteralClass: {
        return NonLoc::MakeVal(BasicVals, cast<IntegerLiteral>(E));
      }

      default:
        return LookupBlkExpr(E);
    }
  }
}

Environment EnvironmentManager::BindExpr(const Environment& Env, Stmt* E,SVal V,
                                         bool isBlkExpr, bool Invalidate) {
  assert (E);

  if (V.isUnknown()) {
    if (Invalidate)
      return isBlkExpr ? RemoveBlkExpr(Env, E) : RemoveSubExpr(Env, E);
    else
      return Env;
  }

  return isBlkExpr ? AddBlkExpr(Env, E, V) : AddSubExpr(Env, E, V);
}

namespace {
class VISIBILITY_HIDDEN MarkLiveCallback : public SymbolVisitor {
  SymbolReaper &SymReaper;
public:
  MarkLiveCallback(SymbolReaper &symreaper) : SymReaper(symreaper) {}
  bool VisitSymbol(SymbolRef sym) { SymReaper.markLive(sym); return true; }
};
} // end anonymous namespace

Environment
EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
                                       SymbolReaper& SymReaper,
                                       GRStateManager& StateMgr,
                                       const GRState *state,
                              llvm::SmallVectorImpl<const MemRegion*>& DRoots) {

  // Drop bindings for subexpressions.
  Env = RemoveSubExprBindings(Env);

  // Iterate over the block-expr bindings.
  for (Environment::beb_iterator I = Env.beb_begin(), E = Env.beb_end();
       I != E; ++I) {
    Stmt* BlkExpr = I.getKey();

    if (SymReaper.isLive(Loc, BlkExpr)) {
      SVal X = I.getData();

      // If the block expr's value is a memory region, then mark that region.
      if (isa<loc::MemRegionVal>(X))
        DRoots.push_back(cast<loc::MemRegionVal>(X).getRegion());

      // Mark all symbols in the block expr's value live.
      MarkLiveCallback cb(SymReaper);
      StateMgr.scanReachableSymbols(X, state, cb);
    } else {
      // The block expr is dead.
      SVal X = I.getData();

      // Do not misclean LogicalExpr or ConditionalOperator.  It is dead at the
      // beginning of itself, but we need its UndefinedVal to determine its
      // SVal.

      if (X.isUndef() && cast<UndefinedVal>(X).getData())
        continue;

      Env = RemoveBlkExpr(Env, BlkExpr);
    }
  }

  return Env;
}
<commit_msg>Add comments.<commit_after>//== Environment.cpp - Map from Stmt* to Locations/Values -------*- C++ -*--==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defined the Environment and EnvironmentManager classes.
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/Compiler.h"

using namespace clang;

SVal Environment::GetSVal(Stmt* E, BasicValueFactory& BasicVals) const {

  for (;;) {

    switch (E->getStmtClass()) {

      case Stmt::AddrLabelExprClass:
        return Loc::MakeVal(cast<AddrLabelExpr>(E));

        // ParenExprs are no-ops.

      case Stmt::ParenExprClass:
        E = cast<ParenExpr>(E)->getSubExpr();
        continue;

      case Stmt::CharacterLiteralClass: {
        CharacterLiteral* C = cast<CharacterLiteral>(E);
        return NonLoc::MakeVal(BasicVals, C->getValue(), C->getType());
      }

      case Stmt::IntegerLiteralClass: {
        return NonLoc::MakeVal(BasicVals, cast<IntegerLiteral>(E));
      }

      // Casts where the source and target type are the same
      // are no-ops.  We blast through these to get the descendant
      // subexpression that has a value.

      case Stmt::ImplicitCastExprClass:
      case Stmt::CStyleCastExprClass: {
        CastExpr* C = cast<CastExpr>(E);
        QualType CT = C->getType();

        if (CT->isVoidType())
          return UnknownVal();

        break;
      }

        // Handle all other Stmt* using a lookup.

      default:
        break;
    };

    break;
  }

  return LookupExpr(E);
}

SVal Environment::GetBlkExprSVal(Stmt* E, BasicValueFactory& BasicVals) const {

  while (1) {
    switch (E->getStmtClass()) {
      case Stmt::ParenExprClass:
        E = cast<ParenExpr>(E)->getSubExpr();
        continue;

      case Stmt::CharacterLiteralClass: {
        CharacterLiteral* C = cast<CharacterLiteral>(E);
        return NonLoc::MakeVal(BasicVals, C->getValue(), C->getType());
      }

      case Stmt::IntegerLiteralClass: {
        return NonLoc::MakeVal(BasicVals, cast<IntegerLiteral>(E));
      }

      default:
        return LookupBlkExpr(E);
    }
  }
}

Environment EnvironmentManager::BindExpr(const Environment& Env, Stmt* E,SVal V,
                                         bool isBlkExpr, bool Invalidate) {
  assert (E);

  if (V.isUnknown()) {
    if (Invalidate)
      return isBlkExpr ? RemoveBlkExpr(Env, E) : RemoveSubExpr(Env, E);
    else
      return Env;
  }

  return isBlkExpr ? AddBlkExpr(Env, E, V) : AddSubExpr(Env, E, V);
}

namespace {
class VISIBILITY_HIDDEN MarkLiveCallback : public SymbolVisitor {
  SymbolReaper &SymReaper;
public:
  MarkLiveCallback(SymbolReaper &symreaper) : SymReaper(symreaper) {}
  bool VisitSymbol(SymbolRef sym) { SymReaper.markLive(sym); return true; }
};
} // end anonymous namespace

// RemoveDeadBindings:
//  - Remove subexpression bindings.
//  - Remove dead block expression bindings.
//  - Keep live block expression bindings:
//   - Mark their reachable symbols live in SymbolReaper,
//     see ScanReachableSymbols.
//   - Mark the region in DRoots if the binding is a loc::MemRegionVal.

Environment
EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
                                       SymbolReaper& SymReaper,
                                       GRStateManager& StateMgr,
                                       const GRState *state,
                              llvm::SmallVectorImpl<const MemRegion*>& DRoots) {

  // Drop bindings for subexpressions.
  Env = RemoveSubExprBindings(Env);

  // Iterate over the block-expr bindings.
  for (Environment::beb_iterator I = Env.beb_begin(), E = Env.beb_end();
       I != E; ++I) {
    Stmt* BlkExpr = I.getKey();

    if (SymReaper.isLive(Loc, BlkExpr)) {
      SVal X = I.getData();

      // If the block expr's value is a memory region, then mark that region.
      if (isa<loc::MemRegionVal>(X))
        DRoots.push_back(cast<loc::MemRegionVal>(X).getRegion());

      // Mark all symbols in the block expr's value live.
      MarkLiveCallback cb(SymReaper);
      StateMgr.scanReachableSymbols(X, state, cb);
    } else {
      // The block expr is dead.
      SVal X = I.getData();

      // Do not misclean LogicalExpr or ConditionalOperator.  It is dead at the
      // beginning of itself, but we need its UndefinedVal to determine its
      // SVal.

      if (X.isUndef() && cast<UndefinedVal>(X).getData())
        continue;

      Env = RemoveBlkExpr(Env, BlkExpr);
    }
  }

  return Env;
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 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/command_line.h"
#include "base/message_loop.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/browser/ui/toolbar/action_box_menu_model.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"

class ActionBoxTest : public InProcessBrowserTest,
                      public content::NotificationObserver {
 protected:
  ActionBoxTest() {}

  virtual void SetUpOnMainThread() {
    ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
    ASSERT_NO_FATAL_FAILURE(SetupComponents());
    chrome::FocusLocationBar(browser());
    // Use Textfield's view id on pure views. See crbug.com/71144.
    ViewID location_bar_focus_view_id = VIEW_ID_LOCATION_BAR;
#if defined(USE_AURA)
    location_bar_focus_view_id = VIEW_ID_OMNIBOX;
#endif
    ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                             location_bar_focus_view_id));
  }

  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    // Enable Action Box UI for the test.
    command_line->AppendSwitchASCII(switches::kActionBox, "1");
  }

  void SetupComponents() {}

  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE {
    switch (type) {
      case content::NOTIFICATION_WEB_CONTENTS_DESTROYED:
      case chrome::NOTIFICATION_TAB_PARENTED:
      case chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY:
      case chrome::NOTIFICATION_BOOKMARK_MODEL_LOADED:
      case chrome::NOTIFICATION_HISTORY_LOADED:
      case chrome::NOTIFICATION_HISTORY_URLS_MODIFIED:
      case chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED:
        break;
      default:
        FAIL() << "Unexpected notification type";
    }
    MessageLoop::current()->Quit();
  }

  DISALLOW_COPY_AND_ASSIGN(ActionBoxTest);
};

// Test if Bookmark star appears after bookmarking a page in the action box, and
// disappears after unbookmarking a page.
IN_PROC_BROWSER_TEST_F(ActionBoxTest, BookmarkAPageTest) {
  LocationBarTesting* loc_bar =
      browser()->window()->GetLocationBar()->GetLocationBarForTesting();

  // Navigate somewhere we can bookmark.
  ui_test_utils::NavigateToURL(browser(), GURL("http://www.google.com"));

  // Page is not bookmarked yet.
  ASSERT_FALSE(loc_bar->GetBookmarkStarVisibility());

  // Simulate an action box click and menu item selection.
  chrome::ExecuteCommand(browser(), IDC_BOOKMARK_PAGE);

  // Page is now bookmarked.
  ASSERT_TRUE(loc_bar->GetBookmarkStarVisibility());

  // Get the BookmarkModel to unbookmark the bookmark.
  BookmarkModel* model =
      BookmarkModelFactory::GetForProfile(browser()->profile());
  ui_test_utils::WaitForBookmarkModelToLoad(model);
  bookmark_utils::RemoveAllBookmarks(model, GURL("http://www.google.com"));

  // Page is now unbookmarked.
  ASSERT_FALSE(loc_bar->GetBookmarkStarVisibility());

}
<commit_msg>Disable ActionBoxTest.BookmarkAPageTest, which is flakily failing.<commit_after>// Copyright (c) 2012 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/command_line.h"
#include "base/message_loop.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/browser/ui/toolbar/action_box_menu_model.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/web_contents.h"

class ActionBoxTest : public InProcessBrowserTest,
                      public content::NotificationObserver {
 protected:
  ActionBoxTest() {}

  virtual void SetUpOnMainThread() {
    ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
    ASSERT_NO_FATAL_FAILURE(SetupComponents());
    chrome::FocusLocationBar(browser());
    // Use Textfield's view id on pure views. See crbug.com/71144.
    ViewID location_bar_focus_view_id = VIEW_ID_LOCATION_BAR;
#if defined(USE_AURA)
    location_bar_focus_view_id = VIEW_ID_OMNIBOX;
#endif
    ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(),
                                             location_bar_focus_view_id));
  }

  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    // Enable Action Box UI for the test.
    command_line->AppendSwitchASCII(switches::kActionBox, "1");
  }

  void SetupComponents() {}

  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE {
    switch (type) {
      case content::NOTIFICATION_WEB_CONTENTS_DESTROYED:
      case chrome::NOTIFICATION_TAB_PARENTED:
      case chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY:
      case chrome::NOTIFICATION_BOOKMARK_MODEL_LOADED:
      case chrome::NOTIFICATION_HISTORY_LOADED:
      case chrome::NOTIFICATION_HISTORY_URLS_MODIFIED:
      case chrome::NOTIFICATION_TEMPLATE_URL_SERVICE_LOADED:
        break;
      default:
        FAIL() << "Unexpected notification type";
    }
    MessageLoop::current()->Quit();
  }

  DISALLOW_COPY_AND_ASSIGN(ActionBoxTest);
};

// Test if Bookmark star appears after bookmarking a page in the action box, and
// disappears after unbookmarking a page.
// Flakily fails: http://crbug.com/163733
IN_PROC_BROWSER_TEST_F(ActionBoxTest, DISABLED_BookmarkAPageTest) {
  LocationBarTesting* loc_bar =
      browser()->window()->GetLocationBar()->GetLocationBarForTesting();

  // Navigate somewhere we can bookmark.
  ui_test_utils::NavigateToURL(browser(), GURL("http://www.google.com"));

  // Page is not bookmarked yet.
  ASSERT_FALSE(loc_bar->GetBookmarkStarVisibility());

  // Simulate an action box click and menu item selection.
  chrome::ExecuteCommand(browser(), IDC_BOOKMARK_PAGE);

  // Page is now bookmarked.
  ASSERT_TRUE(loc_bar->GetBookmarkStarVisibility());

  // Get the BookmarkModel to unbookmark the bookmark.
  BookmarkModel* model =
      BookmarkModelFactory::GetForProfile(browser()->profile());
  ui_test_utils::WaitForBookmarkModelToLoad(model);
  bookmark_utils::RemoveAllBookmarks(model, GURL("http://www.google.com"));

  // Page is now unbookmarked.
  ASSERT_FALSE(loc_bar->GetBookmarkStarVisibility());

}
<|endoftext|>


<commit_before>/*
 * Main Menu-bar
 */

#include <stdint.h>
#include <stdio.h>

#include <vector>

#include <SDL2/SDL.h>

#include "imgui.h"

extern "C" {

#include "util.h"
#include "snepulator.h"
#include "config.h"

#include "gamepad.h"
#include "video/tms9928a.h"
#include "video/sms_vdp.h"
#include "cpu/z80.h"

#include "sg-1000.h"
#include "sms.h"
#include "colecovision.h"

extern Z80_Regs z80_regs;
extern TMS9928A_Mode sms_vdp_mode_get (void);

/* TODO: Access through a function instead of accessing the array */
extern Gamepad_Instance gamepad_list[10];
extern uint32_t gamepad_list_count;
extern Snepulator_Gamepad gamepad_1;
extern Snepulator_Gamepad gamepad_2;
}

#include "gui/input.h"
#include "gui/menubar.h"
#include "gui/open.h"
extern Snepulator_State state;
extern File_Open_State open_state;
extern bool config_capture_events; /* TODO: Move into state */

void snepulator_load_rom (char *path);
void snepulator_load_sms_bios (char *path);
void snepulator_load_colecovision_bios (char *path);

/*
 * Render the menubar.
 */
void snepulator_render_menubar (void)
{
    bool open_modal = false;
    bool input_modal = false;

    if (ImGui::BeginMainMenuBar ())
    {
        if (ImGui::BeginMenu ("File"))
        {
            if (ImGui::MenuItem ("Load ROM...", NULL))
            {
                state.running = false;
                open_state.title = "Load ROM...";
                open_state.regex = ".*\\.(BIN|bin|SMS|sms|sg|col)$";
                open_state.callback = snepulator_load_rom;
                open_modal = true;
            }
            if (ImGui::BeginMenu ("Load BIOS..."))
            {
                if (ImGui::MenuItem ("Master System", NULL))
                {
                    state.running = false;
                    open_state.title = "Load Master System BIOS...";
                    open_state.regex = ".*\\.(BIN|bin|SMS|sms)$";
                    open_state.callback = snepulator_load_sms_bios;
                    open_modal = true;
                }
                if (ImGui::MenuItem ("ColecoVision", NULL))
                {
                    state.running = false;
                    open_state.title = "Load ColecoVision BIOS...";
                    open_state.regex = ".*\\.(col)$";
                    open_state.callback = snepulator_load_colecovision_bios;
                    open_modal = true;
                }
                ImGui::EndMenu ();
            }

            if (ImGui::MenuItem ("Pause", NULL, !state.running)) {
                if (state.ready) {
                    if (state.running)
                    {
                        snepulator_pause ();
                    }
                    else
                    {
                        state.running = true;
                    }
                }
            }
            ImGui::Separator ();
            if (ImGui::MenuItem ("Quit", NULL)) { state.abort = true; }
            ImGui::EndMenu ();
        }

        if (ImGui::BeginMenu ("Audio"))
        {
            if (ImGui::BeginMenu ("Device"))
            {
                int count = SDL_GetNumAudioDevices (0);
                for (int i = 0; i < count; i++)
                {
                    const char *audio_device_name = SDL_GetAudioDeviceName (i, 0);
                    if (audio_device_name == NULL)
                        audio_device_name = "Unknown Audio Device";

                    if (ImGui::MenuItem (audio_device_name, NULL)) { }
                }
                ImGui::EndMenu ();
            }
            ImGui::EndMenu ();
        }

        if (ImGui::BeginMenu ("Video"))
        {
            if (ImGui::BeginMenu ("Filter"))
            {
                if (ImGui::MenuItem ("GL_NEAREST", NULL, state.video_filter == VIDEO_FILTER_NEAREST))
                {
                    state.video_filter = VIDEO_FILTER_NEAREST;
                    config_string_set ("video", "filter", "GL_NEAREST");
                    config_write ();
                }
                if (ImGui::MenuItem ("GL_LINEAR",  NULL, state.video_filter == VIDEO_FILTER_LINEAR))
                {
                    state.video_filter = VIDEO_FILTER_LINEAR;
                    config_string_set ("video", "filter", "GL_LINEAR");
                    config_write ();
                }
                if (ImGui::MenuItem ("Scanlines",  NULL, state.video_filter == VIDEO_FILTER_SCANLINES))
                {
                    state.video_filter = VIDEO_FILTER_SCANLINES;
                    config_string_set ("video", "filter", "Scanlines");
                    config_write ();
                }
                ImGui::EndMenu ();
            }

            if (ImGui::BeginMenu ("3D Mode"))
            {
                if (ImGui::MenuItem ("Left image only", NULL, state.video_3d_mode == VIDEO_3D_LEFT_ONLY))
                {
                    state.video_3d_mode = VIDEO_3D_LEFT_ONLY;
                }
                if (ImGui::MenuItem ("Right image only", NULL, state.video_3d_mode == VIDEO_3D_RIGHT_ONLY))
                {
                    state.video_3d_mode = VIDEO_3D_RIGHT_ONLY;
                }
                if (ImGui::MenuItem ("Red-Cyan", NULL, state.video_3d_mode == VIDEO_3D_RED_CYAN))
                {
                    state.video_3d_mode = VIDEO_3D_RED_CYAN;
                }
                if (ImGui::MenuItem ("Red-Green", NULL, state.video_3d_mode == VIDEO_3D_RED_GREEN))
                {
                    state.video_3d_mode = VIDEO_3D_RED_GREEN;
                }
                if (ImGui::MenuItem ("Magenta-Green", NULL, state.video_3d_mode == VIDEO_3D_MAGENTA_GREEN))
                {
                    state.video_3d_mode = VIDEO_3D_MAGENTA_GREEN;
                }

                ImGui::Separator ();

                if (ImGui::BeginMenu ("Colour"))
                {
                    if (ImGui::MenuItem ("Saturation 0%", NULL, state.video_3d_saturation == 0.0))
                    {
                        state.video_3d_saturation = 0.0;
                    }
                    if (ImGui::MenuItem ("Saturation 25%", NULL, state.video_3d_saturation == 0.25))
                    {
                        state.video_3d_saturation = 0.25;
                    }
                    if (ImGui::MenuItem ("Saturation 50%", NULL, state.video_3d_saturation == 0.50))
                    {
                        state.video_3d_saturation = 0.50;
                    }
                    if (ImGui::MenuItem ("Saturation 75%", NULL, state.video_3d_saturation == 0.75))
                    {
                        state.video_3d_saturation = 0.75;
                    }
                    if (ImGui::MenuItem ("Saturation 100%", NULL, state.video_3d_saturation == 1.0))
                    {
                        state.video_3d_saturation = 1.0;
                    }
                    ImGui::EndMenu ();
                }

                ImGui::EndMenu ();
            }

            if (ImGui::MenuItem ("Take Screenshot"))
            {
                snepulator_take_screenshot ();
            }

            ImGui::EndMenu ();
        }

        if (ImGui::BeginMenu ("Console"))
        {
            if (ImGui::MenuItem ("Hard Reset"))
            {
                system_init ();
            }
            ImGui::Separator ();

            if (ImGui::MenuItem ("World", NULL, state.region == REGION_WORLD)) {
                state.region = REGION_WORLD;
                config_string_set ("sms", "region", "World");
                config_write ();
            }
            if (ImGui::MenuItem ("Japan", NULL, state.region == REGION_JAPAN)) {
                state.region = REGION_JAPAN;
                config_string_set ("sms", "region", "Japan");
                config_write ();
            }
            ImGui::Separator ();

            if (ImGui::MenuItem ("Auto", NULL, state.format_auto)) {
                state.format_auto = true;
                config_string_set ("sms", "format", "Auto");
                config_write ();
            }
            if (ImGui::MenuItem ("NTSC", NULL, state.format == VIDEO_FORMAT_NTSC)) {
                state.format = VIDEO_FORMAT_NTSC;
                state.format_auto = false;
                config_string_set ("sms", "format", "NTSC");
                config_write ();
            }
            if (ImGui::MenuItem ("PAL",  NULL, state.format == VIDEO_FORMAT_PAL))  {
                state.format = VIDEO_FORMAT_PAL;
                state.format_auto = false;
                config_string_set ("sms", "format", "PAL");
                config_write ();
            }
            ImGui::EndMenu ();
        }

        /* TODO: Deal with joysticks being removed from the system mid-game. Maybe auto-pause? */
        if (ImGui::BeginMenu ("Input"))
        {

            if (ImGui::BeginMenu ("Player 1"))
            {
                if (ImGui::BeginMenu ("Type"))
                {
                    if (ImGui::MenuItem ("Auto", NULL, gamepad_1.type_auto))
                    {
                        gamepad_1.type_auto = true;
                    }
                    if (ImGui::MenuItem ("SMS Gamepad", NULL, gamepad_1.type == GAMEPAD_TYPE_SMS))
                    {
                        gamepad_1.type = GAMEPAD_TYPE_SMS;
                        gamepad_1.type_auto = false;
                    }
                    if (ImGui::MenuItem ("SMS Paddle", NULL, gamepad_1.type == GAMEPAD_TYPE_SMS_PADDLE))
                    {
                        gamepad_1.type = GAMEPAD_TYPE_SMS_PADDLE;
                        gamepad_1.type_auto = false;
                    }
                    ImGui::EndMenu ();
                }

                ImGui::Separator ();

                for (int i = 0; i < gamepad_list_count; i++)
                {
                    if (ImGui::MenuItem (gamepad_get_name (i), NULL, gamepad_list [i].instance_id == gamepad_1.instance_id))
                    {
                        gamepad_change_device (1, i);
                    }
                }
                ImGui::EndMenu ();
            }
            if (ImGui::BeginMenu ("Player 2"))
            {
                for (int i = 0; i < gamepad_list_count; i++)
                {
                    if (ImGui::MenuItem (gamepad_get_name (i), NULL, gamepad_list [i].instance_id == gamepad_2.instance_id))
                    {
                        gamepad_change_device (2, i);
                    }
                }
                ImGui::EndMenu ();
            }

            if (ImGui::MenuItem ("Configure...", NULL))
            {
                input_start ();
                input_modal = true;
            }
            ImGui::EndMenu ();
        }

        if (ImGui::BeginMenu ("DEBUG"))
        {
            ImGui::Text ("CPU");
            ImGui::Text ("PC : %04x    SP : %04x", z80_regs.pc, z80_regs.sp);
            ImGui::Text ("AF : %04x    BC : %04x", z80_regs.af, z80_regs.bc);
            ImGui::Text ("DE : %04x    HL : %04x", z80_regs.de, z80_regs.hl);
            ImGui::Text ("IX : %04x    IY : %04x", z80_regs.ix, z80_regs.iy);
            ImGui::Text ("IM : %d       IFF: %d/%d", z80_regs.im, z80_regs.iff1, z80_regs.iff2);

            ImGui::Separator ();

            ImGui::Text ("Video");
            ImGui::Text ("Mode : %s", tms9928a_mode_name_get (sms_vdp_mode_get ()));

            ImGui::Separator ();

            if (ImGui::BeginMenu ("Statistics"))
            {
                ImGui::Text ("Video");
                ImGui::Text ("Host: %.2f fps", state.host_framerate);
                ImGui::Text ("VDP:  %.2f fps", state.vdp_framerate);
                ImGui::Separator ();
                ImGui::Text ("Audio");
                ImGui::Text ("Ring buffer: %.2f%% full", state.audio_ring_utilisation * 100.0);

                ImGui::EndMenu ();
            }

            ImGui::Separator ();

            if (ImGui::MenuItem ("Time Five Minutes", NULL))
            {
                uint32_t start_time;
                uint32_t end_time;
                state.running = false;
                start_time = SDL_GetTicks ();
                state.run (5 * 60000); /* Simulate five minutes */
                end_time = SDL_GetTicks ();
                state.running = true;

                fprintf (stdout, "[DEBUG] Took %d ms to emulate five minutes. (%fx speed-up)\n",
                         end_time - start_time, (5.0 * 60000.0) / (end_time - start_time));
            }

            ImGui::EndMenu ();
        }

        ImGui::EndMainMenuBar ();
    }

    /* Open any popups requested */
    if (open_modal)
    {
        ImGui::OpenPopup (open_state.title);
    }
    if (input_modal)
    {
        config_capture_events = true;
        ImGui::OpenPopup ("Configure device...");
    }

}
<commit_msg>gui: Remove "DEBUG" menu<commit_after>/*
 * Main Menu-bar
 */

#include <stdint.h>
#include <stdio.h>

#include <vector>

#include <SDL2/SDL.h>

#include "imgui.h"

extern "C" {

#include "util.h"
#include "snepulator.h"
#include "config.h"

#include "gamepad.h"
#include "video/tms9928a.h"
#include "video/sms_vdp.h"
#include "cpu/z80.h"

#include "sg-1000.h"
#include "sms.h"
#include "colecovision.h"

extern Z80_Regs z80_regs;
extern TMS9928A_Mode sms_vdp_mode_get (void);

/* TODO: Access through a function instead of accessing the array */
extern Gamepad_Instance gamepad_list[10];
extern uint32_t gamepad_list_count;
extern Snepulator_Gamepad gamepad_1;
extern Snepulator_Gamepad gamepad_2;
}

#include "gui/input.h"
#include "gui/menubar.h"
#include "gui/open.h"
extern Snepulator_State state;
extern File_Open_State open_state;
extern bool config_capture_events; /* TODO: Move into state */

void snepulator_load_rom (char *path);
void snepulator_load_sms_bios (char *path);
void snepulator_load_colecovision_bios (char *path);

/*
 * Render the menubar.
 */
void snepulator_render_menubar (void)
{
    bool open_modal = false;
    bool input_modal = false;

    if (ImGui::BeginMainMenuBar ())
    {
        if (ImGui::BeginMenu ("File"))
        {
            if (ImGui::MenuItem ("Load ROM...", NULL))
            {
                state.running = false;
                open_state.title = "Load ROM...";
                open_state.regex = ".*\\.(BIN|bin|SMS|sms|sg|col)$";
                open_state.callback = snepulator_load_rom;
                open_modal = true;
            }
            if (ImGui::BeginMenu ("Load BIOS..."))
            {
                if (ImGui::MenuItem ("Master System", NULL))
                {
                    state.running = false;
                    open_state.title = "Load Master System BIOS...";
                    open_state.regex = ".*\\.(BIN|bin|SMS|sms)$";
                    open_state.callback = snepulator_load_sms_bios;
                    open_modal = true;
                }
                if (ImGui::MenuItem ("ColecoVision", NULL))
                {
                    state.running = false;
                    open_state.title = "Load ColecoVision BIOS...";
                    open_state.regex = ".*\\.(col)$";
                    open_state.callback = snepulator_load_colecovision_bios;
                    open_modal = true;
                }
                ImGui::EndMenu ();
            }

            if (ImGui::MenuItem ("Pause", NULL, !state.running)) {
                if (state.ready) {
                    if (state.running)
                    {
                        snepulator_pause ();
                    }
                    else
                    {
                        state.running = true;
                    }
                }
            }
            ImGui::Separator ();
            if (ImGui::MenuItem ("Quit", NULL)) { state.abort = true; }
            ImGui::EndMenu ();
        }

        if (ImGui::BeginMenu ("Audio"))
        {
            if (ImGui::BeginMenu ("Device"))
            {
                int count = SDL_GetNumAudioDevices (0);
                for (int i = 0; i < count; i++)
                {
                    const char *audio_device_name = SDL_GetAudioDeviceName (i, 0);
                    if (audio_device_name == NULL)
                        audio_device_name = "Unknown Audio Device";

                    if (ImGui::MenuItem (audio_device_name, NULL)) { }
                }
                ImGui::EndMenu ();
            }
            ImGui::EndMenu ();
        }

        if (ImGui::BeginMenu ("Video"))
        {
            if (ImGui::BeginMenu ("Filter"))
            {
                if (ImGui::MenuItem ("GL_NEAREST", NULL, state.video_filter == VIDEO_FILTER_NEAREST))
                {
                    state.video_filter = VIDEO_FILTER_NEAREST;
                    config_string_set ("video", "filter", "GL_NEAREST");
                    config_write ();
                }
                if (ImGui::MenuItem ("GL_LINEAR",  NULL, state.video_filter == VIDEO_FILTER_LINEAR))
                {
                    state.video_filter = VIDEO_FILTER_LINEAR;
                    config_string_set ("video", "filter", "GL_LINEAR");
                    config_write ();
                }
                if (ImGui::MenuItem ("Scanlines",  NULL, state.video_filter == VIDEO_FILTER_SCANLINES))
                {
                    state.video_filter = VIDEO_FILTER_SCANLINES;
                    config_string_set ("video", "filter", "Scanlines");
                    config_write ();
                }
                ImGui::EndMenu ();
            }

            if (ImGui::BeginMenu ("3D Mode"))
            {
                if (ImGui::MenuItem ("Left image only", NULL, state.video_3d_mode == VIDEO_3D_LEFT_ONLY))
                {
                    state.video_3d_mode = VIDEO_3D_LEFT_ONLY;
                }
                if (ImGui::MenuItem ("Right image only", NULL, state.video_3d_mode == VIDEO_3D_RIGHT_ONLY))
                {
                    state.video_3d_mode = VIDEO_3D_RIGHT_ONLY;
                }
                if (ImGui::MenuItem ("Red-Cyan", NULL, state.video_3d_mode == VIDEO_3D_RED_CYAN))
                {
                    state.video_3d_mode = VIDEO_3D_RED_CYAN;
                }
                if (ImGui::MenuItem ("Red-Green", NULL, state.video_3d_mode == VIDEO_3D_RED_GREEN))
                {
                    state.video_3d_mode = VIDEO_3D_RED_GREEN;
                }
                if (ImGui::MenuItem ("Magenta-Green", NULL, state.video_3d_mode == VIDEO_3D_MAGENTA_GREEN))
                {
                    state.video_3d_mode = VIDEO_3D_MAGENTA_GREEN;
                }

                ImGui::Separator ();

                if (ImGui::BeginMenu ("Colour"))
                {
                    if (ImGui::MenuItem ("Saturation 0%", NULL, state.video_3d_saturation == 0.0))
                    {
                        state.video_3d_saturation = 0.0;
                    }
                    if (ImGui::MenuItem ("Saturation 25%", NULL, state.video_3d_saturation == 0.25))
                    {
                        state.video_3d_saturation = 0.25;
                    }
                    if (ImGui::MenuItem ("Saturation 50%", NULL, state.video_3d_saturation == 0.50))
                    {
                        state.video_3d_saturation = 0.50;
                    }
                    if (ImGui::MenuItem ("Saturation 75%", NULL, state.video_3d_saturation == 0.75))
                    {
                        state.video_3d_saturation = 0.75;
                    }
                    if (ImGui::MenuItem ("Saturation 100%", NULL, state.video_3d_saturation == 1.0))
                    {
                        state.video_3d_saturation = 1.0;
                    }
                    ImGui::EndMenu ();
                }

                ImGui::EndMenu ();
            }

            if (ImGui::MenuItem ("Take Screenshot"))
            {
                snepulator_take_screenshot ();
            }

            ImGui::EndMenu ();
        }

        if (ImGui::BeginMenu ("Console"))
        {
            if (ImGui::MenuItem ("Hard Reset"))
            {
                system_init ();
            }
            ImGui::Separator ();

            if (ImGui::MenuItem ("World", NULL, state.region == REGION_WORLD)) {
                state.region = REGION_WORLD;
                config_string_set ("sms", "region", "World");
                config_write ();
            }
            if (ImGui::MenuItem ("Japan", NULL, state.region == REGION_JAPAN)) {
                state.region = REGION_JAPAN;
                config_string_set ("sms", "region", "Japan");
                config_write ();
            }
            ImGui::Separator ();

            if (ImGui::MenuItem ("Auto", NULL, state.format_auto)) {
                state.format_auto = true;
                config_string_set ("sms", "format", "Auto");
                config_write ();
            }
            if (ImGui::MenuItem ("NTSC", NULL, state.format == VIDEO_FORMAT_NTSC)) {
                state.format = VIDEO_FORMAT_NTSC;
                state.format_auto = false;
                config_string_set ("sms", "format", "NTSC");
                config_write ();
            }
            if (ImGui::MenuItem ("PAL",  NULL, state.format == VIDEO_FORMAT_PAL))  {
                state.format = VIDEO_FORMAT_PAL;
                state.format_auto = false;
                config_string_set ("sms", "format", "PAL");
                config_write ();
            }
            ImGui::Separator ();

            if (ImGui::BeginMenu ("Info"))
            {
                ImGui::Text ("CPU");
                ImGui::Text ("PC : %04x    SP : %04x", z80_regs.pc, z80_regs.sp);
                ImGui::Text ("AF : %04x    BC : %04x", z80_regs.af, z80_regs.bc);
                ImGui::Text ("DE : %04x    HL : %04x", z80_regs.de, z80_regs.hl);
                ImGui::Text ("IX : %04x    IY : %04x", z80_regs.ix, z80_regs.iy);
                ImGui::Text ("IM : %d       IFF: %d/%d", z80_regs.im, z80_regs.iff1, z80_regs.iff2);

                ImGui::Separator ();

                ImGui::Text ("Video");
                ImGui::Text ("Mode : %s", tms9928a_mode_name_get (sms_vdp_mode_get ()));

                ImGui::EndMenu ();
            }
            if (ImGui::BeginMenu ("Statistics"))
            {
                ImGui::Text ("Video");
                ImGui::Text ("Host: %.2f fps", state.host_framerate);
                ImGui::Text ("VDP:  %.2f fps", state.vdp_framerate);
                ImGui::Separator ();
                ImGui::Text ("Audio");
                ImGui::Text ("Ring buffer: %.2f%% full", state.audio_ring_utilisation * 100.0);

                ImGui::EndMenu ();
            }
            if (ImGui::MenuItem ("Time Five Minutes", NULL))
            {
                uint32_t start_time;
                uint32_t end_time;
                state.running = false;
                start_time = SDL_GetTicks ();
                state.run (5 * 60000); /* Simulate five minutes */
                end_time = SDL_GetTicks ();
                state.running = true;

                fprintf (stdout, "[DEBUG] Took %d ms to emulate five minutes. (%fx speed-up)\n",
                         end_time - start_time, (5.0 * 60000.0) / (end_time - start_time));
            }

            ImGui::EndMenu ();
        }

        /* TODO: Deal with joysticks being removed from the system mid-game. Maybe auto-pause? */
        if (ImGui::BeginMenu ("Input"))
        {

            if (ImGui::BeginMenu ("Player 1"))
            {
                if (ImGui::BeginMenu ("Type"))
                {
                    if (ImGui::MenuItem ("Auto", NULL, gamepad_1.type_auto))
                    {
                        gamepad_1.type_auto = true;
                    }
                    if (ImGui::MenuItem ("SMS Gamepad", NULL, gamepad_1.type == GAMEPAD_TYPE_SMS))
                    {
                        gamepad_1.type = GAMEPAD_TYPE_SMS;
                        gamepad_1.type_auto = false;
                    }
                    if (ImGui::MenuItem ("SMS Paddle", NULL, gamepad_1.type == GAMEPAD_TYPE_SMS_PADDLE))
                    {
                        gamepad_1.type = GAMEPAD_TYPE_SMS_PADDLE;
                        gamepad_1.type_auto = false;
                    }
                    ImGui::EndMenu ();
                }

                ImGui::Separator ();

                for (int i = 0; i < gamepad_list_count; i++)
                {
                    if (ImGui::MenuItem (gamepad_get_name (i), NULL, gamepad_list [i].instance_id == gamepad_1.instance_id))
                    {
                        gamepad_change_device (1, i);
                    }
                }
                ImGui::EndMenu ();
            }
            if (ImGui::BeginMenu ("Player 2"))
            {
                for (int i = 0; i < gamepad_list_count; i++)
                {
                    if (ImGui::MenuItem (gamepad_get_name (i), NULL, gamepad_list [i].instance_id == gamepad_2.instance_id))
                    {
                        gamepad_change_device (2, i);
                    }
                }
                ImGui::EndMenu ();
            }

            if (ImGui::MenuItem ("Configure...", NULL))
            {
                input_start ();
                input_modal = true;
            }
            ImGui::EndMenu ();
        }

        ImGui::EndMainMenuBar ();
    }

    /* Open any popups requested */
    if (open_modal)
    {
        ImGui::OpenPopup (open_state.title);
    }
    if (input_modal)
    {
        config_capture_events = true;
        ImGui::OpenPopup ("Configure device...");
    }

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007-2008 Digital Bazaar, Inc.  All rights reserved.
 */
#include "db/io/FileInputStream.h"

using namespace std;
using namespace db::io;
using namespace db::rt;

FileInputStream::FileInputStream(File* file, bool cleanup)
{
   // store file, clean up setting
   mFile = file;
   mCleanupFile = cleanup;
}

FileInputStream::~FileInputStream()
{
   // close the ifstream if it is open
   if(mStream.is_open())
   {
      mStream.close();
   }

   // clean up file
   if(mCleanupFile)
   {
      delete mFile;
   }
}

bool FileInputStream::ensureOpen()
{
   bool rval = true;

   // try to open the file
   if(!mStream.is_open())
   {
      mStream.open(mFile->getName(), ios::in | ios::binary);
      if(!mStream.is_open())
      {
         rval = false;
         char temp[strlen(mFile->getName()) + 30];
         sprintf(temp, "Could not open file '%s'!", mFile->getName());
         ExceptionRef e = new IOException(temp);
         Exception::setLast(e, false);
      }
   }

   return rval;
}

int FileInputStream::read(char* b, int length)
{
   int rval = -1;

   if(ensureOpen())
   {
      rval = 0;

      if(!mStream.eof())
      {
         // do read
         mStream.read(b, length);

         // see if a failure other than EOF occurred
         if(mStream.fail() && !mStream.eof())
         {
            rval = -1;
            char temp[strlen(mFile->getName()) + 40];
            sprintf(temp, "Could not read from file '%s'!", mFile->getName());
            ExceptionRef e = new IOException(temp);
            Exception::setLast(e, false);
         }
         else if(mStream.gcount() > 0)
         {
            // get the number of bytes read
            rval = mStream.gcount();
         }
      }
   }

   return rval;
}

long long FileInputStream::skip(long long count)
{
   long long rval = -1;

   if(ensureOpen())
   {
      // store current position and the end position
      streampos curr = mStream.tellg();
      mStream.seekg(0, ios::end);
      streampos end = mStream.tellg();
      mStream.seekg(curr, ios::beg);

      rval = count;
      if(rval > 0 && curr < end)
      {
         // do not skip past EOF
         if(rval > (end - curr))
         {
            rval = end - curr;
         }

         // skip from current offset
         mStream.seekg(rval, ios::cur);
         curr = mStream.tellg();
      }

      // see if a failure other than EOF occurred
      if(mStream.fail() && !mStream.eof())
      {
         rval = -1;
         char temp[strlen(mFile->getName()) + 40];
         sprintf(temp, "Could not read from file '%s'!", mFile->getName());
         ExceptionRef e = new IOException(temp);
         Exception::setLast(e, false);
      }
   }

   return rval;
}

void FileInputStream::close()
{
   // close the stream
   mStream.close();
}
<commit_msg>Added more specific checks to file input stream.<commit_after>/*
 * Copyright (c) 2007-2008 Digital Bazaar, Inc.  All rights reserved.
 */
#include "db/io/FileInputStream.h"

using namespace std;
using namespace db::io;
using namespace db::rt;

FileInputStream::FileInputStream(File* file, bool cleanup)
{
   // store file, clean up setting
   mFile = file;
   mCleanupFile = cleanup;
}

FileInputStream::~FileInputStream()
{
   // close the ifstream if it is open
   if(mStream.is_open())
   {
      mStream.close();
   }

   // clean up file
   if(mCleanupFile)
   {
      delete mFile;
   }
}

bool FileInputStream::ensureOpen()
{
   bool rval = true;

   // try to open the file
   if(!mStream.is_open())
   {
      if(!mFile->exists())
      {
         rval = false;
         char temp[strlen(mFile->getName()) + 60];
         sprintf(temp, "Could not open file '%s'! File does not exist.",
            mFile->getName());
         ExceptionRef e = new IOException(temp);
         Exception::setLast(e, false);
      }
      else if(!mFile->isReadable())
      {
         rval = false;
         char temp[strlen(mFile->getName()) + 60];
         sprintf(temp, "Could not open file '%s'! Access denied.",
            mFile->getName());
         ExceptionRef e = new IOException(temp);
         Exception::setLast(e, false);
      }
      else
      {
         mStream.open(mFile->getName(), ios::in | ios::binary);
         if(!mStream.is_open())
         {
            rval = false;
            char temp[strlen(mFile->getName()) + 30];
            sprintf(temp, "Could not open file '%s'!", mFile->getName());
            ExceptionRef e = new IOException(temp);
            Exception::setLast(e, false);
         }
      }
   }

   return rval;
}

int FileInputStream::read(char* b, int length)
{
   int rval = -1;

   if(ensureOpen())
   {
      rval = 0;

      if(!mStream.eof())
      {
         // do read
         mStream.read(b, length);

         // see if a failure other than EOF occurred
         if(mStream.fail() && !mStream.eof())
         {
            rval = -1;
            char temp[strlen(mFile->getName()) + 40];
            sprintf(temp, "Could not read from file '%s'!", mFile->getName());
            ExceptionRef e = new IOException(temp);
            Exception::setLast(e, false);
         }
         else if(mStream.gcount() > 0)
         {
            // get the number of bytes read
            rval = mStream.gcount();
         }
      }
   }

   return rval;
}

long long FileInputStream::skip(long long count)
{
   long long rval = -1;

   if(ensureOpen())
   {
      // store current position and the end position
      streampos curr = mStream.tellg();
      mStream.seekg(0, ios::end);
      streampos end = mStream.tellg();
      mStream.seekg(curr, ios::beg);

      rval = count;
      if(rval > 0 && curr < end)
      {
         // do not skip past EOF
         if(rval > (end - curr))
         {
            rval = end - curr;
         }

         // skip from current offset
         mStream.seekg(rval, ios::cur);
         curr = mStream.tellg();
      }

      // see if a failure other than EOF occurred
      if(mStream.fail() && !mStream.eof())
      {
         rval = -1;
         char temp[strlen(mFile->getName()) + 40];
         sprintf(temp, "Could not read from file '%s'!", mFile->getName());
         ExceptionRef e = new IOException(temp);
         Exception::setLast(e, false);
      }
   }

   return rval;
}

void FileInputStream::close()
{
   // close the stream
   mStream.close();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <fstream>

#include "../include/args.h"

#include "errors/RuntimeError.h"
#include "execution/Program.h"
#include "loader/ProgramReader.h"

int main(int argc, char **argv)
{
    args::ArgumentParser parser("thinglang's runtime environment");
    args::HelpFlag help(parser, "help", "Display this help", {'h', "help"});
    args::Group group(parser, "", args::Group::Validators::Xor);
    args::Positional<std::string> filename(group, "file", "a file containing thinglang bytecode");
    args::Flag version(group, "version", "Prints the version and exits", {'v', "version"});

    try {
        parser.ParseCLI(argc, argv);
    } catch (args::Help) {
        std::cout << parser;
        return 0;
    } catch (args::Error e)  {
        std::cerr << e.what() << std::endl;
        std::cerr << parser;
        return 1;
    }

    if(version) {
        std::cerr << "thinglang runtime, version 0.0.0" << std::endl;
        return 0;
    }

    auto reader = ProgramReader(filename.Get());

    try {
        auto info = reader.process();
        Program::load(info);
        Program::start();
    } catch (const RuntimeError &err) {
        std::cerr << "Error during execution: " << err.what() << std::endl;
        return 1;
    }
}<commit_msg>Fix const qualifer, since that's the most critical thing according to CLion<commit_after>#include <iostream>
#include <vector>
#include <fstream>

#include "../include/args.h"

#include "errors/RuntimeError.h"
#include "execution/Program.h"
#include "loader/ProgramReader.h"

int main(const int argc, const char **argv)
{
    args::ArgumentParser parser("thinglang's runtime environment");
    args::HelpFlag help(parser, "help", "Display this help", {'h', "help"});
    args::Group group(parser, "", args::Group::Validators::Xor);
    args::Positional<std::string> filename(group, "file", "a file containing thinglang bytecode");
    args::Flag version(group, "version", "Prints the version and exits", {'v', "version"});

    try {
        parser.ParseCLI(argc, argv);
    } catch (args::Help) {
        std::cout << parser;
        return 0;
    } catch (args::Error e)  {
        std::cerr << e.what() << std::endl;
        std::cerr << parser;
        return 1;
    }

    if(version) {
        std::cerr << "thinglang runtime, version 0.0.0" << std::endl;
        return 0;
    }

    auto reader = ProgramReader(filename.Get());

    try {
        auto info = reader.process();
        Program::load(info);
        Program::start();
    } catch (const RuntimeError &err) {
        std::cerr << "Error during execution: " << err.what() << std::endl;
        return 1;
    }
}<|endoftext|>