<commit_before>//===--- OpenBSD.cpp - OpenBSD ToolChain Implementations --------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "OpenBSD.h"
#include "Arch/Mips.h"
#include "Arch/Sparc.h"
#include "CommonArgs.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/SanitizerArgs.h"
#include "llvm/Option/ArgList.h"

using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang::driver::toolchains;
using namespace clang;
using namespace llvm::opt;

void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
                                      const InputInfo &Output,
                                      const InputInfoList &Inputs,
                                      const ArgList &Args,
                                      const char *LinkingOutput) const {
  claimNoWarnArgs(Args);
  ArgStringList CmdArgs;

  switch (getToolChain().getArch()) {
  case llvm::Triple::x86:
    // When building 32-bit code on OpenBSD/amd64, we have to explicitly
    // instruct as in the base system to assemble 32-bit code.
    CmdArgs.push_back("--32");
    break;

  case llvm::Triple::ppc:
    CmdArgs.push_back("-mppc");
    CmdArgs.push_back("-many");
    break;

  case llvm::Triple::sparc:
  case llvm::Triple::sparcel: {
    CmdArgs.push_back("-32");
    std::string CPU = getCPUName(Args, getToolChain().getTriple());
    CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
    break;
  }

  case llvm::Triple::sparcv9: {
    CmdArgs.push_back("-64");
    std::string CPU = getCPUName(Args, getToolChain().getTriple());
    CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
    break;
  }

  case llvm::Triple::mips64:
  case llvm::Triple::mips64el: {
    StringRef CPUName;
    StringRef ABIName;
    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);

    CmdArgs.push_back("-mabi");
    CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());

    if (getToolChain().getTriple().isLittleEndian())
      CmdArgs.push_back("-EL");
    else
      CmdArgs.push_back("-EB");

    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
    break;
  }

  default:
    break;
  }

  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);

  CmdArgs.push_back("-o");
  CmdArgs.push_back(Output.getFilename());

  for (const auto &II : Inputs)
    CmdArgs.push_back(II.getFilename());

  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
}

void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
                                   const InputInfo &Output,
                                   const InputInfoList &Inputs,
                                   const ArgList &Args,
                                   const char *LinkingOutput) const {
  const toolchains::OpenBSD &ToolChain =
      static_cast<const toolchains::OpenBSD &>(getToolChain());
  const Driver &D = getToolChain().getDriver();
  ArgStringList CmdArgs;

  // Silence warning for "clang -g foo.o -o foo"
  Args.ClaimAllArgs(options::OPT_g_Group);
  // and "clang -emit-llvm foo.o -o foo"
  Args.ClaimAllArgs(options::OPT_emit_llvm);
  // and for "clang -w foo.o -o foo". Other warning options are already
  // handled somewhere else.
  Args.ClaimAllArgs(options::OPT_w);

  if (getToolChain().getArch() == llvm::Triple::mips64)
    CmdArgs.push_back("-EB");
  else if (getToolChain().getArch() == llvm::Triple::mips64el)
    CmdArgs.push_back("-EL");

  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
    CmdArgs.push_back("-e");
    CmdArgs.push_back("__start");
  }

  CmdArgs.push_back("--eh-frame-hdr");
  if (Args.hasArg(options::OPT_static)) {
    CmdArgs.push_back("-Bstatic");
  } else {
    if (Args.hasArg(options::OPT_rdynamic))
      CmdArgs.push_back("-export-dynamic");
    CmdArgs.push_back("-Bdynamic");
    if (Args.hasArg(options::OPT_shared)) {
      CmdArgs.push_back("-shared");
    } else {
      CmdArgs.push_back("-dynamic-linker");
      CmdArgs.push_back("/usr/libexec/ld.so");
    }
  }

  if (Args.hasArg(options::OPT_pie))
    CmdArgs.push_back("-pie");
  if (Args.hasArg(options::OPT_nopie))
    CmdArgs.push_back("-nopie");

  if (Output.isFilename()) {
    CmdArgs.push_back("-o");
    CmdArgs.push_back(Output.getFilename());
  } else {
    assert(Output.isNothing() && "Invalid output.");
  }

  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
    if (!Args.hasArg(options::OPT_shared)) {
      if (Args.hasArg(options::OPT_pg))
        CmdArgs.push_back(
            Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
      else if (Args.hasArg(options::OPT_static) &&
               !Args.hasArg(options::OPT_nopie))
        CmdArgs.push_back(
            Args.MakeArgString(getToolChain().GetFilePath("rcrt0.o")));
      else
        CmdArgs.push_back(
            Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
      CmdArgs.push_back(
          Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
    } else {
      CmdArgs.push_back(
          Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
    }
  }

  std::string Triple = getToolChain().getTripleString();
  if (Triple.substr(0, 6) == "x86_64")
    Triple.replace(0, 6, "amd64");
  CmdArgs.push_back(
      Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + "/4.2.1"));
  CmdArgs.push_back(Args.MakeArgString("-L/usr/lib"));

  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
                            options::OPT_e, options::OPT_s, options::OPT_t,
                            options::OPT_Z_Flag, options::OPT_r});

  bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
  bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);

  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
    if (D.CCCIsCXX()) {
      if (getToolChain().ShouldLinkCXXStdlib(Args))
        getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
      if (Args.hasArg(options::OPT_pg))
        CmdArgs.push_back("-lm_p");
      else
        CmdArgs.push_back("-lm");
    }
    if (NeedsSanitizerDeps) {
      CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins", false));
      linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
    }
    if (NeedsXRayDeps) {
      CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins", false));
      linkXRayRuntimeDeps(ToolChain, CmdArgs);
    }
    // FIXME: For some reason GCC passes -lgcc before adding
    // the default system libraries. Just mimic this for now.
    CmdArgs.push_back("-lgcc");

    if (Args.hasArg(options::OPT_pthread)) {
      if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg))
        CmdArgs.push_back("-lpthread_p");
      else
        CmdArgs.push_back("-lpthread");
    }

    if (!Args.hasArg(options::OPT_shared)) {
      if (Args.hasArg(options::OPT_pg))
        CmdArgs.push_back("-lc_p");
      else
        CmdArgs.push_back("-lc");
    }

    CmdArgs.push_back("-lgcc");
  }

  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
    if (!Args.hasArg(options::OPT_shared))
      CmdArgs.push_back(
          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
    else
      CmdArgs.push_back(
          Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
  }

  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
}

SanitizerMask OpenBSD::getSupportedSanitizers() const {
  const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;

  // For future use, only UBsan at the moment
  SanitizerMask Res = ToolChain::getSupportedSanitizers();

  if (IsX86 || IsX86_64) {
    Res |= SanitizerKind::Vptr;
    Res |= SanitizerKind::Fuzzer;
    Res |= SanitizerKind::FuzzerNoLink;
  }

  return Res;
}

/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.

OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple,
                 const ArgList &Args)
    : Generic_ELF(D, Triple, Args) {
  getFilePaths().push_back(getDriver().Dir + "/../lib");
  getFilePaths().push_back("/usr/lib");
}

void OpenBSD::AddCXXStdlibLibArgs(const ArgList &Args,
                                  ArgStringList &CmdArgs) const {
  bool Profiling = Args.hasArg(options::OPT_pg);

  CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
  CmdArgs.push_back(Profiling ? "-lc++abi_p" : "-lc++abi");
}

Tool *OpenBSD::buildAssembler() const {
  return new tools::openbsd::Assembler(*this);
}

Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); }
<commit_msg>OpenBSD driver needs ld.lld in sanitizer context<commit_after>//===--- OpenBSD.cpp - OpenBSD ToolChain Implementations --------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "OpenBSD.h"
#include "Arch/Mips.h"
#include "Arch/Sparc.h"
#include "CommonArgs.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/SanitizerArgs.h"
#include "llvm/Option/ArgList.h"

using namespace clang::driver;
using namespace clang::driver::tools;
using namespace clang::driver::toolchains;
using namespace clang;
using namespace llvm::opt;

void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
                                      const InputInfo &Output,
                                      const InputInfoList &Inputs,
                                      const ArgList &Args,
                                      const char *LinkingOutput) const {
  claimNoWarnArgs(Args);
  ArgStringList CmdArgs;

  switch (getToolChain().getArch()) {
  case llvm::Triple::x86:
    // When building 32-bit code on OpenBSD/amd64, we have to explicitly
    // instruct as in the base system to assemble 32-bit code.
    CmdArgs.push_back("--32");
    break;

  case llvm::Triple::ppc:
    CmdArgs.push_back("-mppc");
    CmdArgs.push_back("-many");
    break;

  case llvm::Triple::sparc:
  case llvm::Triple::sparcel: {
    CmdArgs.push_back("-32");
    std::string CPU = getCPUName(Args, getToolChain().getTriple());
    CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
    break;
  }

  case llvm::Triple::sparcv9: {
    CmdArgs.push_back("-64");
    std::string CPU = getCPUName(Args, getToolChain().getTriple());
    CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
    break;
  }

  case llvm::Triple::mips64:
  case llvm::Triple::mips64el: {
    StringRef CPUName;
    StringRef ABIName;
    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);

    CmdArgs.push_back("-mabi");
    CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());

    if (getToolChain().getTriple().isLittleEndian())
      CmdArgs.push_back("-EL");
    else
      CmdArgs.push_back("-EB");

    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
    break;
  }

  default:
    break;
  }

  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);

  CmdArgs.push_back("-o");
  CmdArgs.push_back(Output.getFilename());

  for (const auto &II : Inputs)
    CmdArgs.push_back(II.getFilename());

  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
}

void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
                                   const InputInfo &Output,
                                   const InputInfoList &Inputs,
                                   const ArgList &Args,
                                   const char *LinkingOutput) const {
  const toolchains::OpenBSD &ToolChain =
      static_cast<const toolchains::OpenBSD &>(getToolChain());
  const Driver &D = getToolChain().getDriver();
  ArgStringList CmdArgs;

  // Silence warning for "clang -g foo.o -o foo"
  Args.ClaimAllArgs(options::OPT_g_Group);
  // and "clang -emit-llvm foo.o -o foo"
  Args.ClaimAllArgs(options::OPT_emit_llvm);
  // and for "clang -w foo.o -o foo". Other warning options are already
  // handled somewhere else.
  Args.ClaimAllArgs(options::OPT_w);

  if (getToolChain().getArch() == llvm::Triple::mips64)
    CmdArgs.push_back("-EB");
  else if (getToolChain().getArch() == llvm::Triple::mips64el)
    CmdArgs.push_back("-EL");

  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
    CmdArgs.push_back("-e");
    CmdArgs.push_back("__start");
  }

  CmdArgs.push_back("--eh-frame-hdr");
  if (Args.hasArg(options::OPT_static)) {
    CmdArgs.push_back("-Bstatic");
  } else {
    if (Args.hasArg(options::OPT_rdynamic))
      CmdArgs.push_back("-export-dynamic");
    CmdArgs.push_back("-Bdynamic");
    if (Args.hasArg(options::OPT_shared)) {
      CmdArgs.push_back("-shared");
    } else {
      CmdArgs.push_back("-dynamic-linker");
      CmdArgs.push_back("/usr/libexec/ld.so");
    }
  }

  if (Args.hasArg(options::OPT_pie))
    CmdArgs.push_back("-pie");
  if (Args.hasArg(options::OPT_nopie))
    CmdArgs.push_back("-nopie");

  if (Output.isFilename()) {
    CmdArgs.push_back("-o");
    CmdArgs.push_back(Output.getFilename());
  } else {
    assert(Output.isNothing() && "Invalid output.");
  }

  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
    if (!Args.hasArg(options::OPT_shared)) {
      if (Args.hasArg(options::OPT_pg))
        CmdArgs.push_back(
            Args.MakeArgString(getToolChain().GetFilePath("gcrt0.o")));
      else if (Args.hasArg(options::OPT_static) &&
               !Args.hasArg(options::OPT_nopie))
        CmdArgs.push_back(
            Args.MakeArgString(getToolChain().GetFilePath("rcrt0.o")));
      else
        CmdArgs.push_back(
            Args.MakeArgString(getToolChain().GetFilePath("crt0.o")));
      CmdArgs.push_back(
          Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
    } else {
      CmdArgs.push_back(
          Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
    }
  }

  std::string Triple = getToolChain().getTripleString();
  if (Triple.substr(0, 6) == "x86_64")
    Triple.replace(0, 6, "amd64");
  CmdArgs.push_back(
      Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple + "/4.2.1"));
  CmdArgs.push_back(Args.MakeArgString("-L/usr/lib"));

  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
                            options::OPT_e, options::OPT_s, options::OPT_t,
                            options::OPT_Z_Flag, options::OPT_r});

  bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
  bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);

  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
    if (D.CCCIsCXX()) {
      if (getToolChain().ShouldLinkCXXStdlib(Args))
        getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
      if (Args.hasArg(options::OPT_pg))
        CmdArgs.push_back("-lm_p");
      else
        CmdArgs.push_back("-lm");
    }
    if (NeedsSanitizerDeps) {
      CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins", false));
      linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
    }
    if (NeedsXRayDeps) {
      CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins", false));
      linkXRayRuntimeDeps(ToolChain, CmdArgs);
    }
    // FIXME: For some reason GCC passes -lgcc before adding
    // the default system libraries. Just mimic this for now.
    CmdArgs.push_back("-lgcc");

    if (Args.hasArg(options::OPT_pthread)) {
      if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg))
        CmdArgs.push_back("-lpthread_p");
      else
        CmdArgs.push_back("-lpthread");
    }

    if (!Args.hasArg(options::OPT_shared)) {
      if (Args.hasArg(options::OPT_pg))
        CmdArgs.push_back("-lc_p");
      else
        CmdArgs.push_back("-lc");
    }

    CmdArgs.push_back("-lgcc");
  }

  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
    if (!Args.hasArg(options::OPT_shared))
      CmdArgs.push_back(
          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
    else
      CmdArgs.push_back(
          Args.MakeArgString(getToolChain().GetFilePath("crtendS.o")));
  }

  const char *Exec = Args.MakeArgString(
      !NeedsSanitizerDeps ? getToolChain().GetLinkerPath()
                          : getToolChain().GetProgramPath("ld.lld"));
  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
}

