<commit_before>
/*************************************************************************
> File Name: main.cpp
> Project Name: Hearthstone++
> Author: Chan-Ho Chris Ohk
> Purpose: Main entry of Hearthstone++ tool.
> Created Time: 2018/08/21
> Copyright (c) 2018, Chan-Ho Chris Ohk
*************************************************************************/
#include <Cards/Cards.h>

#include <clara.hpp>

#include <fstream>
#include <iostream>
#include <string>
#include <vector>

using namespace Hearthstonepp;

inline std::string ToString(const clara::Opt& opt)
{
    std::ostringstream oss;
    oss << (clara::Parser() | opt);
    return oss.str();
}

inline std::string ToString(const clara::Parser& p)
{
    std::ostringstream oss;
    oss << p;
    return oss.str();
}

inline std::vector<Card*> QueryCardSetList(CardSet cardSet)
{
    if (cardSet == +CardSet::ALL)
    {
        return Cards::GetInstance()->GetAllCards();
    }

    return Cards::GetInstance()->FindCardBySet(cardSet);
}

inline std::tuple<size_t, size_t, size_t> GetMaxLengthsInCards(
    std::vector<Card*>& cards)
{
    size_t cardIDMaxLen = std::numeric_limits<size_t>::min();
    size_t cardSetMaxLen = std::numeric_limits<size_t>::min();
    size_t cardNameMaxLen = std::numeric_limits<size_t>::min();

    for (auto& card : cards)
    {
        if (card->id.length() > cardIDMaxLen)
        {
            cardIDMaxLen = card->id.length();
        }

        if (std::strlen(card->cardSet._to_string()) > cardSetMaxLen)
        {
            cardSetMaxLen = std::strlen(card->cardSet._to_string());
        }

        if (card->name.length() > cardNameMaxLen)
        {
            cardNameMaxLen = card->name.length();
        }
    }

    return std::make_tuple(cardIDMaxLen, cardSetMaxLen, cardNameMaxLen);
}

inline void ExportFile(const std::string& fileName)
{
    std::ofstream outputFile(fileName + ".md");
    if (outputFile)
    {
        // TODO: export card data
    }
    else
    {
        fprintf(stderr, "Failed to write file %s\n", fileName.c_str());
        exit(EXIT_FAILURE);
    }
}

int main(int argc, char* argv[])
{
    // Parse command
    bool showHelp = false;
    bool exportAllCard = false;
    std::string cardSetName;

    // Parsing
    auto parser = clara::Help(showHelp) |
                  clara::Opt(exportAllCard)["-a"]["--all"](
                      "Export all card set list to markdown format") |
                  clara::Opt(cardSetName, "cardSet")["-c"]["--cardset"](
                      "Export specific card set list to markdown format");

    auto result = parser.parse(clara::Args(argc, argv));
    if (!result)
    {
        std::cerr << "Error in command line: " << result.errorMessage() << '\n';
        exit(EXIT_FAILURE);
    }

    if (showHelp)
    {
        std::cout << ToString(parser) << '\n';
        exit(EXIT_SUCCESS);
    }

    std::vector<Card*> cards;

    if (exportAllCard)
    {
        cards = QueryCardSetList(CardSet::ALL);
    }
    else if (!cardSetName.empty())
    {
        auto maybeCardSet = CardSet::_from_string_nothrow(cardSetName.c_str());
        if (!maybeCardSet)
        {
            std::cerr << "Invalid card set name: " << cardSetName << '\n';
            exit(EXIT_FAILURE);
        }

        cards = QueryCardSetList(*maybeCardSet);
    }

    if (cards.empty())
    {
        std::cerr << "Your search did not generate any hits.\n";
        exit(EXIT_SUCCESS);
    }

    auto[cardIDMaxLen, cardSetMaxLen, cardNameMaxLen] = GetMaxLengthsInCards(cards);

    exit(EXIT_SUCCESS);
}<commit_msg>[ci skip] [WIP] Implement ExportFile function<commit_after>
/*************************************************************************
> File Name: main.cpp
> Project Name: Hearthstone++
> Author: Chan-Ho Chris Ohk
> Purpose: Main entry of Hearthstone++ tool.
> Created Time: 2018/08/21
> Copyright (c) 2018, Chan-Ho Chris Ohk
*************************************************************************/
#include <Cards/Cards.h>

#include <clara.hpp>

#include <fstream>
#include <iostream>
#include <string>
#include <vector>

using namespace Hearthstonepp;

inline std::string ToString(const clara::Opt& opt)
{
    std::ostringstream oss;
    oss << (clara::Parser() | opt);
    return oss.str();
}

inline std::string ToString(const clara::Parser& p)
{
    std::ostringstream oss;
    oss << p;
    return oss.str();
}

inline std::vector<Card*> QueryCardSetList(CardSet cardSet)
{
    if (cardSet == +CardSet::ALL)
    {
        return Cards::GetInstance()->GetAllCards();
    }

    return Cards::GetInstance()->FindCardBySet(cardSet);
}

inline void ExportFile(const std::string& fileName, std::vector<Card*> cards)
{
    std::ofstream outputFile(fileName + ".md");
    if (outputFile)
    {
        outputFile << "Set | ID | Name\n";
        outputFile << "--- | --- | ---\n";

        for (auto& card : cards)
        {
            if (!card->isCollectible)
            {
                continue;
            }

            outputFile << card->cardSet._to_string() << " | " << card->id
                       << " | " << card->name << '\n';
        }
    }
    else
    {
        fprintf(stderr, "Failed to write file %s\n", fileName.c_str());
        exit(EXIT_FAILURE);
    }
}

int main(int argc, char* argv[])
{
    // Parse command
    bool showHelp = false;
    bool exportAllCard = false;
    std::string cardSetName;

    // Parsing
    auto parser = clara::Help(showHelp) |
                  clara::Opt(exportAllCard)["-a"]["--all"](
                      "Export all card set list to markdown format") |
                  clara::Opt(cardSetName, "cardSet")["-c"]["--cardset"](
                      "Export specific card set list to markdown format");

    auto result = parser.parse(clara::Args(argc, argv));
    if (!result)
    {
        std::cerr << "Error in command line: " << result.errorMessage() << '\n';
        exit(EXIT_FAILURE);
    }

    if (showHelp)
    {
        std::cout << ToString(parser) << '\n';
        exit(EXIT_SUCCESS);
    }

    std::vector<Card*> cards;

    if (exportAllCard)
    {
        cards = QueryCardSetList(CardSet::ALL);
    }
    else if (!cardSetName.empty())
    {
        auto maybeCardSet = CardSet::_from_string_nothrow(cardSetName.c_str());
        if (!maybeCardSet)
        {
            std::cerr << "Invalid card set name: " << cardSetName << '\n';
            exit(EXIT_FAILURE);
        }

        cards = QueryCardSetList(*maybeCardSet);
    }

    if (cards.empty())
    {
        std::cerr << "Your search did not generate any hits.\n";
        exit(EXIT_SUCCESS);
    }

    ExportFile("result", cards);

    exit(EXIT_SUCCESS);
}<|endoftext|>


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

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

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "build/build_config.h"

namespace {

// Return true if we're in debug-plugin-loading mode.
bool DebugPluginLoading() {
  static const char kDebugPluginLoading[] = "debug-plugin-loading";
  return CommandLine::ForCurrentProcess()->HasSwitch(kDebugPluginLoading);
}

// Shorthand way of logging plugin load status.
#define PLUG_LOG if (DebugPluginLoading()) LOG(INFO)

// We build up a list of files and mtimes so we can sort them.
typedef std::pair<FilePath, base::Time> FileAndTime;
typedef std::vector<FileAndTime> FileTimeList;

// Comparator used to sort by descending mtime then ascending filename.
bool CompareTime(const FileAndTime& a, const FileAndTime& b) {
  if (a.second == b.second) {
    // Fall back on filename sorting, just to make the predicate valid.
    return a.first < b.first;
  }

  // Sort by mtime, descending.
  return a.second > b.second;
}

// Some plugins are shells around other plugins; we prefer to use the
// real plugin directly, if it's available.  This function returns
// true if we should prefer other plugins over this one.  We'll still
// use a "undesirable" plugin if no other option is available.
bool IsUndesirablePlugin(const WebPluginInfo& info) {
  std::string filename = info.path.BaseName().value();
  return (filename.find("npcxoffice") != std::string::npos || // Crossover
          filename.find("npwrapper") != std::string::npos);   // nspluginwrapper
}

// Return true if we shouldn't load a plugin at all.
// This is an ugly hack to blacklist Adobe Acrobat due to not supporting
// its Xt-based mainloop.
// http://code.google.com/p/chromium/issues/detail?id=38229
bool IsBlacklistedPlugin(const WebPluginInfo& info) {
  std::string filename = info.path.BaseName().value();
  return filename.find("nppdf.so") != std::string::npos;
}

}  // anonymous namespace

