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

#include "swift/Frontend/FrontendOptions.h"

#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/Option/Options.h"
#include "swift/Parse/Lexer.h"
#include "swift/Strings.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/Path.h"

using namespace swift;
using namespace llvm::opt;

bool FrontendInputs::shouldTreatAsLLVM() const {
  if (hasSingleInput()) {
    StringRef Input(getFilenameOfFirstInput());
    return llvm::sys::path::extension(Input).endswith(LLVM_BC_EXTENSION) ||
           llvm::sys::path::extension(Input).endswith(LLVM_IR_EXTENSION);
  }
  return false;
}

bool FrontendInputs::shouldTreatAsSIL() const {
  if (hasSingleInput()) {
    // If we have exactly one input filename, and its extension is "sil",
    // treat the input as SIL.
    StringRef Input(getFilenameOfFirstInput());
    return llvm::sys::path::extension(Input).endswith(SIL_EXTENSION);
  }
  // If we have one primary input and it's a filename with extension "sil",
  // treat the input as SIL.
  unsigned silPrimaryCount = numberOfPrimaryInputsEndingWith(SIL_EXTENSION);
  if (silPrimaryCount == 0)
    return false;
  if (silPrimaryCount == primaryInputCount())
    return true;
  llvm_unreachable("Either all primaries or none must end with .sil");
}

unsigned
FrontendInputs::numberOfPrimaryInputsEndingWith(const char *extension) const {
  return count_if(
      PrimaryInputs, [&](const llvm::StringMapEntry<unsigned> &elem) -> bool {
        StringRef filename = AllFiles[elem.second].getFile();
        return llvm::sys::path::extension(filename).endswith(extension);
      });
}

bool FrontendInputs::verifyInputs(DiagnosticEngine &diags, bool treatAsSIL,
                                  bool isREPLRequested,
                                  bool isNoneRequested) const {
  if (isREPLRequested) {
    if (hasInputs()) {
      diags.diagnose(SourceLoc(), diag::error_repl_requires_no_input_files);
      return true;
    }
  } else if (treatAsSIL) {
    if (isWholeModule()) {
      if (inputCount() != 1) {
        diags.diagnose(SourceLoc(), diag::error_mode_requires_one_input_file);
        return true;
      }
    } else {
      assertMustNotBeMoreThanOnePrimaryInput();
      // If we have the SIL as our primary input, we can waive the one file
      // requirement as long as all the other inputs are SIBs.
      if (!areAllNonPrimariesSIB()) {
        diags.diagnose(SourceLoc(),
                       diag::error_mode_requires_one_sil_multi_sib);
        return true;
      }
    }
  } else if (!isNoneRequested && !hasInputs()) {
    diags.diagnose(SourceLoc(), diag::error_mode_requires_an_input_file);
    return true;
  }
  return false;
}

bool FrontendInputs::areAllNonPrimariesSIB() const {
  for (const InputFile &input : getAllFiles()) {
    assert(!input.getFile().empty() && "all files have (perhaps pseudo) names");
    if (input.getIsPrimary())
      continue;
    if (!llvm::sys::path::extension(input.getFile()).endswith(SIB_EXTENSION)) {
      return false;
    }
  }
  return true;
}

bool FrontendOptions::needsProperModuleName(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::DumpParse:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::DumpInterfaceHash:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
    return false;
  case ActionType::EmitPCH:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitModuleOnly:
  case ActionType::MergeModules:
    return true;
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;
  case ActionType::EmitAssembly:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
    return true;
  }
  llvm_unreachable("Unknown ActionType");
}

bool FrontendOptions::isActionImmediate(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::DumpParse:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::DumpInterfaceHash:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::EmitPCH:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitModuleOnly:
  case ActionType::MergeModules:
    return false;
  case ActionType::Immediate:
  case ActionType::REPL:
    return true;
  case ActionType::EmitAssembly:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
    return false;
  }
  llvm_unreachable("Unknown ActionType");
}

void FrontendOptions::forAllOutputPaths(
    std::function<void(const std::string &)> fn) const {
  if (RequestedAction != FrontendOptions::ActionType::EmitModuleOnly &&
      RequestedAction != FrontendOptions::ActionType::MergeModules) {
    for (const std::string &OutputFileName : OutputFilenames) {
      fn(OutputFileName);
    }
  }
  const std::string *outputs[] = {
    &ModuleOutputPath,
    &ModuleDocOutputPath,
    &ObjCHeaderOutputPath
  };
  for (const std::string *next : outputs) {
    if (!next->empty())
      fn(*next);
  }
}

StringRef FrontendOptions::originalPath() const {
  if (hasNamedOutputFile())
    // Put the serialized diagnostics file next to the output file.
    return getSingleOutputFilename();

  // If we have a primary input, so use that as the basis for the name of the
  // serialized diagnostics file, otherwise fall back on the
  // module name.
  const auto input = Inputs.getUniquePrimaryInput();
  return input ? llvm::sys::path::filename(input->getFile())
               : StringRef(ModuleName);
}

bool FrontendOptions::isOutputFileDirectory() const {
  return hasNamedOutputFile() &&
         llvm::sys::fs::is_directory(getSingleOutputFilename());
}

const char *
FrontendOptions::suffixForPrincipalOutputFileForAction(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
    return nullptr;

  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::DumpParse:
  case ActionType::DumpInterfaceHash:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
    return nullptr;

  case ActionType::EmitPCH:
    return PCH_EXTENSION;

  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
    return SIL_EXTENSION;

  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
    return SIB_EXTENSION;

  case ActionType::MergeModules:
  case ActionType::EmitModuleOnly:
    return SERIALIZED_MODULE_EXTENSION;

  case ActionType::Immediate:
  case ActionType::REPL:
    // These modes have no frontend-generated output.
    return nullptr;

  case ActionType::EmitAssembly:
    return "s";

  case ActionType::EmitIR:
    return "ll";

  case ActionType::EmitBC:
    return "bc";

  case ActionType::EmitObject:
    return "o";

  case ActionType::EmitImportedModules:
    return "importedmodules";
  }
}

bool FrontendOptions::hasUnusedDependenciesFilePath() const {
  return !DependenciesFilePath.empty() &&
         !canActionEmitDependencies(RequestedAction);
}

bool FrontendOptions::canActionEmitDependencies(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::DumpParse:
  case ActionType::DumpInterfaceHash:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;
  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::MergeModules:
  case ActionType::EmitModuleOnly:
  case ActionType::EmitPCH:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitAssembly:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
    return true;
  }
}

bool FrontendOptions::hasUnusedObjCHeaderOutputPath() const {
  return !ObjCHeaderOutputPath.empty() && !canActionEmitHeader(RequestedAction);
}

bool FrontendOptions::canActionEmitHeader(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::DumpParse:
  case ActionType::DumpInterfaceHash:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::PrintAST:
  case ActionType::EmitPCH:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;
  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::MergeModules:
  case ActionType::EmitModuleOnly:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitAssembly:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
    return true;
  }
}

bool FrontendOptions::hasUnusedLoadedModuleTracePath() const {
  return !LoadedModuleTracePath.empty() &&
         !canActionEmitLoadedModuleTrace(RequestedAction);
}

bool FrontendOptions::canActionEmitLoadedModuleTrace(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::Parse:
  case ActionType::DumpParse:
  case ActionType::DumpInterfaceHash:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;
  case ActionType::Typecheck:
  case ActionType::MergeModules:
  case ActionType::EmitModuleOnly:
  case ActionType::EmitPCH:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitAssembly:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
    return true;
  }
}

bool FrontendOptions::hasUnusedModuleOutputPath() const {
  return !ModuleOutputPath.empty() && !canActionEmitModule(RequestedAction);
}

bool FrontendOptions::hasUnusedModuleDocOutputPath() const {
  return !ModuleDocOutputPath.empty() && !canActionEmitModule(RequestedAction);
}

bool FrontendOptions::canActionEmitModule(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::DumpParse:
  case ActionType::DumpInterfaceHash:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::PrintAST:
  case ActionType::EmitPCH:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::EmitSILGen:
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;
  case ActionType::MergeModules:
  case ActionType::EmitModuleOnly:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitAssembly:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
    return true;
  }
}

bool FrontendOptions::canActionEmitModuleDoc(ActionType action) {
  return canActionEmitModule(action);
}

bool FrontendOptions::doesActionProduceOutput(ActionType action) {
  switch (action) {
  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::DumpParse:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::DumpInterfaceHash:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::EmitPCH:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitModuleOnly:
  case ActionType::EmitAssembly:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
  case ActionType::MergeModules:
    return true;

  case ActionType::NoneAction:
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;
  }
  llvm_unreachable("Unknown ActionType");
}

bool FrontendOptions::doesActionProduceTextualOutput(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::EmitPCH:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::MergeModules:
  case ActionType::EmitModuleOnly:
  case ActionType::EmitBC:
  case ActionType::EmitObject:
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;

  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::DumpParse:
  case ActionType::DumpInterfaceHash:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::EmitImportedModules:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitAssembly:
  case ActionType::EmitIR:
    return true;
  }
}
<commit_msg>Added assertion for single primary to shouldTreatAsSIL<commit_after>//===--- FrontendOptions.cpp ----------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/Frontend/FrontendOptions.h"

#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/Option/Options.h"
#include "swift/Parse/Lexer.h"
#include "swift/Strings.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/Path.h"

using namespace swift;
using namespace llvm::opt;

bool FrontendInputs::shouldTreatAsLLVM() const {
  if (hasSingleInput()) {
    StringRef Input(getFilenameOfFirstInput());
    return llvm::sys::path::extension(Input).endswith(LLVM_BC_EXTENSION) ||
           llvm::sys::path::extension(Input).endswith(LLVM_IR_EXTENSION);
  }
  return false;
}

bool FrontendInputs::shouldTreatAsSIL() const {
  if (hasSingleInput()) {
    // If we have exactly one input filename, and its extension is "sil",
    // treat the input as SIL.
    StringRef Input(getFilenameOfFirstInput());
    return llvm::sys::path::extension(Input).endswith(SIL_EXTENSION);
  }
  // If we have one primary input and it's a filename with extension "sil",
  // treat the input as SIL.
  unsigned silPrimaryCount = numberOfPrimaryInputsEndingWith(SIL_EXTENSION);
  if (silPrimaryCount == 0)
    return false;
  if (silPrimaryCount == primaryInputCount()) {
    // Not clear what to do someday with multiple primaries
    assertMustNotBeMoreThanOnePrimaryInput();
    return true;
  }
  llvm_unreachable("Either all primaries or none must end with .sil");
}