SanitizerMask OpenBSD::getSupportedSanitizers() const {
  const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;

  // For future use, only UBsan at the moment
  SanitizerMask Res = ToolChain::getSupportedSanitizers();

  if (IsX86 || IsX86_64) {
    Res |= SanitizerKind::Vptr;
    Res |= SanitizerKind::Fuzzer;
    Res |= SanitizerKind::FuzzerNoLink;
  }

  return Res;
}

/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.

OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple,
                 const ArgList &Args)
    : Generic_ELF(D, Triple, Args) {
  getFilePaths().push_back(getDriver().Dir + "/../lib");
  getFilePaths().push_back("/usr/lib");
}

void OpenBSD::AddCXXStdlibLibArgs(const ArgList &Args,
                                  ArgStringList &CmdArgs) const {
  bool Profiling = Args.hasArg(options::OPT_pg);

  CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
  CmdArgs.push_back(Profiling ? "-lc++abi_p" : "-lc++abi");
}

Tool *OpenBSD::buildAssembler() const {
  return new tools::openbsd::Assembler(*this);
}

Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); }
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <unistd.h>
#include <fnord-base/UTF8.h>
#include "common.h"

namespace cm {

/**
 * mandatory params:
 *  v    -- pixel ver.  -- value: 1
 *  c    -- clickid     -- format "<uid>~<eventid>", e.g. "f97650cb~b28c61d5c"
 *  e    -- eventtype   -- format "{q,v}" (query, visit)
 *
 * params for eventtype=q (query):
 *  is   -- item ids    -- format "<setid>~<itemid>~<pos>,..."
 *
 * params for eventtype=v (visit):
 *  i    -- itemid      -- format "<setid>~<itemid>"
 *
 */
bool isReservedPixelParam(const std::string p) {
  return p == "c" || p == "e" || p == "i" || p == "is" || p == "v";
}

std::string cmHostname() {
  char hostname[128];
  gethostname(hostname, sizeof(hostname));
  hostname[127] = 0;
  return std::string(hostname);
}

Option<String> extractAttr(const Vector<String>& attrs, const String& attr) {
  auto prefix = attr + ":";

  for (const auto& a : attrs) {
    if (StringUtil::beginsWith(a, prefix)) {
      return Some(a.substr(prefix.length()));
    }
  }

  return None<String>();
}

String extractDeviceTypeString(const Vector<String>& attrs) {
  return deviceTypeToString(extractDeviceType(attrs));
}

DeviceType extractDeviceType(const Vector<String>& attrs) {
  auto x_str = extractAttr(attrs, "u_x");
  auto y_str = extractAttr(attrs, "u_y");

  if (x_str.isEmpty() || y_str.isEmpty()) {
    return DeviceType::UNKNOWN;
  }

  auto x = std::stod(x_str.get());
  auto y = std::stod(x_str.get());

  if (x < 10 || y < 10) {
    return DeviceType::UNKNOWN;
  }

  if (x < 1000) {
    return DeviceType::PHONE;
  }

  if (x < 1400) {
    return DeviceType::TABLET;
  }

  return DeviceType::DESKTOP;
}

String deviceTypeToString(DeviceType device_type) {
  switch (device_type) {
    case DeviceType::UNKNOWN: return "unknown";
    case DeviceType::PHONE: return "phone";
    case DeviceType::TABLET: return "tablet";
    case DeviceType::DESKTOP: return "desktop";
  }
}

DeviceType deviceTypeFromString(const String& device_type) {
  if (device_type == "phone") {
    return DeviceType::PHONE;
  }

  if (device_type == "tablet") {
    return DeviceType::TABLET;
  }

  if (device_type == "desktop") {
    return DeviceType::DESKTOP;
  }

  return DeviceType::UNKNOWN;
}

String extractTestGroup(const Vector<String>& attrs) {
  auto test_group = extractAttr(attrs, "dw_ab");
  return test_group.isEmpty() ? "unknown" : test_group.get();
}

Option<uint32_t> extractABTestGroup(const Vector<String>& attrs) {
  auto test_group = extractAttr(attrs, "dw_ab");

  if (test_group.isEmpty()) {
    return None<uint32_t>();
  } else {
    return Some<uint32_t>(std::stoul(test_group.get()));
  }
}

Language extractLanguage(const Vector<String>& attrs) {
  auto l = extractAttr(attrs, "l");

  if (!l.isEmpty()) {
    return languageFromString(l.get());
  }

  // FIXPAUL hack!!!
  if (!extractAttr(attrs, "qstr~de").isEmpty()) {
    return Language::DE;
  }

  if (!extractAttr(attrs, "qstr~pl").isEmpty()) {
    return Language::PL;
  }

  return Language::UNKNOWN;
}

String extractPageTypeString(const Vector<String>& attrs) {
  for (const auto& a : attrs) {
    if (StringUtil::beginsWith(a, "qstr~")) {
      return "search";
    }

    if (StringUtil::beginsWith(a, "q_cat")) {
      return "catalog";
    }
  }

  return "unknown";
}

PageType extractPageType(const Vector<String>& attrs) {
  return pageTypeFromString(extractPageTypeString(attrs));
}

PageType pageTypeFromString(const String& page_type) {
  if (page_type == "search") {
    return PageType::SEARCH_PAGE;
  }

  if (page_type == "catalog") {
    return PageType::CATALOG_PAGE;
  }

  return PageType::UNKNOWN;
}

String pageTypeToString(PageType page_type) {
  switch (page_type) {
    case PageType::UNKNOWN: return "unknown";
    case PageType::SEARCH_PAGE: return "search_page";
    case PageType::CATALOG_PAGE: return "catalog_page";
    case PageType::PRODUCT_PAGE: return "product_page";
  }
}

String joinBagOfWords(const Set<String>& words) {
  Vector<String> v;

  for (const auto& w : words) {
    if (w.length() == 0) {
      continue;
    }

    v.emplace_back(w);
  }

  std::sort(v.begin(), v.end());

  return StringUtil::join(v, " ");
}

bool isQueryEligible(
    ItemEligibility eligibility,
    const cm::JoinedQuery& query) {
  switch (eligibility) {

    case ItemEligibility::DAWANDA_ALL_NOBOTS: {
      auto pgs = extractAttr(query.attrs, "pg");
      if (pgs.isEmpty()) {
        return true;
      } else {
        auto pg = std::stoul(pgs.get());
        return pg <= 3;
      }
    }

    case ItemEligibility::ALL:
      return true;

  }
}

bool isItemEligible(
    ItemEligibility eligibility,
    const cm::JoinedQuery& query,
    const cm::JoinedQueryItem& item) {
  switch (eligibility) {

    case ItemEligibility::DAWANDA_ALL_NOBOTS:
      return item.position <= 40 && item.position > 0;

    case ItemEligibility::ALL:
      return true;

  }
}

Option<String> extractQueryString(const Vector<String>& attrs) {
  for (const auto& a : attrs) {
    if (StringUtil::beginsWith(a, "qstr~")) {
      auto o = StringUtil::find(a, ':');
      if (o != String::npos) {
        return Some(URI::urlDecode(a.substr(o + 1)));
      }
    }
  }

  return None<String>();
}

}
<commit_msg>catch urldecode errors<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <unistd.h>
#include <fnord-base/UTF8.h>
#include "common.h"

