<commit_before>//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is the llc code generator driver. It provides a convenient
// command-line interface for generating native assembly-language code
// or C code, given LLVM bitcode.
//
//===----------------------------------------------------------------------===//

#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Support/IRReader.h"
#include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
#include "llvm/CodeGen/LinkAllCodegenComponents.h"
#include "llvm/Config/config.h"
#include "llvm/LinkAllVMCore.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/System/Host.h"
#include "llvm/System/Signals.h"
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include <memory>
using namespace llvm;

// General options for llc.  Other pass-specific options are specified
// within the corresponding llc passes, and target-specific options
// and back-end code generation options are specified with the target machine.
//
static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));

static cl::opt<bool>
Force("f", cl::desc("Enable binary output on terminals"));

// Determine optimization level.
static cl::opt<char>
OptLevel("O",
         cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
                  "(default = '-O2')"),
         cl::Prefix,
         cl::ZeroOrMore,
         cl::init(' '));

static cl::opt<std::string>
TargetTriple("mtriple", cl::desc("Override target triple for module"));

static cl::opt<std::string>
MArch("march", cl::desc("Architecture to generate code for (see --version)"));

static cl::opt<std::string>
MCPU("mcpu",
  cl::desc("Target a specific cpu type (-mcpu=help for details)"),
  cl::value_desc("cpu-name"),
  cl::init(""));

static cl::list<std::string>
MAttrs("mattr",
  cl::CommaSeparated,
  cl::desc("Target specific attributes (-mattr=help for details)"),
  cl::value_desc("a1,+a2,-a3,..."));

cl::opt<TargetMachine::CodeGenFileType>
FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
  cl::desc("Choose a file type (not all types are supported by all targets):"),
  cl::values(
       clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm",
                  "Emit an assembly ('.s') file"),
       clEnumValN(TargetMachine::CGFT_ObjectFile, "obj",
                  "Emit a native object ('.o') file [experimental]"),
       clEnumValN(TargetMachine::CGFT_Null, "null",
                  "Emit nothing, for performance testing"),
       clEnumValEnd));

cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
                       cl::desc("Do not verify input module"));

static cl::opt<bool>
DisableRedZone("disable-red-zone",
  cl::desc("Do not emit code that uses the red zone."),
  cl::init(false));

static cl::opt<bool>
NoImplicitFloats("no-implicit-float",
  cl::desc("Don't generate implicit floating point instructions (x86-only)"),
  cl::init(false));

// GetFileNameRoot - Helper function to get the basename of a filename.
static inline std::string
GetFileNameRoot(const std::string &InputFilename) {
  std::string IFN = InputFilename;
  std::string outputFilename;
  int Len = IFN.length();
  if ((Len > 2) &&
      IFN[Len-3] == '.' &&
      ((IFN[Len-2] == 'b' && IFN[Len-1] == 'c') ||
       (IFN[Len-2] == 'l' && IFN[Len-1] == 'l'))) {
    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
  } else {
    outputFilename = IFN;
  }
  return outputFilename;
}

static formatted_raw_ostream *GetOutputStream(const char *TargetName,
                                              const char *ProgName) {
  if (OutputFilename != "") {
    if (OutputFilename == "-")
      return &fouts();

    // Make sure that the Out file gets unlinked from the disk if we get a
    // SIGINT
    sys::RemoveFileOnSignal(sys::Path(OutputFilename));

    std::string error;
    raw_fd_ostream *FDOut =
      new raw_fd_ostream(OutputFilename.c_str(), error,
                         raw_fd_ostream::F_Binary);
    if (!error.empty()) {
      errs() << error << '\n';
      delete FDOut;
      return 0;
    }
    formatted_raw_ostream *Out =
      new formatted_raw_ostream(*FDOut, formatted_raw_ostream::DELETE_STREAM);

    return Out;
  }

  if (InputFilename == "-") {
    OutputFilename = "-";
    return &fouts();
  }

  OutputFilename = GetFileNameRoot(InputFilename);

  bool Binary = false;
  switch (FileType) {
  default: assert(0 && "Unknown file type");
  case TargetMachine::CGFT_AssemblyFile:
    if (TargetName[0] == 'c') {
      if (TargetName[1] == 0)
        OutputFilename += ".cbe.c";
      else if (TargetName[1] == 'p' && TargetName[2] == 'p')
        OutputFilename += ".cpp";
      else
        OutputFilename += ".s";
    } else
      OutputFilename += ".s";
    break;
  case TargetMachine::CGFT_ObjectFile:
    OutputFilename += ".o";
    Binary = true;
    break;
  case TargetMachine::CGFT_Null:
    OutputFilename += ".null";
    Binary = true;
    break;
  }

  // Make sure that the Out file gets unlinked from the disk if we get a
  // SIGINT
  sys::RemoveFileOnSignal(sys::Path(OutputFilename));

  std::string error;
  unsigned OpenFlags = 0;
  if (Binary) OpenFlags |= raw_fd_ostream::F_Binary;
  raw_fd_ostream *FDOut = new raw_fd_ostream(OutputFilename.c_str(), error,
                                             OpenFlags);
  if (!error.empty()) {
    errs() << error << '\n';
    delete FDOut;
    return 0;
  }

  formatted_raw_ostream *Out =
    new formatted_raw_ostream(*FDOut, formatted_raw_ostream::DELETE_STREAM);

  return Out;
}

// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);

  // Enable debug stream buffering.
  EnableDebugBuffering = true;

  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Initialize targets first, so that --version shows registered targets.
  InitializeAllTargets();
  InitializeAllAsmPrinters();

  cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");

  // Load the module to be compiled...
  SMDiagnostic Err;
  std::auto_ptr<Module> M;

  M.reset(ParseIRFile(InputFilename, Err, Context));
  if (M.get() == 0) {
    Err.Print(argv[0], errs());
    return 1;
  }
  Module &mod = *M.get();

  // If we are supposed to override the target triple, do so now.
  if (!TargetTriple.empty())
    mod.setTargetTriple(TargetTriple);

  Triple TheTriple(mod.getTargetTriple());
  if (TheTriple.getTriple().empty())
    TheTriple.setTriple(sys::getHostTriple());

  // Allocate target machine.  First, check whether the user has explicitly
  // specified an architecture to compile for. If so we have to look it up by
  // name, because it might be a backend that has no mapping to a target triple.
  const Target *TheTarget = 0;
  if (!MArch.empty()) {
    for (TargetRegistry::iterator it = TargetRegistry::begin(),
           ie = TargetRegistry::end(); it != ie; ++it) {
      if (MArch == it->getName()) {
        TheTarget = &*it;
        break;
      }
    }

    if (!TheTarget) {
      errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n";
      return 1;
    }

    // Adjust the triple to match (if known), otherwise stick with the
    // module/host triple.
    Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
    if (Type != Triple::UnknownArch)
      TheTriple.setArch(Type);
  } else {
    std::string Err;
    TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err);
    if (TheTarget == 0) {
      errs() << argv[0] << ": error auto-selecting target for module '"
             << Err << "'.  Please use the -march option to explicitly "
             << "pick a target.\n";
      return 1;
    }
  }

  // Package up features to be passed to target/subtarget
  std::string FeaturesStr;
  if (MCPU.size() || MAttrs.size()) {
    SubtargetFeatures Features;
    Features.setCPU(MCPU);
    for (unsigned i = 0; i != MAttrs.size(); ++i)
      Features.AddFeature(MAttrs[i]);
    FeaturesStr = Features.getString();
  }

  std::auto_ptr<TargetMachine>
    target(TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr));
  assert(target.get() && "Could not allocate target machine!");
  TargetMachine &Target = *target.get();

  // Figure out where we are going to send the output...
  formatted_raw_ostream *Out = GetOutputStream(TheTarget->getName(), argv[0]);
  if (Out == 0) return 1;

  CodeGenOpt::Level OLvl = CodeGenOpt::Default;
  switch (OptLevel) {
  default:
    errs() << argv[0] << ": invalid optimization level.\n";
    return 1;
  case ' ': break;
  case '0': OLvl = CodeGenOpt::None; break;
  case '1': OLvl = CodeGenOpt::Less; break;
  case '2': OLvl = CodeGenOpt::Default; break;
  case '3': OLvl = CodeGenOpt::Aggressive; break;
  }

  // If this target requires addPassesToEmitWholeFile, do it now.  This is
  // used by strange things like the C backend.
  if (Target.WantsWholeFile()) {
    PassManager PM;

    // Add the target data from the target machine, if it exists, or the module.
    if (const TargetData *TD = Target.getTargetData())
      PM.add(new TargetData(*TD));
    else
      PM.add(new TargetData(&mod));

    if (!NoVerify)
      PM.add(createVerifierPass());

    // Ask the target to add backend passes as necessary.
    if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, OLvl)) {
      errs() << argv[0] << ": target does not support generation of this"
             << " file type!\n";
      if (Out != &fouts()) delete Out;
      // And the Out file is empty and useless, so remove it now.
      sys::Path(OutputFilename).eraseFromDisk();
      return 1;
    }
    PM.run(mod);
  } else {
    // Build up all of the passes that we want to do to the module.
    FunctionPassManager Passes(M.get());

    // Add the target data from the target machine, if it exists, or the module.
    if (const TargetData *TD = Target.getTargetData())
      Passes.add(new TargetData(*TD));
    else
      Passes.add(new TargetData(&mod));

#ifndef NDEBUG
    if (!NoVerify)
      Passes.add(createVerifierPass());
#endif

    // Override default to generate verbose assembly.
    Target.setAsmVerbosityDefault(true);

    if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl)) {
      errs() << argv[0] << ": target does not support generation of this"
             << " file type!\n";
      if (Out != &fouts()) delete Out;
      // And the Out file is empty and useless, so remove it now.
      sys::Path(OutputFilename).eraseFromDisk();
      return 1;
    }

    Passes.doInitialization();

    // Run our queue of passes all at once now, efficiently.
    // TODO: this could lazily stream functions out of the module.
    for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I)
      if (!I->isDeclaration()) {
        if (DisableRedZone)
          I->addFnAttr(Attribute::NoRedZone);
        if (NoImplicitFloats)
          I->addFnAttr(Attribute::NoImplicitFloat);
        Passes.run(*I);
      }

    Passes.doFinalization();
  }

  // Delete the ostream if it's not a stdout stream
  if (Out != &fouts()) delete Out;

  return 0;
}
<commit_msg>Make llc opt into the addPassesToEmitFile verify pass.<commit_after>//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is the llc code generator driver. It provides a convenient
// command-line interface for generating native assembly-language code
// or C code, given LLVM bitcode.
//
//===----------------------------------------------------------------------===//