unsigned
FrontendInputs::numberOfPrimaryInputsEndingWith(const char *extension) const {
  return count_if(
      PrimaryInputs, [&](const llvm::StringMapEntry<unsigned> &elem) -> bool {
        StringRef filename = AllFiles[elem.second].getFile();
        return llvm::sys::path::extension(filename).endswith(extension);
      });
}

bool FrontendInputs::verifyInputs(DiagnosticEngine &diags, bool treatAsSIL,
                                  bool isREPLRequested,
                                  bool isNoneRequested) const {
  if (isREPLRequested) {
    if (hasInputs()) {
      diags.diagnose(SourceLoc(), diag::error_repl_requires_no_input_files);
      return true;
    }
  } else if (treatAsSIL) {
    if (isWholeModule()) {
      if (inputCount() != 1) {
        diags.diagnose(SourceLoc(), diag::error_mode_requires_one_input_file);
        return true;
      }
    } else {
      assertMustNotBeMoreThanOnePrimaryInput();
      // If we have the SIL as our primary input, we can waive the one file
      // requirement as long as all the other inputs are SIBs.
      if (!areAllNonPrimariesSIB()) {
        diags.diagnose(SourceLoc(),
                       diag::error_mode_requires_one_sil_multi_sib);
        return true;
      }
    }
  } else if (!isNoneRequested && !hasInputs()) {
    diags.diagnose(SourceLoc(), diag::error_mode_requires_an_input_file);
    return true;
  }
  return false;
}

bool FrontendInputs::areAllNonPrimariesSIB() const {
  for (const InputFile &input : getAllFiles()) {
    assert(!input.getFile().empty() && "all files have (perhaps pseudo) names");
    if (input.getIsPrimary())
      continue;
    if (!llvm::sys::path::extension(input.getFile()).endswith(SIB_EXTENSION)) {
      return false;
    }
  }
  return true;
}

bool FrontendOptions::needsProperModuleName(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::DumpParse:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::DumpInterfaceHash:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
    return false;
  case ActionType::EmitPCH:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitModuleOnly:
  case ActionType::MergeModules:
    return true;
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;
  case ActionType::EmitAssembly:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
    return true;
  }
  llvm_unreachable("Unknown ActionType");
}

bool FrontendOptions::isActionImmediate(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::DumpParse:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::DumpInterfaceHash:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::EmitPCH:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitModuleOnly:
  case ActionType::MergeModules:
    return false;
  case ActionType::Immediate:
  case ActionType::REPL:
    return true;
  case ActionType::EmitAssembly:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
    return false;
  }
  llvm_unreachable("Unknown ActionType");
}

void FrontendOptions::forAllOutputPaths(
    std::function<void(const std::string &)> fn) const {
  if (RequestedAction != FrontendOptions::ActionType::EmitModuleOnly &&
      RequestedAction != FrontendOptions::ActionType::MergeModules) {
    for (const std::string &OutputFileName : OutputFilenames) {
      fn(OutputFileName);
    }
  }
  const std::string *outputs[] = {
    &ModuleOutputPath,
    &ModuleDocOutputPath,
    &ObjCHeaderOutputPath
  };
  for (const std::string *next : outputs) {
    if (!next->empty())
      fn(*next);
  }
}

StringRef FrontendOptions::originalPath() const {
  if (hasNamedOutputFile())
    // Put the serialized diagnostics file next to the output file.
    return getSingleOutputFilename();

  // If we have a primary input, so use that as the basis for the name of the
  // serialized diagnostics file, otherwise fall back on the
  // module name.
  const auto input = Inputs.getUniquePrimaryInput();
  return input ? llvm::sys::path::filename(input->getFile())
               : StringRef(ModuleName);
}

bool FrontendOptions::isOutputFileDirectory() const {
  return hasNamedOutputFile() &&
         llvm::sys::fs::is_directory(getSingleOutputFilename());
}

const char *
FrontendOptions::suffixForPrincipalOutputFileForAction(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
    return nullptr;

  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::DumpParse:
  case ActionType::DumpInterfaceHash:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
    return nullptr;

  case ActionType::EmitPCH:
    return PCH_EXTENSION;

  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
    return SIL_EXTENSION;

  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
    return SIB_EXTENSION;

  case ActionType::MergeModules:
  case ActionType::EmitModuleOnly:
    return SERIALIZED_MODULE_EXTENSION;

  case ActionType::Immediate:
  case ActionType::REPL:
    // These modes have no frontend-generated output.
    return nullptr;

  case ActionType::EmitAssembly:
    return "s";

  case ActionType::EmitIR:
    return "ll";

  case ActionType::EmitBC:
    return "bc";

  case ActionType::EmitObject:
    return "o";

  case ActionType::EmitImportedModules:
    return "importedmodules";
  }
}

bool FrontendOptions::hasUnusedDependenciesFilePath() const {
  return !DependenciesFilePath.empty() &&
         !canActionEmitDependencies(RequestedAction);
}

bool FrontendOptions::canActionEmitDependencies(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::DumpParse:
  case ActionType::DumpInterfaceHash:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;
  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::MergeModules:
  case ActionType::EmitModuleOnly:
  case ActionType::EmitPCH:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitAssembly:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
    return true;
  }
}

bool FrontendOptions::hasUnusedObjCHeaderOutputPath() const {
  return !ObjCHeaderOutputPath.empty() && !canActionEmitHeader(RequestedAction);
}

bool FrontendOptions::canActionEmitHeader(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::DumpParse:
  case ActionType::DumpInterfaceHash:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::PrintAST:
  case ActionType::EmitPCH:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;
  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::MergeModules:
  case ActionType::EmitModuleOnly:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitAssembly:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
    return true;
  }
}

bool FrontendOptions::hasUnusedLoadedModuleTracePath() const {
  return !LoadedModuleTracePath.empty() &&
         !canActionEmitLoadedModuleTrace(RequestedAction);
}

bool FrontendOptions::canActionEmitLoadedModuleTrace(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::Parse:
  case ActionType::DumpParse:
  case ActionType::DumpInterfaceHash:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;
  case ActionType::Typecheck:
  case ActionType::MergeModules:
  case ActionType::EmitModuleOnly:
  case ActionType::EmitPCH:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitAssembly:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
    return true;
  }
}

bool FrontendOptions::hasUnusedModuleOutputPath() const {
  return !ModuleOutputPath.empty() && !canActionEmitModule(RequestedAction);
}

bool FrontendOptions::hasUnusedModuleDocOutputPath() const {
  return !ModuleDocOutputPath.empty() && !canActionEmitModule(RequestedAction);
}

bool FrontendOptions::canActionEmitModule(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::DumpParse:
  case ActionType::DumpInterfaceHash:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::PrintAST:
  case ActionType::EmitPCH:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::EmitSILGen:
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;
  case ActionType::MergeModules:
  case ActionType::EmitModuleOnly:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitAssembly:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
    return true;
  }
}

bool FrontendOptions::canActionEmitModuleDoc(ActionType action) {
  return canActionEmitModule(action);
}

bool FrontendOptions::doesActionProduceOutput(ActionType action) {
  switch (action) {
  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::DumpParse:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::DumpInterfaceHash:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::EmitPCH:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::EmitModuleOnly:
  case ActionType::EmitAssembly:
  case ActionType::EmitIR:
  case ActionType::EmitBC:
  case ActionType::EmitObject:
  case ActionType::EmitImportedModules:
  case ActionType::MergeModules:
    return true;

  case ActionType::NoneAction:
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;
  }
  llvm_unreachable("Unknown ActionType");
}

bool FrontendOptions::doesActionProduceTextualOutput(ActionType action) {
  switch (action) {
  case ActionType::NoneAction:
  case ActionType::EmitPCH:
  case ActionType::EmitSIBGen:
  case ActionType::EmitSIB:
  case ActionType::MergeModules:
  case ActionType::EmitModuleOnly:
  case ActionType::EmitBC:
  case ActionType::EmitObject:
  case ActionType::Immediate:
  case ActionType::REPL:
    return false;

  case ActionType::Parse:
  case ActionType::Typecheck:
  case ActionType::DumpParse:
  case ActionType::DumpInterfaceHash:
  case ActionType::DumpAST:
  case ActionType::EmitSyntax:
  case ActionType::PrintAST:
  case ActionType::DumpScopeMaps:
  case ActionType::DumpTypeRefinementContexts:
  case ActionType::EmitImportedModules:
  case ActionType::EmitSILGen:
  case ActionType::EmitSIL:
  case ActionType::EmitAssembly:
  case ActionType::EmitIR:
    return true;
  }
}
<|endoftext|>


<commit_before>//The MIT License (MIT)
//
//Copyright (c) 2015
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.

#include "LFX2.h" //Can be found as part of the AlienFX SDK
#include "ProcessHandler.h"
#include <iostream>

bool gProcError = false;

FARPROC WINAPI GetProcAddress_s (__in HMODULE hModule, __in LPCSTR lpProcName)
{
	FARPROC out = GetProcAddress(hModule, lpProcName);
	if(out == NULL)
	{
		gProcError = true;
	}
	return out;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	HINSTANCE hLibrary = LoadLibrary(L"LightFX.dll");
	if(hLibrary)
	{
		LFX2INITIALIZE LFX_Initialize = (LFX2INITIALIZE)GetProcAddress_s(hLibrary, LFX_DLL_INITIALIZE);
		LFX2RELEASE LFX_Release = (LFX2RELEASE)GetProcAddress_s(hLibrary, LFX_DLL_RELEASE);
		LFX2RESET LFX_Reset = (LFX2RESET)GetProcAddress_s(hLibrary,LFX_DLL_RESET);
		LFX2UPDATE LFX_Update = (LFX2UPDATE)GetProcAddress_s(hLibrary, LFX_DLL_UPDATE);
		LFX2LIGHT LFX_Light = (LFX2LIGHT)GetProcAddress_s(hLibrary,LFX_DLL_LIGHT);

		if(gProcError)
		{
			MessageBox(0,L"ERROR: LightFX.dll does not contain a required function",0,0);
			return 2;
		}

		BYTE* pHealth = nullptr;
		HANDLE hProcess = OpenFirstSupportedProcess(&pHealth);

		if(hProcess && pHealth)
		{
			LFX_Initialize();

			int playerHealth = 0;
			int playerMaxHealth = 0;

			int readBuf = NULL;
			SIZE_T numofbytesread = NULL;

			while(ReadProcessMemory(hProcess,pHealth,&readBuf,sizeof(int),&numofbytesread))
			{
				if(playerHealth != readBuf) //prevents updating unnecessarily
				{
					playerHealth = readBuf;

					if(playerHealth > playerMaxHealth)
						playerMaxHealth = playerHealth;

					LFX_Reset();

					unsigned int brightness = (playerMaxHealth-playerHealth)*0x1000000;
					unsigned int lightSettings = LFX_RED | brightness;

					LFX_Light(LFX_ALL,lightSettings);
					LFX_Update();

					if(playerHealth <= 0) //Fix for lights on instant death from maximum health
						playerMaxHealth = 1;

					Sleep(10);
				}
			}

			LFX_Release();
			CloseHandle(hProcess);
			FreeLibrary(hLibrary);
		}
		else
		{
			MessageBox(0,L"ERROR: Couldn't find a supported process\nClosing health monitor",0,0);
			FreeLibrary(hLibrary);
			return 1;
		}
	}
	else
	{
		MessageBox(0,L"ERROR: Couldn't load LightFX.dll\n",0,0);
	}
	return 0;
}<commit_msg>Optimized for Fewer Idle Updates<commit_after>//The MIT License (MIT)
//
//Copyright (c) 2015
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.

