<commit_before>//===-- BuildSystemCommand.cpp --------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "llbuild/Commands/Commands.h"

#include "llbuild/Basic/LLVM.h"
#include "llbuild/BuildSystem/BuildFile.h"
#include "llbuild/BuildSystem/BuildSystem.h"
#include "llbuild/BuildSystem/BuildSystemFrontend.h"
#include "llbuild/BuildSystem/BuildValue.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"

#include "CommandUtil.h"

#include <cerrno>

using namespace llbuild;
using namespace llbuild::commands;
using namespace llbuild::core;
using namespace llbuild::buildsystem;

namespace {

/*  Parse Command */

class ParseBuildFileDelegate : public BuildFileDelegate {
  bool showOutput;
  StringRef bufferBeingParsed;

public:
  ParseBuildFileDelegate(bool showOutput) : showOutput(showOutput) {}
  ~ParseBuildFileDelegate() {}

  virtual bool shouldShowOutput() { return showOutput; }

  virtual void setFileContentsBeingParsed(StringRef buffer) override;

  virtual void error(StringRef filename,
                     const BuildFileToken& at,
                     const Twine& message) override;

  virtual bool configureClient(const ConfigureContext&, StringRef name,
                               uint32_t version,
                               const property_list_type& properties) override;

  virtual std::unique_ptr<Tool> lookupTool(StringRef name) override;

  virtual void loadedTarget(StringRef name,
                            const Target& target) override;

  virtual std::unique_ptr<Node> lookupNode(StringRef name,
                                           bool isImplicit) override;

  virtual void loadedCommand(StringRef name,
                             const Command& command) override;
};

class ParseDummyNode : public Node {
  ParseBuildFileDelegate& delegate;

public:
  ParseDummyNode(ParseBuildFileDelegate& delegate, StringRef name)
      : Node(name), delegate(delegate) {}

  virtual bool configureAttribute(const ConfigureContext&, StringRef name,
                                  StringRef value) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- '%s': '%s'\n", name.str().c_str(), value.str().c_str());
    }
    return true;
  }

  virtual bool configureAttribute(const ConfigureContext&, StringRef name,
                                  ArrayRef<StringRef> values) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- '%s': [", name.str().c_str());
      bool first = true;
      for (const auto& value: values) {
        printf("%s'%s'", first ? "" : ", ", value.str().c_str());
        first = false;
      }
      printf("]\n");
    }
    return true;
  }
};

class ParseDummyCommand : public Command {
  ParseBuildFileDelegate& delegate;

public:
  ParseDummyCommand(ParseBuildFileDelegate& delegate, StringRef name)
      : Command(name), delegate(delegate) {}

  virtual void configureDescription(const ConfigureContext&, StringRef description) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- 'description': '%s'", description.str().c_str());
    }
  }

  virtual void configureInputs(const ConfigureContext&, const std::vector<Node*>& inputs) override {
    if (delegate.shouldShowOutput()) {
      bool first = true;
      printf("  -- 'inputs': [");
      for (const auto& node: inputs) {
        printf("%s'%s'", first ? "" : ", ", node->getName().str().c_str());
        first = false;
      }
      printf("]\n");
    }
  }

  virtual void configureOutputs(const ConfigureContext&, const std::vector<Node*>& outputs) override {
    if (delegate.shouldShowOutput()) {
      bool first = true;
      printf("  -- 'outputs': [");
      for (const auto& node: outputs) {
        printf("%s'%s'", first ? "" : ", ", node->getName().str().c_str());
        first = false;
      }
      printf("]\n");
    }
  }

  virtual bool configureAttribute(const ConfigureContext&, StringRef name,
                                  StringRef value) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- '%s': '%s'\n", name.str().c_str(), value.str().c_str());
    }
    return true;
  }
  virtual bool configureAttribute(const ConfigureContext&, StringRef name,
                                  ArrayRef<StringRef> values) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- '%s': [", name.str().c_str());
      bool first = true;
      for (const auto& value: values) {
        printf("%s'%s'", first ? "" : ", ", value.str().c_str());
        first = false;
      }
      printf("]\n");
    }
    return true;
  }

  virtual BuildValue getResultForOutput(Node* node,
                                        const BuildValue& value) override {
    return BuildValue::makeMissingInput();
  }
  virtual bool isResultValid(const BuildValue&) override { return false; }
  virtual void start(BuildSystemCommandInterface&, Task*) override {}
  virtual void providePriorValue(BuildSystemCommandInterface&, Task*,
                                 const BuildValue&) override {}
  virtual void provideValue(BuildSystemCommandInterface&, Task*,
                                 uintptr_t inputID,
                                 const BuildValue&) override {}
  virtual void inputsAvailable(BuildSystemCommandInterface&, Task*) override {}
};

class ParseDummyTool : public Tool {
  ParseBuildFileDelegate& delegate;

public:
  ParseDummyTool(ParseBuildFileDelegate& delegate, StringRef name)
      : Tool(name), delegate(delegate) {}

  virtual bool configureAttribute(const ConfigureContext&, StringRef name,
                                  StringRef value) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- '%s': '%s'\n", name.str().c_str(), value.str().c_str());
    }
    return true;
  }
  virtual bool configureAttribute(const ConfigureContext&, StringRef name,
                                  ArrayRef<StringRef> values) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- '%s': [", name.str().c_str());
      bool first = true;
      for (const auto& value: values) {
        printf("%s'%s'", first ? "" : ", ", value.str().c_str());
        first = false;
      }
      printf("]\n");
    }
    return true;
  }

  virtual std::unique_ptr<Command> createCommand(
      StringRef name) override {
    if (delegate.shouldShowOutput()) {
      printf("command('%s')\n", name.str().c_str());
      printf("  -- 'tool': '%s')\n", getName().str().c_str());
    }

    return llvm::make_unique<ParseDummyCommand>(delegate, name);
  }
};

void ParseBuildFileDelegate::setFileContentsBeingParsed(StringRef buffer) {
  bufferBeingParsed = buffer;
}

void ParseBuildFileDelegate::error(StringRef filename,
                                   const BuildFileToken& at,
                                   const Twine& message) {
  if (at.start) {
    util::emitError(filename, message.str(), at.start, at.length,
                    bufferBeingParsed);
  } else {
    fprintf(stderr, "%s: error: %s\n", filename.str().c_str(),
            message.str().c_str());
  }
}

bool
ParseBuildFileDelegate::configureClient(const ConfigureContext&,
                                        StringRef name,
                                        uint32_t version,
                                        const property_list_type& properties) {
  if (showOutput) {
    // Dump the client information.
    printf("client ('%s', version: %u)\n", name.str().c_str(), version);
    for (const auto& property: properties) {
      printf("  -- '%s': '%s'\n", property.first.c_str(),
             property.second.c_str());
    }
  }

  return true;
}

std::unique_ptr<Tool>
ParseBuildFileDelegate::lookupTool(StringRef name) {
  if (showOutput) {
    printf("tool('%s')\n", name.str().c_str());
  }

  return llvm::make_unique<ParseDummyTool>(*this, name);
}

void ParseBuildFileDelegate::loadedTarget(StringRef name,
                                          const Target& target) {
  if (showOutput) {
    printf("target('%s')\n", target.getName().str().c_str());

    // Print the nodes in the target.
    bool first = true;
    printf(" -- nodes: [");
    for (const auto& node: target.getNodes()) {
      printf("%s'%s'", first ? "" : ", ", node->getName().str().c_str());
      first = false;
    }
    printf("]\n");
  }
}

std::unique_ptr<Node>
ParseBuildFileDelegate::lookupNode(StringRef name,
                                   bool isImplicit) {
  if (!isImplicit) {
    if (showOutput) {
      printf("node('%s')\n", name.str().c_str());
    }
  }

  return llvm::make_unique<ParseDummyNode>(*this, name);
}

void ParseBuildFileDelegate::loadedCommand(StringRef name,
                                        const Command& command) {
  if (showOutput) {
    printf("  -- -- loaded command('%s')\n", command.getName().str().c_str());
  }
}

static void parseUsage(int exitCode) {
  int optionWidth = 20;
  fprintf(stderr, "Usage: %s buildsystem parse [options] <path>\n",
          getProgramName());
  fprintf(stderr, "\nOptions:\n");
  fprintf(stderr, "  %-*s %s\n", optionWidth, "--help",
          "show this help message and exit");
  fprintf(stderr, "  %-*s %s\n", optionWidth, "--no-output",
          "don't display parser output");
  ::exit(exitCode);
}

static int executeParseCommand(std::vector<std::string> args) {
  bool showOutput = true;

  while (!args.empty() && args[0][0] == '-') {
    const std::string option = args[0];
    args.erase(args.begin());

    if (option == "--")
      break;

    if (option == "--help") {
      parseUsage(0);
    } else if (option == "--no-output") {
      showOutput = false;
    } else {
      fprintf(stderr, "\error: %s: invalid option: '%s'\n\n",
              getProgramName(), option.c_str());
      parseUsage(1);
    }
  }

  if (args.size() != 1) {
    fprintf(stderr, "error: %s: invalid number of arguments\n", getProgramName());
    parseUsage(1);
  }

  std::string filename = args[0].c_str();

  // Load the BuildFile.
  fprintf(stderr, "note: parsing '%s'\n", filename.c_str());
  ParseBuildFileDelegate delegate(showOutput);
  BuildFile buildFile(filename, delegate);
  buildFile.load();

  return 0;
}

/* Build Command */

class BasicBuildSystemFrontendDelegate : public BuildSystemFrontendDelegate {
public:
  BasicBuildSystemFrontendDelegate(llvm::SourceMgr& sourceMgr,
                                   const BuildSystemInvocation& invocation)
      : BuildSystemFrontendDelegate(sourceMgr, invocation,
                                    "basic", /*version=*/0) {}

  virtual std::unique_ptr<Tool> lookupTool(StringRef name) override {
    // We do not support any non-built-in tools.
    return nullptr;
  }
};

static void buildUsage(int exitCode) {
  int optionWidth = 25;
  fprintf(stderr, "Usage: %s buildsystem build [options] [<target>]\n",
          getProgramName());
  fprintf(stderr, "\nOptions:\n");
  BuildSystemInvocation::getUsage(optionWidth, llvm::errs());
  ::exit(exitCode);
}