#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Support/IRReader.h"
#include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
#include "llvm/CodeGen/LinkAllCodegenComponents.h"
#include "llvm/Config/config.h"
#include "llvm/LinkAllVMCore.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/System/Host.h"
#include "llvm/System/Signals.h"
#include "llvm/Target/SubtargetFeature.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include <memory>
using namespace llvm;

// General options for llc.  Other pass-specific options are specified
// within the corresponding llc passes, and target-specific options
// and back-end code generation options are specified with the target machine.
//
static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));

static cl::opt<bool>
Force("f", cl::desc("Enable binary output on terminals"));

// Determine optimization level.
static cl::opt<char>
OptLevel("O",
         cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
                  "(default = '-O2')"),
         cl::Prefix,
         cl::ZeroOrMore,
         cl::init(' '));

static cl::opt<std::string>
TargetTriple("mtriple", cl::desc("Override target triple for module"));

static cl::opt<std::string>
MArch("march", cl::desc("Architecture to generate code for (see --version)"));

static cl::opt<std::string>
MCPU("mcpu",
  cl::desc("Target a specific cpu type (-mcpu=help for details)"),
  cl::value_desc("cpu-name"),
  cl::init(""));

static cl::list<std::string>
MAttrs("mattr",
  cl::CommaSeparated,
  cl::desc("Target specific attributes (-mattr=help for details)"),
  cl::value_desc("a1,+a2,-a3,..."));

cl::opt<TargetMachine::CodeGenFileType>
FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
  cl::desc("Choose a file type (not all types are supported by all targets):"),
  cl::values(
       clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm",
                  "Emit an assembly ('.s') file"),
       clEnumValN(TargetMachine::CGFT_ObjectFile, "obj",
                  "Emit a native object ('.o') file [experimental]"),
       clEnumValN(TargetMachine::CGFT_Null, "null",
                  "Emit nothing, for performance testing"),
       clEnumValEnd));

cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
                       cl::desc("Do not verify input module"));

static cl::opt<bool>
DisableRedZone("disable-red-zone",
  cl::desc("Do not emit code that uses the red zone."),
  cl::init(false));

static cl::opt<bool>
NoImplicitFloats("no-implicit-float",
  cl::desc("Don't generate implicit floating point instructions (x86-only)"),
  cl::init(false));

// GetFileNameRoot - Helper function to get the basename of a filename.
static inline std::string
GetFileNameRoot(const std::string &InputFilename) {
  std::string IFN = InputFilename;
  std::string outputFilename;
  int Len = IFN.length();
  if ((Len > 2) &&
      IFN[Len-3] == '.' &&
      ((IFN[Len-2] == 'b' && IFN[Len-1] == 'c') ||
       (IFN[Len-2] == 'l' && IFN[Len-1] == 'l'))) {
    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
  } else {
    outputFilename = IFN;
  }
  return outputFilename;
}

static formatted_raw_ostream *GetOutputStream(const char *TargetName,
                                              const char *ProgName) {
  if (OutputFilename != "") {
    if (OutputFilename == "-")
      return &fouts();

    // Make sure that the Out file gets unlinked from the disk if we get a
    // SIGINT
    sys::RemoveFileOnSignal(sys::Path(OutputFilename));

    std::string error;
    raw_fd_ostream *FDOut =
      new raw_fd_ostream(OutputFilename.c_str(), error,
                         raw_fd_ostream::F_Binary);
    if (!error.empty()) {
      errs() << error << '\n';
      delete FDOut;
      return 0;
    }
    formatted_raw_ostream *Out =
      new formatted_raw_ostream(*FDOut, formatted_raw_ostream::DELETE_STREAM);

    return Out;
  }

  if (InputFilename == "-") {
    OutputFilename = "-";
    return &fouts();
  }

  OutputFilename = GetFileNameRoot(InputFilename);

  bool Binary = false;
  switch (FileType) {
  default: assert(0 && "Unknown file type");
  case TargetMachine::CGFT_AssemblyFile:
    if (TargetName[0] == 'c') {
      if (TargetName[1] == 0)
        OutputFilename += ".cbe.c";
      else if (TargetName[1] == 'p' && TargetName[2] == 'p')
        OutputFilename += ".cpp";
      else
        OutputFilename += ".s";
    } else
      OutputFilename += ".s";
    break;
  case TargetMachine::CGFT_ObjectFile:
    OutputFilename += ".o";
    Binary = true;
    break;
  case TargetMachine::CGFT_Null:
    OutputFilename += ".null";
    Binary = true;
    break;
  }

  // Make sure that the Out file gets unlinked from the disk if we get a
  // SIGINT
  sys::RemoveFileOnSignal(sys::Path(OutputFilename));

  std::string error;
  unsigned OpenFlags = 0;
  if (Binary) OpenFlags |= raw_fd_ostream::F_Binary;
  raw_fd_ostream *FDOut = new raw_fd_ostream(OutputFilename.c_str(), error,
                                             OpenFlags);
  if (!error.empty()) {
    errs() << error << '\n';
    delete FDOut;
    return 0;
  }

  formatted_raw_ostream *Out =
    new formatted_raw_ostream(*FDOut, formatted_raw_ostream::DELETE_STREAM);

  return Out;
}

// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
  sys::PrintStackTraceOnErrorSignal();
  PrettyStackTraceProgram X(argc, argv);

  // Enable debug stream buffering.
  EnableDebugBuffering = true;

  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  // Initialize targets first, so that --version shows registered targets.
  InitializeAllTargets();
  InitializeAllAsmPrinters();

  cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");

  // Load the module to be compiled...
  SMDiagnostic Err;
  std::auto_ptr<Module> M;

  M.reset(ParseIRFile(InputFilename, Err, Context));
  if (M.get() == 0) {
    Err.Print(argv[0], errs());
    return 1;
  }
  Module &mod = *M.get();

  // If we are supposed to override the target triple, do so now.
  if (!TargetTriple.empty())
    mod.setTargetTriple(TargetTriple);

  Triple TheTriple(mod.getTargetTriple());
  if (TheTriple.getTriple().empty())
    TheTriple.setTriple(sys::getHostTriple());

  // Allocate target machine.  First, check whether the user has explicitly
  // specified an architecture to compile for. If so we have to look it up by
  // name, because it might be a backend that has no mapping to a target triple.
  const Target *TheTarget = 0;
  if (!MArch.empty()) {
    for (TargetRegistry::iterator it = TargetRegistry::begin(),
           ie = TargetRegistry::end(); it != ie; ++it) {
      if (MArch == it->getName()) {
        TheTarget = &*it;
        break;
      }
    }

    if (!TheTarget) {
      errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n";
      return 1;
    }

    // Adjust the triple to match (if known), otherwise stick with the
    // module/host triple.
    Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
    if (Type != Triple::UnknownArch)
      TheTriple.setArch(Type);
  } else {
    std::string Err;
    TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err);
    if (TheTarget == 0) {
      errs() << argv[0] << ": error auto-selecting target for module '"
             << Err << "'.  Please use the -march option to explicitly "
             << "pick a target.\n";
      return 1;
    }
  }

  // Package up features to be passed to target/subtarget
  std::string FeaturesStr;
  if (MCPU.size() || MAttrs.size()) {
    SubtargetFeatures Features;
    Features.setCPU(MCPU);
    for (unsigned i = 0; i != MAttrs.size(); ++i)
      Features.AddFeature(MAttrs[i]);
    FeaturesStr = Features.getString();
  }

  std::auto_ptr<TargetMachine>
    target(TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr));
  assert(target.get() && "Could not allocate target machine!");
  TargetMachine &Target = *target.get();

  // Figure out where we are going to send the output...
  formatted_raw_ostream *Out = GetOutputStream(TheTarget->getName(), argv[0]);
  if (Out == 0) return 1;

  CodeGenOpt::Level OLvl = CodeGenOpt::Default;
  switch (OptLevel) {
  default:
    errs() << argv[0] << ": invalid optimization level.\n";
    return 1;
  case ' ': break;
  case '0': OLvl = CodeGenOpt::None; break;
  case '1': OLvl = CodeGenOpt::Less; break;
  case '2': OLvl = CodeGenOpt::Default; break;
  case '3': OLvl = CodeGenOpt::Aggressive; break;
  }

  // Request that addPassesToEmitFile run the Verifier after running
  // passes which modify the IR.