namespace cm {

/**
 * mandatory params:
 *  v    -- pixel ver.  -- value: 1
 *  c    -- clickid     -- format "<uid>~<eventid>", e.g. "f97650cb~b28c61d5c"
 *  e    -- eventtype   -- format "{q,v}" (query, visit)
 *
 * params for eventtype=q (query):
 *  is   -- item ids    -- format "<setid>~<itemid>~<pos>,..."
 *
 * params for eventtype=v (visit):
 *  i    -- itemid      -- format "<setid>~<itemid>"
 *
 */
bool isReservedPixelParam(const std::string p) {
  return p == "c" || p == "e" || p == "i" || p == "is" || p == "v";
}

std::string cmHostname() {
  char hostname[128];
  gethostname(hostname, sizeof(hostname));
  hostname[127] = 0;
  return std::string(hostname);
}

Option<String> extractAttr(const Vector<String>& attrs, const String& attr) {
  auto prefix = attr + ":";

  for (const auto& a : attrs) {
    if (StringUtil::beginsWith(a, prefix)) {
      return Some(a.substr(prefix.length()));
    }
  }

  return None<String>();
}

String extractDeviceTypeString(const Vector<String>& attrs) {
  return deviceTypeToString(extractDeviceType(attrs));
}

DeviceType extractDeviceType(const Vector<String>& attrs) {
  auto x_str = extractAttr(attrs, "u_x");
  auto y_str = extractAttr(attrs, "u_y");

  if (x_str.isEmpty() || y_str.isEmpty()) {
    return DeviceType::UNKNOWN;
  }

  auto x = std::stod(x_str.get());
  auto y = std::stod(x_str.get());

  if (x < 10 || y < 10) {
    return DeviceType::UNKNOWN;
  }

  if (x < 1000) {
    return DeviceType::PHONE;
  }

  if (x < 1400) {
    return DeviceType::TABLET;
  }

  return DeviceType::DESKTOP;
}

String deviceTypeToString(DeviceType device_type) {
  switch (device_type) {
    case DeviceType::UNKNOWN: return "unknown";
    case DeviceType::PHONE: return "phone";
    case DeviceType::TABLET: return "tablet";
    case DeviceType::DESKTOP: return "desktop";
  }
}

DeviceType deviceTypeFromString(const String& device_type) {
  if (device_type == "phone") {
    return DeviceType::PHONE;
  }

  if (device_type == "tablet") {
    return DeviceType::TABLET;
  }

  if (device_type == "desktop") {
    return DeviceType::DESKTOP;
  }

  return DeviceType::UNKNOWN;
}

String extractTestGroup(const Vector<String>& attrs) {
  auto test_group = extractAttr(attrs, "dw_ab");
  return test_group.isEmpty() ? "unknown" : test_group.get();
}

Option<uint32_t> extractABTestGroup(const Vector<String>& attrs) {
  auto test_group = extractAttr(attrs, "dw_ab");

  if (test_group.isEmpty()) {
    return None<uint32_t>();
  } else {
    return Some<uint32_t>(std::stoul(test_group.get()));
  }
}

Language extractLanguage(const Vector<String>& attrs) {
  auto l = extractAttr(attrs, "l");

  if (!l.isEmpty()) {
    return languageFromString(l.get());
  }

  // FIXPAUL hack!!!
  if (!extractAttr(attrs, "qstr~de").isEmpty()) {
    return Language::DE;
  }

  if (!extractAttr(attrs, "qstr~pl").isEmpty()) {
    return Language::PL;
  }

  return Language::UNKNOWN;
}

String extractPageTypeString(const Vector<String>& attrs) {
  for (const auto& a : attrs) {
    if (StringUtil::beginsWith(a, "qstr~")) {
      return "search";
    }

    if (StringUtil::beginsWith(a, "q_cat")) {
      return "catalog";
    }
  }

  return "unknown";
}

PageType extractPageType(const Vector<String>& attrs) {
  return pageTypeFromString(extractPageTypeString(attrs));
}

PageType pageTypeFromString(const String& page_type) {
  if (page_type == "search") {
    return PageType::SEARCH_PAGE;
  }

  if (page_type == "catalog") {
    return PageType::CATALOG_PAGE;
  }

  return PageType::UNKNOWN;
}

String pageTypeToString(PageType page_type) {
  switch (page_type) {
    case PageType::UNKNOWN: return "unknown";
    case PageType::SEARCH_PAGE: return "search_page";
    case PageType::CATALOG_PAGE: return "catalog_page";
    case PageType::PRODUCT_PAGE: return "product_page";
  }
}

String joinBagOfWords(const Set<String>& words) {
  Vector<String> v;

  for (const auto& w : words) {
    if (w.length() == 0) {
      continue;
    }

    v.emplace_back(w);
  }

  std::sort(v.begin(), v.end());

  return StringUtil::join(v, " ");
}

bool isQueryEligible(
    ItemEligibility eligibility,
    const cm::JoinedQuery& query) {
  switch (eligibility) {

    case ItemEligibility::DAWANDA_ALL_NOBOTS: {
      auto pgs = extractAttr(query.attrs, "pg");
      if (pgs.isEmpty()) {
        return true;
      } else {
        auto pg = std::stoul(pgs.get());
        return pg <= 3;
      }
    }

    case ItemEligibility::ALL:
      return true;

  }
}

bool isItemEligible(
    ItemEligibility eligibility,
    const cm::JoinedQuery& query,
    const cm::JoinedQueryItem& item) {
  switch (eligibility) {

    case ItemEligibility::DAWANDA_ALL_NOBOTS:
      return item.position <= 40 && item.position > 0;

    case ItemEligibility::ALL:
      return true;

  }
}

Option<String> extractQueryString(const Vector<String>& attrs) {
  for (const auto& a : attrs) {
    if (StringUtil::beginsWith(a, "qstr~")) {
      auto o = StringUtil::find(a, ':');
      if (o != String::npos) {
        try {
          return Some(URI::urlDecode(a.substr(o + 1)));
        } catch (...) {
          return None<String>();
        }
      }
    }
  }

  return None<String>();
}

}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/

#include "cmakeprojectmanager.h"
#include "cmakeprojectconstants.h"
#include "cmakeproject.h"
#include "cmakeprojectconstants.h"

#include <coreplugin/icore.h>
#include <coreplugin/uniqueidmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/environment.h>
#include <qtconcurrent/QtConcurrentTools>
#include <QtCore/QtConcurrentRun>
#include <QtCore/QSettings>
#include <QtGui/QFormLayout>
#include <QtGui/QDesktopServices>
#include <QtGui/QApplication>

using namespace CMakeProjectManager::Internal;

CMakeManager::CMakeManager(CMakeSettingsPage *cmakeSettingsPage)
    : m_settingsPage(cmakeSettingsPage)
{
    Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance();
    m_projectContext = uidm->uniqueIdentifier(CMakeProjectManager::Constants::PROJECTCONTEXT);
    m_projectLanguage = uidm->uniqueIdentifier(ProjectExplorer::Constants::LANG_CXX);
}

CMakeSettingsPage::~CMakeSettingsPage()
{

}

int CMakeManager::projectContext() const
{
    return m_projectContext;
}

int CMakeManager::projectLanguage() const
{
    return m_projectLanguage;
}

ProjectExplorer::Project *CMakeManager::openProject(const QString &fileName)
{
    // TODO check wheter this project is already opened
    // Check that we have a cmake executable first
    // Look at the settings first
    QString cmakeExecutable = m_settingsPage->cmakeExecutable();
    if (cmakeExecutable.isNull())
        m_settingsPage->askUserForCMakeExecutable();
    cmakeExecutable = m_settingsPage->cmakeExecutable();
    if (cmakeExecutable.isNull())
        return 0;
    return new CMakeProject(this, fileName);
}

QString CMakeManager::mimeType() const
{
    return Constants::CMAKEMIMETYPE;
}

QString CMakeManager::cmakeExecutable() const
{
    return m_settingsPage->cmakeExecutable();
}

// TODO need to refactor this out
// we probably want the process instead of this function
// cmakeproject then could even run the cmake process in the background, adding the files afterwards
// sounds like a plan
QProcess *CMakeManager::createXmlFile(const QStringList &arguments, const QString &sourceDirectory, const QDir &buildDirectory)
{
    // We create a cbp file, only if we didn't find a cbp file in the base directory
    // Yet that can still override cbp files in subdirectories
    // And we are creating tons of files in the source directories
    // All of that is not really nice.
    // The mid term plan is to move away from the CodeBlocks Generator and use our own
    // QtCreator generator, which actually can be very similar to the CodeBlock Generator

    // TODO we need to pass on the same paremeters as the cmakestep
    QString buildDirectoryPath = buildDirectory.absolutePath();
    qDebug()<<"Creating cbp file in"<<buildDirectoryPath;
    buildDirectory.mkpath(buildDirectoryPath);
    QProcess * cmake = new QProcess;
    cmake->setWorkingDirectory(buildDirectoryPath);

#ifdef Q_OS_WIN
    QString generator = "-GCodeBlocks - MinGW Makefiles";
#else // Q_OS_WIN
   QString generator = "-GCodeBlocks - Unix Makefiles";
#endif // Q_OS_WIN
    qDebug()<<cmakeExecutable()<<sourceDirectory << arguments<<generator;
    cmake->start(cmakeExecutable(), QStringList() << sourceDirectory << arguments << generator);
    return cmake;
}

QString CMakeManager::findCbpFile(const QDir &directory)
{
    // Find the cbp file
    //   TODO the cbp file is named like the project() command in the CMakeList.txt file
    //   so this method below could find the wrong cbp file, if the user changes the project()
    //   2name
    foreach (const QString &cbpFile , directory.entryList()) {
        if (cbpFile.endsWith(".cbp"))
            return directory.path() + "/" + cbpFile;
    }
    return QString::null;
}

// This code is duplicated from qtversionmanager
QString CMakeManager::qtVersionForQMake(const QString &qmakePath)
{
    QProcess qmake;
    qmake.start(qmakePath, QStringList()<<"--version");
    if (!qmake.waitForFinished())
        return false;
    QString output = qmake.readAllStandardOutput();
    QRegExp regexp("(QMake version|Qmake version:)[\\s]*([\\d.]*)");
    regexp.indexIn(output);
    if (regexp.cap(2).startsWith("2.")) {
        QRegExp regexp2("Using Qt version[\\s]*([\\d\\.]*)");
        regexp2.indexIn(output);
        return regexp2.cap(1);
    }
    return QString();
}

QString CMakeManager::findQtDir(const ProjectExplorer::Environment &env)
{
    QStringList possibleCommands;
        // On windows noone has renamed qmake, right?
#ifdef Q_OS_WIN
    possibleCommands << "qmake.exe";
#endif
    // On unix some distributions renamed qmake to avoid clashes
    possibleCommands << "qmake-qt4" << "qmake4" << "qmake";

    QStringList paths = env.path();
    foreach (const QString &path, paths) {
        foreach (const QString &possibleCommand, possibleCommands) {
            QFileInfo qmake(path + "/" + possibleCommand);
            if (qmake.exists()) {
                if (!qtVersionForQMake(qmake.absoluteFilePath()).isNull()) {
                    QDir dir(qmake.absoluteDir());
                    dir.cdUp();
                    return dir.absolutePath();
                }
            }
        }
    }
    return QString();
}

// This code is more or less duplicated in qtversionmanager
QString CMakeManager::findDumperLibrary(const ProjectExplorer::Environment &env)
{
    static ProjectExplorer::Environment lastenv;
    static QString lastpath;
    if (lastenv == env)
        return lastpath;
    QString qtdir = findQtDir(env);
    if (qtdir.isEmpty())
        return QString();

    uint hash = qHash(qtdir);
    QStringList directories;
    directories
            << (qtdir + "/qtc-debugging-helper/")
            << (QApplication::applicationDirPath() + "/../qtc-debugging-helper/" + QString::number(hash)) + "/"
            << (QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "/qtc-debugging-helper/" + QString::number(hash)) + "/";
    foreach(const QString &directory, directories) {
#if defined(Q_OS_WIN)
        QFileInfo fi(directory + "debug/gdbmacros.dll");
#elif defined(Q_OS_MAC)
        QFileInfo fi(directory + "libgdbmacros.dylib");
#else // generic UNIX
        QFileInfo fi(directory + "libgdbmacros.so");
#endif
        if (fi.exists()) {
            lastpath = fi.filePath();
            return lastpath;
        }
    }
    lastpath = QString();
    return lastpath;
}

/////
// CMakeRunner
////
// TODO give a better name, what this class is to update cached information
// about a cmake executable, with qtconcurrent
// The nifty feature of this class is that it does so in a seperate thread,
// not blocking the main thread

CMakeRunner::CMakeRunner()
    : m_cacheUpToDate(false)
{

}

void CMakeRunner::run(QFutureInterface<void> &fi)
{
    m_mutex.lock();
    QString executable = m_executable;
    m_mutex.unlock();
    QProcess cmake;
    cmake.start(executable, QStringList()<<"--help");
    cmake.waitForFinished();
    QString response = cmake.readAll();
    QRegExp versionRegexp("^cmake version ([*\\d\\.]*)-(|patch (\\d*))(|\\r)\\n");
    versionRegexp.indexIn(response);

    m_mutex.lock();
    m_supportsQtCreator = response.contains("QtCreator");
    m_version = versionRegexp.cap(1);
    if (!versionRegexp.capturedTexts().size()>3)
        m_version += "." + versionRegexp.cap(3);
    m_cacheUpToDate = true;
    m_mutex.unlock();
    fi.reportFinished();
}

void CMakeRunner::setExecutable(const QString &executable)
{
    waitForUpToDate();
    m_mutex.lock();
    m_executable = executable;
    m_cacheUpToDate = false;
    m_mutex.unlock();
    m_future = QtConcurrent::run(&CMakeRunner::run, this);
}

QString CMakeRunner::executable() const
{
    waitForUpToDate();
    m_mutex.lock();
    QString result = m_executable;
    m_mutex.unlock();
    return result;
}

QString CMakeRunner::version() const
{
    waitForUpToDate();
    m_mutex.lock();
    QString result = m_version;
    m_mutex.unlock();
    return result;
}

bool CMakeRunner::supportsQtCreator() const
{
    waitForUpToDate();
    m_mutex.lock();
    bool result = m_supportsQtCreator;
    m_mutex.unlock();
    return result;
}