static int executeBuildCommand(std::vector<std::string> args) {
  // The source manager to use for diagnostics.
  llvm::SourceMgr sourceMgr;

  // Create the invocation.
  BuildSystemInvocation invocation{};

  // Initialize defaults.
  invocation.dbPath = "build.db";
  invocation.buildFilePath = "build.llbuild";
  invocation.parse(args, sourceMgr);

  // Handle invocation actions.
  if (invocation.showUsage) {
    buildUsage(0);
  } else if (invocation.hadErrors) {
    buildUsage(1);
  }

  if (invocation.positionalArgs.size() > 1) {
    fprintf(stderr, "error: %s: invalid number of arguments\n",
            getProgramName());
    buildUsage(1);
  }

  // Select the target to build.
  std::string targetToBuild =
    invocation.positionalArgs.empty() ? "" : invocation.positionalArgs[0];

  // Create the frontend object.
  BasicBuildSystemFrontendDelegate delegate(sourceMgr, invocation);
  BuildSystemFrontend frontend(delegate, invocation);
  if (!frontend.build(targetToBuild)) {
    return 1;
  }

  return 0;
}

}

#pragma mark - Build System Top-Level Command

static void usage(int exitCode) {
  fprintf(stderr, "Usage: %s buildsystem [--help] <command> [<args>]\n",
          getProgramName());
  fprintf(stderr, "\n");
  fprintf(stderr, "Available commands:\n");
  fprintf(stderr, "  parse         -- Parse a build file\n");
  fprintf(stderr, "  build         -- Build using a build file\n");
  fprintf(stderr, "\n");
  exit(exitCode);
}

int commands::executeBuildSystemCommand(const std::vector<std::string> &args) {
  // Expect the first argument to be the name of another subtool to delegate to.
  if (args.empty() || args[0] == "--help")
    usage(0);

  if (args[0] == "parse") {
    return executeParseCommand({args.begin()+1, args.end()});
  } else if (args[0] == "build") {
    return executeBuildCommand({args.begin()+1, args.end()});
  } else {
    fprintf(stderr, "error: %s: unknown command '%s'\n", getProgramName(),
            args[0].c_str());
    usage(1);
    return 1;
  }
}
<commit_msg>[Commands] Fix 80-col violas.<commit_after>//===-- BuildSystemCommand.cpp --------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "llbuild/Commands/Commands.h"

#include "llbuild/Basic/LLVM.h"
#include "llbuild/BuildSystem/BuildFile.h"
#include "llbuild/BuildSystem/BuildSystem.h"
#include "llbuild/BuildSystem/BuildSystemFrontend.h"
#include "llbuild/BuildSystem/BuildValue.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"

#include "CommandUtil.h"

#include <cerrno>

using namespace llbuild;
using namespace llbuild::commands;
using namespace llbuild::core;
using namespace llbuild::buildsystem;

namespace {

/*  Parse Command */

class ParseBuildFileDelegate : public BuildFileDelegate {
  bool showOutput;
  StringRef bufferBeingParsed;

public:
  ParseBuildFileDelegate(bool showOutput) : showOutput(showOutput) {}
  ~ParseBuildFileDelegate() {}

  virtual bool shouldShowOutput() { return showOutput; }

  virtual void setFileContentsBeingParsed(StringRef buffer) override;

  virtual void error(StringRef filename,
                     const BuildFileToken& at,
                     const Twine& message) override;

  virtual bool configureClient(const ConfigureContext&, StringRef name,
                               uint32_t version,
                               const property_list_type& properties) override;

  virtual std::unique_ptr<Tool> lookupTool(StringRef name) override;

  virtual void loadedTarget(StringRef name,
                            const Target& target) override;

  virtual std::unique_ptr<Node> lookupNode(StringRef name,
                                           bool isImplicit) override;

  virtual void loadedCommand(StringRef name,
                             const Command& command) override;
};

class ParseDummyNode : public Node {
  ParseBuildFileDelegate& delegate;

public:
  ParseDummyNode(ParseBuildFileDelegate& delegate, StringRef name)
      : Node(name), delegate(delegate) {}

  virtual bool configureAttribute(const ConfigureContext&, StringRef name,
                                  StringRef value) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- '%s': '%s'\n", name.str().c_str(), value.str().c_str());
    }
    return true;
  }

  virtual bool configureAttribute(const ConfigureContext&, StringRef name,
                                  ArrayRef<StringRef> values) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- '%s': [", name.str().c_str());
      bool first = true;
      for (const auto& value: values) {
        printf("%s'%s'", first ? "" : ", ", value.str().c_str());
        first = false;
      }
      printf("]\n");
    }
    return true;
  }
};

class ParseDummyCommand : public Command {
  ParseBuildFileDelegate& delegate;

public:
  ParseDummyCommand(ParseBuildFileDelegate& delegate, StringRef name)
      : Command(name), delegate(delegate) {}

  virtual void configureDescription(const ConfigureContext&,
                                    StringRef description) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- 'description': '%s'", description.str().c_str());
    }
  }

  virtual void configureInputs(const ConfigureContext&,
                               const std::vector<Node*>& inputs) override {
    if (delegate.shouldShowOutput()) {
      bool first = true;
      printf("  -- 'inputs': [");
      for (const auto& node: inputs) {
        printf("%s'%s'", first ? "" : ", ", node->getName().str().c_str());
        first = false;
      }
      printf("]\n");
    }
  }

  virtual void configureOutputs(const ConfigureContext&,
                                const std::vector<Node*>& outputs) override {
    if (delegate.shouldShowOutput()) {
      bool first = true;
      printf("  -- 'outputs': [");
      for (const auto& node: outputs) {
        printf("%s'%s'", first ? "" : ", ", node->getName().str().c_str());
        first = false;
      }
      printf("]\n");
    }
  }

  virtual bool configureAttribute(const ConfigureContext&, StringRef name,
                                  StringRef value) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- '%s': '%s'\n", name.str().c_str(), value.str().c_str());
    }
    return true;
  }
  virtual bool configureAttribute(const ConfigureContext&, StringRef name,
                                  ArrayRef<StringRef> values) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- '%s': [", name.str().c_str());
      bool first = true;
      for (const auto& value: values) {
        printf("%s'%s'", first ? "" : ", ", value.str().c_str());
        first = false;
      }
      printf("]\n");
    }
    return true;
  }

  virtual BuildValue getResultForOutput(Node* node,
                                        const BuildValue& value) override {
    return BuildValue::makeMissingInput();
  }
  virtual bool isResultValid(const BuildValue&) override { return false; }
  virtual void start(BuildSystemCommandInterface&, Task*) override {}
  virtual void providePriorValue(BuildSystemCommandInterface&, Task*,
                                 const BuildValue&) override {}
  virtual void provideValue(BuildSystemCommandInterface&, Task*,
                                 uintptr_t inputID,
                                 const BuildValue&) override {}
  virtual void inputsAvailable(BuildSystemCommandInterface&, Task*) override {}
};

class ParseDummyTool : public Tool {
  ParseBuildFileDelegate& delegate;

public:
  ParseDummyTool(ParseBuildFileDelegate& delegate, StringRef name)
      : Tool(name), delegate(delegate) {}

  virtual bool configureAttribute(const ConfigureContext&, StringRef name,
                                  StringRef value) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- '%s': '%s'\n", name.str().c_str(), value.str().c_str());
    }
    return true;
  }
  virtual bool configureAttribute(const ConfigureContext&, StringRef name,
                                  ArrayRef<StringRef> values) override {
    if (delegate.shouldShowOutput()) {
      printf("  -- '%s': [", name.str().c_str());
      bool first = true;
      for (const auto& value: values) {
        printf("%s'%s'", first ? "" : ", ", value.str().c_str());
        first = false;
      }
      printf("]\n");
    }
    return true;
  }

  virtual std::unique_ptr<Command> createCommand(
      StringRef name) override {
    if (delegate.shouldShowOutput()) {
      printf("command('%s')\n", name.str().c_str());
      printf("  -- 'tool': '%s')\n", getName().str().c_str());
    }

    return llvm::make_unique<ParseDummyCommand>(delegate, name);
  }
};

void ParseBuildFileDelegate::setFileContentsBeingParsed(StringRef buffer) {
  bufferBeingParsed = buffer;
}

void ParseBuildFileDelegate::error(StringRef filename,
                                   const BuildFileToken& at,
                                   const Twine& message) {
  if (at.start) {
    util::emitError(filename, message.str(), at.start, at.length,
                    bufferBeingParsed);
  } else {
    fprintf(stderr, "%s: error: %s\n", filename.str().c_str(),
            message.str().c_str());
  }
}

bool
ParseBuildFileDelegate::configureClient(const ConfigureContext&,
                                        StringRef name,
                                        uint32_t version,
                                        const property_list_type& properties) {
  if (showOutput) {
    // Dump the client information.
    printf("client ('%s', version: %u)\n", name.str().c_str(), version);
    for (const auto& property: properties) {
      printf("  -- '%s': '%s'\n", property.first.c_str(),
             property.second.c_str());
    }
  }

  return true;
}

std::unique_ptr<Tool>
ParseBuildFileDelegate::lookupTool(StringRef name) {
  if (showOutput) {
    printf("tool('%s')\n", name.str().c_str());
  }

  return llvm::make_unique<ParseDummyTool>(*this, name);
}

void ParseBuildFileDelegate::loadedTarget(StringRef name,
                                          const Target& target) {
  if (showOutput) {
    printf("target('%s')\n", target.getName().str().c_str());

    // Print the nodes in the target.
    bool first = true;
    printf(" -- nodes: [");
    for (const auto& node: target.getNodes()) {
      printf("%s'%s'", first ? "" : ", ", node->getName().str().c_str());
      first = false;
    }
    printf("]\n");
  }
}

std::unique_ptr<Node>
ParseBuildFileDelegate::lookupNode(StringRef name,
                                   bool isImplicit) {
  if (!isImplicit) {
    if (showOutput) {
      printf("node('%s')\n", name.str().c_str());
    }
  }

  return llvm::make_unique<ParseDummyNode>(*this, name);
}

void ParseBuildFileDelegate::loadedCommand(StringRef name,
                                        const Command& command) {
  if (showOutput) {
    printf("  -- -- loaded command('%s')\n", command.getName().str().c_str());
  }
}

static void parseUsage(int exitCode) {
  int optionWidth = 20;
  fprintf(stderr, "Usage: %s buildsystem parse [options] <path>\n",
          getProgramName());
  fprintf(stderr, "\nOptions:\n");
  fprintf(stderr, "  %-*s %s\n", optionWidth, "--help",
          "show this help message and exit");
  fprintf(stderr, "  %-*s %s\n", optionWidth, "--no-output",
          "don't display parser output");
  ::exit(exitCode);
}