#ifndef NDEBUG
  bool DisableVerify = false;
#else
  bool DisableVerify = true;
#endif

  // If this target requires addPassesToEmitWholeFile, do it now.  This is
  // used by strange things like the C backend.
  if (Target.WantsWholeFile()) {
    PassManager PM;

    // Add the target data from the target machine, if it exists, or the module.
    if (const TargetData *TD = Target.getTargetData())
      PM.add(new TargetData(*TD));
    else
      PM.add(new TargetData(&mod));

    if (!NoVerify)
      PM.add(createVerifierPass());

    // Ask the target to add backend passes as necessary.
    if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, OLvl,
                                        DisableVerify)) {
      errs() << argv[0] << ": target does not support generation of this"
             << " file type!\n";
      if (Out != &fouts()) delete Out;
      // And the Out file is empty and useless, so remove it now.
      sys::Path(OutputFilename).eraseFromDisk();
      return 1;
    }
    PM.run(mod);
  } else {
    // Build up all of the passes that we want to do to the module.
    FunctionPassManager Passes(M.get());

    // Add the target data from the target machine, if it exists, or the module.
    if (const TargetData *TD = Target.getTargetData())
      Passes.add(new TargetData(*TD));
    else
      Passes.add(new TargetData(&mod));

#ifndef NDEBUG
    if (!NoVerify)
      Passes.add(createVerifierPass());
#endif

    // Override default to generate verbose assembly.
    Target.setAsmVerbosityDefault(true);

    if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl,
                                   DisableVerify)) {
      errs() << argv[0] << ": target does not support generation of this"
             << " file type!\n";
      if (Out != &fouts()) delete Out;
      // And the Out file is empty and useless, so remove it now.
      sys::Path(OutputFilename).eraseFromDisk();
      return 1;
    }

    Passes.doInitialization();

    // Run our queue of passes all at once now, efficiently.
    // TODO: this could lazily stream functions out of the module.
    for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I)
      if (!I->isDeclaration()) {
        if (DisableRedZone)
          I->addFnAttr(Attribute::NoRedZone);
        if (NoImplicitFloats)
          I->addFnAttr(Attribute::NoImplicitFloat);
        Passes.run(*I);
      }

    Passes.doFinalization();
  }

  // Delete the ostream if it's not a stdout stream
  if (Out != &fouts()) delete Out;

  return 0;
}
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////
//
//      SneezyMUD++ 4.5 - All rights reserved, SneezyMUD Coding Team
//      "opal.cc" - Methods for TOpal class
//
//      Last revision December 18, 1997.
//
///////////////////////////////////////////////////////////////////////////

#include "stdsneezy.h"
#include "obj_opal.h"

TOpal::TOpal() :
  TObj(),
  psSize(0),
  psStrength(0),
  psMana(0),
  psFails(0)
{
}

TOpal::TOpal(const TOpal &a) :
  TObj(a),
  psSize(a.psSize),
  psStrength(a.psStrength),
  psMana(a.psMana),
  psFails(a.psFails)
{
}

TOpal & TOpal::operator=(const TOpal &a)
{
  if (this == &a) return *this;
  TObj::operator=(a);
  psSize = a.psSize;
  psStrength = a.psStrength;
  psMana = a.psMana;
  psFails = a.psFails;
  return *this;
}

TOpal::~TOpal()
{
}

int TOpal::psGetStrength() const
{
  return (psStrength);
}

void TOpal::psSetStrength(int num)
{
  psStrength = num;
}

void TOpal::psAddStrength(int num)
{
  psStrength += num;
}

int TOpal::psGetConsecFails() const
{
  return (psFails);
}

void TOpal::psSetConsecFails(int num)
{
  psFails = num;
}

void TOpal::psAddConsecFails(int num)
{
  psFails += num;
}

int TOpal::psGetMaxMana() const
{
  return (psStrength * 10);
}

int TOpal::psGetCarats() const
{
  return (psSize);
}

void TOpal::psSetCarats(int num)
{
  psSize = num;
}

void TOpal::assignFourValues(int x1, int x2, int x3, int x4)
{
  psSetCarats(x1);
  psSetStrength(x2);
  psSetConsecFails(x4);
}

void TOpal::getFourValues(int *x1, int *x2, int *x3, int *x4) const
{
  *x1 = psGetCarats();
  *x2 = psGetStrength();
  *x3 = -1;
  *x4 = psGetConsecFails();
}

int TOpal::objectSell(TBeing *ch, TMonster *keeper)
{
  keeper->doTell(ch->getName(), "I'm sorry, I don't buy back opal powerstones.");
  return TRUE;
}

sstring TOpal::statObjInfo() const
{
  char buf[256];

  sprintf(buf, "Carats: %d, Strength: %d, Consecutive Fails: %d",
                psGetCarats(),
                psGetStrength(),psGetConsecFails());

  sstring a(buf);
  return a;
}

void TOpal::describeObjectSpecifics(const TBeing *ch) const
{
}

TOpal *find_biggest_powerstone(TBeing *ch)
{
  TOpal *stone = NULL;
  TThing *t;
  int i;

  // Check through char's equipment -- only the biggest powerstone charges
  for (i = MIN_WEAR; i < MAX_WEAR; i++) {
    if (!(t = ch->equipment[i]))
      continue;

    t->powerstoneCheck(&stone);
  }
  // Check through char's inventory -- only the biggest powerstone charges
  for (t = ch->getStuff(); t; t = t->nextThing)
    t->powerstoneCheck(&stone);

  return stone;
}

void TOpal::powerstoneCheck(TOpal **topMax)
{
  if (!*topMax || (psGetStrength() > (*topMax)->psGetStrength()))
    *topMax = this;
}

int TOpal::suggestedPrice() const
{
  // these formulas are strictly for consistency and have not been evaluated
  // with respect to balance
  int str = psGetStrength();

  // first term increases based on how charged the powerstone is
  // second term is simply to make larger opals more expensive
  return (80 * str * str * str) + (100 * psGetCarats());
}

void TOpal::lowCheck()
{
  int ap = suggestedPrice();
  if (ap != obj_flags.cost && ap) {
    vlogf(LOG_LOW, fmt("Opal (%s:%d) has a bad price (%d).  should be (%d)") %
         getName() % objVnum() % obj_flags.cost % ap);
    obj_flags.cost = ap;
  }

  TObj::lowCheck();
}

<commit_msg>added a message to show if opal is at full strength or not<commit_after>///////////////////////////////////////////////////////////////////////////
//
//      SneezyMUD++ 4.5 - All rights reserved, SneezyMUD Coding Team
//      "opal.cc" - Methods for TOpal class
//
//      Last revision December 18, 1997.
//
///////////////////////////////////////////////////////////////////////////

#include "stdsneezy.h"
#include "obj_opal.h"

TOpal::TOpal() :
  TObj(),
  psSize(0),
  psStrength(0),
  psMana(0),
  psFails(0)
{
}

TOpal::TOpal(const TOpal &a) :
  TObj(a),
  psSize(a.psSize),
  psStrength(a.psStrength),
  psMana(a.psMana),
  psFails(a.psFails)
{
}

TOpal & TOpal::operator=(const TOpal &a)
{
  if (this == &a) return *this;
  TObj::operator=(a);
  psSize = a.psSize;
  psStrength = a.psStrength;
  psMana = a.psMana;
  psFails = a.psFails;
  return *this;
}

TOpal::~TOpal()
{
}

int TOpal::psGetStrength() const
{
  return (psStrength);
}

void TOpal::psSetStrength(int num)
{
  psStrength = num;
}

void TOpal::psAddStrength(int num)
{
  psStrength += num;
}

int TOpal::psGetConsecFails() const
{
  return (psFails);
}

void TOpal::psSetConsecFails(int num)
{
  psFails = num;
}

void TOpal::psAddConsecFails(int num)
{
  psFails += num;
}

int TOpal::psGetMaxMana() const
{
  return (psStrength * 10);
}

int TOpal::psGetCarats() const
{
  return (psSize);
}

void TOpal::psSetCarats(int num)
{
  psSize = num;
}

void TOpal::assignFourValues(int x1, int x2, int x3, int x4)
{
  psSetCarats(x1);
  psSetStrength(x2);
  psSetConsecFails(x4);
}