#include "LFX2.h" //Can be found as part of the AlienFX SDK
#include "ProcessHandler.h"
#include <iostream>

bool gProcError = false;

FARPROC WINAPI GetProcAddress_s (__in HMODULE hModule, __in LPCSTR lpProcName)
{
	FARPROC out = GetProcAddress(hModule, lpProcName);
	if(out == NULL)
	{
		gProcError = true;
	}
	return out;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	HINSTANCE hLibrary = LoadLibrary(L"LightFX.dll");
	if(hLibrary)
	{
		LFX2INITIALIZE LFX_Initialize = (LFX2INITIALIZE)GetProcAddress_s(hLibrary, LFX_DLL_INITIALIZE);
		LFX2RELEASE LFX_Release = (LFX2RELEASE)GetProcAddress_s(hLibrary, LFX_DLL_RELEASE);
		LFX2RESET LFX_Reset = (LFX2RESET)GetProcAddress_s(hLibrary,LFX_DLL_RESET);
		LFX2UPDATE LFX_Update = (LFX2UPDATE)GetProcAddress_s(hLibrary, LFX_DLL_UPDATE);
		LFX2LIGHT LFX_Light = (LFX2LIGHT)GetProcAddress_s(hLibrary,LFX_DLL_LIGHT);

		if(gProcError)
		{
			MessageBox(0,L"ERROR: LightFX.dll does not contain a required function",0,0);
			return 2;
		}

		BYTE* pHealth = nullptr;
		HANDLE hProcess = OpenFirstSupportedProcess(&pHealth);

		if(hProcess && pHealth)
		{
			LFX_Initialize();

			int playerHealth = 0;
			int playerMaxHealth = 0;

			int readBuf = NULL;
			SIZE_T numofbytesread = NULL;

			while(ReadProcessMemory(hProcess,pHealth,&readBuf,sizeof(int),&numofbytesread))
			{
				if(playerHealth != readBuf) //prevents updating unnecessarily
				{
					playerHealth = readBuf;

					if(playerHealth > playerMaxHealth)
						playerMaxHealth = playerHealth;

					LFX_Reset();

					unsigned int brightness = (playerMaxHealth-playerHealth)*0x1000000;
					unsigned int lightSettings = LFX_RED | brightness;

					LFX_Light(LFX_ALL,lightSettings);
					LFX_Update();

					if(playerHealth <= 0) //Fix for lights on instant death from maximum health
						playerMaxHealth = 1;
				}

				Sleep(10);
			}

			LFX_Release();
			CloseHandle(hProcess);
			FreeLibrary(hLibrary);
		}
		else
		{
			MessageBox(0,L"ERROR: Couldn't find a supported process\nClosing health monitor",0,0);
			FreeLibrary(hLibrary);
			return 1;
		}
	}
	else
	{
		MessageBox(0,L"ERROR: Couldn't load LightFX.dll\n",0,0);
	}
	return 0;
}<|endoftext|>


<commit_before>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file gaussian_filter_kf_test.cpp
 * \date Febuary 2015
 * \author Jan Issac (jan.issac@gmail.com)
 */

#include <gtest/gtest.h>
#include "../typecast.hpp"

#include <Eigen/Dense>

#include "gaussian_filter_test_suite.hpp"

#include <fl/filter/gaussian/unscented_transform.hpp>
#include <fl/filter/gaussian/monte_carlo_transform.hpp>
#include <fl/filter/gaussian/gaussian_filter_ukf.hpp>

template <int StateDimension, int InputDimension, int ObsrvDimension>
struct UnscentedKalmanFilterTestConfiguration
{
    enum: signed int
    {
        StateDim = StateDimension,
        InputDim = InputDimension,
        ObsrvDim = ObsrvDimension
    };

    template <typename StateTransitionModel, typename ObservationModel>
    struct FilterDefinition
    {
        typedef fl::GaussianFilter<
                    StateTransitionModel,
                    ObservationModel,
                    fl::UnscentedTransform
                > Type;
    };

    template <typename F, typename H>
    static typename FilterDefinition<F, H>::Type create_filter(F&& f, H&& h)
    {
        return typename FilterDefinition<F, H>::Type(f, h, fl::UnscentedTransform());
    }
};

typedef ::testing::Types<
            fl::StaticTest<UnscentedKalmanFilterTestConfiguration<3, 1, 2>>,
            fl::StaticTest<UnscentedKalmanFilterTestConfiguration<3, 3, 10>>,
            fl::StaticTest<UnscentedKalmanFilterTestConfiguration<10, 10, 20>>,

            fl::DynamicTest<UnscentedKalmanFilterTestConfiguration<3, 1, 2>>,
            fl::DynamicTest<UnscentedKalmanFilterTestConfiguration<3, 3, 10>>,
            fl::DynamicTest<UnscentedKalmanFilterTestConfiguration<10, 10, 20>>
        > TestTypes;

INSTANTIATE_TYPED_TEST_CASE_P(UnscentedKalmanFilterTest,
                              GaussianFilterTest,
                              TestTypes);
<commit_msg>Updated test implementation<commit_after>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file gaussian_filter_kf_test.cpp
 * \date Febuary 2015
 * \author Jan Issac (jan.issac@gmail.com)
 */

#include <gtest/gtest.h>
#include "../typecast.hpp"

#include <Eigen/Dense>

#include "gaussian_filter_test_suite.hpp"
#include <fl/util/meta.hpp>
#include <fl/filter/gaussian/gaussian_filter.hpp>

template <int StateDimension, int InputDimension, int ObsrvDimension>
struct UnscentedKalmanFilterTestConfiguration
{
    enum: signed int
    {
        StateDim = StateDimension,
        InputDim = InputDimension,
        ObsrvDim = ObsrvDimension
    };

    template <typename StateTransitionModel, typename ObservationModel>
    struct FilterDefinition
    {
        typedef fl::SigmaPointQuadrature<fl::UnscentedTransform> Quadrature;

        typedef fl::GaussianFilter<
                        StateTransitionModel,
                        ObservationModel,
                        Quadrature
                > Type;
    };

    template <typename F, typename H>
    static typename FilterDefinition<F, H>::Type create_filter(F&& f, H&& h)
    {
        return typename FilterDefinition<F, H>::Type(
            f, h, fl::SigmaPointQuadrature<fl::UnscentedTransform>(
                        fl::UnscentedTransform()));
    }
};

typedef ::testing::Types<
            fl::StaticTest<UnscentedKalmanFilterTestConfiguration<3, 1, 2>>,
            fl::StaticTest<UnscentedKalmanFilterTestConfiguration<3, 3, 10>>,
            fl::StaticTest<UnscentedKalmanFilterTestConfiguration<10, 10, 20>>,

            fl::DynamicTest<UnscentedKalmanFilterTestConfiguration<3, 1, 2>>,
            fl::DynamicTest<UnscentedKalmanFilterTestConfiguration<3, 3, 10>>,
            fl::DynamicTest<UnscentedKalmanFilterTestConfiguration<10, 10, 20>>
        > TestTypes;

INSTANTIATE_TYPED_TEST_CASE_P(UnscentedKalmanFilterTest,
                              GaussianFilterTest,
                              TestTypes);
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>
#include "ElectricElements.h"
#include "Condensator.h"
using namespace std;

CondensatorFactory::CondensatorFactory() {
	seqType.divider = 0;
	seqType.pos = 0;
}

int CondensatorFactory::InputData(vector<ElectricElements> &elementList) {
	cout << "?" << endl;
	readStringFromKeyboard(name);
	cout << "?" << endl;
	readStringFromKeyboard(name);
	cout << "? ( )" << endl;
	readIntFromKeyboard(voltage);
	cout << "? ( )" << endl;
	readIntFromKeyboard(tke);
	cout << "? ( )" << endl;
	readDoubleFromKeyboard(tolerance);
	cout << "   " << endl;
	readDoubleFromKeyboard(minmax);
	cout << "?" << endl;
	readStringFromKeyboard(tu);
	cout << "?" << endl;
	readStringFromKeyboard(manufacturer);
	cout << " :" << endl;
	getSequenceType(seqType);
	return GenerateComponents(elementList);
}

int CondensatorFactory::GenerateComponents(vector < ElectricElements> &elementList)
{
	if (minmax.size() != 2) {
		cout << "  " << endl;
		return -1;
	}
	int minIdx = 0;
	int maxIdx = 0;
	int minSize = 0;
	int maxSize = 0;
	GetIndexAndSize(minmax[0], minIdx, minSize);
	GetIndexAndSize(minmax[1], maxIdx, maxSize);

	for (int sizeIdx = minSize; sizeIdx <= maxSize; ++sizeIdx) {
		for (int valueIndex = 0; valueIndex < numberOfValues; valueIndex +=seqType.divider) {
			if (((valueIndex < minIdx) && (sizeIdx == minSize)) || ((valueIndex > maxIdx) && (sizeIdx == maxSize))) {
				continue;//of of order;
			}
			else {
				for (auto voltagePtr = voltage.begin(); voltagePtr < voltage.end(); ++voltagePtr) {

					for (auto tksPtr = tke.begin(); tksPtr < tke.end(); ++tksPtr) {
						for (auto tolerancePtr = tolerance.begin(); tolerancePtr < tolerance.end(); ++tolerancePtr) {
							elementList.push_back(Condensator(
								name,
								_value[valueIndex] * pow(10, sizeIdx),
								*voltagePtr,
								*tolerancePtr,
								tu,
								*tksPtr,
								performance
								));
						}
					}
				}
			}
		}
	}
	return 0;
}