namespace NPAPI {

void PluginList::PlatformInit() {
}

void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) {
  // See http://groups.google.com/group/chromium-dev/browse_thread/thread/7a70e5fcbac786a9
  // for discussion.
  // We first consult Chrome-specific dirs, then fall back on the logic
  // Mozilla uses.

  // Note: "extra" plugin dirs, including the Plugins subdirectory of
  // your Chrome config, are examined before these.  See the logic
  // related to extra_plugin_dirs in plugin_list.cc.

  // The Chrome binary dir + "plugins/".
  FilePath dir;
  PathService::Get(base::DIR_EXE, &dir);
  plugin_dirs->push_back(dir.Append("plugins"));

  // Mozilla code to reference:
  // http://mxr.mozilla.org/firefox/ident?i=NS_APP_PLUGINS_DIR_LIST
  // and tens of accompanying files (mxr is very helpful).
  // This code carefully matches their behavior for compat reasons.

  // 1) MOZ_PLUGIN_PATH env variable.
  const char* moz_plugin_path = getenv("MOZ_PLUGIN_PATH");
  if (moz_plugin_path) {
    std::vector<std::string> paths;
    SplitString(moz_plugin_path, ':', &paths);
    for (size_t i = 0; i < paths.size(); ++i)
      plugin_dirs->push_back(FilePath(paths[i]));
  }

  // 2) NS_USER_PLUGINS_DIR: ~/.mozilla/plugins.
  // This is a de-facto standard, so even though we're not Mozilla, let's
  // look in there too.
  FilePath home = file_util::GetHomeDir();
  if (!home.empty())
    plugin_dirs->push_back(home.Append(".mozilla/plugins"));

  // 3) NS_SYSTEM_PLUGINS_DIR:
  // This varies across different browsers and versions, so check 'em all.
  plugin_dirs->push_back(FilePath("/usr/lib/browser-plugins"));
  plugin_dirs->push_back(FilePath("/usr/lib/mozilla/plugins"));
  plugin_dirs->push_back(FilePath("/usr/lib/firefox/plugins"));
  plugin_dirs->push_back(FilePath("/usr/lib/xulrunner-addons/plugins"));

#if defined(ARCH_CPU_64_BITS)
  // On my Ubuntu system, /usr/lib64 is a symlink to /usr/lib.
  // But a user reported on their Fedora system they are separate.
  plugin_dirs->push_back(FilePath("/usr/lib64/browser-plugins"));
  plugin_dirs->push_back(FilePath("/usr/lib64/mozilla/plugins"));
  plugin_dirs->push_back(FilePath("/usr/lib64/firefox/plugins"));
  plugin_dirs->push_back(FilePath("/usr/lib64/xulrunner-addons/plugins"));
#endif
}

void PluginList::LoadPluginsFromDir(const FilePath& dir_path,
                                    std::vector<WebPluginInfo>* plugins,
                                    std::set<FilePath>* visited_plugins) {
  // See ScanPluginsDirectory near
  // http://mxr.mozilla.org/firefox/source/modules/plugin/base/src/nsPluginHostImpl.cpp#5052

  // Construct and stat a list of all filenames under consideration, for
  // later sorting by mtime.
  FileTimeList files;
  file_util::FileEnumerator enumerator(dir_path,
                                       false,  // not recursive
                                       file_util::FileEnumerator::FILES);
  for (FilePath path = enumerator.Next(); !path.value().empty();
       path = enumerator.Next()) {
    // Skip over Mozilla .xpt files.
    if (path.MatchesExtension(FILE_PATH_LITERAL(".xpt")))
      continue;

    // Java doesn't like being loaded through a symlink, since it uses
    // its path to find dependent data files.
    // file_util::AbsolutePath calls through to realpath(), which resolves
    // symlinks.
    FilePath orig_path = path;
    file_util::AbsolutePath(&path);
    PLUG_LOG << "Resolved " << orig_path.value() << " -> " << path.value();

    if (visited_plugins->find(path) != visited_plugins->end()) {
      PLUG_LOG << "Skipping duplicate instance of " << path.value();
      continue;
    }
    visited_plugins->insert(path);

    // Flash stops working if the containing directory involves 'netscape'.
    // No joke.  So use the other path if it's better.
    static const char kFlashPlayerFilename[] = "libflashplayer.so";
    static const char kNetscapeInPath[] = "/netscape/";
    if (path.BaseName().value() == kFlashPlayerFilename &&
        path.value().find(kNetscapeInPath) != std::string::npos) {
      if (orig_path.value().find(kNetscapeInPath) == std::string::npos) {
        // Go back to the old path.
        path = orig_path;
      } else {
        LOG(ERROR) << "Flash misbehaves when used from a directory containing "
                   << kNetscapeInPath << ", so skipping " << orig_path.value();
        continue;
      }
    }

    // Get mtime.
    file_util::FileInfo info;
    if (!file_util::GetFileInfo(path, &info))
      continue;

    files.push_back(std::make_pair(path, info.last_modified));
  }

  // Sort the file list by time (and filename).
  std::sort(files.begin(), files.end(), CompareTime);

  // Load the files in order.
  for (FileTimeList::const_iterator i = files.begin(); i != files.end(); ++i) {
    LoadPlugin(i->first, plugins);
  }
}

bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
                                  std::vector<WebPluginInfo>* plugins) {
  PLUG_LOG << "Considering " << info.path.value() << " (" << info.name << ")";

  if (IsBlacklistedPlugin(info)) {
    PLUG_LOG << "Skipping blacklisted plugin " << info.path.value();
    return false;
  }

  if (IsUndesirablePlugin(info)) {
    PLUG_LOG << info.path.value() << " is undesirable.";

    // See if we have a better version of this plugin.
    for (size_t i = 0; i < plugins->size(); ++i) {
      if (plugins->at(i).name == info.name &&
          !IsUndesirablePlugin(plugins->at(i))) {
        // Skip the current undesirable one so we can use the better one
        // we just found.
        PLUG_LOG << "Skipping " << info.path.value() << ", preferring "
                 << plugins->at(i).path.value();
        return false;
      }
    }
  }

  // TODO(evanm): prefer the newest version of flash, etc. here?

  PLUG_LOG << "Using " << info.path.value();

  return true;
}

}  // namespace NPAPI
<commit_msg>Linux: Blacklist the gecko-mediaplayer plugin. It sometimes hangs/crashes the browser.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "build/build_config.h"

namespace {

// Return true if we're in debug-plugin-loading mode.
bool DebugPluginLoading() {
  static const char kDebugPluginLoading[] = "debug-plugin-loading";
  return CommandLine::ForCurrentProcess()->HasSwitch(kDebugPluginLoading);
}

// Shorthand way of logging plugin load status.
#define PLUG_LOG if (DebugPluginLoading()) LOG(INFO)

// We build up a list of files and mtimes so we can sort them.
typedef std::pair<FilePath, base::Time> FileAndTime;
typedef std::vector<FileAndTime> FileTimeList;

// Comparator used to sort by descending mtime then ascending filename.
bool CompareTime(const FileAndTime& a, const FileAndTime& b) {
  if (a.second == b.second) {
    // Fall back on filename sorting, just to make the predicate valid.
    return a.first < b.first;
  }

  // Sort by mtime, descending.
  return a.second > b.second;
}

// Some plugins are shells around other plugins; we prefer to use the
// real plugin directly, if it's available.  This function returns
// true if we should prefer other plugins over this one.  We'll still
// use a "undesirable" plugin if no other option is available.
bool IsUndesirablePlugin(const WebPluginInfo& info) {
  std::string filename = info.path.BaseName().value();
  const char* kUndesiredPlugins[] = {
    "npcxoffice",  // Crossover
    "npwrapper",   // nspluginwrapper
  };
  for (size_t i = 0; i < arraysize(kUndesiredPlugins); i++) {
    if (filename.find(kUndesiredPlugins[i]) != std::string::npos) {
      return true;
    }
  }
  return false;
}

// Return true if we shouldn't load a plugin at all.
// This is an ugly hack to blacklist Adobe Acrobat due to not supporting
// its Xt-based mainloop.
// http://code.google.com/p/chromium/issues/detail?id=38229
// The gecko-mediaplayer plugins also crashes the entire browser sometimes.
// http://code.google.com/p/chromium/issues/detail?id=24507
bool IsBlacklistedPlugin(const WebPluginInfo& info) {
  const char* kBlackListedPlugins[] = {
    "nppdf.so",           // Adobe PDF
    "gecko-mediaplayer",  // Gecko Media Player
  };
  std::string filename = info.path.BaseName().value();
  for (size_t i = 0; i < arraysize(kBlackListedPlugins); i++) {
    if (filename.find(kBlackListedPlugins[i]) != std::string::npos) {
      return true;
    }
  }
  return false;
}

}  // anonymous namespace

namespace NPAPI {

void PluginList::PlatformInit() {
}

void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) {
  // See http://groups.google.com/group/chromium-dev/browse_thread/thread/7a70e5fcbac786a9
  // for discussion.
  // We first consult Chrome-specific dirs, then fall back on the logic
  // Mozilla uses.

  // Note: "extra" plugin dirs, including the Plugins subdirectory of
  // your Chrome config, are examined before these.  See the logic
  // related to extra_plugin_dirs in plugin_list.cc.

  // The Chrome binary dir + "plugins/".
  FilePath dir;
  PathService::Get(base::DIR_EXE, &dir);
  plugin_dirs->push_back(dir.Append("plugins"));

  // Mozilla code to reference:
  // http://mxr.mozilla.org/firefox/ident?i=NS_APP_PLUGINS_DIR_LIST
  // and tens of accompanying files (mxr is very helpful).
  // This code carefully matches their behavior for compat reasons.

  // 1) MOZ_PLUGIN_PATH env variable.
  const char* moz_plugin_path = getenv("MOZ_PLUGIN_PATH");
  if (moz_plugin_path) {
    std::vector<std::string> paths;
    SplitString(moz_plugin_path, ':', &paths);
    for (size_t i = 0; i < paths.size(); ++i)
      plugin_dirs->push_back(FilePath(paths[i]));
  }

  // 2) NS_USER_PLUGINS_DIR: ~/.mozilla/plugins.
  // This is a de-facto standard, so even though we're not Mozilla, let's
  // look in there too.
  FilePath home = file_util::GetHomeDir();
  if (!home.empty())
    plugin_dirs->push_back(home.Append(".mozilla/plugins"));

  // 3) NS_SYSTEM_PLUGINS_DIR:
  // This varies across different browsers and versions, so check 'em all.
  plugin_dirs->push_back(FilePath("/usr/lib/browser-plugins"));
  plugin_dirs->push_back(FilePath("/usr/lib/mozilla/plugins"));
  plugin_dirs->push_back(FilePath("/usr/lib/firefox/plugins"));
  plugin_dirs->push_back(FilePath("/usr/lib/xulrunner-addons/plugins"));

#if defined(ARCH_CPU_64_BITS)
  // On my Ubuntu system, /usr/lib64 is a symlink to /usr/lib.
  // But a user reported on their Fedora system they are separate.
  plugin_dirs->push_back(FilePath("/usr/lib64/browser-plugins"));
  plugin_dirs->push_back(FilePath("/usr/lib64/mozilla/plugins"));
  plugin_dirs->push_back(FilePath("/usr/lib64/firefox/plugins"));
  plugin_dirs->push_back(FilePath("/usr/lib64/xulrunner-addons/plugins"));
#endif
}