void TOpal::getFourValues(int *x1, int *x2, int *x3, int *x4) const
{
  *x1 = psGetCarats();
  *x2 = psGetStrength();
  *x3 = -1;
  *x4 = psGetConsecFails();
}

int TOpal::objectSell(TBeing *ch, TMonster *keeper)
{
  keeper->doTell(ch->getName(), "I'm sorry, I don't buy back opal powerstones.");
  return TRUE;
}

sstring TOpal::statObjInfo() const
{
  char buf[256];

  sprintf(buf, "Carats: %d, Strength: %d, Consecutive Fails: %d",
                psGetCarats(),
                psGetStrength(),psGetConsecFails());

  sstring a(buf);
  return a;
}

void TOpal::describeObjectSpecifics(const TBeing *ch) const
{
  if(psGetStrength() < psGetCarats())
    ch->sendTo(COLOR_OBJECTS, "Is is not at full strength.\n\r");
  else
    ch->sendTo(COLOR_OBJECTS, "Is is at full strength.\n\r");
}

TOpal *find_biggest_powerstone(TBeing *ch)
{
  TOpal *stone = NULL;
  TThing *t;
  int i;

  // Check through char's equipment -- only the biggest powerstone charges
  for (i = MIN_WEAR; i < MAX_WEAR; i++) {
    if (!(t = ch->equipment[i]))
      continue;

    t->powerstoneCheck(&stone);
  }
  // Check through char's inventory -- only the biggest powerstone charges
  for (t = ch->getStuff(); t; t = t->nextThing)
    t->powerstoneCheck(&stone);

  return stone;
}

void TOpal::powerstoneCheck(TOpal **topMax)
{
  if (!*topMax || (psGetStrength() > (*topMax)->psGetStrength()))
    *topMax = this;
}

int TOpal::suggestedPrice() const
{
  // these formulas are strictly for consistency and have not been evaluated
  // with respect to balance
  int str = psGetStrength();

  // first term increases based on how charged the powerstone is
  // second term is simply to make larger opals more expensive
  return (80 * str * str * str) + (100 * psGetCarats());
}

void TOpal::lowCheck()
{
  int ap = suggestedPrice();
  if (ap != obj_flags.cost && ap) {
    vlogf(LOG_LOW, fmt("Opal (%s:%d) has a bad price (%d).  should be (%d)") %
         getName() % objVnum() % obj_flags.cost % ap);
    obj_flags.cost = ap;
  }

  TObj::lowCheck();
}

<|endoftext|>


<commit_before>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "test.hpp"
#include "testutils/timing_test.hpp"

using namespace ::testing;
using ::testing::Return;

#define private public
#define protected public
#include "iceoryx_posh/internal/roudi/introspection/process_introspection.hpp"
#undef private
#undef protected

#include "iceoryx_posh/internal/popo/ports/publisher_port_data.hpp"
#include "mocks/chunk_mock.hpp"
#include "mocks/publisher_mock.hpp"

class MockPublisherPortUserIntrospection : public MockPublisherPortUser
{
  public:
    using Topic = iox::roudi::ProcessIntrospectionFieldTopic;

    MockPublisherPortUserIntrospection() = default;
    MockPublisherPortUserIntrospection(iox::popo::PublisherPortData*){};

    ChunkMock<Topic> m_chunk;

    iox::cxx::expected<iox::mepoo::ChunkHeader*, iox::popo::AllocationError> tryAllocateChunk(const uint32_t)
    {
        return iox::cxx::success<iox::mepoo::ChunkHeader*>(m_chunk.chunkHeader());
    }

    ChunkMock<Topic>* getChunk()
    {
        return &m_chunk;
    }
};

class ProcessIntrospectionAccess : public iox::roudi::ProcessIntrospection<MockPublisherPortUserIntrospection>
{
  public:
    using iox::roudi::ProcessIntrospection<MockPublisherPortUserIntrospection>::send;

    iox::cxx::optional<MockPublisherPortUserIntrospection>& getPublisherPort()
    {
        return this->m_publisherPort;
    }
};

class ProcessIntrospection_test : public Test
{
  public:
    using Topic = iox::roudi::ProcessIntrospectionFieldTopic;

    ProcessIntrospection_test()
    {
    }

    ~ProcessIntrospection_test()
    {
    }

    virtual void SetUp()
    {
        internal::CaptureStdout();
    }

    virtual void TearDown()
    {
        std::string output = internal::GetCapturedStdout();
        if (Test::HasFailure())
        {
            std::cout << output << std::endl;
        }
    }

    ChunkMock<Topic>* createMemoryChunkAndSend(ProcessIntrospectionAccess& introspectionAccess)
    {
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), sendChunk(_)).Times(1);

        introspectionAccess.send();

        return introspectionAccess.getPublisherPort().value().getChunk();
    }

    iox::mepoo::MemoryManager m_memoryManager;
    iox::capro::ServiceDescription m_serviceDescription;
    iox::popo::PublisherPortData m_publisherPortData{m_serviceDescription, "Foo", &m_memoryManager};
};

TEST_F(ProcessIntrospection_test, CTOR)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        EXPECT_THAT(introspectionAccess.getPublisherPort().has_value(), Eq(false));
    }
}

TEST_F(ProcessIntrospection_test, registerPublisherPort)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        introspectionAccess.registerPublisherPort(&m_publisherPortData);
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), stopOffer()).Times(1);
    }

    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, send)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        auto chunk = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk->sample()->m_processList.size(), Eq(0U));
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), stopOffer()).Times(1);
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, addRemoveProcess)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        const int PID = 42;
        const char PROCESS_NAME[] = "/chuck_norris";

        // invalid removal doesn't cause problems
        introspectionAccess.removeProcess(PID);
        auto chunk1 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk1->sample()->m_processList.size(), Eq(0U));

        // a new process should be sent
        introspectionAccess.addProcess(PID, iox::ProcessName_t(PROCESS_NAME));
        auto chunk2 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk2->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk2->sample()->m_processList[0].m_pid, Eq(PID));
        EXPECT_THAT(iox::ProcessName_t(PROCESS_NAME) == chunk2->sample()->m_processList[0].m_name, Eq(true));

        // list should be empty after removal
        introspectionAccess.removeProcess(PID);
        auto chunk3 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk3->sample()->m_processList.size(), Eq(0U));

        // if there isn't any change, no data are deliverd
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), sendChunk(_)).Times(0);
        introspectionAccess.send();
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, thread)
{
    {
        const int PID = 42;
        const char PROCESS_NAME[] = "/chuck_norris";

        ProcessIntrospectionAccess introspectionAccess;

        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), offer()).Times(1);
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), sendChunk(_)).Times(AtLeast(1));

        // we use the deliverChunk call to check how often the thread calls the send method
        std::chrono::milliseconds& sendIntervalSleep =
            const_cast<std::chrono::milliseconds&>(introspectionAccess.m_sendIntervalSleep);
        sendIntervalSleep = std::chrono::milliseconds(10);

        introspectionAccess.setSendInterval(10);
        introspectionAccess.run();

        for (size_t i = 0; i < 3; ++i)
        {
            introspectionAccess.addProcess(PID, iox::ProcessName_t(PROCESS_NAME));
            std::this_thread::sleep_for(std::chrono::milliseconds(15));
            introspectionAccess.removeProcess(PID);
            std::this_thread::sleep_for(std::chrono::milliseconds(15));
        }

        // within this time, the thread should have sent the 6 updates
        introspectionAccess.stop();
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, addRemoveNode)
{
    {
        ProcessIntrospectionAccess introspectionAccess;

        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        const int PID = 42;
        const char PROCESS_NAME[] = "/chuck_norris";
        const char NODE_1[] = "the_wrecking_crew";
        const char NODE_2[] = "the_octagon";
        const char NODE_3[] = "the_hitman";

        // invalid removal of unknown runnable of unknown process
        introspectionAccess.removeNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_1));
        auto chunk1 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk1->sample()->m_processList.size(), Eq(0U));

        // a new process
        introspectionAccess.addProcess(PID, iox::ProcessName_t(PROCESS_NAME));

        // invalid removal of unknown runnable of known process
        introspectionAccess.removeNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_1));
        auto chunk2 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk2->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk2->sample()->m_processList[0].m_nodes.size(), Eq(0U));

        // add a runnable
        introspectionAccess.addNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_1));
        auto chunk3 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk3->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk3->sample()->m_processList[0].m_nodes.size(), Eq(1U));

        // add it again, must be ignored
        introspectionAccess.addNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_1));
        auto chunk4 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk4->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk4->sample()->m_processList[0].m_nodes.size(), Eq(1U));

        // add some more
        introspectionAccess.addNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_2));
        introspectionAccess.addNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_3));
        auto chunk5 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk5->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk5->sample()->m_processList[0].m_nodes.size(), Eq(3U));

        // remove some runnables
        introspectionAccess.removeNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_1));
        introspectionAccess.removeNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_3));
        auto chunk6 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk6->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk6->sample()->m_processList[0].m_nodes.size(), Eq(1U));
        EXPECT_THAT(strcmp(NODE_2, chunk6->sample()->m_processList[0].m_nodes[0].c_str()), Eq(0));

        // remove last runnable list empty again
        introspectionAccess.removeNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_2));
        auto chunk7 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk7->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk7->sample()->m_processList[0].m_nodes.size(), Eq(0U));
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}
<commit_msg>iox-#252 Re-instantiate test<commit_after>// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "test.hpp"
#include "testutils/timing_test.hpp"