static int executeParseCommand(std::vector<std::string> args) {
  bool showOutput = true;

  while (!args.empty() && args[0][0] == '-') {
    const std::string option = args[0];
    args.erase(args.begin());

    if (option == "--")
      break;

    if (option == "--help") {
      parseUsage(0);
    } else if (option == "--no-output") {
      showOutput = false;
    } else {
      fprintf(stderr, "\error: %s: invalid option: '%s'\n\n",
              getProgramName(), option.c_str());
      parseUsage(1);
    }
  }

  if (args.size() != 1) {
    fprintf(stderr, "error: %s: invalid number of arguments\n",
            getProgramName());
    parseUsage(1);
  }

  std::string filename = args[0].c_str();

  // Load the BuildFile.
  fprintf(stderr, "note: parsing '%s'\n", filename.c_str());
  ParseBuildFileDelegate delegate(showOutput);
  BuildFile buildFile(filename, delegate);
  buildFile.load();

  return 0;
}

/* Build Command */

class BasicBuildSystemFrontendDelegate : public BuildSystemFrontendDelegate {
public:
  BasicBuildSystemFrontendDelegate(llvm::SourceMgr& sourceMgr,
                                   const BuildSystemInvocation& invocation)
      : BuildSystemFrontendDelegate(sourceMgr, invocation,
                                    "basic", /*version=*/0) {}

  virtual std::unique_ptr<Tool> lookupTool(StringRef name) override {
    // We do not support any non-built-in tools.
    return nullptr;
  }
};

static void buildUsage(int exitCode) {
  int optionWidth = 25;
  fprintf(stderr, "Usage: %s buildsystem build [options] [<target>]\n",
          getProgramName());
  fprintf(stderr, "\nOptions:\n");
  BuildSystemInvocation::getUsage(optionWidth, llvm::errs());
  ::exit(exitCode);
}

static int executeBuildCommand(std::vector<std::string> args) {
  // The source manager to use for diagnostics.
  llvm::SourceMgr sourceMgr;

  // Create the invocation.
  BuildSystemInvocation invocation{};

  // Initialize defaults.
  invocation.dbPath = "build.db";
  invocation.buildFilePath = "build.llbuild";
  invocation.parse(args, sourceMgr);

  // Handle invocation actions.
  if (invocation.showUsage) {
    buildUsage(0);
  } else if (invocation.hadErrors) {
    buildUsage(1);
  }

  if (invocation.positionalArgs.size() > 1) {
    fprintf(stderr, "error: %s: invalid number of arguments\n",
            getProgramName());
    buildUsage(1);
  }

  // Select the target to build.
  std::string targetToBuild =
    invocation.positionalArgs.empty() ? "" : invocation.positionalArgs[0];

  // Create the frontend object.
  BasicBuildSystemFrontendDelegate delegate(sourceMgr, invocation);
  BuildSystemFrontend frontend(delegate, invocation);
  if (!frontend.build(targetToBuild)) {
    return 1;
  }

  return 0;
}

}

#pragma mark - Build System Top-Level Command

static void usage(int exitCode) {
  fprintf(stderr, "Usage: %s buildsystem [--help] <command> [<args>]\n",
          getProgramName());
  fprintf(stderr, "\n");
  fprintf(stderr, "Available commands:\n");
  fprintf(stderr, "  parse         -- Parse a build file\n");
  fprintf(stderr, "  build         -- Build using a build file\n");
  fprintf(stderr, "\n");
  exit(exitCode);
}

int commands::executeBuildSystemCommand(const std::vector<std::string> &args) {
  // Expect the first argument to be the name of another subtool to delegate to.
  if (args.empty() || args[0] == "--help")
    usage(0);

  if (args[0] == "parse") {
    return executeParseCommand({args.begin()+1, args.end()});
  } else if (args[0] == "build") {
    return executeBuildCommand({args.begin()+1, args.end()});
  } else {
    fprintf(stderr, "error: %s: unknown command '%s'\n", getProgramName(),
            args[0].c_str());
    usage(1);
    return 1;
  }
}
<|endoftext|>


<commit_before>// CS3230-PA1-DE
// Multiplication of 2 n-digit integers.
// Naive O(n^2) multiplication algorithm (Karatsuba + Long Multiplication)
// Name: Tay Yang Shun

#include <sys/time.h>
#include <sys/resource.h>
#include <iostream>
#include <sstream>
#include <math.h>

using namespace std;

#define     FOR(i,s,e)      for(int (i) = (s); (i) <  (e); ++(i))
#define     REP(i,n)        FOR(i,0,n)
#define     FORE(i,s,e)     for(int (i) = (s); (i) <= (e); ++(i))

const string    Digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char      RADIX_POINT = '.';
const int       CHUNK_SIZE = 5;
const int       MAXSIZE = 126000;
const int       CUT_OFF = 2000;

long getMemoryUsage() {
    struct rusage usage;
    if(0 == getrusage(RUSAGE_SELF, &usage)) {
        return usage.ru_maxrss / 1000; // bytes
    } else {
        return 0;
    }
}

inline int valueOf(char x){ // integer value of a digit
    if ('0' <= x and x <= '9') return x - '0';
    if ('A' <= x and x <= 'Z') return x - 'A' +10;
    return 255;
};

int A[MAXSIZE], B[MAXSIZE], *temp, *res;

// Trim unnecessary zeros and radix point
string trim(string aStr){
    string X = aStr;
    //leading zeros:
    while(X.length()>1 and X[0] == '0'and X[1] != RADIX_POINT) X.erase(0,1); //000.001

    //trailing zeros and radix point:
    if (X.find(RADIX_POINT) != string::npos) {
        while (X.length() >= 1 and X[X.length()-1] == '0') {
            X.erase(X.length()-1,1);//0.010; 1.000
        }
        if (X.length() >= 1 and X[X.length()-1] == RADIX_POINT) {
            X.erase(X.length()-1);//123.
        }
        if (X[0] == RADIX_POINT) {
            X = "0" + X; // insert "0" into ".123"
        }
    };
    if (X == "") X = "0";
    return X;
};

// Convert string into array of integer:
// A[0] stores length of the number;
// Digits are stored in reverse order, example:
// X = "123456789"
// A = {3,6789,2345,1};
void convert2IntArr(string X, int *A){

    X = trim(X);
    int len = X.length() / CHUNK_SIZE;
    int rem = (X.length() % CHUNK_SIZE);
    int padLength;
    if (rem > 0) {
        padLength = CHUNK_SIZE - rem;
        for (int i = 0; i < padLength; i++) {
            X = "0" + X;
        }
        len += 1;
    }
    A[0] = len;
    int j = 1;
    for (int i = X.length()-1; i >= 0; i-=CHUNK_SIZE) {
        int num = 0;
        for (int k = 0; k < CHUNK_SIZE; k++) {
            num += valueOf(X[i-k]) * pow(10, k);
        }
        A[j] = num;
        j++;
    }
    // for (int i = 1; i <= A[0]; i++) {
    //     cout << A[i] << endl;
    // }
}

// Convert an array A to string:
string convertIntArr2Str(int *A){
    string result = "";
    int len = A[0];
    for (int i = len; i >= 1; i--) {
        string s = to_string(A[i]);
        int currLen = s.length();
        for (int j = 0; j < CHUNK_SIZE - currLen; j++) {
            s = "0" + s;
        }
        result += s;
    }
    return trim(result);
};

// Adding two arrays with offset: USEFUL for karatsuba algorithm!!
// A = A + B * base^offset
inline void add(int *A, int *B, int offset, int base){
    int lenA = A[0], lenB = B[0];
    int carry = 0;
    int i = 1;
    offset++;

    int b;
    while (i <= lenB or carry > 0) {
        if (offset > lenA) {
            A[offset] = 0;
        }
        if (i > lenB) {
            b = 0;
        } else {
            b = B[i];
        }

        carry = A[offset] + b + carry;
        A[offset] = carry % base;
        carry = carry >= base ? 1 : 0;

        i++;
        offset++;
    };

    offset--;
    while (offset > 1 and A[offset] == 0) {
        offset--;
    }
    if (offset > lenA) {
        A[0] = offset;
    }
};

inline void subtract(int *A, int *B, int base) {
    // A = A - B
    // Requirement: A > B
    int lenA = A[0];
    int lenB = B[0];
    for (int i = 1; i <= lenB; i++) {
        if (A[i] < B[i]) {
            int j = i + 1;
            while (A[j] == 0) {
                A[j] = base - 1;
                j++;
            }
            A[j] -= 1;
            A[i] = base + A[i] - B[i];
        } else {
            A[i] -= B[i];
        }
    }
    while (lenA > 1 and A[lenA] == 0) {
        lenA--;
    }
    A[0] = lenA;
};

// Faster multiplication:
// res = A * B;
int* mulTwoArrays(int *A, int *B, int base) {
    res = new int[MAXSIZE];
    temp = new int[MAXSIZE];
    REP(i, A[0]+2) res[i] = temp[i] = 0;
    int lenA = A[0];
    int lenB = B[0];

    FORE(i, 1, lenA)
    FORE(j, 1, lenB) {
        temp[i+j-1] += A[i] * B[j];
    };

    int lenR = lenA + lenB + 1;
    int carry = 0;
    FORE(i, 1, lenR) {
        carry += temp[i];
        res[i] = carry % base;
        carry  = carry / base;
    };

    while (lenR>1 and res[lenR] == 0) {
        lenR--;
    }
    res[0] = lenR;

    return res;
};

void splitAt(int *input, int *high, int *low, int R) {
    int lenInput = input[0];

    for (int i = 1; i <= R; i++) {
        low[i] = (i <= lenInput) ? input[i] : 0;
    }
    low[0] = (lenInput <= R) ? lenInput : R;

    for (int i = 1; i <= R; i++) {
        high[i] = (i <= lenInput) ? input[i+R] : 0;
    }
    high[0] = (lenInput - R > 0) ? lenInput - R : 0;
};

int* karatsuba(int *A, int *B, int base) {
    int lenA = A[0];
    int lenB = B[0];

    if (lenA < CUT_OFF or lenB < CUT_OFF) {
        return mulTwoArrays(A, B, base);
    }

    int R = ((lenA > lenB ? lenA : lenB)+1) / 2;

    int highX[R+2];
    int lowX[R+2];
    int highY[R+2];
    int lowY[R+2];
    splitAt(A, highX, lowX, R);
    splitAt(B, highY, lowY, R);

    int *z0 = karatsuba(lowX, lowY, base);
    int *z2 = karatsuba(highX, highY, base);

    add(lowX, highX, 0, base);
    add(lowY, highY, 0, base);

    int *z1 = karatsuba(lowX, lowY, base);

    subtract(z1, z0, base);
    subtract(z1, z2, base);
    add(z0, z2, 2 * R, base);
    add(z0, z1, R, base);

    return z0;
}