string Condensator::GetCsvString()
{
	stringstream data;
	data << GetName().c_str() << endl;

	return data.str();
}
<commit_msg>Delete Condensator.cpp<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unneeded headers.<commit_after><|endoftext|>


<commit_before>#include <torrentsync/dht/message/query/FindNode.h>
#include <torrentsync/dht/message/reply/FindNode.h>
#include <torrentsync/utils/log/Logger.h>
#include <torrentsync/utils/Buffer.h>
#include <torrentsync/dht/RoutingTable.h>

#include <iterator>
#include <array>
#include <atomic>
#include <mutex>
#include <tuple>

#include <boost/asio.hpp>

//! list of known bootstrap servers for the DHT network
static constexpr std::array< // domain/ip address, port, needs to be resolved
    std::pair<const char *, const char *>, 3> BOOTSTRAP_ADDRESSES = {
    std::make_pair("router.bittorrent.com", "8991"),
    std::make_pair("router.utorrent.com", "6881"),
    std::make_pair("dht.transmissionbt.com", "6881")};

//! Number of nodes that return my address when looking for my node
//! to be sure that I can't get any closer.
static const size_t DHT_CLOSE_ENOUGH = 10;

//! number of batches per second while initializing the DHT.
static const size_t INITIALIZE_PING_BATCH_INTERVAL = 1000;

namespace torrentsync {
namespace dht {

namespace msg = dht::message;
using namespace torrentsync;

void RoutingTable::initializeTable() {
  if (_initialization_completed)
    return;

  auto timer = std::make_shared<boost::asio::deadline_timer>(
      _io_service,
      boost::posix_time::milliseconds(INITIALIZE_PING_BATCH_INTERVAL));

  LOG(DEBUG, "RoutingTable * Register initializeTable timer");
  timer->async_wait([&, timer](const boost::system::error_code &e) {
    using namespace boost::asio;
    initializeTable();

    std::lock_guard<std::mutex> lock(_initializer_mutex);

    LOG(DEBUG, "RoutingTable * " << _initial_addresses.size()
                                 << " initializing addresses");

    if (e.value() != 0) {
      LOG(ERROR,
          "Error in RoutingTable initializeTable timer: " << e.message());
      initializeTable();
      return;
    }

    if (_initial_addresses.empty()) {
      bootstrap();
      LOG(DEBUG, "RoutingTable * "
                     << _initial_addresses.size()
                     << " initializing addresses after bootstrap");
    }

    for (size_t i = 0;
         i < INITIALIZE_PING_BATCH_SIZE && !_initial_addresses.empty(); ++i) {
      // copy to local and remove from list
      const auto endpoint = _initial_addresses.front();
      _initial_addresses.pop_front();

      LOG(DEBUG, "RoutingTable * initializing ping with " << endpoint);

      const auto transaction = newTransaction();

      // create and send the message
      const utils::Buffer msg = dht::message::query::FindNode::make(
          transaction, _table.getTableNode(), _table.getTableNode());

      registerCallback(
          [&](const boost::optional<Callback::payload_type> data,
              const dht::Callback &) {

            if (!data)
              return;

            // there is no assert for no-exception
            const auto *reply = boost::get<msg::reply::Reply>(&data->message);
            assert(reply != nullptr);

            const auto *error = boost::get<msg::reply::Error>(reply);
            if (error != nullptr) {
              LOG(DEBUG, "Error returned in initialization: " << error);
              return;
            }

            const auto *find_node = boost::get<msg::reply::FindNode>(reply);
            if (find_node == nullptr) {
              LOG(WARN, "A message different from find node received");
              return;
            }

            for (const auto &t : find_node->getNodes()) {
              if (*t == _table.getTableNode()) {
                _initialization_completed = true;
                LOG(INFO, " Initialization finished");
                break;
              } else {
                if (!!t->getEndpoint())
                  _initial_addresses.push_front(*t->getEndpoint());
                LOG(DEBUG, "Distance: " << (*t ^ _table.getTableNode()));
                std::lock_guard<std::mutex> lock_table(_table_mutex);
                _table.addNode(t);
              }
            }
          },
          transaction);

      // send the message
      sendMessage(msg, endpoint);
    }

    LOG(DEBUG, "RoutingTable * " << _initial_addresses.size()
                                 << " initializing addresses remaining");

  });
}

void RoutingTable::bootstrap() {
  if (!_initial_addresses.empty()) {
    LOG(INFO, "RoutingTable * bootstrap Can't bootstrap while I still "
                  << "have initial addresses");
    return;
  }

  std::lock_guard<std::mutex> lock_table(_table_mutex);
  LOG(INFO, "RoutingTable * Proceeding with boostrap procedure from "
                << "known nodes; count: " << _table.size());

  udp::resolver resolver(_io_service);

  for (const auto &addr : BOOTSTRAP_ADDRESSES) {
    LOG(DEBUG, "Bootstrapping with " << addr.first << ":" << addr.second);
    boost::system::error_code error;
    udp::resolver::query query(udp::v4(), addr.first, addr.second);
    udp::resolver::iterator iterator = resolver.resolve(query, error);

    while (iterator != udp::resolver::iterator()) {
      LOG(DEBUG, "Resolved to " << iterator->endpoint());
      _initial_addresses.push_back(iterator->endpoint());
      ++iterator;
    }
  }
}

}; // dht
}; // torrentsync
<commit_msg>Skip initialization if process is too slow<commit_after>#include <torrentsync/dht/message/query/FindNode.h>
#include <torrentsync/dht/message/reply/FindNode.h>
#include <torrentsync/utils/log/Logger.h>
#include <torrentsync/utils/Buffer.h>
#include <torrentsync/dht/RoutingTable.h>

#include <iterator>
#include <array>
#include <atomic>
#include <mutex>
#include <tuple>

#include <boost/asio.hpp>

//! list of known bootstrap servers for the DHT network
static constexpr std::array< // domain/ip address, port, needs to be resolved
    std::pair<const char *, const char *>, 3> BOOTSTRAP_ADDRESSES = {
    std::make_pair("router.bittorrent.com", "8991"),
    std::make_pair("router.utorrent.com", "6881"),
    std::make_pair("dht.transmissionbt.com", "6881")};

//! Number of nodes that return my address when looking for my node
//! to be sure that I can't get any closer.
static const size_t DHT_CLOSE_ENOUGH = 10;

//! number of batches per second while initializing the DHT.
static const size_t INITIALIZE_PING_BATCH_INTERVAL = 1000;

namespace torrentsync {
namespace dht {

namespace msg = dht::message;
using namespace torrentsync;

void RoutingTable::initializeTable() {
  if (_initialization_completed)
    return;

  auto timer = std::make_shared<boost::asio::deadline_timer>(
      _io_service,
      boost::posix_time::milliseconds(INITIALIZE_PING_BATCH_INTERVAL));

  LOG(DEBUG, "RoutingTable * Register initializeTable timer");
  timer->async_wait([&, timer](const boost::system::error_code &e) {
    using namespace boost::asio;
    initializeTable();

    if (e.value() != 0) {
      LOG(ERROR,
          "Error in RoutingTable initializeTable timer: " << e.message());
      return;
    }

    // still running from previous execution! skip this round
    // otherwise get the lock and go on
    std::unique_lock<std::mutex> lock_table(_initializer_mutex, std::try_to_lock);
    if (!lock_table.owns_lock())
    {
        LOG(DEBUG, "RoutingTable * Initializations till running");
        return;
    }

    LOG(DEBUG, "RoutingTable * " << _initial_addresses.size()
                                 << " initializing addresses");

    if (_initial_addresses.empty()) {
      bootstrap();
      LOG(DEBUG, "RoutingTable * "
                     << _initial_addresses.size()
                     << " initializing addresses after bootstrap");
    }

    for (size_t i = 0;
         i < INITIALIZE_PING_BATCH_SIZE && !_initial_addresses.empty(); ++i) {
      // copy to local and remove from list
      const auto endpoint = _initial_addresses.front();
      _initial_addresses.pop_front();

      LOG(DEBUG, "RoutingTable * initializing ping with " << endpoint);

      const auto transaction = newTransaction();

      // create and send the message
      const utils::Buffer msg = dht::message::query::FindNode::make(
          transaction, _table.getTableNode(), _table.getTableNode());

      registerCallback(
          [&](const boost::optional<Callback::payload_type> data,
              const dht::Callback &) {

            if (!data)
              return;

            // there is no assert for no-exception
            const auto *reply = boost::get<msg::reply::Reply>(&data->message);
            assert(reply != nullptr);

            const auto *error = boost::get<msg::reply::Error>(reply);
            if (error != nullptr) {
              LOG(DEBUG, "Error returned in initialization: " << error);
              return;
            }

            const auto *find_node = boost::get<msg::reply::FindNode>(reply);
            if (find_node == nullptr) {
              LOG(WARN, "A message different from find node received");
              return;
            }

            for (const auto &t : find_node->getNodes()) {
              if (*t == _table.getTableNode()) {
                _initialization_completed = true;
                LOG(INFO, " Initialization finished");
                break;
              } else {
                if (!!t->getEndpoint())
                  _initial_addresses.push_front(*t->getEndpoint());
                LOG(DEBUG, "Distance: " << (*t ^ _table.getTableNode()));
                std::lock_guard<std::mutex> lock_table(_table_mutex);
                _table.addNode(t);
              }
            }
          },
          transaction);

      // send the message
      sendMessage(msg, endpoint);
    }

    LOG(DEBUG, "RoutingTable * " << _initial_addresses.size()
                                 << " initializing addresses remaining");

  });
}

void RoutingTable::bootstrap() {
  if (!_initial_addresses.empty()) {
    LOG(INFO, "RoutingTable * bootstrap Can't bootstrap while I still "
                  << "have initial addresses");
    return;
  }

  std::lock_guard<std::mutex> lock_table(_table_mutex);
  LOG(INFO, "RoutingTable * Proceeding with boostrap procedure from "
                << "known nodes; count: " << _table.size());

  udp::resolver resolver(_io_service);

  for (const auto &addr : BOOTSTRAP_ADDRESSES) {
    LOG(DEBUG, "Bootstrapping with " << addr.first << ":" << addr.second);
    boost::system::error_code error;
    udp::resolver::query query(udp::v4(), addr.first, addr.second);
    udp::resolver::iterator iterator = resolver.resolve(query, error);

    while (iterator != udp::resolver::iterator()) {
      LOG(DEBUG, "Resolved to " << iterator->endpoint());
      _initial_addresses.push_back(iterator->endpoint());
      ++iterator;
    }
  }
}

}; // dht
}; // torrentsync
<|endoftext|>