using namespace ::testing;
using ::testing::Return;

#define private public
#define protected public
#include "iceoryx_posh/internal/roudi/introspection/process_introspection.hpp"
#undef private
#undef protected

#include "iceoryx_posh/internal/popo/ports/publisher_port_data.hpp"
#include "mocks/chunk_mock.hpp"
#include "mocks/publisher_mock.hpp"

class MockPublisherPortUserIntrospection : public MockPublisherPortUser
{
  public:
    using Topic = iox::roudi::ProcessIntrospectionFieldTopic;

    MockPublisherPortUserIntrospection() = default;
    MockPublisherPortUserIntrospection(iox::popo::PublisherPortData*){};

    ChunkMock<Topic> m_chunk;

    iox::cxx::expected<iox::mepoo::ChunkHeader*, iox::popo::AllocationError> tryAllocateChunk(const uint32_t)
    {
        return iox::cxx::success<iox::mepoo::ChunkHeader*>(m_chunk.chunkHeader());
    }

    ChunkMock<Topic>* getChunk()
    {
        return &m_chunk;
    }
};

class ProcessIntrospectionAccess : public iox::roudi::ProcessIntrospection<MockPublisherPortUserIntrospection>
{
  public:
    using iox::roudi::ProcessIntrospection<MockPublisherPortUserIntrospection>::send;

    iox::cxx::optional<MockPublisherPortUserIntrospection>& getPublisherPort()
    {
        return this->m_publisherPort;
    }
};

class ProcessIntrospection_test : public Test
{
  public:
    using Topic = iox::roudi::ProcessIntrospectionFieldTopic;

    ProcessIntrospection_test()
    {
    }

    ~ProcessIntrospection_test()
    {
    }

    virtual void SetUp()
    {
        internal::CaptureStdout();
    }

    virtual void TearDown()
    {
        std::string output = internal::GetCapturedStdout();
        if (Test::HasFailure())
        {
            std::cout << output << std::endl;
        }
    }

    ChunkMock<Topic>* createMemoryChunkAndSend(ProcessIntrospectionAccess& introspectionAccess)
    {
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), sendChunk(_)).Times(1);

        introspectionAccess.send();

        return introspectionAccess.getPublisherPort().value().getChunk();
    }

    iox::mepoo::MemoryManager m_memoryManager;
    iox::capro::ServiceDescription m_serviceDescription;
    iox::popo::PublisherPortData m_publisherPortData{m_serviceDescription, "Foo", &m_memoryManager};
};

TEST_F(ProcessIntrospection_test, CTOR)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        EXPECT_THAT(introspectionAccess.getPublisherPort().has_value(), Eq(false));
    }
}

TEST_F(ProcessIntrospection_test, registerPublisherPort)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        introspectionAccess.registerPublisherPort(&m_publisherPortData);
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), stopOffer()).Times(1);
    }

    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, send)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        auto chunk = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk->sample()->m_processList.size(), Eq(0U));
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), stopOffer()).Times(1);
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, addRemoveProcess)
{
    {
        ProcessIntrospectionAccess introspectionAccess;
        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        const int PID = 42;
        const char PROCESS_NAME[] = "/chuck_norris";

        // invalid removal doesn't cause problems
        introspectionAccess.removeProcess(PID);
        auto chunk1 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk1->sample()->m_processList.size(), Eq(0U));

        // a new process should be sent
        introspectionAccess.addProcess(PID, iox::ProcessName_t(PROCESS_NAME));
        auto chunk2 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk2->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk2->sample()->m_processList[0].m_pid, Eq(PID));
        EXPECT_THAT(iox::ProcessName_t(PROCESS_NAME) == chunk2->sample()->m_processList[0].m_name, Eq(true));

        // list should be empty after removal
        introspectionAccess.removeProcess(PID);
        auto chunk3 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk3->sample()->m_processList.size(), Eq(0U));

        // if there isn't any change, no data are deliverd
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), sendChunk(_)).Times(0);
        introspectionAccess.send();
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, thread)
{
    {
        const int PID = 42;
        const char PROCESS_NAME[] = "/chuck_norris";

        ProcessIntrospectionAccess introspectionAccess;

        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), offer()).Times(1);
        EXPECT_CALL(introspectionAccess.getPublisherPort().value(), sendChunk(_)).Times(Between(4, 8));

        std::chrono::milliseconds& sendIntervalSleep =
            const_cast<std::chrono::milliseconds&>(introspectionAccess.m_sendIntervalSleep);
        sendIntervalSleep = std::chrono::milliseconds(10);

        introspectionAccess.setSendInterval(10);
        introspectionAccess.run();

        for (size_t i = 0; i < 3; ++i)
        {
            introspectionAccess.addProcess(PID, iox::ProcessName_t(PROCESS_NAME));
            std::this_thread::sleep_for(std::chrono::milliseconds(15));
            introspectionAccess.removeProcess(PID);
            std::this_thread::sleep_for(std::chrono::milliseconds(15));
        }

        introspectionAccess.stop();

        for (size_t i = 0; i < 3; ++i)
        // within this time, the thread should have sent the 6 updates
        {
            introspectionAccess.stop();
            std::this_thread::sleep_for(std::chrono::milliseconds(15));
            introspectionAccess.addProcess(PID, iox::ProcessName_t(PROCESS_NAME));
            std::this_thread::sleep_for(std::chrono::milliseconds(15));
            introspectionAccess.removeProcess(PID);
        }
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}

TEST_F(ProcessIntrospection_test, addRemoveNode)
{
    {
        ProcessIntrospectionAccess introspectionAccess;

        introspectionAccess.registerPublisherPort(&m_publisherPortData);

        const int PID = 42;
        const char PROCESS_NAME[] = "/chuck_norris";
        const char NODE_1[] = "the_wrecking_crew";
        const char NODE_2[] = "the_octagon";
        const char NODE_3[] = "the_hitman";

        // invalid removal of unknown runnable of unknown process
        introspectionAccess.removeNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_1));
        auto chunk1 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk1->sample()->m_processList.size(), Eq(0U));

        // a new process
        introspectionAccess.addProcess(PID, iox::ProcessName_t(PROCESS_NAME));

        // invalid removal of unknown runnable of known process
        introspectionAccess.removeNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_1));
        auto chunk2 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk2->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk2->sample()->m_processList[0].m_nodes.size(), Eq(0U));

        // add a runnable
        introspectionAccess.addNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_1));
        auto chunk3 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk3->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk3->sample()->m_processList[0].m_nodes.size(), Eq(1U));

        // add it again, must be ignored
        introspectionAccess.addNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_1));
        auto chunk4 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk4->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk4->sample()->m_processList[0].m_nodes.size(), Eq(1U));

        // add some more
        introspectionAccess.addNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_2));
        introspectionAccess.addNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_3));
        auto chunk5 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk5->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk5->sample()->m_processList[0].m_nodes.size(), Eq(3U));

        // remove some runnables
        introspectionAccess.removeNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_1));
        introspectionAccess.removeNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_3));
        auto chunk6 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk6->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk6->sample()->m_processList[0].m_nodes.size(), Eq(1U));
        EXPECT_THAT(strcmp(NODE_2, chunk6->sample()->m_processList[0].m_nodes[0].c_str()), Eq(0));

        // remove last runnable list empty again
        introspectionAccess.removeNode(iox::ProcessName_t(PROCESS_NAME), iox::NodeName_t(NODE_2));
        auto chunk7 = createMemoryChunkAndSend(introspectionAccess);
        EXPECT_THAT(chunk7->sample()->m_processList.size(), Eq(1U));
        EXPECT_THAT(chunk7->sample()->m_processList[0].m_nodes.size(), Eq(0U));
    }
    // stopOffer was called
    EXPECT_THAT(m_publisherPortData.m_offeringRequested, Eq(false));
}
<|endoftext|>


<commit_before>#include "maintenancetool.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QDebug>

MaintenanceTool::MaintenanceTool(QObject *parent) :
  QObject(parent)
, m_state(MaintenanceTool::NotRunning)
, m_hasUpdate(false)
{
  //プロセスが開始時のシグナル
  connect(&m_process, SIGNAL(started()), this, SLOT(processStarted()));
  //プロセスが終了時のシグナル
  connect(&m_process, SIGNAL(finished(int, QProcess::ExitStatus))
          , this, SLOT(processFinished(int, QProcess::ExitStatus)));
  //プロセスがエラー終了時のシグナル
  connect(&m_process, SIGNAL(error(QProcess::ProcessError))
          , this, SLOT(processError(QProcess::ProcessError)));
}