int main() {
    int T;
    string V, M, P;
    int base;

    cin >> T;
    FORE(t, 1, T) {
        cin >> base;
        cin >> V >> M;

        convert2IntArr(V, A);
        convert2IntArr(M, B);
        // cout << convertIntArr2Str(A) << endl;
        cout << convertIntArr2Str(B) << endl;
        // cout << convertIntArr2Str(karatsuba(A, B, base), 0) << endl;
    };
    cout << "Memory used: " << getMemoryUsage() << " KB" << endl;
    return 0;
}
<commit_msg>[PA1] Converted mulTwoArrays function<commit_after>// CS3230-PA1-DE
// Multiplication of 2 n-digit integers.
// Naive O(n^2) multiplication algorithm (Karatsuba + Long Multiplication)
// Name: Tay Yang Shun

#include <sys/time.h>
#include <sys/resource.h>
#include <iostream>
#include <sstream>
#include <math.h>

using namespace std;

#define     FOR(i,s,e)      for(int (i) = (s); (i) <  (e); ++(i))
#define     REP(i,n)        FOR(i,0,n)
#define     FORE(i,s,e)     for(int (i) = (s); (i) <= (e); ++(i))

const string    Digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char      RADIX_POINT = '.';
const int       CHUNK_SIZE = 4;
const int       MAXSIZE = 126000;
const int       CUT_OFF = 2000;

const int       CHUNK_BASE = pow(10, CHUNK_SIZE);

long getMemoryUsage() {
    struct rusage usage;
    if(0 == getrusage(RUSAGE_SELF, &usage)) {
        return usage.ru_maxrss / 1000; // bytes
    } else {
        return 0;
    }
}

inline int valueOf(char x){ // integer value of a digit
    if ('0' <= x and x <= '9') return x - '0';
    if ('A' <= x and x <= 'Z') return x - 'A' +10;
    return 255;
};

int A[MAXSIZE], B[MAXSIZE], *temp, *res;

// Trim unnecessary zeros and radix point
string trim(string aStr){
    string X = aStr;
    //leading zeros:
    while(X.length()>1 and X[0] == '0'and X[1] != RADIX_POINT) X.erase(0,1); //000.001

    //trailing zeros and radix point:
    if (X.find(RADIX_POINT) != string::npos) {
        while (X.length() >= 1 and X[X.length()-1] == '0') {
            X.erase(X.length()-1,1);//0.010; 1.000
        }
        if (X.length() >= 1 and X[X.length()-1] == RADIX_POINT) {
            X.erase(X.length()-1);//123.
        }
        if (X[0] == RADIX_POINT) {
            X = "0" + X; // insert "0" into ".123"
        }
    };
    if (X == "") X = "0";
    return X;
};

// Convert string into array of integer:
// A[0] stores length of the number;
// Digits are stored in reverse order, example:
// X = "123456789"
// A = {3,6789,2345,1};
void convert2IntArr(string X, int *A){

    X = trim(X);
    int len = X.length() / CHUNK_SIZE;
    int rem = (X.length() % CHUNK_SIZE);
    int padLength;
    if (rem > 0) {
        padLength = CHUNK_SIZE - rem;
        for (int i = 0; i < padLength; i++) {
            X = "0" + X;
        }
        len += 1;
    }
    A[0] = len;
    int j = 1;
    for (int i = X.length()-1; i >= 0; i-=CHUNK_SIZE) {
        int num = 0;
        for (int k = 0; k < CHUNK_SIZE; k++) {
            num += valueOf(X[i-k]) * pow(10, k);
        }
        A[j] = num;
        j++;
    }
    // for (int i = 1; i <= A[0]; i++) {
    //     cout << A[i] << endl;
    // }
}

// Convert an array A to string:
string convertIntArr2Str(int *A){
    string result = "";
    int len = A[0];
    for (int i = len; i >= 1; i--) {
        string s = to_string(A[i]);
        int currLen = s.length();
        for (int j = 0; j < CHUNK_SIZE - currLen; j++) {
            s = "0" + s;
        }
        result += s;
    }
    return trim(result);
};

// Adding two arrays with offset: USEFUL for karatsuba algorithm!!
// A = A + B * base^offset
inline void add(int *A, int *B, int offset, int base){
    int lenA = A[0], lenB = B[0];
    int carry = 0;
    int i = 1;
    offset++;

    int b;
    while (i <= lenB or carry > 0) {
        if (offset > lenA) {
            A[offset] = 0;
        }
        if (i > lenB) {
            b = 0;
        } else {
            b = B[i];
        }

        carry = A[offset] + b + carry;
        A[offset] = carry % base;
        carry = carry >= base ? 1 : 0;

        i++;
        offset++;
    };

    offset--;
    while (offset > 1 and A[offset] == 0) {
        offset--;
    }
    if (offset > lenA) {
        A[0] = offset;
    }
};

inline void subtract(int *A, int *B, int base) {
    // A = A - B
    // Requirement: A > B
    int lenA = A[0];
    int lenB = B[0];
    for (int i = 1; i <= lenB; i++) {
        if (A[i] < B[i]) {
            int j = i + 1;
            while (A[j] == 0) {
                A[j] = base - 1;
                j++;
            }
            A[j] -= 1;
            A[i] = base + A[i] - B[i];
        } else {
            A[i] -= B[i];
        }
    }
    while (lenA > 1 and A[lenA] == 0) {
        lenA--;
    }
    A[0] = lenA;
};

// Faster multiplication:
// res = A * B;
int* mulTwoArrays(int *A, int *B) {
    res = new int[MAXSIZE];
    temp = new int[MAXSIZE];
    REP(i, A[0]+2) res[i] = temp[i] = 0;
    int lenA = A[0];
    int lenB = B[0];

    FORE(i, 1, lenA)
    FORE(j, 1, lenB) {
        temp[i+j-1] += A[i] * B[j];
    };

    int lenR = lenA + lenB + 1;
    int carry = 0;
    FORE(i, 1, lenR) {
        carry += temp[i];
        res[i] = carry % CHUNK_BASE;
        carry  = carry / CHUNK_BASE;
    };

    while (lenR>1 and res[lenR] == 0) {
        lenR--;
    }
    res[0] = lenR;

    return res;
};

void splitAt(int *input, int *high, int *low, int R) {
    int lenInput = input[0];

    for (int i = 1; i <= R; i++) {
        low[i] = (i <= lenInput) ? input[i] : 0;
    }
    low[0] = (lenInput <= R) ? lenInput : R;

    for (int i = 1; i <= R; i++) {
        high[i] = (i <= lenInput) ? input[i+R] : 0;
    }
    high[0] = (lenInput - R > 0) ? lenInput - R : 0;
};

int* karatsuba(int *A, int *B, int base) {
    int lenA = A[0];
    int lenB = B[0];

    if (lenA < CUT_OFF or lenB < CUT_OFF) {
        return mulTwoArrays(A, B);
    }

    int R = ((lenA > lenB ? lenA : lenB)+1) / 2;

    int highX[R+2];
    int lowX[R+2];
    int highY[R+2];
    int lowY[R+2];
    splitAt(A, highX, lowX, R);
    splitAt(B, highY, lowY, R);

    int *z0 = karatsuba(lowX, lowY, base);
    int *z2 = karatsuba(highX, highY, base);

    add(lowX, highX, 0, base);
    add(lowY, highY, 0, base);

    int *z1 = karatsuba(lowX, lowY, base);

    subtract(z1, z0, base);
    subtract(z1, z2, base);
    add(z0, z2, 2 * R, base);
    add(z0, z1, R, base);

    return z0;
}

int main() {
    int T;
    string V, M, P;
    int base;

    cin >> T;
    FORE(t, 1, T) {
        cin >> base;
        cin >> V >> M;

        convert2IntArr(V, A);
        convert2IntArr(M, B);
        cout << convertIntArr2Str(mulTwoArrays(A, B)) << endl;
    };
    cout << "Memory used: " << getMemoryUsage() << " KB" << endl;
    return 0;
}
<|endoftext|>


<commit_before>//===-- GlobalDCE.cpp - DCE unreachable internal functions ----------------===//
//
// This transform is designed to eliminate unreachable internal globals
// FIXME: GlobalDCE should update the callgraph, not destroy it!
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO/GlobalDCE.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Analysis/CallGraph.h"
#include "Support/DepthFirstIterator.h"
#include "Support/StatisticReporter.h"

static Statistic<> NumRemoved("globaldce\t- Number of global values removed");

static bool RemoveUnreachableFunctions(Module &M, CallGraph &CallGraph) {
  // Calculate which functions are reachable from the external functions in the
  // call graph.
  //
  std::set<CallGraphNode*> ReachableNodes(df_begin(&CallGraph),
                                          df_end(&CallGraph));

  // Loop over the functions in the module twice.  The first time is used to
  // drop references that functions have to each other before they are deleted.
  // The second pass removes the functions that need to be removed.
  //
  std::vector<CallGraphNode*> FunctionsToDelete;   // Track unused functions
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    CallGraphNode *N = CallGraph[I];

    if (!ReachableNodes.count(N)) {              // Not reachable??
      I->dropAllReferences();
      N->removeAllCalledFunctions();
      FunctionsToDelete.push_back(N);
      ++NumRemoved;
    }
  }

  // Nothing to do if no unreachable functions have been found...
  if (FunctionsToDelete.empty()) return false;

  // Unreachables functions have been found and should have no references to
  // them, delete them now.
  //
  for (std::vector<CallGraphNode*>::iterator I = FunctionsToDelete.begin(),
	 E = FunctionsToDelete.end(); I != E; ++I)
    delete CallGraph.removeFunctionFromModule(*I);

  return true;
}

static bool RemoveUnreachableGlobalVariables(Module &M) {
  bool Changed = false;
  // Eliminate all global variables that are unused, and that are internal, or
  // do not have an initializer.
  //
  for (Module::giterator I = M.gbegin(); I != M.gend(); )
    if (!I->use_empty() || (I->hasExternalLinkage() && I->hasInitializer()))
      ++I;                     // Cannot eliminate global variable
    else {
      I = M.getGlobalList().erase(I);
      ++NumRemoved;
      Changed = true;
    }
  return Changed;
}

namespace {
  struct GlobalDCE : public Pass {
    const char *getPassName() const { return "Dead Global Elimination"; }