void CMakeRunner::waitForUpToDate() const
{
    m_future.waitForFinished();
}

/////
// CMakeSettingsPage
////

CMakeSettingsPage::CMakeSettingsPage()
{
    Core::ICore *core = Core::ICore::instance();
    QSettings * settings = core->settings();
    settings->beginGroup("CMakeSettings");
    m_cmakeRunner.setExecutable(settings->value("cmakeExecutable").toString());
    settings->endGroup();
}

QString CMakeSettingsPage::findCmakeExecutable() const
{
    ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
    return env.searchInPath("cmake");
}

QString CMakeSettingsPage::id() const
{
    return QLatin1String("CMake");
}

QString CMakeSettingsPage::trName() const
{
    return tr("CMake");
}

QString CMakeSettingsPage::category() const
{
    return QLatin1String("CMake");
}

QString CMakeSettingsPage::trCategory() const
{
    return tr("CMake");
}

QWidget *CMakeSettingsPage::createPage(QWidget *parent)
{
    QWidget *w = new QWidget(parent);
    QFormLayout *fl = new QFormLayout(w);
    m_pathchooser = new Core::Utils::PathChooser(w);
    m_pathchooser->setExpectedKind(Core::Utils::PathChooser::Command);
    fl->addRow("CMake executable", m_pathchooser);
    m_pathchooser->setPath(cmakeExecutable());
    return w;
}

void CMakeSettingsPage::saveSettings() const
{
    QSettings *settings = Core::ICore::instance()->settings();
    settings->beginGroup("CMakeSettings");
    settings->setValue("cmakeExecutable", m_cmakeRunner.executable());
    settings->endGroup();
}

void CMakeSettingsPage::apply()
{
    m_cmakeRunner.setExecutable(m_pathchooser->path());
    saveSettings();
}

void CMakeSettingsPage::finish()
{

}

QString CMakeSettingsPage::cmakeExecutable() const
{
    if (m_cmakeRunner.executable().isEmpty()) {
        QString cmakeExecutable = findCmakeExecutable();
        if (!cmakeExecutable.isEmpty()) {
            m_cmakeRunner.setExecutable(cmakeExecutable);
            saveSettings();
        }
    }
    return m_cmakeRunner.executable();
}

void CMakeSettingsPage::askUserForCMakeExecutable()
{
    // TODO implement
    // That is ideally add a label to the settings page, which says something
    // to the effect: please configure the cmake executable
    // and show the settings page
    // ensure that we rehide the label in the finish() function
    // But to test that i need an environment without cmake, e.g. windows
}
<commit_msg>re-use pre-existing builds<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/

#include "cmakeprojectmanager.h"
#include "cmakeprojectconstants.h"
#include "cmakeproject.h"
#include "cmakeprojectconstants.h"

#include <coreplugin/icore.h>
#include <coreplugin/uniqueidmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/environment.h>
#include <qtconcurrent/QtConcurrentTools>
#include <QtCore/QtConcurrentRun>
#include <QtCore/QSettings>
#include <QtGui/QFormLayout>
#include <QtGui/QDesktopServices>
#include <QtGui/QApplication>

using namespace CMakeProjectManager::Internal;

CMakeManager::CMakeManager(CMakeSettingsPage *cmakeSettingsPage)
    : m_settingsPage(cmakeSettingsPage)
{
    Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance();
    m_projectContext = uidm->uniqueIdentifier(CMakeProjectManager::Constants::PROJECTCONTEXT);
    m_projectLanguage = uidm->uniqueIdentifier(ProjectExplorer::Constants::LANG_CXX);
}

CMakeSettingsPage::~CMakeSettingsPage()
{

}

int CMakeManager::projectContext() const
{
    return m_projectContext;
}

int CMakeManager::projectLanguage() const
{
    return m_projectLanguage;
}

ProjectExplorer::Project *CMakeManager::openProject(const QString &fileName)
{
    // TODO check wheter this project is already opened
    // Check that we have a cmake executable first
    // Look at the settings first
    QString cmakeExecutable = m_settingsPage->cmakeExecutable();
    if (cmakeExecutable.isNull())
        m_settingsPage->askUserForCMakeExecutable();
    cmakeExecutable = m_settingsPage->cmakeExecutable();
    if (cmakeExecutable.isNull())
        return 0;
    return new CMakeProject(this, fileName);
}

QString CMakeManager::mimeType() const
{
    return Constants::CMAKEMIMETYPE;
}

QString CMakeManager::cmakeExecutable() const
{
    return m_settingsPage->cmakeExecutable();
}

// TODO need to refactor this out
// we probably want the process instead of this function
// cmakeproject then could even run the cmake process in the background, adding the files afterwards
// sounds like a plan
QProcess *CMakeManager::createXmlFile(const QStringList &arguments, const QString &sourceDirectory, const QDir &buildDirectory)
{
    // We create a cbp file, only if we didn't find a cbp file in the base directory
    // Yet that can still override cbp files in subdirectories
    // And we are creating tons of files in the source directories
    // All of that is not really nice.
    // The mid term plan is to move away from the CodeBlocks Generator and use our own
    // QtCreator generator, which actually can be very similar to the CodeBlock Generator

    // TODO we need to pass on the same paremeters as the cmakestep
    QString buildDirectoryPath = buildDirectory.absolutePath();
    qDebug()<<"Creating cbp file in"<<buildDirectoryPath;
    buildDirectory.mkpath(buildDirectoryPath);
    QProcess * cmake = new QProcess;
    cmake->setWorkingDirectory(buildDirectoryPath);

#ifdef Q_OS_WIN
    QString generator = "-GCodeBlocks - MinGW Makefiles";
#else // Q_OS_WIN
    QString generator = "-GCodeBlocks - Unix Makefiles";
#endif // Q_OS_WIN
    QString srcdir = buildDirectory.exists("CMakeCache.txt") ? QString(".") : sourceDirectory;
    qDebug()<<cmakeExecutable()<<srcdir<<arguments<<generator;
    cmake->start(cmakeExecutable(), QStringList() << srcdir << arguments << generator);
    return cmake;
}

QString CMakeManager::findCbpFile(const QDir &directory)
{
    // Find the cbp file
    //   TODO the cbp file is named like the project() command in the CMakeList.txt file
    //   so this method below could find the wrong cbp file, if the user changes the project()
    //   2name
    foreach (const QString &cbpFile , directory.entryList()) {
        if (cbpFile.endsWith(".cbp"))
            return directory.path() + "/" + cbpFile;
    }
    return QString::null;
}

// This code is duplicated from qtversionmanager
QString CMakeManager::qtVersionForQMake(const QString &qmakePath)
{
    QProcess qmake;
    qmake.start(qmakePath, QStringList()<<"--version");
    if (!qmake.waitForFinished())
        return false;
    QString output = qmake.readAllStandardOutput();
    QRegExp regexp("(QMake version|Qmake version:)[\\s]*([\\d.]*)");
    regexp.indexIn(output);
    if (regexp.cap(2).startsWith("2.")) {
        QRegExp regexp2("Using Qt version[\\s]*([\\d\\.]*)");
        regexp2.indexIn(output);
        return regexp2.cap(1);
    }
    return QString();
}

QString CMakeManager::findQtDir(const ProjectExplorer::Environment &env)
{
    QStringList possibleCommands;
        // On windows noone has renamed qmake, right?
#ifdef Q_OS_WIN
    possibleCommands << "qmake.exe";
#endif
    // On unix some distributions renamed qmake to avoid clashes
    possibleCommands << "qmake-qt4" << "qmake4" << "qmake";

    QStringList paths = env.path();
    foreach (const QString &path, paths) {
        foreach (const QString &possibleCommand, possibleCommands) {
            QFileInfo qmake(path + "/" + possibleCommand);
            if (qmake.exists()) {
                if (!qtVersionForQMake(qmake.absoluteFilePath()).isNull()) {
                    QDir dir(qmake.absoluteDir());
                    dir.cdUp();
                    return dir.absolutePath();
                }
            }
        }
    }
    return QString();
}

// This code is more or less duplicated in qtversionmanager
QString CMakeManager::findDumperLibrary(const ProjectExplorer::Environment &env)
{
    static ProjectExplorer::Environment lastenv;
    static QString lastpath;
    if (lastenv == env)
        return lastpath;
    QString qtdir = findQtDir(env);
    if (qtdir.isEmpty())
        return QString();

    uint hash = qHash(qtdir);
    QStringList directories;
    directories
            << (qtdir + "/qtc-debugging-helper/")
            << (QApplication::applicationDirPath() + "/../qtc-debugging-helper/" + QString::number(hash)) + "/"
            << (QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "/qtc-debugging-helper/" + QString::number(hash)) + "/";
    foreach(const QString &directory, directories) {
#if defined(Q_OS_WIN)
        QFileInfo fi(directory + "debug/gdbmacros.dll");
#elif defined(Q_OS_MAC)
        QFileInfo fi(directory + "libgdbmacros.dylib");
#else // generic UNIX
        QFileInfo fi(directory + "libgdbmacros.so");
#endif
        if (fi.exists()) {
            lastpath = fi.filePath();
            return lastpath;
        }
    }
    lastpath = QString();
    return lastpath;
}

/////
// CMakeRunner
////
// TODO give a better name, what this class is to update cached information
// about a cmake executable, with qtconcurrent
// The nifty feature of this class is that it does so in a seperate thread,
// not blocking the main thread

CMakeRunner::CMakeRunner()
    : m_cacheUpToDate(false)
{

}

void CMakeRunner::run(QFutureInterface<void> &fi)
{
    m_mutex.lock();
    QString executable = m_executable;
    m_mutex.unlock();
    QProcess cmake;
    cmake.start(executable, QStringList()<<"--help");
    cmake.waitForFinished();
    QString response = cmake.readAll();
    QRegExp versionRegexp("^cmake version ([*\\d\\.]*)-(|patch (\\d*))(|\\r)\\n");
    versionRegexp.indexIn(response);

    m_mutex.lock();
    m_supportsQtCreator = response.contains("QtCreator");
    m_version = versionRegexp.cap(1);
    if (!versionRegexp.capturedTexts().size()>3)
        m_version += "." + versionRegexp.cap(3);
    m_cacheUpToDate = true;
    m_mutex.unlock();
    fi.reportFinished();
}

void CMakeRunner::setExecutable(const QString &executable)
{
    waitForUpToDate();
    m_mutex.lock();
    m_executable = executable;
    m_cacheUpToDate = false;
    m_mutex.unlock();
    m_future = QtConcurrent::run(&CMakeRunner::run, this);
}

QString CMakeRunner::executable() const
{
    waitForUpToDate();
    m_mutex.lock();
    QString result = m_executable;
    m_mutex.unlock();
    return result;
}

QString CMakeRunner::version() const
{
    waitForUpToDate();
    m_mutex.lock();
    QString result = m_version;
    m_mutex.unlock();
    return result;
}

bool CMakeRunner::supportsQtCreator() const
{
    waitForUpToDate();
    m_mutex.lock();
    bool result = m_supportsQtCreator;
    m_mutex.unlock();
    return result;
}

void CMakeRunner::waitForUpToDate() const
{
    m_future.waitForFinished();
}

/////
// CMakeSettingsPage
////

CMakeSettingsPage::CMakeSettingsPage()
{
    Core::ICore *core = Core::ICore::instance();
    QSettings * settings = core->settings();
    settings->beginGroup("CMakeSettings");
    m_cmakeRunner.setExecutable(settings->value("cmakeExecutable").toString());
    settings->endGroup();
}

QString CMakeSettingsPage::findCmakeExecutable() const
{
    ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
    return env.searchInPath("cmake");
}

QString CMakeSettingsPage::id() const
{
    return QLatin1String("CMake");
}

QString CMakeSettingsPage::trName() const
{
    return tr("CMake");
}

QString CMakeSettingsPage::category() const
{
    return QLatin1String("CMake");
}

QString CMakeSettingsPage::trCategory() const
{
    return tr("CMake");
}