//更新の確認開始
void MaintenanceTool::checkUpdate()
{
  startMaintenanceTool(MaintenanceTool::CheckUpdate);
}

void MaintenanceTool::startMaintenanceTool(StartMode mode)
{
  //フルパスを作成（カレントがどこにあるかわからないので）
  QString toolName;
  QString path;
#if defined(Q_OS_WIN)
  toolName = "maintenancetool.exe";
#elif defined(Q_OS_MAC)
  toolName = "../../../maintenancetool.app/Contents/MacOS/maintenancetool";
#else
  toolName = "maintenancetool";
#endif
  path = QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(toolName);
  qDebug() << path;

  QStringList args;
  if(mode == MaintenanceTool::CheckUpdate){
    //プロセスが動いてなかったら実行
    if(m_process.state() == QProcess::NotRunning){
      //取得していた情報などをクリア
      setUpdateDetails(QString());
      setHasUpdate(false);
      //アップデート確認用のオプションを設定                            [1]
      args.append("--checkupdates");
      //実行
      m_process.start(path, args);
    }else{
      qDebug() << "Already started.";
    }
  }else{
    //更新用のオプションを設定                                   [2]
    args.append("--updater");
    //メンテツールの通常起動はプロセス管理しない
    QProcess::startDetached(path, args);
  }
}
//メンテツールの状態
MaintenanceTool::ProcessState MaintenanceTool::state() const
{
  return m_state;
}
void MaintenanceTool::setState(ProcessState state)
{
  if(m_state == state)  return;
  m_state = state;
  emit stateChanged(m_state);
}
//更新があるかの取得
bool MaintenanceTool::hasUpdate() const
{
  return m_hasUpdate;
}
void MaintenanceTool::setHasUpdate(bool hasUpdate)
{
  if(m_hasUpdate == hasUpdate)  return;
  m_hasUpdate = hasUpdate;
  emit hasUpdateChanged(m_hasUpdate);
}
//更新の詳細情報
QString MaintenanceTool::updateDetails() const
{
  return m_updateDetails;
}
void MaintenanceTool::setUpdateDetails(const QString &updateDetail)
{
  m_updateDetails = updateDetail;
}

//プロセスが開始
void MaintenanceTool::processStarted()
{
  setState(MaintenanceTool::Running);
}
//プロセスが終了
void MaintenanceTool::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
  qDebug() << "exitCode=" << exitCode << ", exitStatus=" << exitStatus;

  if(exitCode == 0){
    //アップデートあり

    //標準出力を取得する                                         [3]
    QByteArray stdOut = m_process.readAllStandardOutput();
    QString stdOutStr = QString::fromLocal8Bit(stdOut);
    qDebug() << "out>" << stdOutStr;
    //exitCode= 0 , exitStatus= 0
    //out> "[0] Warning: Could not create lock file 'C:/Program Files (x86)/HelloWorld/lockmyApp15021976.lock': アクセスが拒否されました。
    // (0x00000005)
    //<updates>
    //    <update version="0.3.0-1" name="The root component" size="175748"/>
    //</updates>
    //
    //"
    //err> ""

    //アップデート情報のタグ部分だけ抽出する                             [4]
    QString xmlStr;
    QStringList lines;
    bool enabled = false;
    lines = stdOutStr.split("\n");
    foreach (const QString &line, lines) {
      if(line.startsWith("<updates>")){
        enabled = true;
        xmlStr.append(line);
      }else if(line.endsWith("</updates>")){
        xmlStr.append(line);
        break;
      }else if(enabled){
        xmlStr.append(line);
      }else{
      }
    }
    //取得した情報などを設定
    if(xmlStr.length() > 0){
      setUpdateDetails(xmlStr);
      setHasUpdate(true);
    }
    //停止状態に変更
    setState(MaintenanceTool::NotRunning);

  }else if(exitCode == 1){
    //アップデートなし
    QByteArray stdErr = m_process.readAllStandardError();
    QString stdErrStr = QString::fromLocal8Bit(stdErr);
    qDebug() << "err>" << stdErrStr;

    //exitCode= 1 , exitStatus= 0
    //out> "[0] Warning: Could not create lock file 'C:/Program Files (x86)/HelloWorld/lockmyApp15021976.lock': アクセスが拒否されました。
    // (0x00000005)
    //"
    //err> "There are currently no updates available.
    //"

    //停止状態に変更
    setState(MaintenanceTool::NotRunning);
  }else{
    //停止状態に変更
    setState(MaintenanceTool::NotRunning);
  }
}
//プロセスがエラー
void MaintenanceTool::processError(QProcess::ProcessError error)
{
  qDebug() << error;
  setState(MaintenanceTool::NotRunning);
}

<commit_msg>fix helloworld update setter<commit_after>#include "maintenancetool.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QDebug>

MaintenanceTool::MaintenanceTool(QObject *parent) :
  QObject(parent)
, m_state(MaintenanceTool::NotRunning)
, m_hasUpdate(false)
{
  //プロセスが開始時のシグナル
  connect(&m_process, SIGNAL(started()), this, SLOT(processStarted()));
  //プロセスが終了時のシグナル
  connect(&m_process, SIGNAL(finished(int, QProcess::ExitStatus))
          , this, SLOT(processFinished(int, QProcess::ExitStatus)));
  //プロセスがエラー終了時のシグナル
  connect(&m_process, SIGNAL(error(QProcess::ProcessError))
          , this, SLOT(processError(QProcess::ProcessError)));
}

//更新の確認開始
void MaintenanceTool::checkUpdate()
{
  startMaintenanceTool(MaintenanceTool::CheckUpdate);
}

void MaintenanceTool::startMaintenanceTool(StartMode mode)
{
  //フルパスを作成（カレントがどこにあるかわからないので）
  QString toolName;
  QString path;
#if defined(Q_OS_WIN)
  toolName = "maintenancetool.exe";
#elif defined(Q_OS_MAC)
  toolName = "../../../maintenancetool.app/Contents/MacOS/maintenancetool";
#else
  toolName = "maintenancetool";
#endif
  path = QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(toolName);
  qDebug() << path;

  QStringList args;
  if(mode == MaintenanceTool::CheckUpdate){
    //プロセスが動いてなかったら実行
    if(m_process.state() == QProcess::NotRunning){
      //取得していた情報などをクリア
      setUpdateDetails(QString());
      setHasUpdate(false);
      //アップデート確認用のオプションを設定                            [1]
      args.append("--checkupdates");
      //実行
      m_process.start(path, args);
    }else{
      qDebug() << "Already started.";
    }
  }else{
    //更新用のオプションを設定                                   [2]
    args.append("--updater");
    //メンテツールの通常起動はプロセス管理しない
    QProcess::startDetached(path, args);
  }
}
//メンテツールの状態
MaintenanceTool::ProcessState MaintenanceTool::state() const
{
  return m_state;
}
void MaintenanceTool::setState(ProcessState state)
{
  if(m_state == state)  return;
  m_state = state;
  emit stateChanged(m_state);
}
//更新があるかの取得
bool MaintenanceTool::hasUpdate() const
{
  return m_hasUpdate;
}
void MaintenanceTool::setHasUpdate(bool hasUpdate)
{
  if(m_hasUpdate == hasUpdate)  return;
  m_hasUpdate = hasUpdate;
  emit hasUpdateChanged(m_hasUpdate);
}
//更新の詳細情報
QString MaintenanceTool::updateDetails() const
{
  return m_updateDetails;
}
void MaintenanceTool::setUpdateDetails(const QString &updateDetails)
{
  if(m_updateDetails == updateDetails) return;
  m_updateDetails = updateDetails;
  emit updateDetailsChanged(m_updateDetails);
}

//プロセスが開始
void MaintenanceTool::processStarted()
{
  setState(MaintenanceTool::Running);
}
//プロセスが終了
void MaintenanceTool::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
  qDebug() << "exitCode=" << exitCode << ", exitStatus=" << exitStatus;

  if(exitCode == 0){
    //アップデートあり

    //標準出力を取得する                                         [3]
    QByteArray stdOut = m_process.readAllStandardOutput();
    QString stdOutStr = QString::fromLocal8Bit(stdOut);
    qDebug() << "out>" << stdOutStr;
    //exitCode= 0 , exitStatus= 0
    //out> "[0] Warning: Could not create lock file 'C:/Program Files (x86)/HelloWorld/lockmyApp15021976.lock': アクセスが拒否されました。
    // (0x00000005)
    //<updates>
    //    <update version="0.3.0-1" name="The root component" size="175748"/>
    //</updates>
    //
    //"
    //err> ""

    //アップデート情報のタグ部分だけ抽出する                             [4]
    QString xmlStr;
    QStringList lines;
    bool enabled = false;
    lines = stdOutStr.split("\n");
    foreach (const QString &line, lines) {
      if(line.startsWith("<updates>")){
        enabled = true;
        xmlStr.append(line);
      }else if(line.endsWith("</updates>")){
        xmlStr.append(line);
        break;
      }else if(enabled){
        xmlStr.append(line);
      }else{
      }
    }
    //取得した情報などを設定
    if(xmlStr.length() > 0){
      setUpdateDetails(xmlStr);
      setHasUpdate(true);
    }
    //停止状態に変更
    setState(MaintenanceTool::NotRunning);

  }else if(exitCode == 1){
    //アップデートなし
    QByteArray stdErr = m_process.readAllStandardError();
    QString stdErrStr = QString::fromLocal8Bit(stdErr);
    qDebug() << "err>" << stdErrStr;

    //exitCode= 1 , exitStatus= 0
    //out> "[0] Warning: Could not create lock file 'C:/Program Files (x86)/HelloWorld/lockmyApp15021976.lock': アクセスが拒否されました。
    // (0x00000005)
    //"
    //err> "There are currently no updates available.
    //"

    //停止状態に変更
    setState(MaintenanceTool::NotRunning);
  }else{
    //停止状態に変更
    setState(MaintenanceTool::NotRunning);
  }
}
//プロセスがエラー
void MaintenanceTool::processError(QProcess::ProcessError error)
{
  qDebug() << error;
  setState(MaintenanceTool::NotRunning);
}