    // run - Do the GlobalDCE pass on the specified module, optionally updating
    // the specified callgraph to reflect the changes.
    //
    bool run(Module &M) {
      return RemoveUnreachableFunctions(M, getAnalysis<CallGraph>()) |
             RemoveUnreachableGlobalVariables(M);
    }

    // getAnalysisUsage - This function works on the call graph of a module.
    // It is capable of updating the call graph to reflect the new state of the
    // module.
    //
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired(CallGraph::ID);
    }
  };
}

Pass *createGlobalDCEPass() { return new GlobalDCE(); }
<commit_msg>Seperate stats for DCE'd functions and vars<commit_after>//===-- GlobalDCE.cpp - DCE unreachable internal functions ----------------===//
//
// This transform is designed to eliminate unreachable internal globals
// FIXME: GlobalDCE should update the callgraph, not destroy it!
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO/GlobalDCE.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Analysis/CallGraph.h"
#include "Support/DepthFirstIterator.h"
#include "Support/StatisticReporter.h"

static Statistic<> NumFunctions("globaldce\t- Number of functions removed");
static Statistic<> NumVariables("globaldce\t- Number of global variables removed");

static bool RemoveUnreachableFunctions(Module &M, CallGraph &CallGraph) {
  // Calculate which functions are reachable from the external functions in the
  // call graph.
  //
  std::set<CallGraphNode*> ReachableNodes(df_begin(&CallGraph),
                                          df_end(&CallGraph));

  // Loop over the functions in the module twice.  The first time is used to
  // drop references that functions have to each other before they are deleted.
  // The second pass removes the functions that need to be removed.
  //
  std::vector<CallGraphNode*> FunctionsToDelete;   // Track unused functions
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    CallGraphNode *N = CallGraph[I];

    if (!ReachableNodes.count(N)) {              // Not reachable??
      I->dropAllReferences();
      N->removeAllCalledFunctions();
      FunctionsToDelete.push_back(N);
      ++NumFunctions;
    }
  }

  // Nothing to do if no unreachable functions have been found...
  if (FunctionsToDelete.empty()) return false;

  // Unreachables functions have been found and should have no references to
  // them, delete them now.
  //
  for (std::vector<CallGraphNode*>::iterator I = FunctionsToDelete.begin(),
	 E = FunctionsToDelete.end(); I != E; ++I)
    delete CallGraph.removeFunctionFromModule(*I);

  return true;
}

static bool RemoveUnreachableGlobalVariables(Module &M) {
  bool Changed = false;
  // Eliminate all global variables that are unused, and that are internal, or
  // do not have an initializer.
  //
  for (Module::giterator I = M.gbegin(); I != M.gend(); )
    if (!I->use_empty() || (I->hasExternalLinkage() && I->hasInitializer()))
      ++I;                     // Cannot eliminate global variable
    else {
      I = M.getGlobalList().erase(I);
      ++NumVariables;
      Changed = true;
    }
  return Changed;
}

namespace {
  struct GlobalDCE : public Pass {
    const char *getPassName() const { return "Dead Global Elimination"; }

    // run - Do the GlobalDCE pass on the specified module, optionally updating
    // the specified callgraph to reflect the changes.
    //
    bool run(Module &M) {
      return RemoveUnreachableFunctions(M, getAnalysis<CallGraph>()) |
             RemoveUnreachableGlobalVariables(M);
    }

    // getAnalysisUsage - This function works on the call graph of a module.
    // It is capable of updating the call graph to reflect the new state of the
    // module.
    //
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired(CallGraph::ID);
    }
  };
}

Pass *createGlobalDCEPass() { return new GlobalDCE(); }
<|endoftext|>


<commit_before>#include "service_led_strip.h"

#define ANIMATION_INDEX 0
#define ANIMATION_END 1000

static RgbColor wheel(uint8_t pos) {
    if (pos < 85) {
        return RgbColor(pos * 3, 255 - pos * 3, 0);
    } else if (pos < 170) {
        pos -= 85;
        return RgbColor(255 - pos * 3, 0, pos * 3);
    } else {
        pos -= 170;
        return RgbColor(0, pos * 3, 255 - pos * 3);
    }
}

// TODO: use something more optimized
static HsbColor wheel(const uint8_t pos, const float b) {
    HsbColor color = HsbColor(wheel(pos));
    color.B = b;
    return color;
}

void LedStripService::animation_0(const AnimationParam &param) {
    const uint8_t step = (uint8_t)(param.progress * 255);
    for (uint16_t i = 0; i < get_len(); i++) {
        led_strip->set_pixel(i, wheel((uint8_t)(i + step), color.B));
    }
    if (param.state == AnimationState_Completed) {
        //animator->RestartAnimation(ANIMATION_INDEX);
    }
}

void LedStripService::animation_1(const AnimationParam &param) {
    const uint8_t step = (uint8_t)(param.progress * 255);
    for (uint16_t i = 0; i < get_len(); i++) {
        led_strip->set_pixel(i, wheel((uint8_t)((i * 256 / get_len()) + step), color.B));
    }
    if (param.state == AnimationState_Completed) {
        //animator->RestartAnimation(ANIMATION_INDEX);
    }
}

LedStripService::LedStripService(const LED_STRIP_TYPE t, const LED_STRIP_TRANSFER_MODE mode, const uint16_t len) {
    //animator = new NeoPixelAnimator(ANIMATION_END, 10);
    t_mode = mode;
    type = t;
    switch (type) {
        case GRB:
            switch (t_mode) {
                case DMA800:
                    led_strip = new PixelBus<NeoGrbFeature, NeoEsp8266Dma800KbpsMethod>(len);
                    return;
                case UART800:
                    led_strip = new PixelBus<NeoGrbFeature, NeoEsp8266Uart800KbpsMethod>(len);
                    return;
            }
        case GRBW:
            switch (t_mode) {
                case DMA800:
                    led_strip = new PixelBus<NeoGrbwFeature, NeoEsp8266Dma800KbpsMethod>(len);
                    return;
                case UART800:
                    led_strip = new PixelBus<NeoGrbwFeature, NeoEsp8266Uart800KbpsMethod>(len);
                    return;
            }
    }
    set_color(0, 0, 0);
}

LedStripService::~LedStripService() {
    //delete animator;
}

void LedStripService::set_color(const uint32_t color) {
    set_color((uint8_t)((0x00FF0000 & color) >> 16), (uint8_t)((0x0000FF00 & color) >> 8),
              (uint8_t)(0x000000FF & color));
}

void LedStripService::set_color(const uint8_t r, const uint8_t g, const uint8_t b) {
    color = HsbColor(RgbColor(r, g, b));
    if (SINGLE_COLOR != mode) {
        //animator->StopAll();
        mode = SINGLE_COLOR;
    }
    led_strip->set_all_pixels(color);
}

uint32_t LedStripService::get_color() const {
    const RgbColor rgb = RgbColor(color);
    return (uint32_t)((0x00FF0000 & rgb.R << 16) | (0x0000FF00 & rgb.G << 8) | rgb.B);
}

void LedStripService::set_hue(const uint16_t h) {
    color = HsbColor((h % 65535) / (float) 100, color.S, color.B);
    led_strip->set_all_pixels(color);
}

void LedStripService::set_saturation(const uint8_t s) {
    color = HsbColor(color.H, (s % 101) / (float) 100, color.B);
    led_strip->set_all_pixels(color);
}

void LedStripService::set_brightness(const uint8_t b) {
    color = HsbColor(color.H, color.S, (b % 101) / (float) 100);
    led_strip->set_all_pixels(color);
}

uint16_t LedStripService::get_hue() const {
    return (uint8_t) (color.H * 100);
}

uint8_t LedStripService::get_saturation() const {
    return (uint8_t) (color.S * 100);
}

uint8_t LedStripService::get_brightness() const {
    return (uint8_t) (color.B * 100);
}

void LedStripService::set_delay(const uint16_t d) {
    //animator->setTimeScale(d);
}

void LedStripService::set_mode(const LED_STRIP_ANIM_MODE m) {
    //animator->StopAll();
    switch ((mode = m)) {
        case SINGLE_COLOR:
            led_strip->set_all_pixels(color);
            return;
        case ANIMATION_0:
            /*animator->StartAnimation(ANIMATION_INDEX, ANIMATION_END, [this](const AnimationParam &param) {
                animation_0(param);
            });*/
            break;
        case ANIMATION_1:
            /*animator->StartAnimation(ANIMATION_INDEX, ANIMATION_END, [this](const AnimationParam &param) {
                animation_1(param);
            });*/
            break;
    }
}

void LedStripService::cycle_routine() {
    // Call at least every 10ms
    /*if (animator != NULL && animator->IsAnimating())
        animator->UpdateAnimations();*/
    led_strip->refresh();
}
<commit_msg>Fix led animation count<commit_after>#include "service_led_strip.h"

#define ANIMATION_INDEX 0
#define ANIMATION_END 1000

static RgbColor wheel(uint8_t pos) {
    if (pos < 85) {
        return RgbColor(pos * 3, 255 - pos * 3, 0);
    } else if (pos < 170) {
        pos -= 85;
        return RgbColor(255 - pos * 3, 0, pos * 3);
    } else {
        pos -= 170;
        return RgbColor(0, pos * 3, 255 - pos * 3);
    }
}

// TODO: use something more optimized
static HsbColor wheel(const uint8_t pos, const float b) {
    HsbColor color = HsbColor(wheel(pos));
    color.B = b;
    return color;
}

void LedStripService::animation_0(const AnimationParam &param) {
    const uint8_t step = (uint8_t)(param.progress * 255);
    for (uint16_t i = 0; i < get_len(); i++) {
        led_strip->set_pixel(i, wheel((uint8_t)(i + step), color.B));
    }
    if (param.state == AnimationState_Completed) {
        animator->RestartAnimation(ANIMATION_INDEX);
    }
}

void LedStripService::animation_1(const AnimationParam &param) {
    const uint8_t step = (uint8_t)(param.progress * 255);
    for (uint16_t i = 0; i < get_len(); i++) {
        led_strip->set_pixel(i, wheel((uint8_t)((i * 256 / get_len()) + step), color.B));
    }
    if (param.state == AnimationState_Completed) {
        animator->RestartAnimation(ANIMATION_INDEX);
    }
}