void PluginList::LoadPluginsFromDir(const FilePath& dir_path,
                                    std::vector<WebPluginInfo>* plugins,
                                    std::set<FilePath>* visited_plugins) {
  // See ScanPluginsDirectory near
  // http://mxr.mozilla.org/firefox/source/modules/plugin/base/src/nsPluginHostImpl.cpp#5052

  // Construct and stat a list of all filenames under consideration, for
  // later sorting by mtime.
  FileTimeList files;
  file_util::FileEnumerator enumerator(dir_path,
                                       false,  // not recursive
                                       file_util::FileEnumerator::FILES);
  for (FilePath path = enumerator.Next(); !path.value().empty();
       path = enumerator.Next()) {
    // Skip over Mozilla .xpt files.
    if (path.MatchesExtension(FILE_PATH_LITERAL(".xpt")))
      continue;

    // Java doesn't like being loaded through a symlink, since it uses
    // its path to find dependent data files.
    // file_util::AbsolutePath calls through to realpath(), which resolves
    // symlinks.
    FilePath orig_path = path;
    file_util::AbsolutePath(&path);
    PLUG_LOG << "Resolved " << orig_path.value() << " -> " << path.value();

    if (visited_plugins->find(path) != visited_plugins->end()) {
      PLUG_LOG << "Skipping duplicate instance of " << path.value();
      continue;
    }
    visited_plugins->insert(path);

    // Flash stops working if the containing directory involves 'netscape'.
    // No joke.  So use the other path if it's better.
    static const char kFlashPlayerFilename[] = "libflashplayer.so";
    static const char kNetscapeInPath[] = "/netscape/";
    if (path.BaseName().value() == kFlashPlayerFilename &&
        path.value().find(kNetscapeInPath) != std::string::npos) {
      if (orig_path.value().find(kNetscapeInPath) == std::string::npos) {
        // Go back to the old path.
        path = orig_path;
      } else {
        LOG(ERROR) << "Flash misbehaves when used from a directory containing "
                   << kNetscapeInPath << ", so skipping " << orig_path.value();
        continue;
      }
    }

    // Get mtime.
    file_util::FileInfo info;
    if (!file_util::GetFileInfo(path, &info))
      continue;

    files.push_back(std::make_pair(path, info.last_modified));
  }

  // Sort the file list by time (and filename).
  std::sort(files.begin(), files.end(), CompareTime);

  // Load the files in order.
  for (FileTimeList::const_iterator i = files.begin(); i != files.end(); ++i) {
    LoadPlugin(i->first, plugins);
  }
}

bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info,
                                  std::vector<WebPluginInfo>* plugins) {
  PLUG_LOG << "Considering " << info.path.value() << " (" << info.name << ")";

  if (IsBlacklistedPlugin(info)) {
    PLUG_LOG << "Skipping blacklisted plugin " << info.path.value();
    return false;
  }

  if (IsUndesirablePlugin(info)) {
    PLUG_LOG << info.path.value() << " is undesirable.";

    // See if we have a better version of this plugin.
    for (size_t i = 0; i < plugins->size(); ++i) {
      if (plugins->at(i).name == info.name &&
          !IsUndesirablePlugin(plugins->at(i))) {
        // Skip the current undesirable one so we can use the better one
        // we just found.
        PLUG_LOG << "Skipping " << info.path.value() << ", preferring "
                 << plugins->at(i).path.value();
        return false;
      }
    }
  }

  // TODO(evanm): prefer the newest version of flash, etc. here?

  PLUG_LOG << "Using " << info.path.value();

  return true;
}

}  // namespace NPAPI
<|endoftext|>


<commit_before><commit_msg>fix bustage, use new api<commit_after><|endoftext|>


<commit_before>#include <iostream>
#include <cmath>
using namespace std;

struct Vector {
  float x, y,z;

  void init(float x, float y, float z) {
    this->x = x;
    this->y = y;
    this->z = z;
  }

  float length() const {
    return sqrt(x*x + y*y + z*z);
  }

  Vector normalize() const {
    Vector tmp;
    float len = length();
    tmp.x = x / len;
    tmp.y = y / len;
    tmp.z = z / len;

    return tmp;
  }

  void print() const {
    cout << "(" << x << ", " << y << ", " << z << ")";
  }
};

Vector sum(const Vector& v1, const Vector& v2) {
  Vector tmp;
  tmp.x = v1.x + v2.x;
  tmp.y = v1.y + v2.y;
  tmp.z = v1.z + v2.z;

  return tmp;
}

float distance(const Vector& v1, const Vector& v2) {
  return sqrt(
              (v1.x - v2.x)*(v1.x - v2.x) +
              (v1.y - v2.y)*(v1.y - v2.y) +
              (v1.z - v2.z)*(v1.z - v2.z)
            );
}

struct Cube {
  Vector position;
  float size;

  void init(const Vector& v, float _size) {
    position = v;
    size = _size;
  }

  void print() const {
    cout << "Cube<";
    position.print();
    cout << ", " << size << ">";
  }

  Vector move(const Vector& v) {
    position = sum(position, v);
    return position;
  }

  bool collide(const Cube& c) const {
    float d = size + c.size;
    return (abs(position.x - c.position.x) <= d) &&
            (abs(position.y - c.position.y) <= d) &&
            (abs(position.z - c.position.z) <= d);
  }
};

struct Sphere {
  Vector position;
  float size;

  void init(const Vector& v, float _size) {
    position = v;
    size = _size;
  }

  void print() const {
    cout << "Sphere<";
    position.print();
    cout << ", " << size << ">";
  }

  Vector move(const Vector& v) {
    position = sum(position, v);
    return position;
  }

  bool collide(const Sphere& s) const {
    return distance(position, s.position) <= size + s.size;
  }
};

int main() {

  Vector a, b;
  a.init(1,1,1);
  b.init(3,3,1);

  a.normalize().print();
  cout << " len: " << a.normalize().length() << endl;
  b.normalize().print();
  cout << " len: " << b.normalize().length() << endl;

  Cube ca, cb;
  ca.init(a, 1);
  cb.init(b, 0.5);

  ca.print();
  cout << endl;
  cb.print();
  cout << endl;

  cout << "ca collide cb: " << ca.collide(cb) << endl; // false
  cb.size = 1.5;
  cout << "ca collide cb: " << ca.collide(cb) << endl; // true

  // .....

  return 0;
}
<commit_msg>vector normalize fix<commit_after>#include <iostream>
#include <cmath>
using namespace std;

struct Vector {
  float x, y, z;

  void init(float x, float y, float z) {
    this->x = x;
    this->y = y;
    this->z = z;
  }

  float length() const {
    return sqrt(x*x + y*y + z*z);
  }

  Vector normalize() const {
    Vector tmp;
    float len = length();

    if (len > 0) {
      tmp.x = x / len;
      tmp.y = y / len;
      tmp.z = z / len;
    }

    return tmp;
  }

  void print() const {
    cout << "(" << x << ", " << y << ", " << z << ")";
  }
};

Vector sum(const Vector& v1, const Vector& v2) {
  Vector tmp;
  tmp.x = v1.x + v2.x;
  tmp.y = v1.y + v2.y;
  tmp.z = v1.z + v2.z;

  return tmp;
}

float distance(const Vector& v1, const Vector& v2) {
  return sqrt(
              (v1.x - v2.x)*(v1.x - v2.x) +
              (v1.y - v2.y)*(v1.y - v2.y) +
              (v1.z - v2.z)*(v1.z - v2.z)
            );
}

struct Cube {
  Vector position;
  float size;

  void init(const Vector& v, float _size) {
    position = v;
    size = _size;
  }

  void print() const {
    cout << "Cube<";
    position.print();
    cout << ", " << size << ">";
  }

  Vector move(const Vector& v) {
    position = sum(position, v);
    return position;
  }

  bool collide(const Cube& c) const {
    float d = size + c.size;
    return (abs(position.x - c.position.x) <= d) &&
            (abs(position.y - c.position.y) <= d) &&
            (abs(position.z - c.position.z) <= d);
  }
};

struct Sphere {
  Vector position;
  float size;

  void init(const Vector& v, float _size) {
    position = v;
    size = _size;
  }

  void print() const {
    cout << "Sphere<";
    position.print();
    cout << ", " << size << ">";
  }

  Vector move(const Vector& v) {
    position = sum(position, v);
    return position;
  }

  bool collide(const Sphere& s) const {
    return distance(position, s.position) <= size + s.size;
  }
};