<commit_before>/**
  The goal of this tutorial is to implement in Tiramisu a code that is
  equivalent to the following

  for (int i = 0; i < 10; i++)
    for (int j = 0; j < 20; j++)
      output[i, j] = input[i, j] + i + 2;
*/

#include <tiramisu/tiramisu.h>

#define NN 10
#define MM 20

using namespace tiramisu;

int main(int argc, char **argv)
{
    // Set default tiramisu options.
    tiramisu::init();

    // -------------------------------------------------------
    // Layer I
    // -------------------------------------------------------

    // Declare the function tut_08.
    function tut_08("tut_08");

    // Declare two constants N and M. These constants will be used as loop bounds.
    // The parameters of the constant constructor are as follows:
    //    - The name of the constant is "N".
    //    - The value of the constant is expr((int32_t) NN).
    //    - The constant is of type int32.
    //    - The constant is declared in the beginning of the function tut_08 (i.e.,
    //      its scope is the whole function).
    //    - The next two arguments (NULL and 0) are unused here.
    //    - The last argument is the function in which this constant is declared.
    // For more details please refer to the documentation of the constant constructor.
    constant N_const("N", expr((int32_t) NN), p_int32, true, NULL, 0, &tut_08);
    constant M_const("M", expr((int32_t) MM), p_int32, true, NULL, 0, &tut_08);

    // Declare iterator variables.
    var i("i"), j("j");

    // Declare a wrapper around the input.
    // In Tiramisu, if a function reads an input buffer (or writes to it), that buffer
    // cannot be accessed directly, but should first be wrapped in a dummy computation.
    // This is mainly because computations in Tiramisu do not access memory directly,
    // since the algorithm is supposed to be expressed independently of how data is stored.
    // Therefor all algorithms (computations) access other computations.  The actual data
    // layout is only specified later in Layer III.
    // A wrapper is usually declared with an empty expression and is not supposed to be scheduled
    // (check the documentation of the computation constructor for more details).
    computation in("[N, M]->{in[i,j]: 0<=i<N and 0<=j<M}", expr(), false, p_uint8, &tut_08);

    // Declare expression and output computation.
    // To declare a computation, you need to provide:
    // (1) an ISL set representing the iteration space of the computation.
    // Tiramisu uses the ISL syntax to represent sets and maps.  The ISL syntax
    // is described in http://barvinok.gforge.inria.fr/barvinok.pdf (Section
    // 1.2.1 for sets and iteration domains, and 1.2.2 for maps and access
    // relations),
    // (2) a tiramisu expression: this is the expression that will be computed
    // by the computation.
    // (3) the type of the computation which is an unsigned char in this case (p_uint8).
    // (4) a boolean that indicates whether this computation should be
    // scheduled or not (more about this in the next tutorials).
    // (5) the function in which the computation will be declared.
    //
    // The best way to learn about the constructor of computations is to
    // check the documentation of the computation class in
    // https://tiramisu-compiler.github.io/doc
    expr e = in(i, j) + cast(p_uint8, i) + (uint8_t)4;
    computation output("[N, M]->{output[i,j]: 0<=i<N and 0<=j<M}", e, true, p_uint8, &tut_08);

    // -------------------------------------------------------
    // Layer II
    // -------------------------------------------------------

    // Set the schedule of the computation.
    var i0("i0"), i1("i1"), j0("j0"), j1("j1");

    // Tile the i, j loop around output by a 2x2 tile. The names of iterators
    // in the resulting loop are i0, j0, i1, j1.
    output.tile(i, j, 2, 2, i0, j0, i1, j1);

    // Parallelize the outermost loop i0 (OpenMP style parallelism).
    output.parallelize(i0);

    // -------------------------------------------------------
    // Layer III
    // -------------------------------------------------------

    // Declare input and output buffers.
    buffer b_input("b_input", {expr(NN), expr(MM)}, p_uint8, a_input, &tut_08);
    buffer b_output("b_output", {expr(NN), expr(MM)}, p_uint8, a_output, &tut_08);

    // Map the computations to a buffer.
    // The following call indicates that each computation input[i,j]
    // is stored in the buffer element b_input[i,j] (one-to-one mapping).
    // This is the most common mapping to memory.
    in.set_access("{in[i,j]->b_input[i,j]}");
    output.set_access("{output[i,j]->b_output[i,j]}");

    // -------------------------------------------------------
    // Code Generation
    // -------------------------------------------------------

    // Set the arguments to tut_08
    tut_08.codegen({&b_input, &b_output}, "build/generated_fct_developers_tutorial_08.o");

    // Some debugging
    tut_08.dump_halide_stmt();

    return 0;
}

/**
 * Current limitations:
 * - Note that the type of the invariants N and M are "int32_t". This is
 *   important because these invariants are used later as loop bounds and the
 *   type of the bounds and the iterators should be the same for correct code
 *   generation. This implies that the invariants should be of type "int32_t".
 */
<commit_msg>Fix tutorial_08 error comment.<commit_after>/**
  The goal of this tutorial is to implement in Tiramisu a code that is
  equivalent to the following

  for (int i = 0; i < 10; i++)
    for (int j = 0; j < 20; j++)
      output[i, j] = input[i, j] + i + 4;
*/

#include <tiramisu/tiramisu.h>

#define NN 10
#define MM 20

using namespace tiramisu;

int main(int argc, char **argv)
{
    // Set default tiramisu options.
    tiramisu::init();

    // -------------------------------------------------------
    // Layer I
    // -------------------------------------------------------

    // Declare the function tut_08.
    function tut_08("tut_08");

    // Declare two constants N and M. These constants will be used as loop bounds.
    // The parameters of the constant constructor are as follows:
    //    - The name of the constant is "N".
    //    - The value of the constant is expr((int32_t) NN).
    //    - The constant is of type int32.
    //    - The constant is declared in the beginning of the function tut_08 (i.e.,
    //      its scope is the whole function).
    //    - The next two arguments (NULL and 0) are unused here.
    //    - The last argument is the function in which this constant is declared.
    // For more details please refer to the documentation of the constant constructor.
    constant N_const("N", expr((int32_t) NN), p_int32, true, NULL, 0, &tut_08);
    constant M_const("M", expr((int32_t) MM), p_int32, true, NULL, 0, &tut_08);

    // Declare iterator variables.
    var i("i"), j("j");

    // Declare a wrapper around the input.
    // In Tiramisu, if a function reads an input buffer (or writes to it), that buffer
    // cannot be accessed directly, but should first be wrapped in a dummy computation.
    // This is mainly because computations in Tiramisu do not access memory directly,
    // since the algorithm is supposed to be expressed independently of how data is stored.
    // Therefor all algorithms (computations) access other computations.  The actual data
    // layout is only specified later in Layer III.
    // A wrapper is usually declared with an empty expression and is not supposed to be scheduled
    // (check the documentation of the computation constructor for more details).
    computation in("[N, M]->{in[i,j]: 0<=i<N and 0<=j<M}", expr(), false, p_uint8, &tut_08);

    // Declare expression and output computation.
    // To declare a computation, you need to provide:
    // (1) an ISL set representing the iteration space of the computation.
    // Tiramisu uses the ISL syntax to represent sets and maps.  The ISL syntax
    // is described in http://barvinok.gforge.inria.fr/barvinok.pdf (Section
    // 1.2.1 for sets and iteration domains, and 1.2.2 for maps and access
    // relations),
    // (2) a tiramisu expression: this is the expression that will be computed
    // by the computation.
    // (3) the type of the computation which is an unsigned char in this case (p_uint8).
    // (4) a boolean that indicates whether this computation should be
    // scheduled or not (more about this in the next tutorials).
    // (5) the function in which the computation will be declared.
    //
    // The best way to learn about the constructor of computations is to
    // check the documentation of the computation class in
    // https://tiramisu-compiler.github.io/doc
    expr e = in(i, j) + cast(p_uint8, i) + (uint8_t)4;
    computation output("[N, M]->{output[i,j]: 0<=i<N and 0<=j<M}", e, true, p_uint8, &tut_08);

    // -------------------------------------------------------
    // Layer II
    // -------------------------------------------------------

    // Set the schedule of the computation.
    var i0("i0"), i1("i1"), j0("j0"), j1("j1");

    // Tile the i, j loop around output by a 2x2 tile. The names of iterators
    // in the resulting loop are i0, j0, i1, j1.
    output.tile(i, j, 2, 2, i0, j0, i1, j1);

    // Parallelize the outermost loop i0 (OpenMP style parallelism).
    output.parallelize(i0);

    // -------------------------------------------------------
    // Layer III
    // -------------------------------------------------------

    // Declare input and output buffers.
    buffer b_input("b_input", {expr(NN), expr(MM)}, p_uint8, a_input, &tut_08);
    buffer b_output("b_output", {expr(NN), expr(MM)}, p_uint8, a_output, &tut_08);

    // Map the computations to a buffer.
    // The following call indicates that each computation input[i,j]
    // is stored in the buffer element b_input[i,j] (one-to-one mapping).
    // This is the most common mapping to memory.
    in.set_access("{in[i,j]->b_input[i,j]}");
    output.set_access("{output[i,j]->b_output[i,j]}");

    // -------------------------------------------------------
    // Code Generation
    // -------------------------------------------------------

    // Set the arguments to tut_08
    tut_08.codegen({&b_input, &b_output}, "build/generated_fct_developers_tutorial_08.o");

    // Some debugging
    tut_08.dump_halide_stmt();

    return 0;
}

/**
 * Current limitations:
 * - Note that the type of the invariants N and M are "int32_t". This is
 *   important because these invariants are used later as loop bounds and the
 *   type of the bounds and the iterators should be the same for correct code
 *   generation. This implies that the invariants should be of type "int32_t".
 */
<|endoftext|>


<commit_before>/*
 * Displays process and timesync information on LCMGL
 *
 * Author: Andrew Barry, <abarry@csail.mit.edu> 2013
 *
 */

#include <iostream>

using namespace std;

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <mutex>

#include "../../LCM/lcmt_process_control.h"
#include "../../LCM/lcmt_log_size.h"

#include <bot_core/bot_core.h>
#include <bot_param/param_client.h>
#include <GL/gl.h>
#include <bot_lcmgl_client/lcmgl.h>