LedStripService::LedStripService(const LED_STRIP_TYPE t, const LED_STRIP_TRANSFER_MODE mode, const uint16_t len) {
    animator = new NeoPixelAnimator(1, 10);
    t_mode = mode;
    type = t;
    switch (type) {
        case GRB:
            switch (t_mode) {
                case DMA800:
                    led_strip = new PixelBus<NeoGrbFeature, NeoEsp8266Dma800KbpsMethod>(len);
                    return;
                case UART800:
                    led_strip = new PixelBus<NeoGrbFeature, NeoEsp8266Uart800KbpsMethod>(len);
                    return;
            }
        case GRBW:
            switch (t_mode) {
                case DMA800:
                    led_strip = new PixelBus<NeoGrbwFeature, NeoEsp8266Dma800KbpsMethod>(len);
                    return;
                case UART800:
                    led_strip = new PixelBus<NeoGrbwFeature, NeoEsp8266Uart800KbpsMethod>(len);
                    return;
            }
    }
    set_color(0, 0, 0);
}

LedStripService::~LedStripService() {
    delete animator;
}

void LedStripService::set_color(const uint32_t color) {
    set_color((uint8_t)((0x00FF0000 & color) >> 16), (uint8_t)((0x0000FF00 & color) >> 8),
              (uint8_t)(0x000000FF & color));
}

void LedStripService::set_color(const uint8_t r, const uint8_t g, const uint8_t b) {
    color = HsbColor(RgbColor(r, g, b));
    if (SINGLE_COLOR != mode) {
        animator->StopAll();
        mode = SINGLE_COLOR;
    }
    led_strip->set_all_pixels(color);
}

uint32_t LedStripService::get_color() const {
    const RgbColor rgb = RgbColor(color);
    return (uint32_t)((0x00FF0000 & rgb.R << 16) | (0x0000FF00 & rgb.G << 8) | rgb.B);
}

void LedStripService::set_hue(const uint16_t h) {
    color = HsbColor((h % 65535) / (float) 100, color.S, color.B);
    led_strip->set_all_pixels(color);
}

void LedStripService::set_saturation(const uint8_t s) {
    color = HsbColor(color.H, (s % 101) / (float) 100, color.B);
    led_strip->set_all_pixels(color);
}

void LedStripService::set_brightness(const uint8_t b) {
    color = HsbColor(color.H, color.S, (b % 101) / (float) 100);
    led_strip->set_all_pixels(color);
}

uint16_t LedStripService::get_hue() const {
    return (uint8_t) (color.H * 100);
}

uint8_t LedStripService::get_saturation() const {
    return (uint8_t) (color.S * 100);
}

uint8_t LedStripService::get_brightness() const {
    return (uint8_t) (color.B * 100);
}

void LedStripService::set_delay(const uint16_t d) {
    animator->setTimeScale(d);
}

void LedStripService::set_mode(const LED_STRIP_ANIM_MODE m) {
    animator->StopAll();
    switch ((mode = m)) {
        case SINGLE_COLOR:
            led_strip->set_all_pixels(color);
            return;
        case ANIMATION_0:
            animator->StartAnimation(ANIMATION_INDEX, ANIMATION_END, [this](const AnimationParam &param) {
                animation_0(param);
            });
            break;
        case ANIMATION_1:
            animator->StartAnimation(ANIMATION_INDEX, ANIMATION_END, [this](const AnimationParam &param) {
                animation_1(param);
            });
            break;
    }
}

void LedStripService::cycle_routine() {
    // Call at least every 10ms
    if (animator != NULL && animator->IsAnimating())
        animator->UpdateAnimations();
    led_strip->refresh();
}
<|endoftext|>


<commit_before>/**
 * @file		sysmanager.cpp
 * @brief		COSSB system manager
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 7. 29
 * @details
 */

#include "manager.hpp"
#include "configloader.hpp"

namespace cossb {
namespace manager {

system_manager* system_manager::_instance = nullptr;

system_manager* system_manager::get()
{
	if(!_instance)
		_instance = new system_manager;
	return _instance;
}

void system_manager::destroy()
{
	if(_instance)
		delete _instance;
}

bool system_manager::setup(base::config* config)
{
	//1. read config file

	//2. setup the configuration to the database

	//3.run the default servers

	return true;
}

bool system_manager::is_setup() const
{
	return initialized;
}

} /* namespace manager */
} /* namespace cossb */
<commit_msg>edit setup function<commit_after>/**
 * @file		sysmanager.cpp
 * @brief		COSSB system manager
 * @author		Byunghun Hwang<bhhwang@nsynapse.com>
 * @date 		2015. 7. 29
 * @details
 */

#include "manager.hpp"

namespace cossb {
namespace manager {

system_manager::system_manager()
{

}

system_manager::~system_manager()
{

}

bool system_manager::setup(base::config* config)
{
	//1. load dependent components
	for(auto dep:*config->get_dependency()) {
		if(dep->type==base::dependencyType::COMPONENT)
			cossb_component_manager->install(dep->name.c_str());
	}

	return true;
}

bool system_manager::is_setup() const
{
	return initialized;
}

} /* namespace manager */
} /* namespace cossb */
<|endoftext|>


<commit_before>#include "player_context.h"

using namespace space_invaders;

PlayerContext::PlayerContext() : mLevel(1), mScore(0), mLives(3), mShotCount(0), mRelaunchTimer(0)
{
  // ...
}

void PlayerContext::reset()
{
  mLevel = 1;
  mScore = 0;
  mLives = 3;
  mShotCount = 0;
  mRelaunchTimer = 0;
}<commit_msg>Fixed a bug where player context was not clearing the stored states of aliens and shields.<commit_after>#include "player_context.h"

using namespace space_invaders;

PlayerContext::PlayerContext() : mLevel(1), mScore(0), mLives(3), mShotCount(0), mRelaunchTimer(0)
{
  // ...
}

void PlayerContext::reset()
{
  mLevel = 1;
  mScore = 0;
  mLives = 3;
  mShotCount = 0;
  mRelaunchTimer = 0;
  mAliens.clear();
  mShields.clear();
}<|endoftext|>


<commit_before>#ifndef ARABICA_CG_MUTATOR
#define ARABICA_CG_MUTATOR
#include "CGChain.hpp"

namespace arabica
{
    class CGMutator
    {
        std::string mutated_seq;

        CGChnSptr input;
        CGChnSptr mutated;

    public:

        CGMutator(CGChnSptr chain): input(chain) {}
        CGMutator(CGChnSptr chain, std::string seq): input(chain), mutated_seq(seq) {}
        ~CGMutator(){}

        void set_seq(std::string seq){mutated_seq = seq;}
        std::string get_seq() const {return mutated_seq;}

        void mutateDNA();
        void output(std::ofstream& ofs){mutated->write_block(ofs);}

    private:

        void mut_to_A(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end);
        void mut_to_C(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end);
        void mut_to_G(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end);
        void mut_to_T(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end);
    };

    void CGMutator::mutateDNA()
    {
        //only mutation. TODO insertion, elongation, deletion is not spported yet.
        if(mutated_seq.empty())
        {
            std::cout << "CGMutator has no input sequence" << std::endl;
            throw std::invalid_argument("invalid sequence");
        }

        std::vector<BeadSptr> chain(input->get_chain());

        if(mutated_seq.size() != input->get_ResNum())
        {
            std::cout << "mut_seq: " << mutated_seq.size() << std::endl;
            std::cout << "chain  : " << chain.size() << std::endl;
            std::cout << "mut    : " << mutated_seq << std::endl;
            std::cout << "input  : " << input->get_sequence() << std::endl;

            throw std::invalid_argument("length of sequene and chain size is not equal");
        }

        std::vector<BeadSptr>::iterator iter = chain.begin();
        std::vector<BeadSptr>::iterator end = chain.end();

        for(size_t current_seq(0); current_seq < mutated_seq.size(); ++current_seq)
        {
//             std::cout << mutated_seq[current_seq] << std::endl;
            switch(mutated_seq[current_seq])
            {
            case '=':
                break;
            case 'A':
                mut_to_A(iter, end);
                break;
            case 'C':
                mut_to_C(iter, end);
                break;
            case 'G':
                mut_to_G(iter, end);
                break;
            case 'T':
                mut_to_T(iter, end);
                break;
            }
        }

        mutated = std::shared_ptr<CGChain>(new CGChain(chain));

        return;
    }

    void CGMutator::mut_to_A(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end)
    {
        int residue_number((*iter)->get_iResNum());
        while(true)
        {
            if(iter == end) return;

            if((*iter)->get_iResNum() == residue_number)
            {
                (*iter)->set_seq("DA");
                if(iter != end) ++iter;
            }else{
                return;
            }
        }
    }

    void CGMutator::mut_to_C(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end)
    {
        int residue_number((*iter)->get_iResNum());
        while(true)
        {
            if(iter == end) return;

            if((*iter)->get_iResNum() == residue_number)
            {
                (*iter)->set_seq("DC");
                if(iter != end) ++iter;
            }else{
                return;
            }
        }
    }

    void CGMutator::mut_to_G(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end)
    {
        int residue_number((*iter)->get_iResNum());
        while(true)
        {
            if(iter == end) return;

            if((*iter)->get_iResNum() == residue_number)
            {
                (*iter)->set_seq("DG");
                if(iter != end) ++iter;
            }else{
                return;
            }
        }
    }

    void CGMutator::mut_to_T(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end)
    {
        int residue_number((*iter)->get_iResNum());
        while(true)
        {
            if(iter == end) return;

            if((*iter)->get_iResNum() == residue_number)
            {
                (*iter)->set_seq("DT");
                if(iter != end) ++iter;
            }else{
                return;
            }
        }
    }

}
#endif//ARABICA_CG_MUTATOR
<commit_msg>fix: in case of no-change: add method no_mut<commit_after>#ifndef ARABICA_CG_MUTATOR
#define ARABICA_CG_MUTATOR
#include "CGChain.hpp"

namespace arabica
{
    class CGMutator
    {
        std::string mutated_seq;

        CGChnSptr input;
        CGChnSptr mutated;

    public:

        CGMutator(CGChnSptr chain): input(chain) {}
        CGMutator(CGChnSptr chain, std::string seq): input(chain), mutated_seq(seq) {}
        ~CGMutator(){}

        void set_seq(std::string seq){mutated_seq = seq;}
        std::string get_seq() const {return mutated_seq;}

        void mutateDNA();
        void output(std::ofstream& ofs){mutated->write_block(ofs);}

    private:

        void no_mut(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end);
        void mut_to_A(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end);
        void mut_to_C(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end);
        void mut_to_G(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end);
        void mut_to_T(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end);
    };