<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/lattice/trajectory1d/piecewise_jerk_trajectory1d.h"

#include <algorithm>

#include "modules/common/log.h"
#include "modules/planning/common/planning_gflags.h"

#include <iostream>

namespace apollo {
namespace planning {

PiecewiseJerkTrajectory1d::PiecewiseJerkTrajectory1d(
    const double p, const double v, const double a) {
  last_p_ = p;
  last_v_ = v;
  last_a_ = a;
  param_.push_back(0.0);
}

void PiecewiseJerkTrajectory1d::AppendSegment(
    const double jerk, const double param) {
  CHECK_GT(param, FLAGS_lattice_epsilon);

  param_.push_back(param_.back() + param);

  segments_.emplace_back(last_p_, last_v_, last_a_, jerk, param);

  last_p_ = segments_.back().end_position();

  last_v_ = segments_.back().end_velocity();

  last_a_ = segments_.back().end_acceleration();
}

double PiecewiseJerkTrajectory1d::Evaluate(const std::uint32_t order,
    const double param) const {
  if (!(param >= 0.0)) {
    std::cout << "param:\t" << param << std::endl;
    CHECK(false);
  }

  auto it_lower = std::lower_bound(param_.begin(), param_.end(), param);

  if (it_lower == param_.begin()) {
    return segments_[0].Evaluate(order, param);
  }

  if (it_lower == param_.end()) {
    auto index = std::max(0, static_cast<int>(param_.size() - 2));
    return segments_.back().Evaluate(0, param - param_[index]);
  }

  auto index = std::distance(param_.begin(), it_lower);
  return segments_[index - 1].Evaluate(0, param - param_[index - 1]);

  // int index = std::max(0,
  //      static_cast<int>(std::distance(param_.begin(), it_lower)) - 1);

  // AINFO << "index = " << index << " out of size = " << segments_.size();

  // return segments_[index].Evaluate(order, param - param_[index]);
}

double PiecewiseJerkTrajectory1d::ParamLength() const {
  return param_.back();
}

std::string PiecewiseJerkTrajectory1d::ToString() const {
  return "";
}

}  // namespace planning
}  // namespace apollo
<commit_msg>Planning: fix piecewise trajectory evaluate<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/lattice/trajectory1d/piecewise_jerk_trajectory1d.h"

#include <algorithm>

#include "modules/common/log.h"
#include "modules/planning/common/planning_gflags.h"

#include <iostream>