int main() {

  Vector a, b;
  a.init(1,1,1);
  b.init(3,3,1);

  a.normalize().print();
  cout << " len: " << a.normalize().length() << endl;
  b.normalize().print();
  cout << " len: " << b.normalize().length() << endl;

  Cube ca, cb;
  ca.init(a, 1);
  cb.init(b, 0.5);

  ca.print();
  cout << endl;
  cb.print();
  cout << endl;

  cout << "ca collide cb: " << ca.collide(cb) << endl; // false
  cb.size = 1.5;
  cout << "ca collide cb: " << ca.collide(cb) << endl; // true

  // .....

  return 0;
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2121
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1271842 by johtaylo@johtaylo-JTBUILDER03-increment on 2016/05/22 03:00:11<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2122
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3050
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 2038998 by chui@ocl-promo-incrementor on 2019/11/30 03:00:15<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3051
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>#include "mc_instance.hpp"
#include "ppapi/cpp/var_dictionary.h"
#include "ppapi/cpp/var_array.h"
#include <vector>
#include <thread>
#include <functional>

pp::Module* pp::CreateModule() {
  return new InstanceFactory<MonteCarloInstance>();
}

void MonteCarloInstance::Simulate( unsigned int N ) {
  pp::VarArray reply;

  // Run the simulation in 10 parts
  const len_t nParts = 10;
  auto step = N/nParts;
  step = step > 0 ? step : 1;
  len_t runningTotal = 0;
  unsigned int count=0;
  for( len_t i=step; i<=N; i += step) {
    auto res = mc.sim(step);
    pp::VarDictionary outData;
    runningTotal += res.Total;
    outData.Set( "Samples", static_cast<double>(i) );
    outData.Set( "Total", static_cast<double>(runningTotal) );
    auto runningMean = 1.0*runningTotal/i;
    outData.Set( "Mean", runningMean );
    outData.Set( "StdError", sqrt( runningMean*(1.0-runningMean)/i));
    reply.Set( count, outData );
    PostMessage( outData ); // For progress measurement
    count++;
  }
  PostMessage( reply );
}

void MonteCarloInstance::HandleMessage( const pp::Var& var_message ) {
  if ( !var_message.is_number() )
    return; //Early exit
  auto N = var_message.AsInt();

  // std::thread t(&MonteCarloInstance::Simulate, this, N);
  // t.join();
  Simulate(N);
}
<commit_msg>Still fiddling with multithreading.  Commented out - compiles but crashes NaCl when run<commit_after>#include "mc_instance.hpp"
#include "ppapi/cpp/var_dictionary.h"
#include "ppapi/cpp/var_array.h"
#include <vector>
#include <thread>
#include <functional>

pp::Module* pp::CreateModule() {
  return new InstanceFactory<MonteCarloInstance>();
}

void MonteCarloInstance::Simulate( unsigned int N ) {
  pp::VarArray reply;

  // Run the simulation in 10 parts
  const len_t nParts = 10;
  auto step = N/nParts;
  step = step > 0 ? step : 1;
  len_t runningTotal = 0;
  unsigned int count=0;
  for( len_t i=step; i<=N; i += step) {
    auto res = mc.sim(step);
    pp::VarDictionary outData;
    runningTotal += res.Total;
    outData.Set( "Samples", static_cast<double>(i) );
    outData.Set( "Total", static_cast<double>(runningTotal) );
    auto runningMean = 1.0*runningTotal/i;
    outData.Set( "Mean", runningMean );
    outData.Set( "StdError", sqrt( runningMean*(1.0-runningMean)/i));
    reply.Set( count, outData );
    PostMessage( outData ); // For progress measurement
    count++;
  }
  PostMessage( reply );
}

void MonteCarloInstance::HandleMessage( const pp::Var& var_message ) {
  if ( !var_message.is_number() )
    return; //Early exit
  auto N = var_message.AsInt();

  //std::thread t(&MonteCarloInstance::Simulate, this, N);
  //t.detach();
  Simulate(N);
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2853
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1756830 by chui@ocl-promo-incrementor on 2019/03/15 03:00:31<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2854
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2372
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1378742 by johtaylo@johtaylo-jtincrementor-increment on 2017/02/28 03:00:04<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2373
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1791
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1146732 by johtaylo@johtaylo-JTBUILDER03-increment on 2015/05/02 03:00:11<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 1792
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3014
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 2009716 by chui@ocl-promo-incrementor on 2019/10/08 03:00:45<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 3015
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


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

#include "chrome/common/extensions/extension_l10n_util.h"

#include <set>
#include <string>
#include <vector>

#include "app/l10n_util.h"
#include "base/file_util.h"
#include "base/linked_ptr.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_message_bundle.h"
#include "chrome/common/json_value_serializer.h"

namespace errors = extension_manifest_errors;
namespace keys = extension_manifest_keys;

static std::string* GetProcessLocale() {
  static std::string locale;
  return &locale;
}

namespace extension_l10n_util {

void SetProcessLocale(const std::string& locale) {
  *(GetProcessLocale()) = locale;
}

std::string GetDefaultLocaleFromManifest(const DictionaryValue& manifest,
                                         std::string* error) {
  std::string default_locale;
  if (!manifest.GetString(keys::kDefaultLocale, &default_locale)) {
    *error = errors::kInvalidDefaultLocale;
    return "";
  }

  return default_locale;
}

bool AddLocale(const std::set<std::string>& chrome_locales,
               const FilePath& locale_folder,
               const std::string& locale_name,
               std::set<std::string>* valid_locales,
               std::string* error) {
  // Accept name that starts with a . but don't add it to the list of supported
  // locales.
  if (locale_name.find(".") == 0)
    return true;
  if (chrome_locales.find(locale_name) == chrome_locales.end()) {
    // Fail if there is an extension locale that's not in the Chrome list.
    *error = StringPrintf("Supplied locale %s is not supported.",
                          locale_name.c_str());
    return false;
  }
  // Check if messages file is actually present (but don't check content).
  if (file_util::PathExists(
         locale_folder.AppendASCII(Extension::kMessagesFilename))) {
    valid_locales->insert(locale_name);
  } else {
    *error = StringPrintf("Catalog file is missing for locale %s.",
                          locale_name.c_str());
    return false;
  }

  return true;
}

std::string NormalizeLocale(const std::string& locale) {
  std::string normalized_locale(locale);
  std::replace(normalized_locale.begin(), normalized_locale.end(), '-', '_');

  return normalized_locale;
}

void GetParentLocales(const std::string& current_locale,
                      std::vector<std::string>* parent_locales) {
  std::string locale(NormalizeLocale(current_locale));

  const int kNameCapacity = 256;
  char parent[kNameCapacity];
  base::strlcpy(parent, locale.c_str(), kNameCapacity);
  parent_locales->push_back(parent);
  UErrorCode err = U_ZERO_ERROR;
  while (uloc_getParent(parent, parent, kNameCapacity, &err) > 0) {
    if (err != U_ZERO_ERROR)
      break;
    parent_locales->push_back(parent);
  }
}

// Extends list of Chrome locales to them and their parents, so we can do
// proper fallback.
static void GetAllLocales(std::set<std::string>* all_locales) {
  const std::vector<std::string>& available_locales =
      l10n_util::GetAvailableLocales();
  // Add all parents of the current locale to the available locales set.
  // I.e. for sr_Cyrl_RS we add sr_Cyrl_RS, sr_Cyrl and sr.
  for (size_t i = 0; i < available_locales.size(); ++i) {
    std::vector<std::string> result;
    GetParentLocales(available_locales[i], &result);
    all_locales->insert(result.begin(), result.end());
  }
}

bool GetValidLocales(const FilePath& locale_path,
                     std::set<std::string>* valid_locales,
                     std::string* error) {
  static std::set<std::string> chrome_locales;
  GetAllLocales(&chrome_locales);

  // Enumerate all supplied locales in the extension.
  file_util::FileEnumerator locales(locale_path,
                                    false,
                                    file_util::FileEnumerator::DIRECTORIES);
  FilePath locale_folder;
  while (!(locale_folder = locales.Next()).empty()) {
    std::string locale_name =
        WideToASCII(locale_folder.BaseName().ToWStringHack());
    if (!AddLocale(chrome_locales,
                   locale_folder,
                   locale_name,
                   valid_locales,
                   error)) {
      return false;
    }
  }

  if (valid_locales->empty()) {
    *error = extension_manifest_errors::kLocalesNoValidLocaleNamesListed;
    return false;
  }

  return true;
}

// Loads contents of the messages file for given locale. If file is not found,
// or there was parsing error we return NULL and set |error|.
// Caller owns the returned object.
static DictionaryValue* LoadMessageFile(const FilePath& locale_path,
                                        const std::string& locale,
                                        std::string* error) {

  std::string extension_locale = locale;
  FilePath file = locale_path.AppendASCII(extension_locale)
      .AppendASCII(Extension::kMessagesFilename);
  JSONFileValueSerializer messages_serializer(file);
  Value *dictionary = messages_serializer.Deserialize(error);
  if (!dictionary && error->empty()) {
    // JSONFileValueSerializer just returns NULL if file cannot be found. It
    // doesn't set the error, so we have to do it.
    *error = StringPrintf("Catalog file is missing for locale %s.",
                          extension_locale.c_str());
  }

  return static_cast<DictionaryValue*>(dictionary);
}

ExtensionMessageBundle* LoadMessageCatalogs(
    const FilePath& locale_path,
    const std::string& default_locale,
    const std::string& application_locale,
    const std::set<std::string>& valid_locales,
    std::string* error) {
  // Order locales to load as current_locale, first_parent, ..., default_locale.
  std::vector<std::string> all_fallback_locales;
  if (!application_locale.empty() && application_locale != default_locale)
    GetParentLocales(application_locale, &all_fallback_locales);
  all_fallback_locales.push_back(default_locale);

  std::vector<linked_ptr<DictionaryValue> > catalogs;
  for (size_t i = 0; i < all_fallback_locales.size(); ++i) {
    // Skip all parent locales that are not supplied.
    if (valid_locales.find(all_fallback_locales[i]) == valid_locales.end())
      continue;
    linked_ptr<DictionaryValue> catalog(
      LoadMessageFile(locale_path, all_fallback_locales[i], error));
    if (!catalog.get()) {
      // If locale is valid, but messages.json is corrupted or missing, return
      // an error.
      return false;
    } else {
      catalogs.push_back(catalog);
    }
  }

  return ExtensionMessageBundle::Create(catalogs, error);
}

void GetL10nRelativePaths(const FilePath& relative_resource_path,
                          std::vector<FilePath>* l10n_paths) {
  DCHECK(NULL != l10n_paths);

  std::string* current_locale = GetProcessLocale();
  if (current_locale->empty())
    *current_locale = l10n_util::GetApplicationLocale(L"");

  std::vector<std::string> locales;
  GetParentLocales(*current_locale, &locales);

  FilePath locale_relative_path;
  for (size_t i = 0; i < locales.size(); ++i) {
    l10n_paths->push_back(locale_relative_path
        .AppendASCII(Extension::kLocaleFolder)
        .AppendASCII(locales[i])
        .Append(relative_resource_path));
  }
}

}  // namespace extension_l10n_util
<commit_msg>Make error checking more ICU friendly.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/extensions/extension_l10n_util.h"

#include <set>
#include <string>
#include <vector>

#include "app/l10n_util.h"
#include "base/file_util.h"
#include "base/linked_ptr.h"
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_message_bundle.h"
#include "chrome/common/json_value_serializer.h"

namespace errors = extension_manifest_errors;
namespace keys = extension_manifest_keys;

static std::string* GetProcessLocale() {
  static std::string locale;
  return &locale;
}

namespace extension_l10n_util {

void SetProcessLocale(const std::string& locale) {
  *(GetProcessLocale()) = locale;
}

std::string GetDefaultLocaleFromManifest(const DictionaryValue& manifest,
                                         std::string* error) {
  std::string default_locale;
  if (!manifest.GetString(keys::kDefaultLocale, &default_locale)) {
    *error = errors::kInvalidDefaultLocale;
    return "";
  }

  return default_locale;
}

bool AddLocale(const std::set<std::string>& chrome_locales,
               const FilePath& locale_folder,
               const std::string& locale_name,
               std::set<std::string>* valid_locales,
               std::string* error) {
  // Accept name that starts with a . but don't add it to the list of supported
  // locales.
  if (locale_name.find(".") == 0)
    return true;
  if (chrome_locales.find(locale_name) == chrome_locales.end()) {
    // Fail if there is an extension locale that's not in the Chrome list.
    *error = StringPrintf("Supplied locale %s is not supported.",
                          locale_name.c_str());
    return false;
  }
  // Check if messages file is actually present (but don't check content).
  if (file_util::PathExists(
         locale_folder.AppendASCII(Extension::kMessagesFilename))) {
    valid_locales->insert(locale_name);
  } else {
    *error = StringPrintf("Catalog file is missing for locale %s.",
                          locale_name.c_str());
    return false;
  }

  return true;
}

std::string NormalizeLocale(const std::string& locale) {
  std::string normalized_locale(locale);
  std::replace(normalized_locale.begin(), normalized_locale.end(), '-', '_');

  return normalized_locale;
}

void GetParentLocales(const std::string& current_locale,
                      std::vector<std::string>* parent_locales) {
  std::string locale(NormalizeLocale(current_locale));

  const int kNameCapacity = 256;
  char parent[kNameCapacity];
  base::strlcpy(parent, locale.c_str(), kNameCapacity);
  parent_locales->push_back(parent);
  UErrorCode err = U_ZERO_ERROR;
  while (uloc_getParent(parent, parent, kNameCapacity, &err) > 0) {
    if (U_FAILURE(err))
      break;
    parent_locales->push_back(parent);
  }
}

// Extends list of Chrome locales to them and their parents, so we can do
// proper fallback.
static void GetAllLocales(std::set<std::string>* all_locales) {
  const std::vector<std::string>& available_locales =
      l10n_util::GetAvailableLocales();
  // Add all parents of the current locale to the available locales set.
  // I.e. for sr_Cyrl_RS we add sr_Cyrl_RS, sr_Cyrl and sr.
  for (size_t i = 0; i < available_locales.size(); ++i) {
    std::vector<std::string> result;
    GetParentLocales(available_locales[i], &result);
    all_locales->insert(result.begin(), result.end());
  }
}

bool GetValidLocales(const FilePath& locale_path,
                     std::set<std::string>* valid_locales,
                     std::string* error) {
  static std::set<std::string> chrome_locales;
  GetAllLocales(&chrome_locales);

  // Enumerate all supplied locales in the extension.
  file_util::FileEnumerator locales(locale_path,
                                    false,
                                    file_util::FileEnumerator::DIRECTORIES);
  FilePath locale_folder;
  while (!(locale_folder = locales.Next()).empty()) {
    std::string locale_name =
        WideToASCII(locale_folder.BaseName().ToWStringHack());
    if (!AddLocale(chrome_locales,
                   locale_folder,
                   locale_name,
                   valid_locales,
                   error)) {
      return false;
    }
  }

  if (valid_locales->empty()) {
    *error = extension_manifest_errors::kLocalesNoValidLocaleNamesListed;
    return false;
  }

  return true;
}

// Loads contents of the messages file for given locale. If file is not found,
// or there was parsing error we return NULL and set |error|.
// Caller owns the returned object.
static DictionaryValue* LoadMessageFile(const FilePath& locale_path,
                                        const std::string& locale,
                                        std::string* error) {

  std::string extension_locale = locale;
  FilePath file = locale_path.AppendASCII(extension_locale)
      .AppendASCII(Extension::kMessagesFilename);
  JSONFileValueSerializer messages_serializer(file);
  Value *dictionary = messages_serializer.Deserialize(error);
  if (!dictionary && error->empty()) {
    // JSONFileValueSerializer just returns NULL if file cannot be found. It
    // doesn't set the error, so we have to do it.
    *error = StringPrintf("Catalog file is missing for locale %s.",
                          extension_locale.c_str());
  }

  return static_cast<DictionaryValue*>(dictionary);
}

ExtensionMessageBundle* LoadMessageCatalogs(
    const FilePath& locale_path,
    const std::string& default_locale,
    const std::string& application_locale,
    const std::set<std::string>& valid_locales,
    std::string* error) {
  // Order locales to load as current_locale, first_parent, ..., default_locale.
  std::vector<std::string> all_fallback_locales;
  if (!application_locale.empty() && application_locale != default_locale)
    GetParentLocales(application_locale, &all_fallback_locales);
  all_fallback_locales.push_back(default_locale);

  std::vector<linked_ptr<DictionaryValue> > catalogs;
  for (size_t i = 0; i < all_fallback_locales.size(); ++i) {
    // Skip all parent locales that are not supplied.
    if (valid_locales.find(all_fallback_locales[i]) == valid_locales.end())
      continue;
    linked_ptr<DictionaryValue> catalog(
      LoadMessageFile(locale_path, all_fallback_locales[i], error));
    if (!catalog.get()) {
      // If locale is valid, but messages.json is corrupted or missing, return
      // an error.
      return false;
    } else {
      catalogs.push_back(catalog);
    }
  }

  return ExtensionMessageBundle::Create(catalogs, error);
}

void GetL10nRelativePaths(const FilePath& relative_resource_path,
                          std::vector<FilePath>* l10n_paths) {
  DCHECK(NULL != l10n_paths);

  std::string* current_locale = GetProcessLocale();
  if (current_locale->empty())
    *current_locale = l10n_util::GetApplicationLocale(L"");

  std::vector<std::string> locales;
  GetParentLocales(*current_locale, &locales);

  FilePath locale_relative_path;
  for (size_t i = 0; i < locales.size(); ++i) {
    l10n_paths->push_back(locale_relative_path
        .AppendASCII(Extension::kLocaleFolder)
        .AppendASCII(locales[i])
        .Append(relative_resource_path));
  }
}

}  // namespace extension_l10n_util
<|endoftext|>


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

// Implementation of the installation validator.

#include "chrome/installer/util/installation_validator.h"

#include <algorithm>

#include "base/logging.h"
#include "base/version.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/helper.h"
#include "chrome/installer/util/installation_state.h"

namespace installer {

BrowserDistribution::Type
    InstallationValidator::ChromeRules::distribution_type() const {
  return BrowserDistribution::CHROME_BROWSER;
}

void InstallationValidator::ChromeRules::AddProductSwitchExpectations(
    const InstallationState& machine_state,
    bool system_install,
    const ProductState& product_state,
    SwitchExpectations* expectations) const {
  const bool is_multi_install =
      product_state.uninstall_command().HasSwitch(switches::kMultiInstall);

  // --chrome should be present iff --multi-install.
  expectations->push_back(std::make_pair(std::string(switches::kChrome),
                                         is_multi_install));
  // --chrome-frame --ready-mode should be present iff CF in ready mode.
  const ProductState* cf_state =
      machine_state.GetProductState(system_install,
                                    BrowserDistribution::CHROME_FRAME);
  const bool ready_mode =
      cf_state != NULL &&
      cf_state->uninstall_command().HasSwitch(switches::kChromeFrameReadyMode);
  expectations->push_back(std::make_pair(std::string(switches::kChromeFrame),
                                         ready_mode));
  expectations->push_back(
      std::make_pair(std::string(switches::kChromeFrameReadyMode), ready_mode));
}

BrowserDistribution::Type
    InstallationValidator::ChromeFrameRules::distribution_type() const {
  return BrowserDistribution::CHROME_FRAME;
}

void InstallationValidator::ChromeFrameRules::AddProductSwitchExpectations(
    const InstallationState& machine_state,
    bool system_install,
    const ProductState& product_state,
    SwitchExpectations* expectations) const {
  // --chrome-frame must be present.
  expectations->push_back(std::make_pair(std::string(switches::kChromeFrame),
                                         true));
  // --chrome must not be present.
  expectations->push_back(std::make_pair(std::string(switches::kChrome),
                                         false));
}

// static
const InstallationValidator::InstallationType
    InstallationValidator::kInstallationTypes[] = {
  NO_PRODUCTS,
  CHROME_SINGLE,
  CHROME_MULTI,
  CHROME_FRAME_SINGLE,
  CHROME_FRAME_SINGLE_CHROME_SINGLE,
  CHROME_FRAME_SINGLE_CHROME_MULTI,
  CHROME_FRAME_MULTI,
  CHROME_FRAME_MULTI_CHROME_MULTI,
  CHROME_FRAME_READY_MODE_CHROME_MULTI
};

// Validates the multi-install binaries at level |system_level|.
void InstallationValidator::ValidateBinaries(
    const InstallationState& machine_state,
    bool system_install,
    const ProductState& binaries_state,
    bool* is_valid) {
  const ChannelInfo& channel = binaries_state.channel();

  // ap must have -multi
  if (!channel.IsMultiInstall()) {
    *is_valid = false;
    LOG(ERROR) << "Chrome Binaries are missing \"-multi\" in channel name: \""
               << channel.value() << "\"";
  }

  // ap must have -chrome iff Chrome is installed
  const ProductState* chrome_state = machine_state.GetProductState(
      system_install, BrowserDistribution::CHROME_BROWSER);
  if (chrome_state != NULL) {
    if (!channel.IsChrome()) {
      *is_valid = false;
      LOG(ERROR) << "Chrome Binaries are missing \"chrome\" in channel name:"
                 << " \"" << channel.value() << "\"";
    }
  } else if (channel.IsChrome()) {
    *is_valid = false;
    LOG(ERROR) << "Chrome Binaries have \"-chrome\" in channel name, yet Chrome"
                  " is not installed: \"" << channel.value() << "\"";
  }

  // ap must have -chromeframe iff Chrome Frame is installed multi
  const ProductState* cf_state = machine_state.GetProductState(
      system_install, BrowserDistribution::CHROME_FRAME);
  if (cf_state != NULL && cf_state->is_multi_install()) {
    if (!channel.IsChromeFrame()) {
      *is_valid = false;
      LOG(ERROR) << "Chrome Binaries are missing \"-chromeframe\" in channel"
                    " name: \"" << channel.value() << "\"";
    }
  } else if (channel.IsChromeFrame()) {
    *is_valid = false;
    LOG(ERROR) << "Chrome Binaries have \"-chromeframe\" in channel name, yet "
                  "Chrome Frame is not installed multi: \"" << channel.value()
               << "\"";
  }

  // ap must have -readymode iff Chrome Frame is installed in ready-mode
  if (cf_state != NULL &&
      cf_state->uninstall_command().HasSwitch(
          installer::switches::kChromeFrameReadyMode)) {
    if (!channel.IsReadyMode()) {
      *is_valid = false;
      LOG(ERROR) << "Chrome Binaries are missing \"-readymode\" in channel"
                    " name: \"" << channel.value() << "\"";
    }
  } else if (channel.IsReadyMode()) {
    *is_valid = false;
    LOG(ERROR) << "Chrome Binaries have \"-readymode\" in channel name, yet "
                  "Chrome Frame is not in ready mode: \"" << channel.value()
               << "\"";
  }

  // Chrome or Chrome Frame must be present
  if (chrome_state == NULL && cf_state == NULL) {
    *is_valid = false;
    LOG(ERROR) << "Chrome Binaries are present with no other products.";
  }

  // Chrome must be multi-install if present.
  if (chrome_state != NULL && !chrome_state->is_multi_install()) {
    *is_valid = false;
    LOG(ERROR)
        << "Chrome Binaries are present yet Chrome is not multi-install.";
  }

  // Chrome Frame must be multi-install if Chrome is not present.
  if (cf_state != NULL && chrome_state == NULL &&
      !cf_state->is_multi_install()) {
    *is_valid = false;
    LOG(ERROR) << "Chrome Binaries are present without Chrome yet Chrome Frame "
                  "is not multi-install.";
  }
}

// Validates the path to |setup_exe| for the product described by |ctx|.
void InstallationValidator::ValidateSetupPath(const ProductContext& ctx,
                                              const FilePath& setup_exe,
                                              const char* purpose,
                                              bool* is_valid) {
  DCHECK(is_valid);

  BrowserDistribution* bins_dist = ctx.dist;
  if (ctx.state.is_multi_install()) {
    bins_dist = BrowserDistribution::GetSpecificDistribution(
        BrowserDistribution::CHROME_BINARIES);
  }

  FilePath expected_path = installer::GetChromeInstallPath(ctx.system_install,
                                                           bins_dist);
  expected_path = expected_path
      .AppendASCII(ctx.state.version().GetString())
      .Append(installer::kInstallerDir)
      .Append(installer::kSetupExe);
  if (!FilePath::CompareEqualIgnoreCase(expected_path.value(),
                                        setup_exe.value())) {
    *is_valid = false;
    LOG(ERROR) << ctx.dist->GetApplicationName() << " path to " << purpose
               << " is not " << expected_path.value() << ": "
               << setup_exe.value();
  }
}

// Validates that |command| meets the expectations described in |expected|.
void InstallationValidator::ValidateCommandExpectations(
    const ProductContext& ctx,
    const CommandLine& command,
    const SwitchExpectations& expected,
    const char* source,
    bool* is_valid) {
  for (SwitchExpectations::size_type i = 0, size = expected.size(); i < size;
       ++i) {
    const SwitchExpectations::value_type& expectation = expected[i];
    if (command.HasSwitch(expectation.first) != expectation.second) {
      *is_valid = false;
      LOG(ERROR) << ctx.dist->GetApplicationName() << " " << source
                 << (expectation.second ? " is missing" : " has") << " \""
                 << expectation.first << "\""
                 << (expectation.second ? "" : " but shouldn't") << ": "
                 << command.command_line_string();
    }
  }
}

// Validates that |command|, originating from |source|, is formed properly for
// the product described by |ctx|
void InstallationValidator::ValidateUninstallCommand(const ProductContext& ctx,
                                                     const CommandLine& command,
                                                     const char* source,
                                                     bool* is_valid) {
  DCHECK(is_valid);

  ValidateSetupPath(ctx, command.GetProgram(), "uninstaller", is_valid);

  const bool is_multi_install = ctx.state.is_multi_install();
  SwitchExpectations expected;

  expected.push_back(std::make_pair(std::string(switches::kUninstall), true));
  expected.push_back(std::make_pair(std::string(switches::kSystemLevel),
                                    ctx.system_install));
  expected.push_back(std::make_pair(std::string(switches::kMultiInstall),
                                    is_multi_install));
  ctx.rules.AddProductSwitchExpectations(ctx.machine_state,
                                         ctx.system_install,
                                         ctx.state, &expected);

  ValidateCommandExpectations(ctx, command, expected, source, is_valid);
}

// Validates the rename command for the product described by |ctx|.
void InstallationValidator::ValidateRenameCommand(const ProductContext& ctx,
                                                  bool* is_valid) {
  DCHECK(is_valid);
  DCHECK(!ctx.state.rename_cmd().empty());

  CommandLine command = CommandLine::FromString(ctx.state.rename_cmd());

  ValidateSetupPath(ctx, command.GetProgram(), "in-use renamer", is_valid);

  SwitchExpectations expected;

  expected.push_back(std::make_pair(std::string(switches::kRenameChromeExe),
                                    true));
  expected.push_back(std::make_pair(std::string(switches::kSystemLevel),
                                    ctx.system_install));
  expected.push_back(std::make_pair(std::string(switches::kMultiInstall),
                                    ctx.state.is_multi_install()));
  ctx.rules.AddProductSwitchExpectations(ctx.machine_state,
                                         ctx.system_install,
                                         ctx.state, &expected);

  ValidateCommandExpectations(ctx, command, expected, "in-use renamer",
                              is_valid);
}

// Validates the "opv" and "cmd" values for the product described in |ctx|.
void InstallationValidator::ValidateOldVersionValues(
    const ProductContext& ctx,
    bool* is_valid) {
  DCHECK(is_valid);

  // opv and cmd must both be present or both absent
  if (ctx.state.old_version() == NULL) {
    if (!ctx.state.rename_cmd().empty()) {
      *is_valid = false;
      LOG(ERROR) << ctx.dist->GetApplicationName()
                 << " has a rename command but no opv: "
                 << ctx.state.rename_cmd();
    }
  } else {
    if (ctx.state.rename_cmd().empty()) {
      *is_valid = false;
      LOG(ERROR) << ctx.dist->GetApplicationName()
                 << " has an opv but no rename command: "
                 << ctx.state.old_version()->GetString();
    } else {
      ValidateRenameCommand(ctx, is_valid);
    }
  }
}

// Validates the multi-install state of the product described in |ctx|.
void InstallationValidator::ValidateMultiInstallProduct(
    const ProductContext& ctx,
    bool* is_valid) {
  DCHECK(is_valid);

  const ProductState* binaries =
      ctx.machine_state.GetProductState(ctx.system_install,
                                        BrowserDistribution::CHROME_BINARIES);
  DCHECK(binaries);

  // Version must match that of binaries.
  if (ctx.state.version().CompareTo(binaries->version()) != 0) {
    *is_valid = false;
    LOG(ERROR) << "Version of " << ctx.dist->GetApplicationName()
               << " (" << ctx.state.version().GetString() << ") does not "
                  "match that of Chrome Binaries ("
               << binaries->version().GetString() << ").";
  }

  // Channel value must match that of binaries.
  if (!ctx.state.channel().Equals(binaries->channel())) {
    *is_valid = false;
    LOG(ERROR) << "Channel name of " << ctx.dist->GetApplicationName()
               << " (" << ctx.state.channel().value()
               << ") does not match that of Chrome Binaries ("
               << binaries->channel().value() << ").";
  }
}

// Validates the product described in |product_state| according to |rules|.
void InstallationValidator::ValidateProduct(
    const InstallationState& machine_state,
    bool system_install,
    const ProductState& product_state,
    const ProductRules& rules,
    bool* is_valid) {
  DCHECK(is_valid);
  ProductContext ctx = {
    machine_state,
    system_install,
    BrowserDistribution::GetSpecificDistribution(rules.distribution_type()),
    product_state,
    rules
  };

  ValidateUninstallCommand(ctx, product_state.uninstall_command(),
                           "Google Update uninstall command", is_valid);

  ValidateOldVersionValues(ctx, is_valid);

  if (product_state.is_multi_install())
    ValidateMultiInstallProduct(ctx, is_valid);
}

// static
bool InstallationValidator::ValidateInstallationTypeForState(
    const InstallationState& machine_state,
    bool system_level,
    InstallationType* type) {
  DCHECK(type);
  bool rock_on = true;
  *type = NO_PRODUCTS;

  // Does the system have any multi-installed products?
  const ProductState* multi_state =
      machine_state.GetProductState(system_level,
                                    BrowserDistribution::CHROME_BINARIES);
  if (multi_state != NULL)
    ValidateBinaries(machine_state, system_level, *multi_state, &rock_on);

  // Is Chrome installed?
  const ProductState* product_state =
      machine_state.GetProductState(system_level,
                                    BrowserDistribution::CHROME_BROWSER);
  if (product_state != NULL) {
    ChromeRules chrome_rules;
    ValidateProduct(machine_state, system_level, *product_state,
                    chrome_rules, &rock_on);
    *type = static_cast<InstallationType>(
        *type | (product_state->is_multi_install() ?
                 ProductBits::CHROME_MULTI :
                 ProductBits::CHROME_SINGLE));
  }

  // Is Chrome Frame installed?
  product_state =
      machine_state.GetProductState(system_level,
                                    BrowserDistribution::CHROME_FRAME);
  if (product_state != NULL) {
    ChromeFrameRules chrome_frame_rules;
    ValidateProduct(machine_state, system_level, *product_state,
                    chrome_frame_rules, &rock_on);
    int cf_bit = !product_state->is_multi_install() ?
        ProductBits::CHROME_FRAME_SINGLE :
        (product_state->uninstall_command().HasSwitch(
             switches::kChromeFrameReadyMode) ?
                 ProductBits::CHROME_FRAME_READY_MODE :
                 ProductBits::CHROME_FRAME_MULTI);
    *type = static_cast<InstallationType>(*type | cf_bit);
  }

  DCHECK_NE(std::find(&kInstallationTypes[0],
                      &kInstallationTypes[arraysize(kInstallationTypes)],
                      *type),
            &kInstallationTypes[arraysize(kInstallationTypes)])
      << "Invalid combination of products found on system (" << *type << ")";

  return rock_on;
}

// static
bool InstallationValidator::ValidateInstallationType(bool system_level,
                                                     InstallationType* type) {
  DCHECK(type);
  InstallationState machine_state;

  machine_state.Initialize();

  return ValidateInstallationTypeForState(machine_state, system_level, type);
}

}  // namespace installer
<commit_msg>Allow --chrome in a single-install's uninstall and rename commands so that mini installer tests don't cry when they evaluate M10 builds.<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.

// Implementation of the installation validator.

#include "chrome/installer/util/installation_validator.h"

#include <algorithm>

#include "base/logging.h"
#include "base/version.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/helper.h"
#include "chrome/installer/util/installation_state.h"

namespace installer {

BrowserDistribution::Type
    InstallationValidator::ChromeRules::distribution_type() const {
  return BrowserDistribution::CHROME_BROWSER;
}

void InstallationValidator::ChromeRules::AddProductSwitchExpectations(
    const InstallationState& machine_state,
    bool system_install,
    const ProductState& product_state,
    SwitchExpectations* expectations) const {
  const bool is_multi_install =
      product_state.uninstall_command().HasSwitch(switches::kMultiInstall);

  // --chrome should be present iff --multi-install.  This wasn't the case in
  // Chrome 10 (between r68996 and r72497), though, so consider it optional.

  // --chrome-frame --ready-mode should be present iff CF in ready mode.
  const ProductState* cf_state =
      machine_state.GetProductState(system_install,
                                    BrowserDistribution::CHROME_FRAME);
  const bool ready_mode =
      cf_state != NULL &&
      cf_state->uninstall_command().HasSwitch(switches::kChromeFrameReadyMode);
  expectations->push_back(std::make_pair(std::string(switches::kChromeFrame),
                                         ready_mode));
  expectations->push_back(
      std::make_pair(std::string(switches::kChromeFrameReadyMode), ready_mode));
}

BrowserDistribution::Type
    InstallationValidator::ChromeFrameRules::distribution_type() const {
  return BrowserDistribution::CHROME_FRAME;
}

void InstallationValidator::ChromeFrameRules::AddProductSwitchExpectations(
    const InstallationState& machine_state,
    bool system_install,
    const ProductState& product_state,
    SwitchExpectations* expectations) const {
  // --chrome-frame must be present.
  expectations->push_back(std::make_pair(std::string(switches::kChromeFrame),
                                         true));
  // --chrome must not be present.
  expectations->push_back(std::make_pair(std::string(switches::kChrome),
                                         false));
}

// static
const InstallationValidator::InstallationType
    InstallationValidator::kInstallationTypes[] = {
  NO_PRODUCTS,
  CHROME_SINGLE,
  CHROME_MULTI,
  CHROME_FRAME_SINGLE,
  CHROME_FRAME_SINGLE_CHROME_SINGLE,
  CHROME_FRAME_SINGLE_CHROME_MULTI,
  CHROME_FRAME_MULTI,
  CHROME_FRAME_MULTI_CHROME_MULTI,
  CHROME_FRAME_READY_MODE_CHROME_MULTI
};

// Validates the multi-install binaries at level |system_level|.
void InstallationValidator::ValidateBinaries(
    const InstallationState& machine_state,
    bool system_install,
    const ProductState& binaries_state,
    bool* is_valid) {
  const ChannelInfo& channel = binaries_state.channel();

  // ap must have -multi
  if (!channel.IsMultiInstall()) {
    *is_valid = false;
    LOG(ERROR) << "Chrome Binaries are missing \"-multi\" in channel name: \""
               << channel.value() << "\"";
  }

  // ap must have -chrome iff Chrome is installed
  const ProductState* chrome_state = machine_state.GetProductState(
      system_install, BrowserDistribution::CHROME_BROWSER);
  if (chrome_state != NULL) {
    if (!channel.IsChrome()) {
      *is_valid = false;
      LOG(ERROR) << "Chrome Binaries are missing \"chrome\" in channel name:"
                 << " \"" << channel.value() << "\"";
    }
  } else if (channel.IsChrome()) {
    *is_valid = false;
    LOG(ERROR) << "Chrome Binaries have \"-chrome\" in channel name, yet Chrome"
                  " is not installed: \"" << channel.value() << "\"";
  }

  // ap must have -chromeframe iff Chrome Frame is installed multi
  const ProductState* cf_state = machine_state.GetProductState(
      system_install, BrowserDistribution::CHROME_FRAME);
  if (cf_state != NULL && cf_state->is_multi_install()) {
    if (!channel.IsChromeFrame()) {
      *is_valid = false;
      LOG(ERROR) << "Chrome Binaries are missing \"-chromeframe\" in channel"
                    " name: \"" << channel.value() << "\"";
    }
  } else if (channel.IsChromeFrame()) {
    *is_valid = false;
    LOG(ERROR) << "Chrome Binaries have \"-chromeframe\" in channel name, yet "
                  "Chrome Frame is not installed multi: \"" << channel.value()
               << "\"";
  }

  // ap must have -readymode iff Chrome Frame is installed in ready-mode
  if (cf_state != NULL &&
      cf_state->uninstall_command().HasSwitch(
          installer::switches::kChromeFrameReadyMode)) {
    if (!channel.IsReadyMode()) {
      *is_valid = false;
      LOG(ERROR) << "Chrome Binaries are missing \"-readymode\" in channel"
                    " name: \"" << channel.value() << "\"";
    }
  } else if (channel.IsReadyMode()) {
    *is_valid = false;
    LOG(ERROR) << "Chrome Binaries have \"-readymode\" in channel name, yet "
                  "Chrome Frame is not in ready mode: \"" << channel.value()
               << "\"";
  }

  // Chrome or Chrome Frame must be present
  if (chrome_state == NULL && cf_state == NULL) {
    *is_valid = false;
    LOG(ERROR) << "Chrome Binaries are present with no other products.";
  }

  // Chrome must be multi-install if present.
  if (chrome_state != NULL && !chrome_state->is_multi_install()) {
    *is_valid = false;
    LOG(ERROR)
        << "Chrome Binaries are present yet Chrome is not multi-install.";
  }

  // Chrome Frame must be multi-install if Chrome is not present.
  if (cf_state != NULL && chrome_state == NULL &&
      !cf_state->is_multi_install()) {
    *is_valid = false;
    LOG(ERROR) << "Chrome Binaries are present without Chrome yet Chrome Frame "
                  "is not multi-install.";
  }
}

// Validates the path to |setup_exe| for the product described by |ctx|.
void InstallationValidator::ValidateSetupPath(const ProductContext& ctx,
                                              const FilePath& setup_exe,
                                              const char* purpose,
                                              bool* is_valid) {
  DCHECK(is_valid);

  BrowserDistribution* bins_dist = ctx.dist;
  if (ctx.state.is_multi_install()) {
    bins_dist = BrowserDistribution::GetSpecificDistribution(
        BrowserDistribution::CHROME_BINARIES);
  }

  FilePath expected_path = installer::GetChromeInstallPath(ctx.system_install,
                                                           bins_dist);
  expected_path = expected_path
      .AppendASCII(ctx.state.version().GetString())
      .Append(installer::kInstallerDir)
      .Append(installer::kSetupExe);
  if (!FilePath::CompareEqualIgnoreCase(expected_path.value(),
                                        setup_exe.value())) {
    *is_valid = false;
    LOG(ERROR) << ctx.dist->GetApplicationName() << " path to " << purpose
               << " is not " << expected_path.value() << ": "
               << setup_exe.value();
  }
}

// Validates that |command| meets the expectations described in |expected|.
void InstallationValidator::ValidateCommandExpectations(
    const ProductContext& ctx,
    const CommandLine& command,
    const SwitchExpectations& expected,
    const char* source,
    bool* is_valid) {
  for (SwitchExpectations::size_type i = 0, size = expected.size(); i < size;
       ++i) {
    const SwitchExpectations::value_type& expectation = expected[i];
    if (command.HasSwitch(expectation.first) != expectation.second) {
      *is_valid = false;
      LOG(ERROR) << ctx.dist->GetApplicationName() << " " << source
                 << (expectation.second ? " is missing" : " has") << " \""
                 << expectation.first << "\""
                 << (expectation.second ? "" : " but shouldn't") << ": "
                 << command.command_line_string();
    }
  }
}

// Validates that |command|, originating from |source|, is formed properly for
// the product described by |ctx|
void InstallationValidator::ValidateUninstallCommand(const ProductContext& ctx,
                                                     const CommandLine& command,
                                                     const char* source,
                                                     bool* is_valid) {
  DCHECK(is_valid);

  ValidateSetupPath(ctx, command.GetProgram(), "uninstaller", is_valid);

  const bool is_multi_install = ctx.state.is_multi_install();
  SwitchExpectations expected;

  expected.push_back(std::make_pair(std::string(switches::kUninstall), true));
  expected.push_back(std::make_pair(std::string(switches::kSystemLevel),
                                    ctx.system_install));
  expected.push_back(std::make_pair(std::string(switches::kMultiInstall),
                                    is_multi_install));
  ctx.rules.AddProductSwitchExpectations(ctx.machine_state,
                                         ctx.system_install,
                                         ctx.state, &expected);

  ValidateCommandExpectations(ctx, command, expected, source, is_valid);
}

// Validates the rename command for the product described by |ctx|.
void InstallationValidator::ValidateRenameCommand(const ProductContext& ctx,
                                                  bool* is_valid) {
  DCHECK(is_valid);
  DCHECK(!ctx.state.rename_cmd().empty());

  CommandLine command = CommandLine::FromString(ctx.state.rename_cmd());

  ValidateSetupPath(ctx, command.GetProgram(), "in-use renamer", is_valid);

  SwitchExpectations expected;

  expected.push_back(std::make_pair(std::string(switches::kRenameChromeExe),
                                    true));
  expected.push_back(std::make_pair(std::string(switches::kSystemLevel),
                                    ctx.system_install));
  expected.push_back(std::make_pair(std::string(switches::kMultiInstall),
                                    ctx.state.is_multi_install()));
  ctx.rules.AddProductSwitchExpectations(ctx.machine_state,
                                         ctx.system_install,
                                         ctx.state, &expected);

  ValidateCommandExpectations(ctx, command, expected, "in-use renamer",
                              is_valid);
}

// Validates the "opv" and "cmd" values for the product described in |ctx|.
void InstallationValidator::ValidateOldVersionValues(
    const ProductContext& ctx,
    bool* is_valid) {
  DCHECK(is_valid);

  // opv and cmd must both be present or both absent
  if (ctx.state.old_version() == NULL) {
    if (!ctx.state.rename_cmd().empty()) {
      *is_valid = false;
      LOG(ERROR) << ctx.dist->GetApplicationName()
                 << " has a rename command but no opv: "
                 << ctx.state.rename_cmd();
    }
  } else {
    if (ctx.state.rename_cmd().empty()) {
      *is_valid = false;
      LOG(ERROR) << ctx.dist->GetApplicationName()
                 << " has an opv but no rename command: "
                 << ctx.state.old_version()->GetString();
    } else {
      ValidateRenameCommand(ctx, is_valid);
    }
  }
}

// Validates the multi-install state of the product described in |ctx|.
void InstallationValidator::ValidateMultiInstallProduct(
    const ProductContext& ctx,
    bool* is_valid) {
  DCHECK(is_valid);

  const ProductState* binaries =
      ctx.machine_state.GetProductState(ctx.system_install,
                                        BrowserDistribution::CHROME_BINARIES);
  DCHECK(binaries);

  // Version must match that of binaries.
  if (ctx.state.version().CompareTo(binaries->version()) != 0) {
    *is_valid = false;
    LOG(ERROR) << "Version of " << ctx.dist->GetApplicationName()
               << " (" << ctx.state.version().GetString() << ") does not "
                  "match that of Chrome Binaries ("
               << binaries->version().GetString() << ").";
  }

  // Channel value must match that of binaries.
  if (!ctx.state.channel().Equals(binaries->channel())) {
    *is_valid = false;
    LOG(ERROR) << "Channel name of " << ctx.dist->GetApplicationName()
               << " (" << ctx.state.channel().value()
               << ") does not match that of Chrome Binaries ("
               << binaries->channel().value() << ").";
  }
}

// Validates the product described in |product_state| according to |rules|.
void InstallationValidator::ValidateProduct(
    const InstallationState& machine_state,
    bool system_install,
    const ProductState& product_state,
    const ProductRules& rules,
    bool* is_valid) {
  DCHECK(is_valid);
  ProductContext ctx = {
    machine_state,
    system_install,
    BrowserDistribution::GetSpecificDistribution(rules.distribution_type()),
    product_state,
    rules
  };

  ValidateUninstallCommand(ctx, product_state.uninstall_command(),
                           "Google Update uninstall command", is_valid);

  ValidateOldVersionValues(ctx, is_valid);

  if (product_state.is_multi_install())
    ValidateMultiInstallProduct(ctx, is_valid);
}

// static
bool InstallationValidator::ValidateInstallationTypeForState(
    const InstallationState& machine_state,
    bool system_level,
    InstallationType* type) {
  DCHECK(type);
  bool rock_on = true;
  *type = NO_PRODUCTS;

  // Does the system have any multi-installed products?
  const ProductState* multi_state =
      machine_state.GetProductState(system_level,
                                    BrowserDistribution::CHROME_BINARIES);
  if (multi_state != NULL)
    ValidateBinaries(machine_state, system_level, *multi_state, &rock_on);

  // Is Chrome installed?
  const ProductState* product_state =
      machine_state.GetProductState(system_level,
                                    BrowserDistribution::CHROME_BROWSER);
  if (product_state != NULL) {
    ChromeRules chrome_rules;
    ValidateProduct(machine_state, system_level, *product_state,
                    chrome_rules, &rock_on);
    *type = static_cast<InstallationType>(
        *type | (product_state->is_multi_install() ?
                 ProductBits::CHROME_MULTI :
                 ProductBits::CHROME_SINGLE));
  }

  // Is Chrome Frame installed?
  product_state =
      machine_state.GetProductState(system_level,
                                    BrowserDistribution::CHROME_FRAME);
  if (product_state != NULL) {
    ChromeFrameRules chrome_frame_rules;
    ValidateProduct(machine_state, system_level, *product_state,
                    chrome_frame_rules, &rock_on);
    int cf_bit = !product_state->is_multi_install() ?
        ProductBits::CHROME_FRAME_SINGLE :
        (product_state->uninstall_command().HasSwitch(
             switches::kChromeFrameReadyMode) ?
                 ProductBits::CHROME_FRAME_READY_MODE :
                 ProductBits::CHROME_FRAME_MULTI);
    *type = static_cast<InstallationType>(*type | cf_bit);
  }

  DCHECK_NE(std::find(&kInstallationTypes[0],
                      &kInstallationTypes[arraysize(kInstallationTypes)],
                      *type),
            &kInstallationTypes[arraysize(kInstallationTypes)])
      << "Invalid combination of products found on system (" << *type << ")";

  return rock_on;
}

// static
bool InstallationValidator::ValidateInstallationType(bool system_level,
                                                     InstallationType* type) {
  DCHECK(type);
  InstallationState machine_state;

  machine_state.Initialize();

  return ValidateInstallationTypeForState(machine_state, system_level, type);
}

}  // namespace installer
<|endoftext|>