QWidget *CMakeSettingsPage::createPage(QWidget *parent)
{
    QWidget *w = new QWidget(parent);
    QFormLayout *fl = new QFormLayout(w);
    m_pathchooser = new Core::Utils::PathChooser(w);
    m_pathchooser->setExpectedKind(Core::Utils::PathChooser::Command);
    fl->addRow("CMake executable", m_pathchooser);
    m_pathchooser->setPath(cmakeExecutable());
    return w;
}

void CMakeSettingsPage::saveSettings() const
{
    QSettings *settings = Core::ICore::instance()->settings();
    settings->beginGroup("CMakeSettings");
    settings->setValue("cmakeExecutable", m_cmakeRunner.executable());
    settings->endGroup();
}

void CMakeSettingsPage::apply()
{
    m_cmakeRunner.setExecutable(m_pathchooser->path());
    saveSettings();
}

void CMakeSettingsPage::finish()
{

}

QString CMakeSettingsPage::cmakeExecutable() const
{
    if (m_cmakeRunner.executable().isEmpty()) {
        QString cmakeExecutable = findCmakeExecutable();
        if (!cmakeExecutable.isEmpty()) {
            m_cmakeRunner.setExecutable(cmakeExecutable);
            saveSettings();
        }
    }
    return m_cmakeRunner.executable();
}

void CMakeSettingsPage::askUserForCMakeExecutable()
{
    // TODO implement
    // That is ideally add a label to the settings page, which says something
    // to the effect: please configure the cmake executable
    // and show the settings page
    // ensure that we rehide the label in the finish() function
    // But to test that i need an environment without cmake, e.g. windows
}
<|endoftext|>


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

#include <fstream>
#include "itkMatrixIndexSelectionImageFilter.h"
#include "itkImageFileWriter.h"