    void CGMutator::mutateDNA()
    {
        //only mutation. TODO insertion, elongation, deletion is not spported yet.
        if(mutated_seq.empty())
        {
            std::cout << "CGMutator has no input sequence" << std::endl;
            throw std::invalid_argument("invalid sequence");
        }

        std::vector<BeadSptr> chain(input->get_chain());

        if(mutated_seq.size() != input->get_ResNum())
        {
            std::cout << "mut_seq: " << mutated_seq.size() << std::endl;
            std::cout << "chain  : " << chain.size() << std::endl;
            std::cout << "mut    : " << mutated_seq << std::endl;
            std::cout << "input  : " << input->get_sequence() << std::endl;

            throw std::invalid_argument("length of sequene and chain size is not equal");
        }

        std::vector<BeadSptr>::iterator iter = chain.begin();
        std::vector<BeadSptr>::iterator end = chain.end();

        for(size_t current_seq(0); current_seq < mutated_seq.size(); ++current_seq)
        {
//             std::cout << mutated_seq[current_seq] << std::endl;
            switch(mutated_seq[current_seq])
            {
            case '=':
                no_mut(iter, end);
                break;
            case 'A':
                mut_to_A(iter, end);
                break;
            case 'C':
                mut_to_C(iter, end);
                break;
            case 'G':
                mut_to_G(iter, end);
                break;
            case 'T':
                mut_to_T(iter, end);
                break;
            }
        }

        mutated = std::shared_ptr<CGChain>(new CGChain(chain));

        return;
    }

    void CGMutator::no_mut(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end)
    {
        int residue_number((*iter)->get_iResNum());
        while(true)
        {
            if(iter == end) return;

            if((*iter)->get_iResNum() == residue_number)
            {
                if(iter != end) ++iter;
            }else{
                return;
            }
        }
    }

    void CGMutator::mut_to_A(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end)
    {
        int residue_number((*iter)->get_iResNum());
        while(true)
        {
            if(iter == end) return;

            if((*iter)->get_iResNum() == residue_number)
            {
                (*iter)->set_seq("DA");
                if(iter != end) ++iter;
            }else{
                return;
            }
        }
    }

    void CGMutator::mut_to_C(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end)
    {
        int residue_number((*iter)->get_iResNum());
        while(true)
        {
            if(iter == end) return;

            if((*iter)->get_iResNum() == residue_number)
            {
                (*iter)->set_seq("DC");
                if(iter != end) ++iter;
            }else{
                return;
            }
        }
    }

    void CGMutator::mut_to_G(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end)
    {
        int residue_number((*iter)->get_iResNum());
        while(true)
        {
            if(iter == end) return;

            if((*iter)->get_iResNum() == residue_number)
            {
                (*iter)->set_seq("DG");
                if(iter != end) ++iter;
            }else{
                return;
            }
        }
    }

    void CGMutator::mut_to_T(std::vector<BeadSptr>::iterator& iter, std::vector<BeadSptr>::iterator& end)
    {
        int residue_number((*iter)->get_iResNum());
        while(true)
        {
            if(iter == end) return;

            if((*iter)->get_iResNum() == residue_number)
            {
                (*iter)->set_seq("DT");
                if(iter != end) ++iter;
            }else{
                return;
            }
        }
    }

}
#endif//ARABICA_CG_MUTATOR
<|endoftext|>


<commit_before>// Copyright (c) 2018-2020 The Bitcoin Core developers
// Copyright (c) 2020 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php.

#include "interface/wallet.h"
#include "wallet.h"

namespace interfaces {

    WalletBalances Wallet::getBalances() {
        WalletBalances result;
        result.balance = m_wallet.GetAvailableBalance();
        result.unconfirmed_balance = m_wallet.GetUnconfirmedBalance();
        result.immature_balance = m_wallet.GetImmatureBalance();
        result.have_watch_only = m_wallet.HaveWatchOnly();
        if (result.have_watch_only) {
            result.watch_only_balance = m_wallet.GetWatchOnlyBalance();
            result.unconfirmed_watch_only_balance = m_wallet.GetUnconfirmedWatchOnlyBalance();
            result.immature_watch_only_balance = m_wallet.GetImmatureWatchOnlyBalance();
        }
        result.delegate_balance = m_wallet.GetDelegatedBalance();
        result.coldstaked_balance = m_wallet.GetColdStakingBalance();
        result.shielded_balance = m_wallet.GetAvailableShieldedBalance();
        result.unconfirmed_shielded_balance = m_wallet.GetUnconfirmedShieldedBalance();
        return result;
    }

} // namespace interfaces<commit_msg>[BUG][GUI] Cache unconfirmed_balance only for transparent outs<commit_after>// Copyright (c) 2018-2020 The Bitcoin Core developers
// Copyright (c) 2020 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php.

#include "interface/wallet.h"
#include "wallet.h"

namespace interfaces {

    WalletBalances Wallet::getBalances() {
        WalletBalances result;
        result.balance = m_wallet.GetAvailableBalance();
        result.unconfirmed_balance = m_wallet.GetUnconfirmedBalance(ISMINE_SPENDABLE_TRANSPARENT);
        result.immature_balance = m_wallet.GetImmatureBalance();
        result.have_watch_only = m_wallet.HaveWatchOnly();
        if (result.have_watch_only) {
            result.watch_only_balance = m_wallet.GetWatchOnlyBalance();
            result.unconfirmed_watch_only_balance = m_wallet.GetUnconfirmedWatchOnlyBalance();
            result.immature_watch_only_balance = m_wallet.GetImmatureWatchOnlyBalance();
        }
        result.delegate_balance = m_wallet.GetDelegatedBalance();
        result.coldstaked_balance = m_wallet.GetColdStakingBalance();
        result.shielded_balance = m_wallet.GetAvailableShieldedBalance();
        result.unconfirmed_shielded_balance = m_wallet.GetUnconfirmedShieldedBalance();
        return result;
    }

} // namespace interfaces
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <policy/feerate.h>

#include <tinyformat.h>

CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nBytes_)
{
    assert(nBytes_ <= uint64_t(std::numeric_limits<int64_t>::max()));
    int64_t nSize = int64_t(nBytes_);

    if (nSize > 0)
        nSatoshisPerK = nFeePaid * (1000 / nSize);
    else
        nSatoshisPerK = 0;
}

CAmount CFeeRate::GetFee(size_t nBytes_) const
{
    assert(nBytes_ <= uint64_t(std::numeric_limits<int64_t>::max()));
    int64_t nSize = int64_t(nBytes_);

    CAmount nFee = nSatoshisPerK * (nSize / 1000);

    if (nFee == 0 && nSize != 0) {
        if (nSatoshisPerK > 0)
            nFee = CAmount(1);
        if (nSatoshisPerK < 0)
            nFee = CAmount(-1);
    }

    return nFee;
}

std::string CFeeRate::ToString(const FeeEstimateMode& fee_estimate_mode) const
{
    switch (fee_estimate_mode) {
    case FeeEstimateMode::SAT_B:  return strprintf("%d.%03d %s/B", nSatoshisPerK / 1000, nSatoshisPerK % 1000, CURRENCY_ATOM);
    default:                      return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT);
    }
}
<commit_msg>ensure no overflow<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <policy/feerate.h>

#include <tinyformat.h>

CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nBytes_)
{
    assert(nBytes_ <= uint64_t(std::numeric_limits<int64_t>::max()));
    int64_t nSize = int64_t(nBytes_);

    if (nSize > 0)
        nSatoshisPerK = nFeePaid * 1000 / nSize;
    else
        nSatoshisPerK = 0;
}

CAmount CFeeRate::GetFee(size_t nBytes_) const
{
    assert((nBytes_*1000) <= uint64_t(std::numeric_limits<int64_t>::max()));
    int64_t nSize = int64_t(nBytes_);

    CAmount nFee = nSatoshisPerK * nSize / 1000;

    if (nFee == 0 && nSize != 0) {
        if (nSatoshisPerK > 0)
            nFee = CAmount(1);
        if (nSatoshisPerK < 0)
            nFee = CAmount(-1);
    }

    return nFee;
}