#include <bot_core/rotations.h>
#include <bot_frames/bot_frames.h>

lcm_t * lcm;

mutex mux;

lcmt_process_control_subscription_t *process_sub;
lcmt_log_size_subscription_t *log_size_sub;

struct StringsOutStruct {
    string time;
    string logfilesize;
};

StringsOutStruct stringsOut;

static void usage(void)
{
        fprintf(stderr, "usage: plane-health-monitor process-control-channel log-size-channel-name\n");
        fprintf(stderr, "    process-status-channel: LCM channel name with process control messages\n");
        fprintf(stderr, "    log-size-channel: LCM channel name with log size messages\n");
        fprintf(stderr, "  example:\n");
        fprintf(stderr, "    ./plane-health-monitor process_status log_size\n");
}

void PrintStatus()
{
    mux.lock();
    printf("\rPlane time: %s\t\tLogfile: %s", stringsOut.time.c_str(), stringsOut.logfilesize.c_str());
    fflush(stdout);
    mux.unlock();
}

void sighandler(int dum)
{
    printf("\nClosing... ");

    lcmt_process_control_unsubscribe(lcm, process_sub);
    lcmt_log_size_unsubscribe(lcm, log_size_sub);
    lcm_destroy (lcm);

    printf("done.\n");

    exit(0);
}

int64_t getTimestampNow()
{
    struct timeval thisTime;
    gettimeofday(&thisTime, NULL);
    return (thisTime.tv_sec * 1000000.0) + (float)thisTime.tv_usec + 0.5;
}

void process_handler(const lcm_recv_buf_t *rbuf, const char* channel, const lcmt_process_control *msg, void *user)
{
    mux.lock();

    char tmbuf[64], buf[64];

    // figure out what time the plane thinks it is
    struct tm *nowtm;
    time_t tv_sec = msg->timestamp / 1000000.0;
    nowtm = localtime(&tv_sec);
    strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S", nowtm);
    sprintf(buf, "%s", tmbuf);

    stringsOut.time = buf;

    mux.unlock();

    PrintStatus();
}

void log_size_handler(const lcm_recv_buf_t *rbuf, const char* channel, const lcmt_log_size *msg, void *user)
{

    mux.lock();

    char buf[500];

    // got a log size message, display it
    sprintf(buf, "#%d, %010d", msg->log_number, msg->log_size);
    stringsOut.logfilesize = buf;

    mux.unlock();

    PrintStatus();
}

int main(int argc,char** argv)
{
    stringsOut.time = "-------------------";
    stringsOut.logfilesize = "---";
    char *channelProcess = NULL;
    char *channelLogSize = NULL;

    if (argc!=3) {
        usage();
        exit(0);
    }

    channelProcess = argv[1];
    channelLogSize = argv[2];

    lcm = lcm_create ("udpm://239.255.76.67:7667?ttl=0");
    if (!lcm)
    {
        fprintf(stderr, "lcm_create failed.  Quitting.\n");
        return 1;
    }

    signal(SIGINT,sighandler);

    process_sub = lcmt_process_control_subscribe(lcm, channelProcess, &process_handler, NULL);
    log_size_sub = lcmt_log_size_subscribe(lcm, channelLogSize, &log_size_handler, NULL);

    printf("Receiving:\n\t%s\n\t%s\n", channelProcess, channelLogSize);

    while (true)
    {
        // read the LCM channel
        lcm_handle (lcm);
    }

    return 0;
}
<commit_msg>Small change to ui.<commit_after>/*
 * Displays process and timesync information on LCMGL
 *
 * Author: Andrew Barry, <abarry@csail.mit.edu> 2013
 *
 */

#include <iostream>

using namespace std;

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <mutex>

#include "../../LCM/lcmt_process_control.h"
#include "../../LCM/lcmt_log_size.h"

#include <bot_core/bot_core.h>
#include <bot_param/param_client.h>
#include <GL/gl.h>
#include <bot_lcmgl_client/lcmgl.h>

#include <bot_core/rotations.h>
#include <bot_frames/bot_frames.h>

lcm_t * lcm;

mutex mux;

lcmt_process_control_subscription_t *process_sub;
lcmt_log_size_subscription_t *log_size_sub;

struct StringsOutStruct {
    string time;
    string logfilesize;
};

StringsOutStruct stringsOut;

static void usage(void)
{
        fprintf(stderr, "usage: plane-health-monitor process-control-channel log-size-channel-name\n");
        fprintf(stderr, "    process-status-channel: LCM channel name with process control messages\n");
        fprintf(stderr, "    log-size-channel: LCM channel name with log size messages\n");
        fprintf(stderr, "  example:\n");
        fprintf(stderr, "    ./plane-health-monitor process_status log_size\n");
}

void PrintStatus()
{
    mux.lock();
    printf("\rPlane time: %s\t\tLogfile: %s", stringsOut.time.c_str(), stringsOut.logfilesize.c_str());
    fflush(stdout);
    mux.unlock();
}

void sighandler(int dum)
{
    printf("\nClosing... ");

    lcmt_process_control_unsubscribe(lcm, process_sub);
    lcmt_log_size_unsubscribe(lcm, log_size_sub);
    lcm_destroy (lcm);

    printf("done.\n");

    exit(0);
}

int64_t getTimestampNow()
{
    struct timeval thisTime;
    gettimeofday(&thisTime, NULL);
    return (thisTime.tv_sec * 1000000.0) + (float)thisTime.tv_usec + 0.5;
}

void process_handler(const lcm_recv_buf_t *rbuf, const char* channel, const lcmt_process_control *msg, void *user)
{
    mux.lock();

    char tmbuf[64], buf[64];

    // figure out what time the plane thinks it is
    struct tm *nowtm;
    time_t tv_sec = msg->timestamp / 1000000.0;
    nowtm = localtime(&tv_sec);
    strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S", nowtm);
    sprintf(buf, "%s", tmbuf);

    stringsOut.time = buf;

    mux.unlock();

    PrintStatus();
}

void log_size_handler(const lcm_recv_buf_t *rbuf, const char* channel, const lcmt_log_size *msg, void *user)
{

    mux.lock();

    char buf[500];

    // got a log size message, display it
    sprintf(buf, "#%d, %010d", msg->log_number, msg->log_size);
    stringsOut.logfilesize = buf;

    mux.unlock();

    PrintStatus();
}

int main(int argc,char** argv)
{
    stringsOut.time = "-------------------";
    stringsOut.logfilesize = "---";
    char *channelProcess = NULL;
    char *channelLogSize = NULL;

    if (argc!=3) {
        usage();
        exit(0);
    }

    channelProcess = argv[1];
    channelLogSize = argv[2];

    lcm = lcm_create ("udpm://239.255.76.67:7667?ttl=0");
    if (!lcm)
    {
        fprintf(stderr, "lcm_create failed.  Quitting.\n");
        return 1;
    }

    signal(SIGINT,sighandler);

    process_sub = lcmt_process_control_subscribe(lcm, channelProcess, &process_handler, NULL);
    log_size_sub = lcmt_log_size_subscribe(lcm, channelLogSize, &log_size_handler, NULL);

    printf("Receiving:\n\t%s\n\t%s\n--------------------------------------\n", channelProcess, channelLogSize);

    while (true)
    {
        // read the LCM channel
        lcm_handle (lcm);
    }

    return 0;
}
<|endoftext|>


<commit_before>#include <Poco/Timespan.h>

#include "model/Device.h"

using namespace std;
using namespace Poco;
using namespace BeeeOn;

Device::Device()
{
}

Device::Device(const ID &id):
	Entity(id)
{
}

void Device::setGateway(const Gateway &gateway)
{
	m_gateway = gateway;
}

const Gateway &Device::gateway() const
{
	return m_gateway;
}

void Device::setLocation(const Location &location)
{
	m_location = location;
}

const Location &Device::location() const
{
	return m_location;
}

void Device::setName(const string &name)
{
	m_name = name;
}

const string &Device::name() const
{
	return m_name;
}

void Device::setType(const SharedPtr<DeviceInfo> type)
{
	m_type = type;
}

const SharedPtr<DeviceInfo> Device::type() const
{
	return m_type;
}

void Device::setRefresh(const Timespan &refresh)
{
	m_refresh = refresh;
}

const Timespan &Device::refresh() const
{
	return m_refresh;
}

void Device::setBattery(const Nullable<percent> &battery)
{
	m_battery = battery;
}

const Nullable<Device::percent> &Device::battery() const
{
	return m_battery;
}

void Device::setSignal(const Nullable<percent> &signal)
{
	m_signal = signal;
}

const Nullable<Device::percent> &Device::signal() const
{
	return m_signal;
}

void Device::setFirstSeen(const DateTime &at)
{
	m_firstSeen = at;
}

const DateTime &Device::firstSeen() const
{
	return m_firstSeen;
}

void Device::setLastSeen(const DateTime &at)
{
	m_lastSeen = at;
}

const DateTime &Device::lastSeen() const
{
	return m_lastSeen;
}

bool Device::available(const unsigned int multiple,
		const DateTime &ref) const
{
	Timespan diff;
	for (unsigned int i = 0; i < multiple; ++i)
		diff += refresh();

	return lastSeen() + diff >= ref;
}

void Device::setActiveSince(const Nullable<DateTime> &at)
{
	m_activeSince = at;
}

const Nullable<DateTime> &Device::activeSince() const
{
	return m_activeSince;
}
<commit_msg>Device: handle invalid refresh time<commit_after>#include <Poco/Timespan.h>

#include "model/Device.h"

using namespace std;
using namespace Poco;
using namespace BeeeOn;

Device::Device()
{
}

Device::Device(const ID &id):
	Entity(id)
{
}

void Device::setGateway(const Gateway &gateway)
{
	m_gateway = gateway;
}

const Gateway &Device::gateway() const
{
	return m_gateway;
}

void Device::setLocation(const Location &location)
{
	m_location = location;
}

const Location &Device::location() const
{
	return m_location;
}

void Device::setName(const string &name)
{
	m_name = name;
}

const string &Device::name() const
{
	return m_name;
}

void Device::setType(const SharedPtr<DeviceInfo> type)
{
	m_type = type;
}

const SharedPtr<DeviceInfo> Device::type() const
{
	return m_type;
}

void Device::setRefresh(const Timespan &refresh)
{
	m_refresh = refresh;
}

const Timespan &Device::refresh() const
{
	return m_refresh;
}

void Device::setBattery(const Nullable<percent> &battery)
{
	m_battery = battery;
}

const Nullable<Device::percent> &Device::battery() const
{
	return m_battery;
}