int itkMatrixIndexSelectionImageFilterTest(int argc, char* argv[] )
{
  if( argc < 1 )
    {
    std::cerr << "Missing Parameters " << std::endl;
    std::cerr << "Usage: " << argv[0];
    std::cerr << " outputImage" << std::endl;
    return EXIT_FAILURE;
    }

  const unsigned int Dimension = 2;
  typedef itk::Matrix<unsigned short,Dimension,Dimension> PixelType;
  typedef unsigned char                                   OutputPixelType;

  typedef itk::Image<PixelType, Dimension>       ImageType;
  typedef itk::Image<OutputPixelType, Dimension> OutputImageType;

  // create a matrix image
  ImageType::Pointer image = ImageType::New();
  ImageType::RegionType region;
  ImageType::SizeType size; size.Fill(100);
  ImageType::IndexType index; index.Fill(0);

  region.SetSize(size);
  region.SetIndex(index);
  image->SetRegions( region );
  image->Allocate();

  size = region.GetSize();
  index = region.GetIndex();
  unsigned int width = size[0];
  unsigned int height = size[1];

  // populate upper half of image
  size[0] = width;
  size[1] = height / 2;
  index[0] = 0;
  index[1] = 0;
  region.SetSize(size);
  region.SetIndex(index);
  {
  PixelType pixel;
  pixel[0][0] = 128;  pixel[0][1] = 192;
  pixel[1][0] =   0;  pixel[1][1] =  64;
  std::cout << "pixel: " << pixel << std::endl;
  itk::ImageRegionIterator<ImageType> it(image, region);
  std::cout << region;
  it.GoToBegin();
  while (!it.IsAtEnd())
    {
    it.Set(pixel);
    ++it;
    }
  }

  // populate lower half of image
  index[0] = 0;
  index[1] = height / 2;
  region.SetSize(size);
  region.SetIndex(index);
  {
  PixelType pixel;
  pixel[0][0] =  64; pixel[0][1] =  16;
  pixel[1][0] = 255; pixel[1][1] = 192;
  std::cout << "pixel: " << pixel << std::endl;
  std::cout << region;
  itk::ImageRegionIterator<ImageType> it(image, region);
  it.GoToBegin();
  while (!it.IsAtEnd())    {
    it.Set(pixel);
    ++it;
    }
  }

  typedef itk::MatrixIndexSelectionImageFilter<ImageType,OutputImageType> SelectionFilterType;

  SelectionFilterType::Pointer filter = SelectionFilterType::New();
  filter->SetInput(image);
  filter->SetIndices(0,1);
  filter->SetFunctor(filter->GetFunctor());

  typedef itk::ImageFileWriter<OutputImageType> WriterType;
  WriterType::Pointer writer = WriterType::New();

  try
    {
    writer->SetInput(filter->GetOutput());
    writer->SetFileName(argv[1]);
    writer->Update();
    }
  catch( itk::ExceptionObject & excep )
    {
    std::cerr << "Exception caught !" << std::endl;
    std::cerr << excep << std::endl;
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
<commit_msg>ENH: Improve the itkMatrixSelectionImageFilter coverage.<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include <fstream>
#include "itkMatrixIndexSelectionImageFilter.h"
#include "itkImageFileWriter.h"
#include "itkTestingMacros.h"

int itkMatrixIndexSelectionImageFilterTest( int argc, char* argv[] )
{
  if( argc < 1 )
    {
    std::cerr << "Missing Parameters " << std::endl;
    std::cerr << "Usage: " << argv[0];
    std::cerr << " outputImage" << std::endl;
    return EXIT_FAILURE;
    }

  // Define the dimension of the images
  const unsigned int Dimension = 2;

  // Declare the pixel types of the images
  typedef itk::Matrix< unsigned short, Dimension, Dimension > PixelType;
  typedef unsigned char                                       OutputPixelType;

  // Declare the types of the images
  typedef itk::Image< PixelType, Dimension >       InputImageType;
  typedef itk::Image< OutputPixelType, Dimension > OutputImageType;

  // Create a matrix image
  InputImageType::Pointer image = InputImageType::New();
  InputImageType::RegionType region;

  InputImageType::SizeType size;
  size.Fill( 100 );

  InputImageType::IndexType index;
  index.Fill( 0 );

  region.SetSize( size );
  region.SetIndex( index );
  image->SetRegions( region );
  image->Allocate();

  size = region.GetSize();
  index = region.GetIndex();
  unsigned int width = size[0];
  unsigned int height = size[1];

  size[0] = width;
  size[1] = height / 2;

  // Populate upper half of image
  index[0] = 0;
  index[1] = 0;
  region.SetSize( size );
  region.SetIndex( index );
  {
  PixelType pixel;
  pixel[0][0] = 128;
  pixel[0][1] = 192;
  pixel[1][0] =   0;
  pixel[1][1] =  64;

  itk::ImageRegionIterator< InputImageType > it( image, region );
  it.GoToBegin();
  while( !it.IsAtEnd() )
    {
    it.Set( pixel );
    ++it;
    }
  }

  // Populate lower half of image
  index[0] = 0;
  index[1] = height / 2;
  region.SetSize( size );
  region.SetIndex( index );
  {
  PixelType pixel;
  pixel[0][0] =  64;
  pixel[0][1] =  16;
  pixel[1][0] = 255;
  pixel[1][1] = 192;

  itk::ImageRegionIterator< InputImageType > it( image, region );
  it.GoToBegin();
  while( !it.IsAtEnd() )
    {
    it.Set( pixel );
    ++it;
    }
  }

  typedef itk::MatrixIndexSelectionImageFilter< InputImageType, OutputImageType >
    SelectionFilterType;

  SelectionFilterType::Pointer filter = SelectionFilterType::New();

  EXERCISE_BASIC_OBJECT_METHODS( filter, MatrixIndexSelectionImageFilter,
    UnaryFunctorImageFilter );

  filter->SetInput( image );

  unsigned int indexA = 0;
  unsigned int indexB = 1;
  filter->SetIndices( indexA, indexB );

  unsigned int testIndexA;
  unsigned int testIndexB;
  filter->GetIndices( testIndexA, testIndexB );

  if( indexA != testIndexA || indexB != testIndexB )
    {
    std::cerr << "Error " << std::endl;
    std::cerr << " Expected indices: ("
      << indexA << ", "<< indexB << ")" << std::endl;
    std::cerr << " differ from ";
    std::cerr << " obtained indices: ("
      << testIndexA << ", "<< testIndexB << ")" << std::endl;
    return EXIT_FAILURE;
    }

  filter->SetFunctor( filter->GetFunctor() );

  typedef itk::ImageFileWriter< OutputImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();

  writer->SetFileName( argv[1] );
  writer->SetInput( filter->GetOutput() );

  TRY_EXPECT_NO_EXCEPTION( writer->Update() );

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/

#include "remotelinuxrunconfiguration.h"

#include "deploymentinfo.h"
#include "linuxdeviceconfiguration.h"
#include "portlist.h"
#include "remotelinuxdeployconfiguration.h"
#include "remotelinuxrunconfigurationwidget.h"

#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h>
#include <projectexplorer/toolchain.h>
#include <qtsupport/qtoutputformatter.h>
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <qt4projectmanager/qt4nodes.h>
#include <qt4projectmanager/qt4project.h>
#include <qt4projectmanager/qt4target.h>

#include <utils/qtcassert.h>

using namespace ProjectExplorer;
using namespace Qt4ProjectManager;

namespace RemoteLinux {
namespace Internal {
namespace {
const char ArgumentsKey[] = "Qt4ProjectManager.MaemoRunConfiguration.Arguments";
const char ProFileKey[] = "Qt4ProjectManager.MaemoRunConfiguration.ProFile";
const char BaseEnvironmentBaseKey[] = "Qt4ProjectManager.MaemoRunConfiguration.BaseEnvironmentBase";
const char UserEnvironmentChangesKey[]
    = "Qt4ProjectManager.MaemoRunConfiguration.UserEnvironmentChanges";
const char UseAlternateExeKey[] = "RemoteLinux.RunConfig.UseAlternateRemoteExecutable";
const char AlternateExeKey[] = "RemoteLinux.RunConfig.AlternateRemoteExecutable";

} // anonymous namespace

class RemoteLinuxRunConfigurationPrivate {
public:
    RemoteLinuxRunConfigurationPrivate(const QString &proFilePath, const Qt4BaseTarget *target)
        : proFilePath(proFilePath),
          baseEnvironmentType(RemoteLinuxRunConfiguration::SystemBaseEnvironment),
          validParse(target->qt4Project()->validParse(proFilePath)),
          parseInProgress(target->qt4Project()->parseInProgress(proFilePath)),
          useAlternateRemoteExecutable(false)
    {
    }

    RemoteLinuxRunConfigurationPrivate(const RemoteLinuxRunConfigurationPrivate *other)
        : proFilePath(other->proFilePath), gdbPath(other->gdbPath), arguments(other->arguments),
          baseEnvironmentType(other->baseEnvironmentType),
          systemEnvironment(other->systemEnvironment),
          userEnvironmentChanges(other->userEnvironmentChanges),
          validParse(other->validParse),
          parseInProgress(other->parseInProgress),
          useAlternateRemoteExecutable(other->useAlternateRemoteExecutable),
          alternateRemoteExecutable(other->alternateRemoteExecutable)
    {
    }

    QString proFilePath;
    QString gdbPath;
    QString arguments;
    RemoteLinuxRunConfiguration::BaseEnvironmentType baseEnvironmentType;
    Utils::Environment systemEnvironment;
    QList<Utils::EnvironmentItem> userEnvironmentChanges;
    bool validParse;
    bool parseInProgress;
    QString disabledReason;
    bool useAlternateRemoteExecutable;
    QString alternateRemoteExecutable;
};

} // namespace Internal

using namespace Internal;

RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Qt4BaseTarget *parent, const QString &id,
        const QString &proFilePath)
    : RunConfiguration(parent, id),
      d(new RemoteLinuxRunConfigurationPrivate(proFilePath, parent))
{
    init();
}

RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Qt4BaseTarget *parent,
        RemoteLinuxRunConfiguration *source)
    : RunConfiguration(parent, source),
      d(new RemoteLinuxRunConfigurationPrivate(source->d))
{
    init();
}

void RemoteLinuxRunConfiguration::init()
{
    setDefaultDisplayName(defaultDisplayName());
    setUseCppDebugger(true);
    setUseQmlDebugger(false);

    connect(target(),
        SIGNAL(activeDeployConfigurationChanged(ProjectExplorer::DeployConfiguration*)),
        this, SLOT(handleDeployConfigChanged()));
    handleDeployConfigChanged();

    Qt4Project *pro = qt4Target()->qt4Project();
    connect(pro, SIGNAL(proFileUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool)),
            this, SLOT(proFileUpdate(Qt4ProjectManager::Qt4ProFileNode*,bool,bool)));
}

RemoteLinuxRunConfiguration::~RemoteLinuxRunConfiguration()
{
}

Qt4BaseTarget *RemoteLinuxRunConfiguration::qt4Target() const
{
    return static_cast<Qt4BaseTarget *>(target());
}

Qt4BuildConfiguration *RemoteLinuxRunConfiguration::activeQt4BuildConfiguration() const
{
    return static_cast<Qt4BuildConfiguration *>(activeBuildConfiguration());
}

bool RemoteLinuxRunConfiguration::isEnabled() const
{
    if (d->parseInProgress) {
        d->disabledReason = tr("The .pro file is being parsed.");
        return false;
    }
    if (!d->validParse) {
        d->disabledReason = tr("The .pro file could not be parsed.");
        return false;
    }
    if (!deviceConfig()) {
        d->disabledReason = tr("No device configuration set.");
        return false;
    }
    if (!activeQt4BuildConfiguration()) {
        d->disabledReason = tr("No active build configuration.");
        return false;
    }
    if (remoteExecutableFilePath().isEmpty()) {
        d->disabledReason = tr("Don't know what to run.");
        return false;
    }
    d->disabledReason.clear();
    return true;
}

QString RemoteLinuxRunConfiguration::disabledReason() const
{
    return d->disabledReason;
}

QWidget *RemoteLinuxRunConfiguration::createConfigurationWidget()
{
    return new RemoteLinuxRunConfigurationWidget(this);
}

Utils::OutputFormatter *RemoteLinuxRunConfiguration::createOutputFormatter() const
{
    return new QtSupport::QtOutputFormatter(qt4Target()->qt4Project());
}

void RemoteLinuxRunConfiguration::proFileUpdate(Qt4ProjectManager::Qt4ProFileNode *pro, bool success, bool parseInProgress)
{
    if (d->proFilePath == pro->path()) {
        bool enabled = isEnabled();
        d->validParse = success;
        d->parseInProgress = parseInProgress;
        if (enabled != isEnabled())
            updateEnabledState();
        if (!parseInProgress)
            emit targetInformationChanged();
    }
}

QVariantMap RemoteLinuxRunConfiguration::toMap() const
{
    QVariantMap map(RunConfiguration::toMap());
    map.insert(QLatin1String(ArgumentsKey), d->arguments);
    const QDir dir = QDir(target()->project()->projectDirectory());
    map.insert(QLatin1String(ProFileKey), dir.relativeFilePath(d->proFilePath));
    map.insert(QLatin1String(BaseEnvironmentBaseKey), d->baseEnvironmentType);
    map.insert(QLatin1String(UserEnvironmentChangesKey),
        Utils::EnvironmentItem::toStringList(d->userEnvironmentChanges));
    map.insert(QLatin1String(UseAlternateExeKey), d->useAlternateRemoteExecutable);
    map.insert(QLatin1String(AlternateExeKey), d->alternateRemoteExecutable);
    return map;
}

bool RemoteLinuxRunConfiguration::fromMap(const QVariantMap &map)
{
    if (!RunConfiguration::fromMap(map))
        return false;

    d->arguments = map.value(QLatin1String(ArgumentsKey)).toString();
    const QDir dir = QDir(target()->project()->projectDirectory());
    d->proFilePath = QDir::cleanPath(dir.filePath(map.value(QLatin1String(ProFileKey)).toString()));
    d->userEnvironmentChanges =
        Utils::EnvironmentItem::fromStringList(map.value(QLatin1String(UserEnvironmentChangesKey))
        .toStringList());
    d->baseEnvironmentType = static_cast<BaseEnvironmentType>(map.value(QLatin1String(BaseEnvironmentBaseKey),
        SystemBaseEnvironment).toInt());
    d->useAlternateRemoteExecutable = map.value(QLatin1String(UseAlternateExeKey), false).toBool();
    d->alternateRemoteExecutable = map.value(QLatin1String(AlternateExeKey)).toString();

    d->validParse = qt4Target()->qt4Project()->validParse(d->proFilePath);
    d->parseInProgress = qt4Target()->qt4Project()->parseInProgress(d->proFilePath);

    setDefaultDisplayName(defaultDisplayName());

    return true;
}

QString RemoteLinuxRunConfiguration::defaultDisplayName()
{
    if (!d->proFilePath.isEmpty())
        return (QFileInfo(d->proFilePath).completeBaseName()) + QLatin1String(" (remote)");
    //: Remote Linux run configuration default display name
    return tr("Run on remote device");
}

LinuxDeviceConfiguration::ConstPtr RemoteLinuxRunConfiguration::deviceConfig() const
{
    return deployConfig()
        ? deployConfig()->deviceConfiguration() : LinuxDeviceConfiguration::ConstPtr();
}

QString RemoteLinuxRunConfiguration::gdbCmd() const
{
    return QDir::toNativeSeparators(activeBuildConfiguration()->toolChain()->debuggerCommand());
}

RemoteLinuxDeployConfiguration *RemoteLinuxRunConfiguration::deployConfig() const
{
    return qobject_cast<RemoteLinuxDeployConfiguration *>(target()->activeDeployConfiguration());
}

QString RemoteLinuxRunConfiguration::arguments() const
{
    return d->arguments;
}

QString RemoteLinuxRunConfiguration::environmentPreparationCommand() const
{
    QString command;
    const QStringList filesToSource = QStringList() << QLatin1String("/etc/profile")
        << QLatin1String("$HOME/.profile");
    foreach (const QString &filePath, filesToSource)
        command += QString::fromLocal8Bit("test -f %1 && source %1;").arg(filePath);
    command.chop(1); // Trailing semicolon.
    return command;
}

QString RemoteLinuxRunConfiguration::commandPrefix() const
{
    return QString::fromLocal8Bit("%1; DISPLAY=:0.0 %2")
        .arg(environmentPreparationCommand(), userEnvironmentChangesAsString());
}

QString RemoteLinuxRunConfiguration::localExecutableFilePath() const
{
    TargetInformation ti = qt4Target()->qt4Project()->rootQt4ProjectNode()
        ->targetInformation(d->proFilePath);
    if (!ti.valid)
        return QString();

    return QDir::cleanPath(ti.workingDir + QLatin1Char('/') + ti.target);
}

QString RemoteLinuxRunConfiguration::defaultRemoteExecutableFilePath() const
{
    return deployConfig()
        ? deployConfig()->deploymentInfo()->remoteExecutableFilePath(localExecutableFilePath())
        : QString();
}

QString RemoteLinuxRunConfiguration::remoteExecutableFilePath() const
{
    return d->useAlternateRemoteExecutable
        ? alternateRemoteExecutable() : defaultRemoteExecutableFilePath();
}

PortList RemoteLinuxRunConfiguration::freePorts() const
{
    const LinuxDeviceConfiguration::ConstPtr &devConf = deviceConfig();
    if (!devConf)
        return PortList();
    return devConf->freePorts();
}

void RemoteLinuxRunConfiguration::setArguments(const QString &args)
{
    d->arguments = args;
}

void RemoteLinuxRunConfiguration::setUseAlternateExecutable(bool useAlternate)
{
    d->useAlternateRemoteExecutable = useAlternate;
}

bool RemoteLinuxRunConfiguration::useAlternateExecutable() const
{
    return d->useAlternateRemoteExecutable;
}

void RemoteLinuxRunConfiguration::setAlternateRemoteExecutable(const QString &exe)
{
    d->alternateRemoteExecutable = exe;
}

QString RemoteLinuxRunConfiguration::alternateRemoteExecutable() const
{
    return d->alternateRemoteExecutable;
}

RemoteLinuxRunConfiguration::DebuggingType RemoteLinuxRunConfiguration::debuggingType() const
{
    if (useCppDebugger()) {
        if (useQmlDebugger())
            return DebugCppAndQml;
        return DebugCppOnly;
    }
    return DebugQmlOnly;
}

int RemoteLinuxRunConfiguration::portsUsedByDebuggers() const
{
    switch (debuggingType()) {
    case DebugCppOnly:
    case DebugQmlOnly:
        return 1;
    case DebugCppAndQml:
    default:
        return 2;
    }
}

void RemoteLinuxRunConfiguration::updateDeviceConfigurations()
{
    emit deviceConfigurationChanged(target());
    updateEnabledState();
}

void RemoteLinuxRunConfiguration::handleDeployConfigChanged()
{
    RemoteLinuxDeployConfiguration * const activeDeployConf = deployConfig();
    if (activeDeployConf) {
        connect(activeDeployConf->deploymentInfo().data(), SIGNAL(modelReset()),
            SLOT(handleDeployablesUpdated()), Qt::UniqueConnection);
        connect(activeDeployConf, SIGNAL(currentDeviceConfigurationChanged()),
            SLOT(updateDeviceConfigurations()), Qt::UniqueConnection);
    }

    updateDeviceConfigurations();
}

void RemoteLinuxRunConfiguration::handleDeployablesUpdated()
{
    emit deploySpecsChanged();
    updateEnabledState();
}

QString RemoteLinuxRunConfiguration::baseEnvironmentText() const
{
    if (d->baseEnvironmentType == CleanBaseEnvironment)
        return tr("Clean Environment");
    else  if (d->baseEnvironmentType == SystemBaseEnvironment)
        return tr("System Environment");
    return QString();
}

RemoteLinuxRunConfiguration::BaseEnvironmentType RemoteLinuxRunConfiguration::baseEnvironmentType() const
{
    return d->baseEnvironmentType;
}

void RemoteLinuxRunConfiguration::setBaseEnvironmentType(BaseEnvironmentType env)
{
    if (d->baseEnvironmentType != env) {
        d->baseEnvironmentType = env;
        emit baseEnvironmentChanged();
    }
}

Utils::Environment RemoteLinuxRunConfiguration::environment() const
{
    Utils::Environment env = baseEnvironment();
    env.modify(userEnvironmentChanges());
    return env;
}

Utils::Environment RemoteLinuxRunConfiguration::baseEnvironment() const
{
    return (d->baseEnvironmentType == SystemBaseEnvironment ? systemEnvironment()
        : Utils::Environment());
}

QList<Utils::EnvironmentItem> RemoteLinuxRunConfiguration::userEnvironmentChanges() const
{
    return d->userEnvironmentChanges;
}

QString RemoteLinuxRunConfiguration::userEnvironmentChangesAsString() const
{
    QString env;
    QString placeHolder = QLatin1String("%1=%2 ");
    foreach (const Utils::EnvironmentItem &item, userEnvironmentChanges())
        env.append(placeHolder.arg(item.name, item.value));
    return env.mid(0, env.size() - 1);
}

void RemoteLinuxRunConfiguration::setUserEnvironmentChanges(
    const QList<Utils::EnvironmentItem> &diff)
{
    if (d->userEnvironmentChanges != diff) {
        d->userEnvironmentChanges = diff;
        emit userEnvironmentChangesChanged(diff);
    }
}

Utils::Environment RemoteLinuxRunConfiguration::systemEnvironment() const
{
    return d->systemEnvironment;
}

void RemoteLinuxRunConfiguration::setSystemEnvironment(const Utils::Environment &environment)
{
    if (d->systemEnvironment.size() == 0 || d->systemEnvironment != environment) {
        d->systemEnvironment = environment;
        emit systemEnvironmentChanged();
    }
}

QString RemoteLinuxRunConfiguration::proFilePath() const
{
    return d->proFilePath;
}

void RemoteLinuxRunConfiguration::setDisabledReason(const QString &reason) const
{
    d->disabledReason = reason;
}

const QString RemoteLinuxRunConfiguration::Id = QLatin1String("RemoteLinuxRunConfiguration");

} // namespace RemoteLinux
<commit_msg>Added missing tr()<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/