std::string CFeeRate::ToString(const FeeEstimateMode& fee_estimate_mode) const
{
    switch (fee_estimate_mode) {
    case FeeEstimateMode::SAT_B:  return strprintf("%d.%03d %s/B", nSatoshisPerK / 1000, nSatoshisPerK % 1000, CURRENCY_ATOM);
    default:                      return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN, CURRENCY_UNIT);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions 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 "libcef/browser/javascript_dialog_manager.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/javascript_dialog.h"
#include "libcef/browser/thread_util.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/net_util.h"

namespace {

class CefJSDialogCallbackImpl : public CefJSDialogCallback {
 public:
  CefJSDialogCallbackImpl(
      const content::JavaScriptDialogManager::DialogClosedCallback& callback)
      : callback_(callback) {
  }
  ~CefJSDialogCallbackImpl() {
    if (!callback_.is_null()) {
      // The callback is still pending. Cancel it now.
      if (CEF_CURRENTLY_ON_UIT()) {
        CancelNow(callback_);
      } else {
        CEF_POST_TASK(CEF_UIT,
            base::Bind(&CefJSDialogCallbackImpl::CancelNow, callback_));
      }
    }
  }

  virtual void Continue(bool success,
                        const CefString& user_input) OVERRIDE {
    if (CEF_CURRENTLY_ON_UIT()) {
      if (!callback_.is_null()) {
        callback_.Run(success, user_input);
        callback_.Reset();
      }
    } else {
      CEF_POST_TASK(CEF_UIT,
          base::Bind(&CefJSDialogCallbackImpl::Continue, this, success,
              user_input));
    }
  }

  void Disconnect() {
    callback_.Reset();
  }

 private:
  static void CancelNow(
      const content::JavaScriptDialogManager::DialogClosedCallback& callback) {
    CEF_REQUIRE_UIT();
    callback.Run(false, base::string16());
  }

  content::JavaScriptDialogManager::DialogClosedCallback callback_;

  IMPLEMENT_REFCOUNTING(CefJSDialogCallbackImpl);
};

}  // namespace

CefJavaScriptDialogManager::CefJavaScriptDialogManager(
    CefBrowserHostImpl* browser)
    : browser_(browser) {
}

CefJavaScriptDialogManager::~CefJavaScriptDialogManager() {
}

void CefJavaScriptDialogManager::RunJavaScriptDialog(
    content::WebContents* web_contents,
    const GURL& origin_url,
    const std::string& accept_lang,
    content::JavaScriptMessageType message_type,
    const base::string16& message_text,
    const base::string16& default_prompt_text,
    const DialogClosedCallback& callback,
    bool* did_suppress_message) {
  CefRefPtr<CefClient> client = browser_->GetClient();
  if (client.get()) {
    CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
    if (handler.get()) {
      *did_suppress_message = false;

      CefRefPtr<CefJSDialogCallbackImpl> callbackPtr(
          new CefJSDialogCallbackImpl(callback));

      // Execute the user callback.
      bool handled = handler->OnJSDialog(browser_, origin_url.spec(),
          accept_lang,
          static_cast<cef_jsdialog_type_t>(message_type),
          message_text, default_prompt_text, callbackPtr.get(),
          *did_suppress_message);
      if (handled)
        return;

      callbackPtr->Disconnect();
      if (*did_suppress_message)
        return;
    }
  }

#if defined(OS_MACOSX) || defined(OS_WIN) || defined(TOOLKIT_GTK)
  *did_suppress_message = false;

  if (dialog_.get()) {
    // One dialog at a time, please.
    *did_suppress_message = true;
    return;
  }

  base::string16 display_url = net::FormatUrl(origin_url, accept_lang);

  dialog_.reset(new CefJavaScriptDialog(this,
                                        message_type,
                                        display_url,
                                        message_text,
                                        default_prompt_text,
                                        callback));
#else
  // TODO(port): implement CefJavaScriptDialog for other platforms.
  *did_suppress_message = true;
  return;
#endif
}

void CefJavaScriptDialogManager::RunBeforeUnloadDialog(
    content::WebContents* web_contents,
    const base::string16& message_text,
    bool is_reload,
    const DialogClosedCallback& callback) {
  if (browser_->destruction_state() >=
      CefBrowserHostImpl::DESTRUCTION_STATE_ACCEPTED) {
    // Currently destroying the browser. Accept the unload without showing
    // the prompt.
    callback.Run(true, base::string16());
    return;
  }

  CefRefPtr<CefClient> client = browser_->GetClient();
  if (client.get()) {
    CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
    if (handler.get()) {
      CefRefPtr<CefJSDialogCallbackImpl> callbackPtr(
          new CefJSDialogCallbackImpl(callback));

      // Execute the user callback.
      bool handled = handler->OnBeforeUnloadDialog(browser_, message_text,
          is_reload, callbackPtr.get());
      if (handled)
        return;

      callbackPtr->Disconnect();
    }
  }

#if defined(OS_MACOSX) || defined(OS_WIN) || defined(TOOLKIT_GTK)
  if (dialog_.get()) {
    // Seriously!?
    callback.Run(true, base::string16());
    return;
  }

  base::string16 new_message_text =
      message_text +
      base::ASCIIToUTF16("\n\nIs it OK to leave/reload this page?");

  dialog_.reset(
      new CefJavaScriptDialog(this,
                              content::JAVASCRIPT_MESSAGE_TYPE_CONFIRM,
                              base::string16(),  // display_url
                              new_message_text,
                              base::string16(),  // default_prompt_text
                              callback));
#else
  // TODO(port): implement CefJavaScriptDialog for other platforms.
  callback.Run(true, base::string16());
  return;
#endif
}

void CefJavaScriptDialogManager::CancelActiveAndPendingDialogs(
    content::WebContents* web_contents) {
  CefRefPtr<CefClient> client = browser_->GetClient();
  if (client.get()) {
    CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
    if (handler.get()) {
      // Execute the user callback.
      handler->OnResetDialogState(browser_);
    }
  }

#if defined(OS_MACOSX) || defined(OS_WIN) || defined(TOOLKIT_GTK)
  if (dialog_.get()) {
    dialog_->Cancel();
    dialog_.reset();
  }
#endif
}

void CefJavaScriptDialogManager::WebContentsDestroyed(
    content::WebContents* web_contents) {
}

void CefJavaScriptDialogManager::DialogClosed(CefJavaScriptDialog* dialog) {
#if defined(OS_MACOSX) || defined(OS_WIN) || defined(TOOLKIT_GTK)
  DCHECK_EQ(dialog, dialog_.get());
  dialog_.reset();
  CefRefPtr<CefClient> client = browser_->GetClient();
  if (client.get()) {
    CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
    if (handler.get())
      handler->OnDialogClosed(browser_);
  }
#endif
}
<commit_msg>Crash early on incorrect usage of CefJSDialogHandler::OnJSDialog (issue #1206).<commit_after>// Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions 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 "libcef/browser/javascript_dialog_manager.h"
#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/javascript_dialog.h"
#include "libcef/browser/thread_util.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "net/base/net_util.h"

namespace {

class CefJSDialogCallbackImpl : public CefJSDialogCallback {
 public:
  CefJSDialogCallbackImpl(
      const content::JavaScriptDialogManager::DialogClosedCallback& callback)
      : callback_(callback) {
  }
  ~CefJSDialogCallbackImpl() {
    if (!callback_.is_null()) {
      // The callback is still pending. Cancel it now.
      if (CEF_CURRENTLY_ON_UIT()) {
        CancelNow(callback_);
      } else {
        CEF_POST_TASK(CEF_UIT,
            base::Bind(&CefJSDialogCallbackImpl::CancelNow, callback_));
      }
    }
  }

  virtual void Continue(bool success,
                        const CefString& user_input) OVERRIDE {
    if (CEF_CURRENTLY_ON_UIT()) {
      if (!callback_.is_null()) {
        callback_.Run(success, user_input);
        callback_.Reset();
      }
    } else {
      CEF_POST_TASK(CEF_UIT,
          base::Bind(&CefJSDialogCallbackImpl::Continue, this, success,
              user_input));
    }
  }

  void Disconnect() {
    callback_.Reset();
  }

 private:
  static void CancelNow(
      const content::JavaScriptDialogManager::DialogClosedCallback& callback) {
    CEF_REQUIRE_UIT();
    callback.Run(false, base::string16());
  }

  content::JavaScriptDialogManager::DialogClosedCallback callback_;

  IMPLEMENT_REFCOUNTING(CefJSDialogCallbackImpl);
};

}  // namespace

CefJavaScriptDialogManager::CefJavaScriptDialogManager(
    CefBrowserHostImpl* browser)
    : browser_(browser) {
}

CefJavaScriptDialogManager::~CefJavaScriptDialogManager() {
}

void CefJavaScriptDialogManager::RunJavaScriptDialog(
    content::WebContents* web_contents,
    const GURL& origin_url,
    const std::string& accept_lang,
    content::JavaScriptMessageType message_type,
    const base::string16& message_text,
    const base::string16& default_prompt_text,
    const DialogClosedCallback& callback,
    bool* did_suppress_message) {
  CefRefPtr<CefClient> client = browser_->GetClient();
  if (client.get()) {
    CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
    if (handler.get()) {
      *did_suppress_message = false;

      CefRefPtr<CefJSDialogCallbackImpl> callbackPtr(
          new CefJSDialogCallbackImpl(callback));

      // Execute the user callback.
      bool handled = handler->OnJSDialog(browser_, origin_url.spec(),
          accept_lang,
          static_cast<cef_jsdialog_type_t>(message_type),
          message_text, default_prompt_text, callbackPtr.get(),
          *did_suppress_message);
      if (handled) {
        // Invalid combination of values. Crash sooner rather than later.
        CHECK(!*did_suppress_message);
        return;
      }

      callbackPtr->Disconnect();
      if (*did_suppress_message)
        return;
    }
  }

#if defined(OS_MACOSX) || defined(OS_WIN) || defined(TOOLKIT_GTK)
  *did_suppress_message = false;

  if (dialog_.get()) {
    // One dialog at a time, please.
    *did_suppress_message = true;
    return;
  }

  base::string16 display_url = net::FormatUrl(origin_url, accept_lang);

  dialog_.reset(new CefJavaScriptDialog(this,
                                        message_type,
                                        display_url,
                                        message_text,
                                        default_prompt_text,
                                        callback));
#else
  // TODO(port): implement CefJavaScriptDialog for other platforms.
  *did_suppress_message = true;
  return;
#endif
}

void CefJavaScriptDialogManager::RunBeforeUnloadDialog(
    content::WebContents* web_contents,
    const base::string16& message_text,
    bool is_reload,
    const DialogClosedCallback& callback) {
  if (browser_->destruction_state() >=
      CefBrowserHostImpl::DESTRUCTION_STATE_ACCEPTED) {
    // Currently destroying the browser. Accept the unload without showing
    // the prompt.
    callback.Run(true, base::string16());
    return;
  }

  CefRefPtr<CefClient> client = browser_->GetClient();
  if (client.get()) {
    CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
    if (handler.get()) {
      CefRefPtr<CefJSDialogCallbackImpl> callbackPtr(
          new CefJSDialogCallbackImpl(callback));

      // Execute the user callback.
      bool handled = handler->OnBeforeUnloadDialog(browser_, message_text,
          is_reload, callbackPtr.get());
      if (handled)
        return;

      callbackPtr->Disconnect();
    }
  }

#if defined(OS_MACOSX) || defined(OS_WIN) || defined(TOOLKIT_GTK)
  if (dialog_.get()) {
    // Seriously!?
    callback.Run(true, base::string16());
    return;
  }

  base::string16 new_message_text =
      message_text +
      base::ASCIIToUTF16("\n\nIs it OK to leave/reload this page?");

  dialog_.reset(
      new CefJavaScriptDialog(this,
                              content::JAVASCRIPT_MESSAGE_TYPE_CONFIRM,
                              base::string16(),  // display_url
                              new_message_text,
                              base::string16(),  // default_prompt_text
                              callback));
#else
  // TODO(port): implement CefJavaScriptDialog for other platforms.
  callback.Run(true, base::string16());
  return;
#endif
}

void CefJavaScriptDialogManager::CancelActiveAndPendingDialogs(
    content::WebContents* web_contents) {
  CefRefPtr<CefClient> client = browser_->GetClient();
  if (client.get()) {
    CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
    if (handler.get()) {
      // Execute the user callback.
      handler->OnResetDialogState(browser_);
    }
  }

#if defined(OS_MACOSX) || defined(OS_WIN) || defined(TOOLKIT_GTK)
  if (dialog_.get()) {
    dialog_->Cancel();
    dialog_.reset();
  }
#endif
}

void CefJavaScriptDialogManager::WebContentsDestroyed(
    content::WebContents* web_contents) {
}

void CefJavaScriptDialogManager::DialogClosed(CefJavaScriptDialog* dialog) {
#if defined(OS_MACOSX) || defined(OS_WIN) || defined(TOOLKIT_GTK)
  DCHECK_EQ(dialog, dialog_.get());
  dialog_.reset();
  CefRefPtr<CefClient> client = browser_->GetClient();
  if (client.get()) {
    CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
    if (handler.get())
      handler->OnDialogClosed(browser_);
  }
#endif
}
<|endoftext|>