void Device::setSignal(const Nullable<percent> &signal)
{
	m_signal = signal;
}

const Nullable<Device::percent> &Device::signal() const
{
	return m_signal;
}

void Device::setFirstSeen(const DateTime &at)
{
	m_firstSeen = at;
}

const DateTime &Device::firstSeen() const
{
	return m_firstSeen;
}

void Device::setLastSeen(const DateTime &at)
{
	m_lastSeen = at;
}

const DateTime &Device::lastSeen() const
{
	return m_lastSeen;
}

bool Device::available(const unsigned int multiple,
		const DateTime &ref) const
{
	if (refresh() < 1 * Timespan::SECONDS)
		return true; // refresh time is invalid

	Timespan diff;
	for (unsigned int i = 0; i < multiple; ++i)
		diff += refresh();

	return lastSeen() + diff >= ref;
}

void Device::setActiveSince(const Nullable<DateTime> &at)
{
	m_activeSince = at;
}

const Nullable<DateTime> &Device::activeSince() const
{
	return m_activeSince;
}
<|endoftext|>


<commit_before>// Copyright 2014 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 "services/js/js_app_shell.h"

#include "gin/object_template_builder.h"
#include "services/js/js_app.h"

namespace mojo {
namespace js {

gin::WrapperInfo JSAppShell::kWrapperInfo = {gin::kEmbedderNativeGin};

gin::Handle<JSAppShell> JSAppShell::Create(v8::Isolate* isolate,
                                           JSApp* js_app) {
  return CreateHandle(isolate, new JSAppShell(js_app));
}

JSAppShell::JSAppShell(JSApp* js_app) : js_app_(js_app) {
}

JSAppShell::~JSAppShell() {
}

gin::ObjectTemplateBuilder JSAppShell::GetObjectTemplateBuilder(
    v8::Isolate* isolate) {
  return gin::Wrappable<JSAppShell>::GetObjectTemplateBuilder(isolate)
      .SetMethod("connectToApplication", &JSAppShell::ConnectToApplication);
}

void JSAppShell::ConnectToApplication(
    const std::string& application_url, mojo::Handle service_provider) {
  // TODO(hansmuller): Validate arguments.
  // TODO(hansmuller): Service_provider may be a ServiceProviderProxy.
  MessagePipeHandle message_pipe_handle(service_provider.value());
  ScopedMessagePipeHandle scoped_handle(message_pipe_handle);
  js_app_->ConnectToApplication(application_url, scoped_handle.Pass());
}

}  // namespace js
}  // namespace mojo
<commit_msg>Fix Windows build after https://codereview.chromium.org/757703002/<commit_after>// Copyright 2014 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 "services/js/js_app_shell.h"

#include "gin/object_template_builder.h"
#include "services/js/js_app.h"

namespace mojo {
namespace js {

gin::WrapperInfo JSAppShell::kWrapperInfo = {gin::kEmbedderNativeGin};

gin::Handle<JSAppShell> JSAppShell::Create(v8::Isolate* isolate,
                                           JSApp* js_app) {
  return gin::CreateHandle(isolate, new JSAppShell(js_app));
}

JSAppShell::JSAppShell(JSApp* js_app) : js_app_(js_app) {
}

JSAppShell::~JSAppShell() {
}

gin::ObjectTemplateBuilder JSAppShell::GetObjectTemplateBuilder(
    v8::Isolate* isolate) {
  return gin::Wrappable<JSAppShell>::GetObjectTemplateBuilder(isolate)
      .SetMethod("connectToApplication", &JSAppShell::ConnectToApplication);
}

void JSAppShell::ConnectToApplication(
    const std::string& application_url, mojo::Handle service_provider) {
  // TODO(hansmuller): Validate arguments.
  // TODO(hansmuller): Service_provider may be a ServiceProviderProxy.
  MessagePipeHandle message_pipe_handle(service_provider.value());
  ScopedMessagePipeHandle scoped_handle(message_pipe_handle);
  js_app_->ConnectToApplication(application_url, scoped_handle.Pass());
}

}  // namespace js
}  // namespace mojo
<|endoftext|>


<commit_before>//===- Mem2Reg.cpp - The -mem2reg pass, a wrapper around the Utils lib ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass is a simple pass wrapper around the PromoteMemToReg function call
// exposed by the Utils library.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "mem2reg"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Instructions.h"
#include "llvm/Function.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Compiler.h"
using namespace llvm;

STATISTIC(NumPromoted, "Number of alloca's promoted");

namespace {
  struct VISIBILITY_HIDDEN PromotePass : public FunctionPass {
    static char ID; // Pass identification, replacement for typeid
    PromotePass() : FunctionPass(&ID) {}

    // runOnFunction - To run this pass, first we calculate the alloca
    // instructions that are safe for promotion, then we promote each one.
    //
    virtual bool runOnFunction(Function &F);

    // getAnalysisUsage - We need dominance frontiers
    //
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<DominatorTree>();
      AU.addRequired<DominanceFrontier>();
      AU.setPreservesCFG();
      // This is a cluster of orthogonal Transforms
      AU.addPreserved<UnifyFunctionExitNodes>();
      AU.addPreservedID(LowerSwitchID);
      AU.addPreservedID(LowerInvokePassID);
      AU.addPreservedID(LowerAllocationsID);
    }
  };
}  // end of anonymous namespace

char PromotePass::ID = 0;
static RegisterPass<PromotePass> X("mem2reg", "Promote Memory to Register");

/// Remove the invalid or redundant debug information.
static void CleanDbgInfo(Function& F) {
  std::vector<Instruction*> DeadDbgs;
  for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI) {
    if (BBI->size() <= 1)
      continue;
    for (BasicBlock::iterator I = BBI->begin(), E = BBI->getTerminator();
         I != E; ++I) {
      BasicBlock::iterator NextI = I;
      ++NextI;
      if (isa<DbgStopPointInst>(I) && isa<DbgStopPointInst>(NextI))
        DeadDbgs.push_back(I);
      else if (isa<DbgStopPointInst>(I) && isa<BranchInst>(NextI))
        DeadDbgs.push_back(I);
    }
  }

  while (!DeadDbgs.empty()) {
    Instruction *Inst = DeadDbgs.back();
    DeadDbgs.pop_back();
    Inst->eraseFromParent();
  }
}

bool PromotePass::runOnFunction(Function &F) {
  std::vector<AllocaInst*> Allocas;

  BasicBlock &BB = F.getEntryBlock();  // Get the entry node for the function

  bool Changed  = false;

  DominatorTree &DT = getAnalysis<DominatorTree>();
  DominanceFrontier &DF = getAnalysis<DominanceFrontier>();

  while (1) {
    Allocas.clear();

    // Find allocas that are safe to promote, by looking at all instructions in
    // the entry node
    for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
      if (AllocaInst *AI = dyn_cast<AllocaInst>(I))       // Is it an alloca?
        if (isAllocaPromotable(AI))
          Allocas.push_back(AI);

    if (Allocas.empty()) break;

    PromoteMemToReg(Allocas, DT, DF);
    CleanDbgInfo(F);
    NumPromoted += Allocas.size();
    Changed = true;
  }

  return Changed;
}

// Publically exposed interface to pass...
const PassInfo *const llvm::PromoteMemoryToRegisterID = &X;
// createPromoteMemoryToRegister - Provide an entry point to create this pass.
//
FunctionPass *llvm::createPromoteMemoryToRegisterPass() {
  return new PromotePass();
}
<commit_msg>Just roll back the previous change to -mem2reg. Will re-think about this according to Chris's comments.<commit_after>//===- Mem2Reg.cpp - The -mem2reg pass, a wrapper around the Utils lib ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass is a simple pass wrapper around the PromoteMemToReg function call
// exposed by the Utils library.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "mem2reg"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Instructions.h"
#include "llvm/Function.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Compiler.h"
using namespace llvm;

STATISTIC(NumPromoted, "Number of alloca's promoted");

namespace {
  struct VISIBILITY_HIDDEN PromotePass : public FunctionPass {
    static char ID; // Pass identification, replacement for typeid
    PromotePass() : FunctionPass(&ID) {}

    // runOnFunction - To run this pass, first we calculate the alloca
    // instructions that are safe for promotion, then we promote each one.
    //
    virtual bool runOnFunction(Function &F);

    // getAnalysisUsage - We need dominance frontiers
    //
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<DominatorTree>();
      AU.addRequired<DominanceFrontier>();
      AU.setPreservesCFG();
      // This is a cluster of orthogonal Transforms
      AU.addPreserved<UnifyFunctionExitNodes>();
      AU.addPreservedID(LowerSwitchID);
      AU.addPreservedID(LowerInvokePassID);
      AU.addPreservedID(LowerAllocationsID);
    }
  };
}  // end of anonymous namespace

char PromotePass::ID = 0;
static RegisterPass<PromotePass> X("mem2reg", "Promote Memory to Register");

bool PromotePass::runOnFunction(Function &F) {
  std::vector<AllocaInst*> Allocas;

  BasicBlock &BB = F.getEntryBlock();  // Get the entry node for the function

  bool Changed  = false;

  DominatorTree &DT = getAnalysis<DominatorTree>();
  DominanceFrontier &DF = getAnalysis<DominanceFrontier>();

  while (1) {
    Allocas.clear();

    // Find allocas that are safe to promote, by looking at all instructions in
    // the entry node
    for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
      if (AllocaInst *AI = dyn_cast<AllocaInst>(I))       // Is it an alloca?
        if (isAllocaPromotable(AI))
          Allocas.push_back(AI);

    if (Allocas.empty()) break;

    PromoteMemToReg(Allocas, DT, DF);
    NumPromoted += Allocas.size();
    Changed = true;
  }

  return Changed;
}

// Publically exposed interface to pass...
const PassInfo *const llvm::PromoteMemoryToRegisterID = &X;
// createPromoteMemoryToRegister - Provide an entry point to create this pass.
//
FunctionPass *llvm::createPromoteMemoryToRegisterPass() {
  return new PromotePass();
}
<|endoftext|>