namespace apollo {
namespace planning {

PiecewiseJerkTrajectory1d::PiecewiseJerkTrajectory1d(
    const double p, const double v, const double a) {
  last_p_ = p;
  last_v_ = v;
  last_a_ = a;
  param_.push_back(0.0);
}

void PiecewiseJerkTrajectory1d::AppendSegment(
    const double jerk, const double param) {
  CHECK_GT(param, FLAGS_lattice_epsilon);

  param_.push_back(param_.back() + param);

  segments_.emplace_back(last_p_, last_v_, last_a_, jerk, param);

  last_p_ = segments_.back().end_position();

  last_v_ = segments_.back().end_velocity();

  last_a_ = segments_.back().end_acceleration();
}

double PiecewiseJerkTrajectory1d::Evaluate(const std::uint32_t order,
    const double param) const {
  if (!(param >= 0.0)) {
    std::cout << "param:\t" << param << std::endl;
    CHECK(false);
  }

  auto it_lower = std::lower_bound(param_.begin(), param_.end(), param);

  if (it_lower == param_.begin()) {
    return segments_[0].Evaluate(order, param);
  }

  if (it_lower == param_.end()) {
    auto index = std::max(0, static_cast<int>(param_.size() - 2));
    return segments_.back().Evaluate(order, param - param_[index]);
  }

  auto index = std::distance(param_.begin(), it_lower);
  return segments_[index - 1].Evaluate(order, param - param_[index - 1]);

  // int index = std::max(0,
  //      static_cast<int>(std::distance(param_.begin(), it_lower)) - 1);

  // AINFO << "index = " << index << " out of size = " << segments_.size();

  // return segments_[index].Evaluate(order, param - param_[index]);
}

double PiecewiseJerkTrajectory1d::ParamLength() const {
  return param_.back();
}

std::string PiecewiseJerkTrajectory1d::ToString() const {
  return "";
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>void games()
{
   // This macro runs three "games" that each nicely illustrate
   // some of the graphics capabilities of ROOT. Thanks to the
   // clever usage of TTimer objects it looks like they are all
   // executing in parallel (emulation of multi-threading).
   // It uses the small classes generated in $ROOTSYS/test/Hello,
   // Aclock, Tetris

   Bool_t UNIX = strcmp(gSystem->GetName(), "Unix") == 0;
   Int_t st1 = gSystem->Load("$(ROOTSYS)/test/Aclock");
   if (st1 == -1) {
      printf("===>The macro games will try to build the Aclock library\n");
      if (UNIX)
         gSystem->Exec("(cd $ROOTSYS/test; make Aclock.so)");
      else
         gSystem->Exec("(cd %ROOTSYS%\\test && nmake Aclock.dll)");

      st1 = gSystem->Load("$(ROOTSYS)/test/Aclock");
   }
   Int_t st2 = gSystem->Load("$(ROOTSYS)/test/Hello");
   if (st2 == -1) {
      printf("===>The macro games will try to build the Hello library\n");
      if (UNIX)
         gSystem->Exec("(cd $ROOTSYS/test; make Hello.so)");
      else
         gSystem->Exec("(cd %ROOTSYS%\\test && nmake Hello.dll)");

      st2 = gSystem->Load("$(ROOTSYS)/test/Hello");
   }
   Int_t st3 = gSystem->Load("$(ROOTSYS)/test/Tetris");
   if (st3 == -1) {
      if (UNIX) {
         printf("===>The macro games will try to build the Tetris library\n");
         gSystem->Exec("(cd $ROOTSYS/test; make Tetris.so)");
         st3 = gSystem->Load("$(ROOTSYS)/test/Tetris");
      } else {
         printf(" Sorry! No tetris for Windows yet.");
         st3 = 0;
      }
   }

   if (st1 || st2 || st3) {
      printf("ERROR: one of the shared libs in $ROOTSYS/test didn't load properly\n");
      return;
   }

   // run the dancing Hello World
   Hello *hello = new Hello();

   // run the analog clock
   Aclock *clock = new Aclock();

   // run the Tetris game
   if (UNIX) Tetris *tetris = new Tetris();
}
<commit_msg>Tetris works on Windows<commit_after>void games()
{
   // This macro runs three "games" that each nicely illustrate
   // some of the graphics capabilities of ROOT. Thanks to the
   // clever usage of TTimer objects it looks like they are all
   // executing in parallel (emulation of multi-threading).
   // It uses the small classes generated in $ROOTSYS/test/Hello,
   // Aclock, Tetris

   Bool_t UNIX = strcmp(gSystem->GetName(), "Unix") == 0;
   Int_t st1 = gSystem->Load("$(ROOTSYS)/test/Aclock");
   if (st1 == -1) {
      printf("===>The macro games will try to build the Aclock library\n");
      if (UNIX)
         gSystem->Exec("(cd $ROOTSYS/test; make Aclock.so)");
      else
         gSystem->Exec("(cd %ROOTSYS%\\test && nmake Aclock.dll)");

      st1 = gSystem->Load("$(ROOTSYS)/test/Aclock");
   }
   Int_t st2 = gSystem->Load("$(ROOTSYS)/test/Hello");
   if (st2 == -1) {
      printf("===>The macro games will try to build the Hello library\n");
      if (UNIX)
         gSystem->Exec("(cd $ROOTSYS/test; make Hello.so)");
      else
         gSystem->Exec("(cd %ROOTSYS%\\test && nmake Hello.dll)");

      st2 = gSystem->Load("$(ROOTSYS)/test/Hello");
   }
   Int_t st3 = gSystem->Load("$(ROOTSYS)/test/Tetris");
   if (st3 == -1) {
      if (UNIX) {
         printf("===>The macro games will try to build the Tetris library\n");
         gSystem->Exec("(cd $ROOTSYS/test; make Tetris.so)");
      } else {
         gSystem->Exec("(cd $ROOTSYS/test; nmake Tetris.dll)");
      }
      st3 = gSystem->Load("$(ROOTSYS)/test/Tetris");
   }

   if (st1 || st2 || st3) {
      printf("ERROR: one of the shared libs in $ROOTSYS/test didn't load properly\n");
      return;
   }

   // run the dancing Hello World
   Hello *hello = new Hello();

   // run the analog clock
   Aclock *clock = new Aclock();

   // run the Tetris game
   if (UNIX) Tetris *tetris = new Tetris();
}
<|endoftext|>


<commit_before>// This macro gets in memory an histogram from a root file
// and fits a user defined function.
// Note that a user defined function must always be defined
// as in this example:
//  - first parameter: array of variables (in this example only 1-dimension)
//  - second parameter: array of parameters
// Note also that in case of user defined functions, one must set
// an initial value for each parameter.

Double_t fitf(Double_t *x, Double_t *par)
{
   Double_t arg = 0;
   if (par[2]) arg = (x[0] - par[1])/par[2];

   Double_t fitval = par[0]*TMath::Exp(-0.5*arg*arg);
   return fitval;
}
void myfit()
{
   TFile *f = new TFile("hsimple.root");

   TCanvas *c1 = new TCanvas("c1","the fit canvas",500,400);

   TH1F *hpx = (TH1F*)f->Get("hpx");

// Creates a Root function based on function fitf above
   TF1 *func = new TF1("fitf",fitf,-2,2,3);

// Sets initial values and parameter names
   func->SetParameters(100,0,1);
   func->SetParNames("Constant","Mean_value","Sigma");

// Fit histogram in range defined by function
   hpx->Fit(func,"r");

// Gets integral of function between fit limits
   printf("Integral of function = %g\n",func->Integral(-2,2));
}
<commit_msg>Replace test   if ((par[2]) by  if ((par[2] != 0)<commit_after>// This macro gets in memory an histogram from a root file
// and fits a user defined function.
// Note that a user defined function must always be defined
// as in this example:
//  - first parameter: array of variables (in this example only 1-dimension)
//  - second parameter: array of parameters
// Note also that in case of user defined functions, one must set
// an initial value for each parameter.

Double_t fitf(Double_t *x, Double_t *par)
{
   Double_t arg = 0;
   if (par[2] != 0) arg = (x[0] - par[1])/par[2];

   Double_t fitval = par[0]*TMath::Exp(-0.5*arg*arg);
   return fitval;
}
void myfit()
{
   TFile *f = new TFile("hsimple.root");

   TCanvas *c1 = new TCanvas("c1","the fit canvas",500,400);

   TH1F *hpx = (TH1F*)f->Get("hpx");

// Creates a Root function based on function fitf above
   TF1 *func = new TF1("fitf",fitf,-2,2,3);

// Sets initial values and parameter names
   func->SetParameters(100,0,1);
   func->SetParNames("Constant","Mean_value","Sigma");

// Fit histogram in range defined by function
   hpx->Fit(func,"r");

// Gets integral of function between fit limits
   printf("Integral of function = %g\n",func->Integral(-2,2));
}
<|endoftext|>


<commit_before>#include <array>
#include <memory>

template <class T>
using ref = std::shared_ptr<T>;

struct base {
    virtual ~base() { }
};

template <class T, std::size_t... Is>
static std::array<T, sizeof...(Is) + 1> push(const std::array<T, sizeof...(Is)>& firsts, T&& last) {
    return {std::get<Is>(firsts)..., std::move(last)};
}

template <class T, std::size_t... Is>
static std::array<T, sizeof...(Is) + 1> push(std::array<T, sizeof...(Is)>&& firsts, T&& last) {
    return {std::move(std::get<Is>(firsts))..., std::move(last)};
}

template <class T, std::size_t... Is>
static std::array<T, sizeof...(Is)> set(std::array<T, sizeof...(Is)>&& firsts, std::size_t index, T&& value) {
    return { std::move(Is == index ? value : std::get<Is>(firsts))...};
}

template <class T, std::size_t... Is>
static std::array<T, sizeof...(Is)> set(const std::array<T, sizeof...(Is)>& firsts, std::size_t index, const T& value) {
    return { (Is == index ? value : std::get<Is>(firsts))...};
}

template<class T, std::size_t N>
struct chunk: base {
    using values_type = std::array<T, N>;
    values_type values;
    chunk(values_type values): values(std::move(values)) { }

};

template <class T, std::size_t B, std::size_t L, std::size_t D>
struct node: chunk<ref<base>, (1ul << B)> {
    using node::chunk::node;
    // inner node
};

template <class T, std::size_t B, std::size_t L>
struct node<T, B, L, 0>: chunk<T, (1ul << L)> {
    using node::chunk::node;
    // leaf node
};

template <class T, std::size_t B, std::size_t L>
class hamt {
    static constexpr std::size_t bits = sizeof(std::size_t) * 8;
    static_assert(L <= bits, "size error");
    static constexpr std::size_t depth = (bits - L) / B;

    using root_type = node<T, B, L, depth>;
    ref<root_type> root;
public:
    bool empty() const { return !bool(root); }
};

int main(int, char** ) {

    return 0;
}
<commit_msg>split<commit_after>// -*- compile-command: "c++ -std=c++14 hamt2.cpp -o hamt" -*-

#include <array>
#include <memory>

template <class T>
using ref = std::shared_ptr<T>;

struct base {
    virtual ~base() { }
};

template <class T, std::size_t... Is>
static std::array<T, sizeof...(Is) + 1> push(const std::array<T, sizeof...(Is)>& firsts, T&& last) {
    return {std::get<Is>(firsts)..., std::move(last)};
}

template <class T, std::size_t... Is>
static std::array<T, sizeof...(Is) + 1> push(std::array<T, sizeof...(Is)>&& firsts, T&& last) {
    return {std::move(std::get<Is>(firsts))..., std::move(last)};
}

template <class T, std::size_t... Is>
static std::array<T, sizeof...(Is)> set(std::array<T, sizeof...(Is)>&& firsts, std::size_t index, T&& value) {
    return { std::move(Is == index ? value : std::get<Is>(firsts))...};
}

template <class T, std::size_t... Is>
static std::array<T, sizeof...(Is)> set(const std::array<T, sizeof...(Is)>& firsts, std::size_t index, const T& value) {
    return { (Is == index ? value : std::get<Is>(firsts))...};
}

template<class T, std::size_t N>
struct chunk: base {
    using values_type = std::array<T, N>;
    values_type values;
    chunk(values_type values): values(std::move(values)) { }

};

template <class T, std::size_t B, std::size_t L, std::size_t D>
struct node: chunk<ref<base>, (1ul << B)> {
    using node::chunk::node;
    // inner node
};

template <class T, std::size_t B, std::size_t L>
struct node<T, B, L, 0>: chunk<T, (1ul << L)> {
    using node::chunk::node;
    // leaf node
};

namespace detail {
  template<std::size_t B, std::size_t L, std::size_t D>
  static constexpr std::size_t mask() {
    return ((1ul << (L + 1)) - 1) << (D * B);
  }

  template<std::size_t B, std::size_t L, std::size_t D>
  static constexpr std::size_t offset() {
    return D ? L + (D - 1) * B : 0;
  }

  template<std::size_t B, std::size_t L, std::size_t ... Ds>
  static constexpr std::array<std::size_t, sizeof...(Ds)> make_masks(std::index_sequence<Ds...>) {
    return {mask<B, L, Ds>()...};
  }

  template<std::size_t B, std::size_t L, std::size_t ... Ds>
  static constexpr std::array<std::size_t, sizeof...(Ds)> make_offsets(std::index_sequence<Ds...>) {
    return {offset<B, L, Ds>()...};
  }

  template<std::size_t B, std::size_t L, std::size_t ... Ds>
  static std::array<std::size_t, sizeof...(Ds)> split(const std::array<std::size_t, sizeof...(Ds)>& masks,
                                                      const std::array<std::size_t, sizeof...(Ds)>& offsets,
                                                      std::size_t index, std::index_sequence<Ds...>) {
    return {((index & masks[Ds]) >> offsets[Ds])...};
  }

}

template <class T, std::size_t B, std::size_t L>
class hamt {
    static constexpr std::size_t bits = sizeof(std::size_t) * 8;
    static_assert(L <= bits, "size error");
    static constexpr std::size_t depth = (bits - L) / B;

    using indices = std::make_index_sequence<depth>;
    static constexpr auto masks = make_masks<B, L>(indices{});
    static constexpr auto offsets = make_offsets<B, L>(indices{});

    using root_type = node<T, B, L, depth>;
    ref<root_type> root;

public:
    bool empty() const { return !bool(root); }

    const T& get(std::size_t index) const {
        auto split = detail::split(masks, offsets, index, indices{});
        return get(split, root);
    }
};

int main(int, char** ) {

    return 0;
}
<|endoftext|>