#include "remotelinuxrunconfiguration.h"

#include "deploymentinfo.h"
#include "linuxdeviceconfiguration.h"
#include "portlist.h"
#include "remotelinuxdeployconfiguration.h"
#include "remotelinuxrunconfigurationwidget.h"

#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h>
#include <projectexplorer/toolchain.h>
#include <qtsupport/qtoutputformatter.h>
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <qt4projectmanager/qt4nodes.h>
#include <qt4projectmanager/qt4project.h>
#include <qt4projectmanager/qt4target.h>

#include <utils/qtcassert.h>

using namespace ProjectExplorer;
using namespace Qt4ProjectManager;

namespace RemoteLinux {
namespace Internal {
namespace {
const char ArgumentsKey[] = "Qt4ProjectManager.MaemoRunConfiguration.Arguments";
const char ProFileKey[] = "Qt4ProjectManager.MaemoRunConfiguration.ProFile";
const char BaseEnvironmentBaseKey[] = "Qt4ProjectManager.MaemoRunConfiguration.BaseEnvironmentBase";
const char UserEnvironmentChangesKey[]
    = "Qt4ProjectManager.MaemoRunConfiguration.UserEnvironmentChanges";
const char UseAlternateExeKey[] = "RemoteLinux.RunConfig.UseAlternateRemoteExecutable";
const char AlternateExeKey[] = "RemoteLinux.RunConfig.AlternateRemoteExecutable";

} // anonymous namespace

class RemoteLinuxRunConfigurationPrivate {
public:
    RemoteLinuxRunConfigurationPrivate(const QString &proFilePath, const Qt4BaseTarget *target)
        : proFilePath(proFilePath),
          baseEnvironmentType(RemoteLinuxRunConfiguration::SystemBaseEnvironment),
          validParse(target->qt4Project()->validParse(proFilePath)),
          parseInProgress(target->qt4Project()->parseInProgress(proFilePath)),
          useAlternateRemoteExecutable(false)
    {
    }

    RemoteLinuxRunConfigurationPrivate(const RemoteLinuxRunConfigurationPrivate *other)
        : proFilePath(other->proFilePath), gdbPath(other->gdbPath), arguments(other->arguments),
          baseEnvironmentType(other->baseEnvironmentType),
          systemEnvironment(other->systemEnvironment),
          userEnvironmentChanges(other->userEnvironmentChanges),
          validParse(other->validParse),
          parseInProgress(other->parseInProgress),
          useAlternateRemoteExecutable(other->useAlternateRemoteExecutable),
          alternateRemoteExecutable(other->alternateRemoteExecutable)
    {
    }

    QString proFilePath;
    QString gdbPath;
    QString arguments;
    RemoteLinuxRunConfiguration::BaseEnvironmentType baseEnvironmentType;
    Utils::Environment systemEnvironment;
    QList<Utils::EnvironmentItem> userEnvironmentChanges;
    bool validParse;
    bool parseInProgress;
    QString disabledReason;
    bool useAlternateRemoteExecutable;
    QString alternateRemoteExecutable;
};

} // namespace Internal

using namespace Internal;

RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Qt4BaseTarget *parent, const QString &id,
        const QString &proFilePath)
    : RunConfiguration(parent, id),
      d(new RemoteLinuxRunConfigurationPrivate(proFilePath, parent))
{
    init();
}

RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Qt4BaseTarget *parent,
        RemoteLinuxRunConfiguration *source)
    : RunConfiguration(parent, source),
      d(new RemoteLinuxRunConfigurationPrivate(source->d))
{
    init();
}

void RemoteLinuxRunConfiguration::init()
{
    setDefaultDisplayName(defaultDisplayName());
    setUseCppDebugger(true);
    setUseQmlDebugger(false);

    connect(target(),
        SIGNAL(activeDeployConfigurationChanged(ProjectExplorer::DeployConfiguration*)),
        this, SLOT(handleDeployConfigChanged()));
    handleDeployConfigChanged();

    Qt4Project *pro = qt4Target()->qt4Project();
    connect(pro, SIGNAL(proFileUpdated(Qt4ProjectManager::Qt4ProFileNode*,bool,bool)),
            this, SLOT(proFileUpdate(Qt4ProjectManager::Qt4ProFileNode*,bool,bool)));
}

RemoteLinuxRunConfiguration::~RemoteLinuxRunConfiguration()
{
}

Qt4BaseTarget *RemoteLinuxRunConfiguration::qt4Target() const
{
    return static_cast<Qt4BaseTarget *>(target());
}

Qt4BuildConfiguration *RemoteLinuxRunConfiguration::activeQt4BuildConfiguration() const
{
    return static_cast<Qt4BuildConfiguration *>(activeBuildConfiguration());
}

bool RemoteLinuxRunConfiguration::isEnabled() const
{
    if (d->parseInProgress) {
        d->disabledReason = tr("The .pro file is being parsed.");
        return false;
    }
    if (!d->validParse) {
        d->disabledReason = tr("The .pro file could not be parsed.");
        return false;
    }
    if (!deviceConfig()) {
        d->disabledReason = tr("No device configuration set.");
        return false;
    }
    if (!activeQt4BuildConfiguration()) {
        d->disabledReason = tr("No active build configuration.");
        return false;
    }
    if (remoteExecutableFilePath().isEmpty()) {
        d->disabledReason = tr("Don't know what to run.");
        return false;
    }
    d->disabledReason.clear();
    return true;
}

QString RemoteLinuxRunConfiguration::disabledReason() const
{
    return d->disabledReason;
}

QWidget *RemoteLinuxRunConfiguration::createConfigurationWidget()
{
    return new RemoteLinuxRunConfigurationWidget(this);
}

Utils::OutputFormatter *RemoteLinuxRunConfiguration::createOutputFormatter() const
{
    return new QtSupport::QtOutputFormatter(qt4Target()->qt4Project());
}

void RemoteLinuxRunConfiguration::proFileUpdate(Qt4ProjectManager::Qt4ProFileNode *pro, bool success, bool parseInProgress)
{
    if (d->proFilePath == pro->path()) {
        bool enabled = isEnabled();
        d->validParse = success;
        d->parseInProgress = parseInProgress;
        if (enabled != isEnabled())
            updateEnabledState();
        if (!parseInProgress)
            emit targetInformationChanged();
    }
}

QVariantMap RemoteLinuxRunConfiguration::toMap() const
{
    QVariantMap map(RunConfiguration::toMap());
    map.insert(QLatin1String(ArgumentsKey), d->arguments);
    const QDir dir = QDir(target()->project()->projectDirectory());
    map.insert(QLatin1String(ProFileKey), dir.relativeFilePath(d->proFilePath));
    map.insert(QLatin1String(BaseEnvironmentBaseKey), d->baseEnvironmentType);
    map.insert(QLatin1String(UserEnvironmentChangesKey),
        Utils::EnvironmentItem::toStringList(d->userEnvironmentChanges));
    map.insert(QLatin1String(UseAlternateExeKey), d->useAlternateRemoteExecutable);
    map.insert(QLatin1String(AlternateExeKey), d->alternateRemoteExecutable);
    return map;
}

bool RemoteLinuxRunConfiguration::fromMap(const QVariantMap &map)
{
    if (!RunConfiguration::fromMap(map))
        return false;

    d->arguments = map.value(QLatin1String(ArgumentsKey)).toString();
    const QDir dir = QDir(target()->project()->projectDirectory());
    d->proFilePath = QDir::cleanPath(dir.filePath(map.value(QLatin1String(ProFileKey)).toString()));
    d->userEnvironmentChanges =
        Utils::EnvironmentItem::fromStringList(map.value(QLatin1String(UserEnvironmentChangesKey))
        .toStringList());
    d->baseEnvironmentType = static_cast<BaseEnvironmentType>(map.value(QLatin1String(BaseEnvironmentBaseKey),
        SystemBaseEnvironment).toInt());
    d->useAlternateRemoteExecutable = map.value(QLatin1String(UseAlternateExeKey), false).toBool();
    d->alternateRemoteExecutable = map.value(QLatin1String(AlternateExeKey)).toString();

    d->validParse = qt4Target()->qt4Project()->validParse(d->proFilePath);
    d->parseInProgress = qt4Target()->qt4Project()->parseInProgress(d->proFilePath);

    setDefaultDisplayName(defaultDisplayName());

    return true;
}

QString RemoteLinuxRunConfiguration::defaultDisplayName()
{
    if (!d->proFilePath.isEmpty())
        //: %1 is the name of a project which is being run on remote Linux
        return tr("%1 (on Remote Device)").arg(QFileInfo(d->proFilePath).completeBaseName());
    //: Remote Linux run configuration default display name
    return tr("Run on Remote Device");
}

LinuxDeviceConfiguration::ConstPtr RemoteLinuxRunConfiguration::deviceConfig() const
{
    return deployConfig()
        ? deployConfig()->deviceConfiguration() : LinuxDeviceConfiguration::ConstPtr();
}

QString RemoteLinuxRunConfiguration::gdbCmd() const
{
    return QDir::toNativeSeparators(activeBuildConfiguration()->toolChain()->debuggerCommand());
}

RemoteLinuxDeployConfiguration *RemoteLinuxRunConfiguration::deployConfig() const
{
    return qobject_cast<RemoteLinuxDeployConfiguration *>(target()->activeDeployConfiguration());
}

QString RemoteLinuxRunConfiguration::arguments() const
{
    return d->arguments;
}

QString RemoteLinuxRunConfiguration::environmentPreparationCommand() const
{
    QString command;
    const QStringList filesToSource = QStringList() << QLatin1String("/etc/profile")
        << QLatin1String("$HOME/.profile");
    foreach (const QString &filePath, filesToSource)
        command += QString::fromLocal8Bit("test -f %1 && source %1;").arg(filePath);
    command.chop(1); // Trailing semicolon.
    return command;
}

QString RemoteLinuxRunConfiguration::commandPrefix() const
{
    return QString::fromLocal8Bit("%1; DISPLAY=:0.0 %2")
        .arg(environmentPreparationCommand(), userEnvironmentChangesAsString());
}

QString RemoteLinuxRunConfiguration::localExecutableFilePath() const
{
    TargetInformation ti = qt4Target()->qt4Project()->rootQt4ProjectNode()
        ->targetInformation(d->proFilePath);
    if (!ti.valid)
        return QString();

    return QDir::cleanPath(ti.workingDir + QLatin1Char('/') + ti.target);
}

QString RemoteLinuxRunConfiguration::defaultRemoteExecutableFilePath() const
{
    return deployConfig()
        ? deployConfig()->deploymentInfo()->remoteExecutableFilePath(localExecutableFilePath())
        : QString();
}

QString RemoteLinuxRunConfiguration::remoteExecutableFilePath() const
{
    return d->useAlternateRemoteExecutable
        ? alternateRemoteExecutable() : defaultRemoteExecutableFilePath();
}

PortList RemoteLinuxRunConfiguration::freePorts() const
{
    const LinuxDeviceConfiguration::ConstPtr &devConf = deviceConfig();
    if (!devConf)
        return PortList();
    return devConf->freePorts();
}

void RemoteLinuxRunConfiguration::setArguments(const QString &args)
{
    d->arguments = args;
}

void RemoteLinuxRunConfiguration::setUseAlternateExecutable(bool useAlternate)
{
    d->useAlternateRemoteExecutable = useAlternate;
}

bool RemoteLinuxRunConfiguration::useAlternateExecutable() const
{
    return d->useAlternateRemoteExecutable;
}

void RemoteLinuxRunConfiguration::setAlternateRemoteExecutable(const QString &exe)
{
    d->alternateRemoteExecutable = exe;
}