<commit_before>/*
 *   Copyright 2012 Coherent Theory LLC
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Library General Public License as
 *   published by the Free Software Foundation; either version 2, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details
 *
 *   You should have received a copy of the GNU Library General Public
 *   License along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "rpmhandler.h"

#include <QDebug>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QtGui/QDesktopServices>

#include <Daemon>

#include "rpminstalljob.h"
#include "packageidinstalljob.h"
#include <assethandlerfactory.h>

using namespace Bodega;

RpmHandler::RpmHandler(QObject *parent)
    : AssetHandler(parent)
{
}

RpmHandler::~RpmHandler()
{
}

void RpmHandler::init()
{
    QFileInfo info(operations()->assetInfo().filename);
    PackageKit::Transaction *t = new PackageKit::Transaction;
    t->resolve(packageName());

    connect(t, SIGNAL(package(const PackageKit::Package &)),
            this, SLOT(gotPackage(const PackageKit::Package &)));
    connect(t, SIGNAL(finished(PackageKit::Transaction::Exit, uint)),
            this, SLOT(resolveFinished(PackageKit::Transaction::Exit, uint)));
}

QString RpmHandler::remoteName() const
{
    const QString name = operations()->assetInfo().filename;
    qDebug() << "Asked for package name of" << operations()->assetInfo().filename  << "Got" << name;
    //try to extract a package name from a file name
    return name;
}

bool RpmHandler::remoteNameIsDescriptor() const
{
    //Package ids are composed of 4 parts separed by mandattory ;
    //http://www.packagekit.org/gtk-doc/concepts.html#introduction-ideas-packageid
    return operations()->assetInfo().filename.split(QLatin1Char('.'), QString::KeepEmptyParts).last() == QLatin1String("desc");
}

QString RpmHandler::packageName() const
{
    if (remoteNameIsDescriptor()) {
        return remoteName().split(QLatin1Char('.'), QString::KeepEmptyParts).first();
    //is a rpm name
    } else {
        return remoteName().split(QLatin1Char('-'), QString::KeepEmptyParts).first();
    }
}

const PackageKit::Package &RpmHandler::package() const
{
    return m_package;
}

bool RpmHandler::isInstalled() const
{
    //TODO: manage updates
    return !m_package.id().isEmpty() && (m_package.info() == PackageKit::Package::InfoInstalled ||
                m_package.info() == PackageKit::Package::InfoCollectionInstalled);
}

Bodega::InstallJob *RpmHandler::install(QNetworkReply *reply, Session *session)
{
    if (!m_installJob) {
        //Have a package id
        if (remoteNameIsDescriptor()) {
            m_installJob = new PackageIdInstallJob(reply, session, this);
        } else {
            m_installJob = new RpmInstallJob(reply, session, this);
            connect(m_installJob.data(), SIGNAL(jobFinished(Bodega::NetworkJob*)),
                    this, SLOT(registerForUpdates(Bodega::NetworkJob*)));
        }
        connect(m_installJob.data(), SIGNAL(jobFinished(Bodega::NetworkJob *)),
                this, SLOT(installJobFinished()));
    }

    return m_installJob.data();
}

Bodega::UninstallJob *RpmHandler::uninstall(Session *session)
{
    if (!m_uninstallJob) {
        m_uninstallJob = new RpmUninstallJob(session, this);
        //if not QueuedConnection resolve sudenly after the installation will fail
        connect(m_uninstallJob.data(), SIGNAL(jobFinished(Bodega::NetworkJob*)),
                this, SLOT(installJobFinished()), Qt::QueuedConnection);
        connect(m_uninstallJob.data(), SIGNAL(jobFinished(Bodega::NetworkJob*)),
                this, SLOT(unregisterForUpdates(Bodega::NetworkJob*)));
    }

    return m_uninstallJob.data();
}

QString RpmHandler::launchText() const
{
    return tr("Launch");
}

void RpmHandler::launch()
{
    QDesktopServices::openUrl(QUrl(m_desktopFile));
}

void RpmHandler::gotPackage(const PackageKit::Package &package)
{
    m_package = package;

    emit installedChanged();

    PackageKit::Transaction *listT = new PackageKit::Transaction;
    listT->getFiles(package);
    connect(listT, SIGNAL(files(const PackageKit::Package &, const QStringList &)),
            this, SLOT(gotFiles(const PackageKit::Package &, const QStringList &)));
}

void RpmHandler::resolveFinished(PackageKit::Transaction::Exit status, uint runtime)
{
    Q_UNUSED(runtime)

    qDebug() << "Package resolving operation finished, got status:" << status;
    setReady(true);
}

void RpmHandler::installJobFinished()
{
    PackageKit::Transaction *t = new PackageKit::Transaction;
    m_package = PackageKit::Package();

    t->resolve(packageName());
    connect(t, SIGNAL(package(const PackageKit::Package &)),
            this, SLOT(gotPackage(const PackageKit::Package &)));
}

void RpmHandler::gotFiles(const PackageKit::Package &package, const QStringList &fileNames)
{
    Q_UNUSED(package)
    foreach (const QString &file, fileNames) {
        if (file.contains(QRegExp(QLatin1String(".*/applications/.*\\.desktop")))) {
            m_desktopFile = file;
            break;
        }
    }
}

class RpmHandlerFactory : public Bodega::AssetHandlerFactory
{
public:
    virtual AssetHandler* createHandler() { return new RpmHandler; }
};

#include "rpmhandler.moc"
Q_EXPORT_PLUGIN2(rpmhandler, RpmHandlerFactory);

<commit_msg>correctly launch applications<commit_after>/*
 *   Copyright 2012 Coherent Theory LLC
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Library General Public License as
 *   published by the Free Software Foundation; either version 2, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details
 *
 *   You should have received a copy of the GNU Library General Public
 *   License along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "rpmhandler.h"

#include <QDebug>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QProcess>

#include <Daemon>

#include "rpminstalljob.h"
#include "packageidinstalljob.h"
#include <assethandlerfactory.h>

using namespace Bodega;

RpmHandler::RpmHandler(QObject *parent)
    : AssetHandler(parent)
{
}

RpmHandler::~RpmHandler()
{
}

void RpmHandler::init()
{
    QFileInfo info(operations()->assetInfo().filename);
    PackageKit::Transaction *t = new PackageKit::Transaction;
    t->resolve(packageName());

    connect(t, SIGNAL(package(const PackageKit::Package &)),
            this, SLOT(gotPackage(const PackageKit::Package &)));
    connect(t, SIGNAL(finished(PackageKit::Transaction::Exit, uint)),
            this, SLOT(resolveFinished(PackageKit::Transaction::Exit, uint)));
}

QString RpmHandler::remoteName() const
{
    const QString name = operations()->assetInfo().filename;
    qDebug() << "Asked for package name of" << operations()->assetInfo().filename  << "Got" << name;
    //try to extract a package name from a file name
    return name;
}

bool RpmHandler::remoteNameIsDescriptor() const
{
    //Package ids are composed of 4 parts separed by mandattory ;
    //http://www.packagekit.org/gtk-doc/concepts.html#introduction-ideas-packageid
    return operations()->assetInfo().filename.split(QLatin1Char('.'), QString::KeepEmptyParts).last() == QLatin1String("desc");
}

QString RpmHandler::packageName() const
{
    if (remoteNameIsDescriptor()) {
        return remoteName().split(QLatin1Char('.'), QString::KeepEmptyParts).first();
    //is a rpm name
    } else {
        return remoteName().split(QLatin1Char('-'), QString::KeepEmptyParts).first();
    }
}

const PackageKit::Package &RpmHandler::package() const
{
    return m_package;
}

bool RpmHandler::isInstalled() const
{
    //TODO: manage updates
    return !m_package.id().isEmpty() && (m_package.info() == PackageKit::Package::InfoInstalled ||
                m_package.info() == PackageKit::Package::InfoCollectionInstalled);
}

Bodega::InstallJob *RpmHandler::install(QNetworkReply *reply, Session *session)
{
    if (!m_installJob) {
        //Have a package id
        if (remoteNameIsDescriptor()) {
            m_installJob = new PackageIdInstallJob(reply, session, this);
        } else {
            m_installJob = new RpmInstallJob(reply, session, this);
            connect(m_installJob.data(), SIGNAL(jobFinished(Bodega::NetworkJob*)),
                    this, SLOT(registerForUpdates(Bodega::NetworkJob*)));
        }
        connect(m_installJob.data(), SIGNAL(jobFinished(Bodega::NetworkJob *)),
                this, SLOT(installJobFinished()));
    }

    return m_installJob.data();
}

Bodega::UninstallJob *RpmHandler::uninstall(Session *session)
{
    if (!m_uninstallJob) {
        m_uninstallJob = new RpmUninstallJob(session, this);
        //if not QueuedConnection resolve sudenly after the installation will fail
        connect(m_uninstallJob.data(), SIGNAL(jobFinished(Bodega::NetworkJob*)),
                this, SLOT(installJobFinished()), Qt::QueuedConnection);
        connect(m_uninstallJob.data(), SIGNAL(jobFinished(Bodega::NetworkJob*)),
                this, SLOT(unregisterForUpdates(Bodega::NetworkJob*)));
    }

    return m_uninstallJob.data();
}

QString RpmHandler::launchText() const
{
    return tr("Launch");
}

void RpmHandler::launch()
{
    QProcess::startDetached(QString::fromLatin1("kioclient"), QStringList() << QString::fromLatin1("exec") << m_desktopFile);
}

void RpmHandler::gotPackage(const PackageKit::Package &package)
{
    m_package = package;

    emit installedChanged();

    PackageKit::Transaction *listT = new PackageKit::Transaction;
    listT->getFiles(package);
    connect(listT, SIGNAL(files(const PackageKit::Package &, const QStringList &)),
            this, SLOT(gotFiles(const PackageKit::Package &, const QStringList &)));
}

void RpmHandler::resolveFinished(PackageKit::Transaction::Exit status, uint runtime)
{
    Q_UNUSED(runtime)

    qDebug() << "Package resolving operation finished, got status:" << status;
    setReady(true);
}

void RpmHandler::installJobFinished()
{
    PackageKit::Transaction *t = new PackageKit::Transaction;
    m_package = PackageKit::Package();

    t->resolve(packageName());
    connect(t, SIGNAL(package(const PackageKit::Package &)),
            this, SLOT(gotPackage(const PackageKit::Package &)));
}

void RpmHandler::gotFiles(const PackageKit::Package &package, const QStringList &fileNames)
{
    Q_UNUSED(package)
    foreach (const QString &file, fileNames) {
        if (file.contains(QRegExp(QLatin1String(".*/applications/.*\\.desktop")))) {
            m_desktopFile = file;
            break;
        }
    }
}

class RpmHandlerFactory : public Bodega::AssetHandlerFactory
{
public:
    virtual AssetHandler* createHandler() { return new RpmHandler; }
};

#include "rpmhandler.moc"
Q_EXPORT_PLUGIN2(rpmhandler, RpmHandlerFactory);

<|endoftext|>