QString RemoteLinuxRunConfiguration::alternateRemoteExecutable() const
{
    return d->alternateRemoteExecutable;
}

RemoteLinuxRunConfiguration::DebuggingType RemoteLinuxRunConfiguration::debuggingType() const
{
    if (useCppDebugger()) {
        if (useQmlDebugger())
            return DebugCppAndQml;
        return DebugCppOnly;
    }
    return DebugQmlOnly;
}

int RemoteLinuxRunConfiguration::portsUsedByDebuggers() const
{
    switch (debuggingType()) {
    case DebugCppOnly:
    case DebugQmlOnly:
        return 1;
    case DebugCppAndQml:
    default:
        return 2;
    }
}

void RemoteLinuxRunConfiguration::updateDeviceConfigurations()
{
    emit deviceConfigurationChanged(target());
    updateEnabledState();
}

void RemoteLinuxRunConfiguration::handleDeployConfigChanged()
{
    RemoteLinuxDeployConfiguration * const activeDeployConf = deployConfig();
    if (activeDeployConf) {
        connect(activeDeployConf->deploymentInfo().data(), SIGNAL(modelReset()),
            SLOT(handleDeployablesUpdated()), Qt::UniqueConnection);
        connect(activeDeployConf, SIGNAL(currentDeviceConfigurationChanged()),
            SLOT(updateDeviceConfigurations()), Qt::UniqueConnection);
    }

    updateDeviceConfigurations();
}

void RemoteLinuxRunConfiguration::handleDeployablesUpdated()
{
    emit deploySpecsChanged();
    updateEnabledState();
}

QString RemoteLinuxRunConfiguration::baseEnvironmentText() const
{
    if (d->baseEnvironmentType == CleanBaseEnvironment)
        return tr("Clean Environment");
    else  if (d->baseEnvironmentType == SystemBaseEnvironment)
        return tr("System Environment");
    return QString();
}

RemoteLinuxRunConfiguration::BaseEnvironmentType RemoteLinuxRunConfiguration::baseEnvironmentType() const
{
    return d->baseEnvironmentType;
}

void RemoteLinuxRunConfiguration::setBaseEnvironmentType(BaseEnvironmentType env)
{
    if (d->baseEnvironmentType != env) {
        d->baseEnvironmentType = env;
        emit baseEnvironmentChanged();
    }
}

Utils::Environment RemoteLinuxRunConfiguration::environment() const
{
    Utils::Environment env = baseEnvironment();
    env.modify(userEnvironmentChanges());
    return env;
}

Utils::Environment RemoteLinuxRunConfiguration::baseEnvironment() const
{
    return (d->baseEnvironmentType == SystemBaseEnvironment ? systemEnvironment()
        : Utils::Environment());
}

QList<Utils::EnvironmentItem> RemoteLinuxRunConfiguration::userEnvironmentChanges() const
{
    return d->userEnvironmentChanges;
}

QString RemoteLinuxRunConfiguration::userEnvironmentChangesAsString() const
{
    QString env;
    QString placeHolder = QLatin1String("%1=%2 ");
    foreach (const Utils::EnvironmentItem &item, userEnvironmentChanges())
        env.append(placeHolder.arg(item.name, item.value));
    return env.mid(0, env.size() - 1);
}

void RemoteLinuxRunConfiguration::setUserEnvironmentChanges(
    const QList<Utils::EnvironmentItem> &diff)
{
    if (d->userEnvironmentChanges != diff) {
        d->userEnvironmentChanges = diff;
        emit userEnvironmentChangesChanged(diff);
    }
}

Utils::Environment RemoteLinuxRunConfiguration::systemEnvironment() const
{
    return d->systemEnvironment;
}

void RemoteLinuxRunConfiguration::setSystemEnvironment(const Utils::Environment &environment)
{
    if (d->systemEnvironment.size() == 0 || d->systemEnvironment != environment) {
        d->systemEnvironment = environment;
        emit systemEnvironmentChanged();
    }
}

QString RemoteLinuxRunConfiguration::proFilePath() const
{
    return d->proFilePath;
}

void RemoteLinuxRunConfiguration::setDisabledReason(const QString &reason) const
{
    d->disabledReason = reason;
}

const QString RemoteLinuxRunConfiguration::Id = QLatin1String("RemoteLinuxRunConfiguration");

} // namespace RemoteLinux
<|endoftext|>


<commit_before>#define _USE_MATH_DEFINES
#include <cmath>
#include <cstring>
#include <fftw3.h>
#include <string.h>

#include "common.h"
#include "metrix.h"

using namespace std;

template <int over>
void __transpose_and_normalize_and_extract(
    complexd dst[]       // [over][over][support][support]
  , const complexd src[] // [max_support][over][max_support][over]
  , int support
  , int max_support
  , int src_pad
  ) {

  double sums[over][over];  for(int i = 0; i<over*over; i++) (&sums[0][0])[i] = 0.0;

  const complexd * srcp = src;
  for (int suppu = 0; suppu < max_support; suppu++)
  for (int overu = 0; overu < over; overu++)
  for (int suppv = 0; suppv < max_support; suppv++)
  for (int overv = 0; overv < over; overv++)
     sums[overu][overv] += (srcp++)->real();

  int
      src_size = max_support * over
    , src_pitch = src_size + src_pad
    ;

  for (int overu = 0; overu < over; overu++, src+=src_pitch) {
    const complexd * srcp1; srcp1 = src;
    for (int overv = 0; overv < over; overv++, srcp1++) {
      const complexd * srcp2; srcp2 = srcp1;
      for (int suppu = 0; suppu < support; suppu++, srcp2+=over*src_pitch) {
        const complexd * srcp3; srcp3 = srcp2;
        for (int suppv = 0; suppv < support; suppv++, srcp3+=over) {
          *dst++ = *srcp3 / sums[overu][overv];
        }
      }
    }
  }
}

extern "C"
fftw_plan fft_inplace_even(fftw_plan p, complexd * data, int size, int pitch);

// In principle, we can calculate 1 - (t2/r)^2 separately
//   because it does not depend on w and can be reused for
//   all layers, but we don't bother with caching and copying them
//   over and thus recalculate them each time
template <int over>
fftw_plan __mkGCFLayer(
    fftw_plan p
  , complexd dst[]   // [over][over][support][support]
  , complexd * table[]
  , complexd arena[] // Full oversampled layer padded [max_support*over][max_support*over+src_pad]
  , int support
  , int max_support
  , int src_pad      // padding value
  , double t2
  , double w
  ){
  int
      size = max_support * over
    , pitch = size + src_pad
    ;

  int radius = max_support / 2;
  double normer = t2 / double (radius);

  complexd *currp = arena + (pitch+1) * (size/2-radius);
  int
      radiuspos = radius + max_support % 2
    , istep = pitch - max_support
    ;

  memset(arena, 0, size * pitch * sizeof(complexd));
  #pragma omp parallel for // not so much important
  for(int i = -radius; i < radiuspos; i++) {
    for(int j = -radius; j < radiuspos; j++) {
      double x, y, ph;
      x = double(i) * normer;
      y = double(j) * normer;
      ph = w * (1 - sqrt(1 - x*x - y*y));
      double s, c;
      sincos(2.0 * M_PI * ph, &s, &c);
      *currp++ = complexd(c,-s);
    }
    currp += istep;
  }

  fftw_plan plan = fft_inplace_even(p, arena, size, pitch);

  __transpose_and_normalize_and_extract<over>(
      dst
    , arena
    , support
    , max_support
    , src_pad
    );

  // Fill layers table
  complexd * tp = dst;
  for (int i=0; i < over * over; i++) {
    table[i] = tp;
    tp += support * support;
  }

  return plan;
}

// Inst
extern "C"
fftw_plan mkGCFLayer(
    fftw_plan p
  , complexd dst[] // should have [OVER][OVER][support][support] size
  , complexd * table[]
  , complexd arena[]
  , int support
  , int max_support
  , int src_pad
  , double t2
  , double w
  ){
  return __mkGCFLayer<OVER>(
        p
      , dst
      , table
      , arena
      , support
      , max_support
      , src_pad
      , t2
      , w
      );
}
<commit_msg>Redundant include (because of previous commit merge).<commit_after>#define _USE_MATH_DEFINES
#include <cmath>
#include <cstring>
#include <fftw3.h>

#include "common.h"
#include "metrix.h"

using namespace std;

template <int over>
void __transpose_and_normalize_and_extract(
    complexd dst[]       // [over][over][support][support]
  , const complexd src[] // [max_support][over][max_support][over]
  , int support
  , int max_support
  , int src_pad
  ) {

  double sums[over][over];  for(int i = 0; i<over*over; i++) (&sums[0][0])[i] = 0.0;

  const complexd * srcp = src;
  for (int suppu = 0; suppu < max_support; suppu++)
  for (int overu = 0; overu < over; overu++)
  for (int suppv = 0; suppv < max_support; suppv++)
  for (int overv = 0; overv < over; overv++)
     sums[overu][overv] += (srcp++)->real();

  int
      src_size = max_support * over
    , src_pitch = src_size + src_pad
    ;

  for (int overu = 0; overu < over; overu++, src+=src_pitch) {
    const complexd * srcp1; srcp1 = src;
    for (int overv = 0; overv < over; overv++, srcp1++) {
      const complexd * srcp2; srcp2 = srcp1;
      for (int suppu = 0; suppu < support; suppu++, srcp2+=over*src_pitch) {
        const complexd * srcp3; srcp3 = srcp2;
        for (int suppv = 0; suppv < support; suppv++, srcp3+=over) {
          *dst++ = *srcp3 / sums[overu][overv];
        }
      }
    }
  }
}

extern "C"
fftw_plan fft_inplace_even(fftw_plan p, complexd * data, int size, int pitch);

// In principle, we can calculate 1 - (t2/r)^2 separately
//   because it does not depend on w and can be reused for
//   all layers, but we don't bother with caching and copying them
//   over and thus recalculate them each time
template <int over>
fftw_plan __mkGCFLayer(
    fftw_plan p
  , complexd dst[]   // [over][over][support][support]
  , complexd * table[]
  , complexd arena[] // Full oversampled layer padded [max_support*over][max_support*over+src_pad]
  , int support
  , int max_support
  , int src_pad      // padding value
  , double t2
  , double w
  ){
  int
      size = max_support * over
    , pitch = size + src_pad
    ;

  int radius = max_support / 2;
  double normer = t2 / double (radius);

  complexd *currp = arena + (pitch+1) * (size/2-radius);
  int
      radiuspos = radius + max_support % 2
    , istep = pitch - max_support
    ;

  memset(arena, 0, size * pitch * sizeof(complexd));
  #pragma omp parallel for // not so much important
  for(int i = -radius; i < radiuspos; i++) {
    for(int j = -radius; j < radiuspos; j++) {
      double x, y, ph;
      x = double(i) * normer;
      y = double(j) * normer;
      ph = w * (1 - sqrt(1 - x*x - y*y));
      double s, c;
      sincos(2.0 * M_PI * ph, &s, &c);
      *currp++ = complexd(c,-s);
    }
    currp += istep;
  }

  fftw_plan plan = fft_inplace_even(p, arena, size, pitch);

  __transpose_and_normalize_and_extract<over>(
      dst
    , arena
    , support
    , max_support
    , src_pad
    );

  // Fill layers table
  complexd * tp = dst;
  for (int i=0; i < over * over; i++) {
    table[i] = tp;
    tp += support * support;
  }

  return plan;
}

// Inst
extern "C"
fftw_plan mkGCFLayer(
    fftw_plan p
  , complexd dst[] // should have [OVER][OVER][support][support] size
  , complexd * table[]
  , complexd arena[]
  , int support
  , int max_support
  , int src_pad
  , double t2
  , double w
  ){
  return __mkGCFLayer<OVER>(
        p
      , dst
      , table
      , arena
      , support
      , max_support
      , src_pad
      , t2
      , w
      );
}
<|endoftext|>