<commit_before>//===- Driver.cpp ---------------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lld/Common/Driver.h"
#include "Config.h"
#include "InputGlobal.h"
#include "MarkLive.h"
#include "SymbolTable.h"
#include "Writer.h"
#include "lld/Common/Args.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
#include "lld/Common/Threads.h"
#include "lld/Common/Version.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Object/Wasm.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"

#define DEBUG_TYPE "lld"

using namespace llvm;
using namespace llvm::sys;
using namespace llvm::wasm;

using namespace lld;
using namespace lld::wasm;

Configuration *lld::wasm::Config;

namespace {

// Create enum with OPT_xxx values for each option in Options.td
enum {
  OPT_INVALID = 0,
#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
#include "Options.inc"
#undef OPTION
};

class LinkerDriver {
public:
  void link(ArrayRef<const char *> ArgsArr);

private:
  void createFiles(opt::InputArgList &Args);
  void addFile(StringRef Path);
  void addLibrary(StringRef Name);
  std::vector<InputFile *> Files;
  llvm::wasm::WasmGlobal StackPointerGlobal;
};
} // anonymous namespace

bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly,
                     raw_ostream &Error) {
  errorHandler().LogName = Args[0];
  errorHandler().ErrorOS = &Error;
  errorHandler().ColorDiagnostics = Error.has_colors();
  errorHandler().ErrorLimitExceededMsg =
      "too many errors emitted, stopping now (use "
      "-error-limit=0 to see all errors)";

  Config = make<Configuration>();
  Symtab = make<SymbolTable>();

  LinkerDriver().link(Args);

  // Exit immediately if we don't need to return to the caller.
  // This saves time because the overhead of calling destructors
  // for all globally-allocated objects is not negligible.
  if (CanExitEarly)
    exitLld(errorCount() ? 1 : 0);

  freeArena();
  return !errorCount();
}

// Create prefix string literals used in Options.td
#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
#include "Options.inc"
#undef PREFIX

// Create table mapping all options defined in Options.td
static const opt::OptTable::Info OptInfo[] = {
#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \
  {X1, X2, X10,         X11,         OPT_##ID, opt::Option::KIND##Class,       \
   X9, X8, OPT_##GROUP, OPT_##ALIAS, X7,       X12},
#include "Options.inc"
#undef OPTION
};

class WasmOptTable : public llvm::opt::OptTable {
public:
  WasmOptTable() : OptTable(OptInfo) {}
  opt::InputArgList parse(ArrayRef<const char *> Argv);
};

// Set color diagnostics according to -color-diagnostics={auto,always,never}
// or -no-color-diagnostics flags.
static void handleColorDiagnostics(opt::InputArgList &Args) {
  auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
                              OPT_no_color_diagnostics);
  if (!Arg)
    return;

  if (Arg->getOption().getID() == OPT_color_diagnostics)
    errorHandler().ColorDiagnostics = true;
  else if (Arg->getOption().getID() == OPT_no_color_diagnostics)
    errorHandler().ColorDiagnostics = false;
  else {
    StringRef S = Arg->getValue();
    if (S == "always")
      errorHandler().ColorDiagnostics = true;
    if (S == "never")
      errorHandler().ColorDiagnostics = false;
    if (S != "auto")
      error("unknown option: -color-diagnostics=" + S);
  }
}

// Find a file by concatenating given paths.
static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) {
  SmallString<128> S;
  path::append(S, Path1, Path2);
  if (fs::exists(S))
    return S.str().str();
  return None;
}

static void printHelp(const char *Argv0) {
  WasmOptTable().PrintHelp(outs(), Argv0, "LLVM Linker", false);
}

opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> Argv) {
  SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size());

  unsigned MissingIndex;
  unsigned MissingCount;
  opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount);

  handleColorDiagnostics(Args);
  for (auto *Arg : Args.filtered(OPT_UNKNOWN))
    error("unknown argument: " + Arg->getSpelling());
  return Args;
}

// Currently we allow a ".imports" to live alongside a library. This can
// be used to specify a list of symbols which can be undefined at link
// time (imported from the environment.  For example libc.a include an
// import file that lists the syscall functions it relies on at runtime.
// In the long run this information would be better stored as a symbol
// attribute/flag in the object file itself.
// See: https://github.com/WebAssembly/tool-conventions/issues/35
static void readImportFile(StringRef Filename) {
  if (Optional<MemoryBufferRef> Buf = readFile(Filename))
    for (StringRef Sym : args::getLines(*Buf))
      Config->AllowUndefinedSymbols.insert(Sym);
}

void LinkerDriver::addFile(StringRef Path) {
  Optional<MemoryBufferRef> Buffer = readFile(Path);
  if (!Buffer.hasValue())
    return;
  MemoryBufferRef MBRef = *Buffer;

  if (identify_magic(MBRef.getBuffer()) == file_magic::archive) {
    SmallString<128> ImportFile = Path;
    path::replace_extension(ImportFile, ".imports");
    if (fs::exists(ImportFile))
      readImportFile(ImportFile.str());

    Files.push_back(make<ArchiveFile>(MBRef));
    return;
  }

  Files.push_back(make<ObjFile>(MBRef));
}

// Add a given library by searching it from input search paths.
void LinkerDriver::addLibrary(StringRef Name) {
  for (StringRef Dir : Config->SearchPaths) {
    if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".a")) {
      addFile(*S);
      return;
    }
  }

  error("unable to find library -l" + Name);
}

void LinkerDriver::createFiles(opt::InputArgList &Args) {
  for (auto *Arg : Args) {
    switch (Arg->getOption().getUnaliasedOption().getID()) {
    case OPT_l:
      addLibrary(Arg->getValue());
      break;
    case OPT_INPUT:
      addFile(Arg->getValue());
      break;
    }
  }
}

static StringRef getEntry(opt::InputArgList &Args, StringRef Default) {
  auto *Arg = Args.getLastArg(OPT_entry, OPT_no_entry);
  if (!Arg)
    return Default;
  if (Arg->getOption().getID() == OPT_no_entry)
    return "";
  return Arg->getValue();
}

static Symbol *addUndefinedFunction(StringRef Name, const WasmSignature *Type) {
  return Symtab->addUndefined(Name, WASM_SYMBOL_TYPE_FUNCTION, 0, nullptr,
                              Type);
}

void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
  WasmOptTable Parser;
  opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));

  // Handle --help
  if (Args.hasArg(OPT_help)) {
    printHelp(ArgsArr[0]);
    return;
  }

  // Parse and evaluate -mllvm options.
  std::vector<const char *> V;
  V.push_back("wasm-ld (LLVM option parsing)");
  for (auto *Arg : Args.filtered(OPT_mllvm))
    V.push_back(Arg->getValue());
  cl::ParseCommandLineOptions(V.size(), V.data());

  errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);

  if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v)) {
    outs() << getLLDVersion() << "\n";
    return;
  }

  Config->AllowUndefined = Args.hasArg(OPT_allow_undefined);
  Config->CheckSignatures =
      Args.hasFlag(OPT_check_signatures, OPT_no_check_signatures, false);
  Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start");
  Config->ImportMemory = Args.hasArg(OPT_import_memory);
  Config->OutputFile = Args.getLastArgValue(OPT_o);
  Config->Relocatable = Args.hasArg(OPT_relocatable);
  Config->GcSections =
      Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !Config->Relocatable);
  Config->PrintGcSections =
      Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
  Config->SearchPaths = args::getStrings(Args, OPT_L);
  Config->StripAll = Args.hasArg(OPT_strip_all);
  Config->StripDebug = Args.hasArg(OPT_strip_debug);
  errorHandler().Verbose = Args.hasArg(OPT_verbose);
  ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true);

  Config->InitialMemory = args::getInteger(Args, OPT_initial_memory, 0);
  Config->GlobalBase = args::getInteger(Args, OPT_global_base, 1024);
  Config->MaxMemory = args::getInteger(Args, OPT_max_memory, 0);
  Config->ZStackSize =
      args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize);

  if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file))
    readImportFile(Arg->getValue());

  if (!Args.hasArg(OPT_INPUT)) {
    error("no input files");
    return;
  }

  if (Config->OutputFile.empty())
    error("no output file specified");

  if (Config->Relocatable) {
    if (!Config->Entry.empty())
      error("entry point specified for relocatable output file");
    if (Config->GcSections)
      error("-r and --gc-sections may not be used together");
    if (Args.hasArg(OPT_undefined))
      error("-r -and --undefined may not be used together");
  }

  Symbol *EntrySym = nullptr;
  if (!Config->Relocatable) {
    // Can't export the SP right now because it's mutable, and mutable
    // globals aren't yet supported in the official binary format.
    // TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN if/when the
    // "mutable global" proposal is accepted.
    StackPointerGlobal.Type = {WASM_TYPE_I32, true};
    StackPointerGlobal.InitExpr.Value.Int32 = 0;
    StackPointerGlobal.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
    InputGlobal *StackPointer = make<InputGlobal>(StackPointerGlobal);
    StackPointer->Live = true;

    static WasmSignature NullSignature = {{}, WASM_TYPE_NORESULT};
    // Add synthetic symbols before any others
    WasmSym::CallCtors = Symtab->addSyntheticFunction(
        "__wasm_call_ctors", &NullSignature, WASM_SYMBOL_VISIBILITY_HIDDEN);
    WasmSym::StackPointer = Symtab->addSyntheticGlobal(
        "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer);
    WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base");
    WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol(
        "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN);
    WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end");

    if (!Config->Entry.empty())
      EntrySym = addUndefinedFunction(Config->Entry, &NullSignature);

    // Handle the `--undefined <sym>` options.
    for (auto* Arg : Args.filtered(OPT_undefined))
      addUndefinedFunction(Arg->getValue(), nullptr);
  }

  createFiles(Args);
  if (errorCount())
    return;

  // Add all files to the symbol table. This will add almost all
  // symbols that we need to the symbol table.
  for (InputFile *F : Files)
    Symtab->addFile(F);

  // Make sure we have resolved all symbols.
  if (!Config->Relocatable && !Config->AllowUndefined) {
    Symtab->reportRemainingUndefines();
  } else {
    // When we allow undefined symbols we cannot include those defined in
    // -u/--undefined since these undefined symbols have only names and no
    // function signature, which means they cannot be written to the final
    // output.
    for (auto* Arg : Args.filtered(OPT_undefined)) {
      Symbol *Sym = Symtab->find(Arg->getValue());
      if (!Sym->isDefined())
        error("function forced with --undefined not found: " + Sym->getName());
    }
  }
  if (errorCount())
    return;

  for (auto *Arg : Args.filtered(OPT_export)) {
    Symbol *Sym = Symtab->find(Arg->getValue());
    if (!Sym || !Sym->isDefined())
      error("symbol exported via --export not found: " +
            Twine(Arg->getValue()));
    else
      Sym->setHidden(false);
  }

  if (EntrySym)
    EntrySym->setHidden(false);

  if (errorCount())
    return;

  // Do size optimizations: garbage collection
  markLive();

  // Write the result to the file.
  writeResult();
}
<commit_msg>Handle --version before handling --mllvm.<commit_after>//===- Driver.cpp ---------------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lld/Common/Driver.h"
#include "Config.h"
#include "InputGlobal.h"
#include "MarkLive.h"
#include "SymbolTable.h"
#include "Writer.h"
#include "lld/Common/Args.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
#include "lld/Common/Threads.h"
#include "lld/Common/Version.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Object/Wasm.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"

#define DEBUG_TYPE "lld"

using namespace llvm;
using namespace llvm::sys;
using namespace llvm::wasm;

using namespace lld;
using namespace lld::wasm;

Configuration *lld::wasm::Config;

namespace {

// Create enum with OPT_xxx values for each option in Options.td
enum {
  OPT_INVALID = 0,
#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
#include "Options.inc"
#undef OPTION
};

class LinkerDriver {
public:
  void link(ArrayRef<const char *> ArgsArr);

private:
  void createFiles(opt::InputArgList &Args);
  void addFile(StringRef Path);
  void addLibrary(StringRef Name);
  std::vector<InputFile *> Files;
  llvm::wasm::WasmGlobal StackPointerGlobal;
};
} // anonymous namespace

bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly,
                     raw_ostream &Error) {
  errorHandler().LogName = Args[0];
  errorHandler().ErrorOS = &Error;
  errorHandler().ColorDiagnostics = Error.has_colors();
  errorHandler().ErrorLimitExceededMsg =
      "too many errors emitted, stopping now (use "
      "-error-limit=0 to see all errors)";

  Config = make<Configuration>();
  Symtab = make<SymbolTable>();

  LinkerDriver().link(Args);

  // Exit immediately if we don't need to return to the caller.
  // This saves time because the overhead of calling destructors
  // for all globally-allocated objects is not negligible.
  if (CanExitEarly)
    exitLld(errorCount() ? 1 : 0);

  freeArena();
  return !errorCount();
}

// Create prefix string literals used in Options.td
#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
#include "Options.inc"
#undef PREFIX

// Create table mapping all options defined in Options.td
static const opt::OptTable::Info OptInfo[] = {
#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \
  {X1, X2, X10,         X11,         OPT_##ID, opt::Option::KIND##Class,       \
   X9, X8, OPT_##GROUP, OPT_##ALIAS, X7,       X12},
#include "Options.inc"
#undef OPTION
};

class WasmOptTable : public llvm::opt::OptTable {
public:
  WasmOptTable() : OptTable(OptInfo) {}
  opt::InputArgList parse(ArrayRef<const char *> Argv);
};

// Set color diagnostics according to -color-diagnostics={auto,always,never}
// or -no-color-diagnostics flags.
static void handleColorDiagnostics(opt::InputArgList &Args) {
  auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
                              OPT_no_color_diagnostics);
  if (!Arg)
    return;

  if (Arg->getOption().getID() == OPT_color_diagnostics)
    errorHandler().ColorDiagnostics = true;
  else if (Arg->getOption().getID() == OPT_no_color_diagnostics)
    errorHandler().ColorDiagnostics = false;
  else {
    StringRef S = Arg->getValue();
    if (S == "always")
      errorHandler().ColorDiagnostics = true;
    if (S == "never")
      errorHandler().ColorDiagnostics = false;
    if (S != "auto")
      error("unknown option: -color-diagnostics=" + S);
  }
}

// Find a file by concatenating given paths.
static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) {
  SmallString<128> S;
  path::append(S, Path1, Path2);
  if (fs::exists(S))
    return S.str().str();
  return None;
}

static void printHelp(const char *Argv0) {
  WasmOptTable().PrintHelp(outs(), Argv0, "LLVM Linker", false);
}

opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> Argv) {
  SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size());

  unsigned MissingIndex;
  unsigned MissingCount;
  opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount);

  handleColorDiagnostics(Args);
  for (auto *Arg : Args.filtered(OPT_UNKNOWN))
    error("unknown argument: " + Arg->getSpelling());
  return Args;
}

// Currently we allow a ".imports" to live alongside a library. This can
// be used to specify a list of symbols which can be undefined at link
// time (imported from the environment.  For example libc.a include an
// import file that lists the syscall functions it relies on at runtime.
// In the long run this information would be better stored as a symbol
// attribute/flag in the object file itself.
// See: https://github.com/WebAssembly/tool-conventions/issues/35
static void readImportFile(StringRef Filename) {
  if (Optional<MemoryBufferRef> Buf = readFile(Filename))
    for (StringRef Sym : args::getLines(*Buf))
      Config->AllowUndefinedSymbols.insert(Sym);
}

void LinkerDriver::addFile(StringRef Path) {
  Optional<MemoryBufferRef> Buffer = readFile(Path);
  if (!Buffer.hasValue())
    return;
  MemoryBufferRef MBRef = *Buffer;

  if (identify_magic(MBRef.getBuffer()) == file_magic::archive) {
    SmallString<128> ImportFile = Path;
    path::replace_extension(ImportFile, ".imports");
    if (fs::exists(ImportFile))
      readImportFile(ImportFile.str());

    Files.push_back(make<ArchiveFile>(MBRef));
    return;
  }

  Files.push_back(make<ObjFile>(MBRef));
}

// Add a given library by searching it from input search paths.
void LinkerDriver::addLibrary(StringRef Name) {
  for (StringRef Dir : Config->SearchPaths) {
    if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".a")) {
      addFile(*S);
      return;
    }
  }

  error("unable to find library -l" + Name);
}

void LinkerDriver::createFiles(opt::InputArgList &Args) {
  for (auto *Arg : Args) {
    switch (Arg->getOption().getUnaliasedOption().getID()) {
    case OPT_l:
      addLibrary(Arg->getValue());
      break;
    case OPT_INPUT:
      addFile(Arg->getValue());
      break;
    }
  }
}

static StringRef getEntry(opt::InputArgList &Args, StringRef Default) {
  auto *Arg = Args.getLastArg(OPT_entry, OPT_no_entry);
  if (!Arg)
    return Default;
  if (Arg->getOption().getID() == OPT_no_entry)
    return "";
  return Arg->getValue();
}

static Symbol *addUndefinedFunction(StringRef Name, const WasmSignature *Type) {
  return Symtab->addUndefined(Name, WASM_SYMBOL_TYPE_FUNCTION, 0, nullptr,
                              Type);
}

void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
  WasmOptTable Parser;
  opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));

  // Handle --help
  if (Args.hasArg(OPT_help)) {
    printHelp(ArgsArr[0]);
    return;
  }

  // Handle --version
  if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v)) {
    outs() << getLLDVersion() << "\n";
    return;
  }

  // Parse and evaluate -mllvm options.
  std::vector<const char *> V;
  V.push_back("wasm-ld (LLVM option parsing)");
  for (auto *Arg : Args.filtered(OPT_mllvm))
    V.push_back(Arg->getValue());
  cl::ParseCommandLineOptions(V.size(), V.data());

  errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);

  Config->AllowUndefined = Args.hasArg(OPT_allow_undefined);
  Config->CheckSignatures =
      Args.hasFlag(OPT_check_signatures, OPT_no_check_signatures, false);
  Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start");
  Config->ImportMemory = Args.hasArg(OPT_import_memory);
  Config->OutputFile = Args.getLastArgValue(OPT_o);
  Config->Relocatable = Args.hasArg(OPT_relocatable);
  Config->GcSections =
      Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !Config->Relocatable);
  Config->PrintGcSections =
      Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
  Config->SearchPaths = args::getStrings(Args, OPT_L);
  Config->StripAll = Args.hasArg(OPT_strip_all);
  Config->StripDebug = Args.hasArg(OPT_strip_debug);
  errorHandler().Verbose = Args.hasArg(OPT_verbose);
  ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true);

  Config->InitialMemory = args::getInteger(Args, OPT_initial_memory, 0);
  Config->GlobalBase = args::getInteger(Args, OPT_global_base, 1024);
  Config->MaxMemory = args::getInteger(Args, OPT_max_memory, 0);
  Config->ZStackSize =
      args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize);

  if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file))
    readImportFile(Arg->getValue());

  if (!Args.hasArg(OPT_INPUT)) {
    error("no input files");
    return;
  }

  if (Config->OutputFile.empty())
    error("no output file specified");

  if (Config->Relocatable) {
    if (!Config->Entry.empty())
      error("entry point specified for relocatable output file");
    if (Config->GcSections)
      error("-r and --gc-sections may not be used together");
    if (Args.hasArg(OPT_undefined))
      error("-r -and --undefined may not be used together");
  }

  Symbol *EntrySym = nullptr;
  if (!Config->Relocatable) {
    // Can't export the SP right now because it's mutable, and mutable
    // globals aren't yet supported in the official binary format.
    // TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN if/when the
    // "mutable global" proposal is accepted.
    StackPointerGlobal.Type = {WASM_TYPE_I32, true};
    StackPointerGlobal.InitExpr.Value.Int32 = 0;
    StackPointerGlobal.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
    InputGlobal *StackPointer = make<InputGlobal>(StackPointerGlobal);
    StackPointer->Live = true;

    static WasmSignature NullSignature = {{}, WASM_TYPE_NORESULT};
    // Add synthetic symbols before any others
    WasmSym::CallCtors = Symtab->addSyntheticFunction(
        "__wasm_call_ctors", &NullSignature, WASM_SYMBOL_VISIBILITY_HIDDEN);
    WasmSym::StackPointer = Symtab->addSyntheticGlobal(
        "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer);
    WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base");
    WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol(
        "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN);
    WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end");

    if (!Config->Entry.empty())
      EntrySym = addUndefinedFunction(Config->Entry, &NullSignature);

    // Handle the `--undefined <sym>` options.
    for (auto* Arg : Args.filtered(OPT_undefined))
      addUndefinedFunction(Arg->getValue(), nullptr);
  }

  createFiles(Args);
  if (errorCount())
    return;

  // Add all files to the symbol table. This will add almost all
  // symbols that we need to the symbol table.
  for (InputFile *F : Files)
    Symtab->addFile(F);

  // Make sure we have resolved all symbols.
  if (!Config->Relocatable && !Config->AllowUndefined) {
    Symtab->reportRemainingUndefines();
  } else {
    // When we allow undefined symbols we cannot include those defined in
    // -u/--undefined since these undefined symbols have only names and no
    // function signature, which means they cannot be written to the final
    // output.
    for (auto* Arg : Args.filtered(OPT_undefined)) {
      Symbol *Sym = Symtab->find(Arg->getValue());
      if (!Sym->isDefined())
        error("function forced with --undefined not found: " + Sym->getName());
    }
  }
  if (errorCount())
    return;

  for (auto *Arg : Args.filtered(OPT_export)) {
    Symbol *Sym = Symtab->find(Arg->getValue());
    if (!Sym || !Sym->isDefined())
      error("symbol exported via --export not found: " +
            Twine(Arg->getValue()));
    else
      Sym->setHidden(false);
  }

  if (EntrySym)
    EntrySym->setHidden(false);

  if (errorCount())
    return;

  // Do size optimizations: garbage collection
  markLive();

  // Write the result to the file.
  writeResult();
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkLight.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
// .NAME vtkLight - a virtual light for 3D rendering
// .SECTION Description
// vtkLight is a virtual light for 3D rendering. It provides methods to locate
// and point the light, turn it on and off, and set its brightness and color.

#ifndef __vtkLight_hh
#define __vtkLight_hh

#include "vtkObject.hh"

/* need for virtual function */
class vtkRenderer;
class vtkLightDevice;

class vtkLight : public vtkObject
{
public:
  vtkLight();
  ~vtkLight();
  char *GetClassName() {return "vtkLight";};
  void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // Abstract interface to renderer. Each concrete subclass of vtkLight
  // will load its data into graphics system in response to this method
  // invocation.
  virtual void Render(vtkRenderer *ren,int light_index);

  // Description:
  // Set the color of the light.
  vtkSetVector3Macro(Color,float);
  vtkGetVectorMacro(Color,float,3);

  // Description:
  // Set the position of the light.
  vtkSetVector3Macro(Position,float);
  vtkGetVectorMacro(Position,float,3);

  // Description:
  // Set the point at which the light is shining.
  vtkSetVector3Macro(FocalPoint,float);
  vtkGetVectorMacro(FocalPoint,float,3);

  // Description:
  // Set the brightness of the light.
  vtkSetMacro(Intensity,float);
  vtkGetMacro(Intensity,float);

  // Description:
  // Turn the light on/off.
  vtkSetMacro(Switch,int);
  vtkGetMacro(Switch,int);
  vtkBooleanMacro(Switch,int);

  // Description:
  // Turn positional lighting on/off.
  vtkSetMacro(Positional,int);
  vtkGetMacro(Positional,int);
  vtkBooleanMacro(Positional,int);

  // Description:
  // Set the exponent of the cosine used in positional lighting.
  vtkSetMacro(Exponent,float);
  vtkGetMacro(Exponent,float);

  // Description:
  // Set the lighting cone angle in degrees of a positional light.
  vtkSetMacro(ConeAngle,float);
  vtkGetMacro(ConeAngle,float);

  // Description:
  // Set the quadratic attenuation constants, const linear quad in order.
  vtkSetVector3Macro(AttenuationValues,float);
  vtkGetVectorMacro(AttenuationValues,float,3);

protected:
  float FocalPoint[3];
  float Position[3];
  float Intensity;
  float Color[3];
  int   Switch;
  int   Positional;
  float Exponent;
  float ConeAngle;
  float AttenuationValues[3];
  vtkLightDevice *Device;
};

#endif
<commit_msg>upadted comments<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkLight.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
// .NAME vtkLight - a virtual light for 3D rendering
// .SECTION Description
// vtkLight is a virtual light for 3D rendering. It provides methods to locate
// and point the light, turn it on and off, and set its brightness and color.
// In addition to the basic infinite distance point light source atrributes,
// you can also specify the light attenuation values and cone angle.
// These attrributes are only used if the light is a positional light.
// The default is a directional light (e.g. infinite point light source)

// .SECTION see also
// vtkLightDevice

#ifndef __vtkLight_hh
#define __vtkLight_hh

#include "vtkObject.hh"

/* need for virtual function */
class vtkRenderer;
class vtkLightDevice;

class vtkLight : public vtkObject
{
public:
  vtkLight();
  ~vtkLight();
  char *GetClassName() {return "vtkLight";};
  void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // Abstract interface to renderer. Each concrete subclass of vtkLight
  // will load its data into graphics system in response to this method
  // invocation. The actual loading is performed by a vtkLightDevice
  // subclass which will get created automatically.
  virtual void Render(vtkRenderer *ren,int light_index);

  // Description:
  // Set/Get the color of the light.
  vtkSetVector3Macro(Color,float);
  vtkGetVectorMacro(Color,float,3);

  // Description:
  // Set/Get the position of the light.
  vtkSetVector3Macro(Position,float);
  vtkGetVectorMacro(Position,float,3);

  // Description:
  // Set/Get the point at which the light is shining.
  vtkSetVector3Macro(FocalPoint,float);
  vtkGetVectorMacro(FocalPoint,float,3);

  // Description:
  // Set/Get the brightness of the light (from one to zero).
  vtkSetMacro(Intensity,float);
  vtkGetMacro(Intensity,float);

  // Description:
  // Turn the light on or off.
  vtkSetMacro(Switch,int);
  vtkGetMacro(Switch,int);
  vtkBooleanMacro(Switch,int);

  // Description:
  // Turn positional lighting on or off.
  vtkSetMacro(Positional,int);
  vtkGetMacro(Positional,int);
  vtkBooleanMacro(Positional,int);

  // Description:
  // Set/Get the exponent of the cosine used in positional lighting.
  vtkSetMacro(Exponent,float);
  vtkGetMacro(Exponent,float);

  // Description:
  // Set/Get the lighting cone angle of a positional light in degrees.
  vtkSetMacro(ConeAngle,float);
  vtkGetMacro(ConeAngle,float);

  // Description:
  // Set/Get the quadratic attenuation constants. They are specified as
  // constant, linear, quadratic in that order.
  vtkSetVector3Macro(AttenuationValues,float);
  vtkGetVectorMacro(AttenuationValues,float,3);

protected:
  float FocalPoint[3];
  float Position[3];
  float Intensity;
  float Color[3];
  int   Switch;
  int   Positional;
  float Exponent;
  float ConeAngle;
  float AttenuationValues[3];
  vtkLightDevice *Device;
};

#endif
<|endoftext|>


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

#include "TokenKind.h"

namespace ydsh {
namespace parser {

static const char *TOKEN_KIND_STRING[] = {
#define GEN_NAME(ENUM) "<" #ENUM ">",
        EACH_TOKEN(GEN_NAME)
#undef GEN_NAME
};

const char *toString(TokenKind kind) {
    return TOKEN_KIND_STRING[kind];
}

std::ostream &operator<<(std::ostream &stream, TokenKind kind) {
    stream << toString(kind);
    return stream;
}

unsigned int getPrecedence(TokenKind kind) {
    switch(kind) {
    case MUL:
    case DIV:
    case MOD:
        return 300;
    case PLUS:
    case MINUS:
        return 280;
    case LA:
    case RA:
    case LE:
    case GE:
        return 260;
    case IS:
    case AS:
        return 240;
    case EQ:
    case NE:
    case RE_MATCH:
    case RE_UNMATCH:
        return 220;
    case AND:
        return 200;
    case XOR:
        return 180;
    case OR:
        return 160;
    case COND_AND:
        return 140;
    case COND_OR:
        return 120;
    case ASSIGN:
    case ADD_ASSIGN:
    case SUB_ASSIGN:
    case MUL_ASSIGN:
    case DIV_ASSIGN:
    case MOD_ASSIGN:
        return 100;
    default:
        return 0;
    }
}

} // namespace parser
} // namespace ydsh
<commit_msg>fix operator precedence, close #98<commit_after>/*
 * Copyright (C) 2015 Nagisa Sekiguchi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "TokenKind.h"

namespace ydsh {
namespace parser {

static const char *TOKEN_KIND_STRING[] = {
#define GEN_NAME(ENUM) "<" #ENUM ">",
        EACH_TOKEN(GEN_NAME)
#undef GEN_NAME
};

const char *toString(TokenKind kind) {
    return TOKEN_KIND_STRING[kind];
}

std::ostream &operator<<(std::ostream &stream, TokenKind kind) {
    stream << toString(kind);
    return stream;
}

unsigned int getPrecedence(TokenKind kind) {
    switch(kind) {
    case IS:
    case AS:
        return 300;
    case MUL:
    case DIV:
    case MOD:
        return 280;
    case PLUS:
    case MINUS:
        return 260;
    case AND:
        return 220;
    case XOR:
        return 200;
    case OR:
        return 180;
    case LA:
    case RA:
    case LE:
    case GE:
    case EQ:
    case NE:
    case RE_MATCH:
    case RE_UNMATCH:
        return 160;
    case COND_AND:
        return 140;
    case COND_OR:
        return 120;
    case ASSIGN:
    case ADD_ASSIGN:
    case SUB_ASSIGN:
    case MUL_ASSIGN:
    case DIV_ASSIGN:
    case MOD_ASSIGN:
        return 100;
    default:
        return 0;
    }
}

} // namespace parser
} // namespace ydsh
<|endoftext|>


<commit_before>#include "platform.hpp"

#include "../base/logging.hpp"

#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>

//static bool GetUserWritableDir(string & outDir)
//{
//  char * path = ::getenv("HOME");
//  if (path)
//  {
//    outDir = path;
//    outDir += "/.MapsWithMe/";
//    ::mkdir(outDir.c_str(), 0755);
//    return true;
//  }
//  return false;
//}

/// @return directory where binary resides, including slash at the end
static bool GetBinaryFolder(string & outPath)
{
  char path[4096] = {0};
  if (0 < ::readlink("/proc/self/exe", path, ARRAY_SIZE(path)))
  {
    outPath = path;
    outPath.erase(outPath.find_last_of('/') + 1);
    return true;
  }
  return false;
}

Platform::Platform()
{
  // init directories
  string path;
  CHECK(GetBinaryFolder(path), ("Can't retrieve path to executable"));

  // @TODO implement correct resources and writable directories for public releases
  m_resourcesDir = path + "../../data/";
  m_writableDir = m_resourcesDir;
  m_settingsDir = m_writableDir;
  char * tmpDir = ::getenv("TMPDIR");
  if (tmpDir)
    m_tmpDir = tmpDir;
  else
    m_tmpDir = P_tmpdir;

  LOG(LDEBUG, ("Resources directory:", m_resourcesDir));
  LOG(LDEBUG, ("Writable directory:", m_writableDir));
  LOG(LDEBUG, ("Tmp directory:", m_tmpDir));
  LOG(LDEBUG, ("Settings directory:", m_settingsDir));
}

Platform::~Platform()
{
}

bool Platform::IsFileExistsByFullPath(string const & filePath)
{
  struct stat s;
  return stat(filePath.c_str(), &s) == 0;
}

int Platform::CpuCores() const
{
  const long numCPU = sysconf(_SC_NPROCESSORS_ONLN);
  if (numCPU >= 1)
    return static_cast<int>(numCPU);
  return 1;
}

string Platform::UniqueClientId() const
{
  return "@TODO";
}

void Platform::RunOnGuiThread(TFunctor const & fn)
{
  // @TODO
  fn();
}

void Platform::RunAsync(TFunctor const & fn, Priority p)
{
  // @TODO
  fn();
}
<commit_msg>[linux] Fixed build error<commit_after>#include "platform.hpp"

#include "../base/logging.hpp"

#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>

//static bool GetUserWritableDir(string & outDir)
//{
//  char * path = ::getenv("HOME");
//  if (path)
//  {
//    outDir = path;
//    outDir += "/.MapsWithMe/";
//    ::mkdir(outDir.c_str(), 0755);
//    return true;
//  }
//  return false;
//}

/// @return directory where binary resides, including slash at the end
static bool GetBinaryFolder(string & outPath)
{
  char path[4096] = {0};
  if (0 < ::readlink("/proc/self/exe", path, ARRAY_SIZE(path)))
  {
    outPath = path;
    outPath.erase(outPath.find_last_of('/') + 1);
    return true;
  }
  return false;
}

Platform::Platform()
{
  // init directories
  string path;
  CHECK(GetBinaryFolder(path), ("Can't retrieve path to executable"));

  // @TODO implement correct resources and writable directories for public releases
  m_resourcesDir = path + "../../data/";
  m_writableDir = m_resourcesDir;
  m_settingsDir = m_writableDir;
  char * tmpDir = ::getenv("TMPDIR");
  if (tmpDir)
    m_tmpDir = tmpDir;
  else
    m_tmpDir = "/tmp";
  m_tmpDir += '/';

  LOG(LDEBUG, ("Resources directory:", m_resourcesDir));
  LOG(LDEBUG, ("Writable directory:", m_writableDir));
  LOG(LDEBUG, ("Tmp directory:", m_tmpDir));
  LOG(LDEBUG, ("Settings directory:", m_settingsDir));
}

Platform::~Platform()
{
}

bool Platform::IsFileExistsByFullPath(string const & filePath)
{
  struct stat s;
  return stat(filePath.c_str(), &s) == 0;
}

int Platform::CpuCores() const
{
  const long numCPU = sysconf(_SC_NPROCESSORS_ONLN);
  if (numCPU >= 1)
    return static_cast<int>(numCPU);
  return 1;
}

string Platform::UniqueClientId() const
{
  return "@TODO";
}

void Platform::RunOnGuiThread(TFunctor const & fn)
{
  // @TODO
  fn();
}

void Platform::RunAsync(TFunctor const & fn, Priority p)
{
  // @TODO
  fn();
}
<|endoftext|>


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

// this file contains PrivSep functions that use DeamonCore
// facilities

#include "condor_common.h"
#include "condor_debug.h"
#include "condor_daemon_core.h"
#include "condor_privsep.h"

static int
privsep_create_process(const char* cmd,
                       const char* path,
                       ArgList&    args,
                       Env*        env,
                       const char* iwd,
                       int         std_fds[3],
                       const char* std_file_names[3],
                       int         nice_inc,
                       size_t*     core_size_ptr,
                       int         reaper_id,
                       int         dc_job_opts,
                       FamilyInfo* family_info,
                       uid_t       uid)
{
	// if we're using privilege separation, we have to do a bit
	// of extra work to do to launch processes as other UIDs
	// since we need to use the PrivSep Swtichboard. the procedure
	// will be:
	//
	//   1) create two pipes over which we'll communicate with
	//      the switchboard
	//   2) call create process on the switchboard
	//   3) use the input pipe to give the switchboard info about
	//      what binary to run, what files to use for i/o, etc.
	//   4) use the error pipe to see if everything went ok

	// create the pipes
	//
	FILE* in_fp;
	int child_in_fd;
	FILE* err_fp;
	int child_err_fd;
	bool ok;
	ok = privsep_create_pipes(in_fp,
	                          child_in_fd,
	                          err_fp,
	                          child_err_fd);
	if (!ok) {
		dprintf(D_ALWAYS,
		        "privsep_create_process: privsep_create_pipes failure\n");
		errno = 0;
		return FALSE;
	}

	// fire up the switchboard
	//
	MyString sb_path;
	ArgList sb_args;
	privsep_get_switchboard_command(cmd,
	                                child_in_fd,
	                                child_err_fd,
	                                sb_path,
	                                sb_args);
	int pipe_fds[] = {child_in_fd, child_err_fd, 0};
	int pid = daemonCore->Create_Process(
		sb_path.Value(), // switchboard path
		sb_args,         // switchboard args
		PRIV_USER_FINAL, // priv states are ignored in priv sep mode
		reaper_id,       // reaper id
		FALSE,           // no command port
		NULL,            // we'll pass the job's real env via pipe
		NULL,            // we'll pass the job's real iwd via pipe
		family_info,     // tracking info for the ProcD
		NULL,            // no sockets to inherit
		std_fds,         // FDs that will become std{in,out,err}
		pipe_fds,        // tell DC to pass down the in/err pipe FDs
		nice_inc,        // niceness (TODO: need switchboard?)
		NULL,            // don't mess with the signal mask
		dc_job_opts,     // DC job options
		core_size_ptr);  // core size limit (TODO: need switchboard?)
	close(child_in_fd);
	close(child_err_fd);
	if (pid == FALSE) {
		dprintf(D_ALWAYS, "privsep_create_process: DC::Create_Process error\n");
		fclose(in_fp);
		fclose(err_fp);
		return FALSE;
	}

	// feed the switchboard the args to give to the ProcD
	//
	privsep_exec_set_uid(in_fp, uid);
	privsep_exec_set_path(in_fp, path);
	privsep_exec_set_args(in_fp, args);
	if (env != NULL) {
		privsep_exec_set_env(in_fp, *env);
	}
	if (iwd != NULL) {
		privsep_exec_set_iwd(in_fp, iwd);
	}
	for (int i = 0; i < 3; i++) {
		if ((std_fds != NULL) && (std_fds[i] != -1)) {
			privsep_exec_set_inherit_fd(in_fp, i);
		}
		else if (std_file_names) {
			privsep_exec_set_std_file(in_fp, i, std_file_names[i]);
		}
	}
#if defined(LINUX)
	if ((family_info != NULL) && (family_info->group_ptr != NULL)) {
		privsep_exec_set_tracking_group(in_fp, *family_info->group_ptr);
	}
#endif
	fclose(in_fp);

	// check the switchboard's error pipe for any problems
	// (privsep_get_switchboard_response will fclose the error
	// pipe for us)
	//
	if (!privsep_get_switchboard_response(err_fp)) {
		dprintf(D_ALWAYS,
		        "privsep_create_process: "
		            "privsep_get_switchboard_response failure\n");
		errno = 0;
		return FALSE;
	}

	// if we've gotten here, everything worked
	//
	return pid;
}

int
privsep_spawn_procd(const char* path,
                    ArgList& args,
                    int std_fds[3],
                    int reaper_id)
{
	return privsep_create_process("pd",
	                              path,
	                              args,
	                              NULL,
	                              NULL,
	                              std_fds,
	                              NULL,
	                              0,
	                              NULL,
                                  reaper_id,
	                              0,
	                              NULL,
	                              0);
}

int privsep_launch_user_job(uid_t       uid,
                            const char* path,
                            ArgList&    args,
                            Env&        env,
                            const char* iwd,
                            int         std_fds[3],
                            const char* std_file_names[3],
                            int         nice_inc,
                            size_t*     core_size_ptr,
                            int         reaper_id,
                            int         dc_job_opts,
                            FamilyInfo* family_info)
{
	return privsep_create_process("exec",
	                              path,
	                              args,
	                              &env,
	                              iwd,
	                              std_fds,
	                              std_file_names,
	                              nice_inc,
	                              core_size_ptr,
	                              reaper_id,
	                              dc_job_opts,
	                              family_info,
	                              uid);
}
<commit_msg>Fixed indentation problem<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/

// this file contains PrivSep functions that use DeamonCore
// facilities

#include "condor_common.h"
#include "condor_debug.h"
#include "condor_daemon_core.h"
#include "condor_privsep.h"

static int
privsep_create_process(const char* cmd,
                       const char* path,
                       ArgList&    args,
                       Env*        env,
                       const char* iwd,
                       int         std_fds[3],
                       const char* std_file_names[3],
                       int         nice_inc,
                       size_t*     core_size_ptr,
                       int         reaper_id,
                       int         dc_job_opts,
                       FamilyInfo* family_info,
                       uid_t       uid)
{
	// if we're using privilege separation, we have to do a bit
	// of extra work to do to launch processes as other UIDs
	// since we need to use the PrivSep Swtichboard. the procedure
	// will be:
	//
	//   1) create two pipes over which we'll communicate with
	//      the switchboard
	//   2) call create process on the switchboard
	//   3) use the input pipe to give the switchboard info about
	//      what binary to run, what files to use for i/o, etc.
	//   4) use the error pipe to see if everything went ok

	// create the pipes
	//
	FILE* in_fp;
	int child_in_fd;
	FILE* err_fp;
	int child_err_fd;
	bool ok;
	ok = privsep_create_pipes(in_fp,
	                          child_in_fd,
	                          err_fp,
	                          child_err_fd);
	if (!ok) {
		dprintf(D_ALWAYS,
		        "privsep_create_process: privsep_create_pipes failure\n");
		errno = 0;
		return FALSE;
	}

	// fire up the switchboard
	//
	MyString sb_path;
	ArgList sb_args;
	privsep_get_switchboard_command(cmd,
	                                child_in_fd,
	                                child_err_fd,
	                                sb_path,
	                                sb_args);
	int pipe_fds[] = {child_in_fd, child_err_fd, 0};
	int pid = daemonCore->Create_Process(
		sb_path.Value(), // switchboard path
		sb_args,         // switchboard args
		PRIV_USER_FINAL, // priv states are ignored in priv sep mode
		reaper_id,       // reaper id
		FALSE,           // no command port
		NULL,            // we'll pass the job's real env via pipe
		NULL,            // we'll pass the job's real iwd via pipe
		family_info,     // tracking info for the ProcD
		NULL,            // no sockets to inherit
		std_fds,         // FDs that will become std{in,out,err}
		pipe_fds,        // tell DC to pass down the in/err pipe FDs
		nice_inc,        // niceness (TODO: need switchboard?)
		NULL,            // don't mess with the signal mask
		dc_job_opts,     // DC job options
		core_size_ptr);  // core size limit (TODO: need switchboard?)
	close(child_in_fd);
	close(child_err_fd);
	if (pid == FALSE) {
		dprintf(D_ALWAYS, "privsep_create_process: DC::Create_Process error\n");
		fclose(in_fp);
		fclose(err_fp);
		return FALSE;
	}

	// feed the switchboard the args to give to the ProcD
	//
	privsep_exec_set_uid(in_fp, uid);
	privsep_exec_set_path(in_fp, path);
	privsep_exec_set_args(in_fp, args);
	if (env != NULL) {
		privsep_exec_set_env(in_fp, *env);
	}
	if (iwd != NULL) {
		privsep_exec_set_iwd(in_fp, iwd);
	}
	for (int i = 0; i < 3; i++) {
		if ((std_fds != NULL) && (std_fds[i] != -1)) {
			privsep_exec_set_inherit_fd(in_fp, i);
		}
		else if (std_file_names) {
			privsep_exec_set_std_file(in_fp, i, std_file_names[i]);
		}
	}
#if defined(LINUX)
	if ((family_info != NULL) && (family_info->group_ptr != NULL)) {
		privsep_exec_set_tracking_group(in_fp, *family_info->group_ptr);
	}
#endif
	fclose(in_fp);

	// check the switchboard's error pipe for any problems
	// (privsep_get_switchboard_response will fclose the error
	// pipe for us)
	//
	if (!privsep_get_switchboard_response(err_fp)) {
		dprintf(D_ALWAYS,
		        "privsep_create_process: "
		            "privsep_get_switchboard_response failure\n");
		errno = 0;
		return FALSE;
	}

	// if we've gotten here, everything worked
	//
	return pid;
}

int
privsep_spawn_procd(const char* path,
                    ArgList& args,
                    int std_fds[3],
                    int reaper_id)
{
	return privsep_create_process("pd",
	                              path,
	                              args,
	                              NULL,
	                              NULL,
	                              std_fds,
	                              NULL,
	                              0,
	                              NULL,
	                              reaper_id,
	                              0,
	                              NULL,
	                              0);
}

int privsep_launch_user_job(uid_t       uid,
                            const char* path,
                            ArgList&    args,
                            Env&        env,
                            const char* iwd,
                            int         std_fds[3],
                            const char* std_file_names[3],
                            int         nice_inc,
                            size_t*     core_size_ptr,
                            int         reaper_id,
                            int         dc_job_opts,
                            FamilyInfo* family_info)
{
	return privsep_create_process("exec",
	                              path,
	                              args,
	                              &env,
	                              iwd,
	                              std_fds,
	                              std_file_names,
	                              nice_inc,
	                              core_size_ptr,
	                              reaper_id,
	                              dc_job_opts,
	                              family_info,
	                              uid);
}
<|endoftext|>


<commit_before>// Load transforms and build RGB volumes from images

#include "itkRGBPixel.h"
#include "itkVectorResampleImageFilter.h"

// my files
#include "Stack.hpp"
#include "RegistrationBuilder.hpp"
#include "StackAligner.hpp"
#include "StackIOHelpers.hpp"
#include "IOHelpers.hpp"
#include "StackTransforms.hpp"
#include "Dirs.hpp"
#include "Parameters.hpp"
#include "Profiling.hpp"
#include "ScaleImages.hpp"

// boost
#include "boost/filesystem.hpp"
#include "boost/program_options.hpp"
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

namespace po = boost::program_options;
using namespace boost::filesystem;
using namespace boost;

po::variables_map parse_arguments(int argc, char *argv[]);

int main(int argc, char *argv[]) {
  po::variables_map vm = parse_arguments(argc, argv);

	// Process command line arguments
  Dirs::SetDataSet( vm["dataSet"].as<string>() );
  Dirs::SetOutputDirName( vm["outputDir"].as<string>() );
  string blockDir = vm.count("blockDir") ? vm["blockDir"].as<string>() + "/" : Dirs::BlockDir();
  bool LoRes = !vm.count("no-LoRes");
  bool HiRes = !vm["no-HiRes"].as<bool>();
  string roi = vm["roi"].as<string>();

  // get file names
  vector< string > basenames = getBasenames(Dirs::ImageList());
  vector< string > LoResFilePaths, HiResFilePaths;
  if(LoRes) LoResFilePaths = constructPaths(blockDir,         basenames, ".bmp");
  if(HiRes) HiResFilePaths = constructPaths(Dirs::SliceDir(), basenames, ".bmp");

  // initialise stack with correct spacings, sizes, transforms etc
  typedef itk::RGBPixel< unsigned char > PixelType;
  typedef Stack< PixelType, itk::VectorResampleImageFilter, itk::VectorLinearInterpolateImageFunction > StackType;
  StackType::SliceVectorType LoResImages, HiResImages;
  if(LoRes) LoResImages = readImages< StackType::SliceType >(LoResFilePaths);
  if(HiRes) HiResImages = readImages< StackType::SliceType >(HiResFilePaths);
  if(LoRes) scaleImages< StackType::SliceType >(LoResImages, getSpacings<2>("LoRes"));
  if(HiRes) scaleImages< StackType::SliceType >(HiResImages, getSpacings<2>("HiRes"));
  shared_ptr< StackType > LoResStack, HiResStack;
  if(LoRes) LoResStack = make_shared< StackType >(LoResImages, getSpacings<3>("LoRes"), getSize(roi));
  if(HiRes) HiResStack = make_shared< StackType >(HiResImages, getSpacings<3>("LoRes"), getSize(roi));
  if(LoRes) LoResStack->SetBasenames(basenames);
  if(HiRes) HiResStack->SetBasenames(basenames);
  if(HiRes) HiResStack->SetDefaultPixelValue( 255 );

  // prepare for possible saves
  itk::Vector< double, 2 > translation = StackTransforms::GetLoResTranslation(roi) - StackTransforms::GetLoResTranslation("whole_heart");
  create_directory( Dirs::ColourDir() );

  // save LoRes image
  if(LoRes)
  {
    // load transforms
    string loResTransformsDir = vm.count("loResTransformsDir") ? vm["loResTransformsDir"].as<string>() : Dirs::LoResTransformsDir();
    Load(*LoResStack, loResTransformsDir);
    // move stack origins to ROI
    StackTransforms::Translate(*LoResStack, translation);
    // generate and save images
    LoResStack->updateVolumes();
    writeImage< StackType::VolumeType >( LoResStack->GetVolume(), Dirs::ColourDir() + "LoRes.mha");
  }

  // save HiRes rigid, similarity and affine image
  if(HiRes)
  {
    if(vm.count("hiResTransformsDir")) // just process single directory from command line
    {
      string dir = Dirs::ResultsDir() + vm["hiResTransformsDir"].as<string>();
      Load(*HiResStack, dir);
      // move stack origins to ROI
      StackTransforms::Translate(*HiResStack, translation);
      // generate and save images
      HiResStack->updateVolumes();
      writeImage< StackType::VolumeType >( HiResStack->GetVolume(), dir + "/HiRes.mha");

    }
    else // process all three transform optimisations
    {
      // load transforms, translate to correct ROI and save
      vector< string > HiResTransformsDirs;
      HiResTransformsDirs.push_back("CenteredRigid2DTransform");
      HiResTransformsDirs.push_back("CenteredSimilarity2DTransform");
      HiResTransformsDirs.push_back("CenteredAffineTransform");
      for(vector< string >::iterator it = HiResTransformsDirs.begin(); it != HiResTransformsDirs.end(); ++it)
      {
        Load(*HiResStack, Dirs::HiResTransformsDir() + *it);
        // move stack origins to ROI
        StackTransforms::Translate(*HiResStack, translation);
        // generate and save images
        HiResStack->updateVolumes();
        writeImage< StackType::VolumeType >( HiResStack->GetVolume(), Dirs::ColourDir() + *it + ".mha");
      }
    }

  }

  return EXIT_SUCCESS;
}

po::variables_map parse_arguments(int argc, char *argv[])
{
  // Declare the supported options.
  po::options_description opts("Options");
  opts.add_options()
      ("help,h", "produce help message")
      ("dataSet", po::value<string>(), "which rat to use")
      ("outputDir", po::value<string>(), "directory to source transforms and place results")
      ("roi", po::value<string>()->default_value("whole_heart"), "set region of interest")
      ("loResTransformsDir", po::value<string>(), "directory containing LoRes transform files, relative to ResultsDir")
      ("hiResTransformsDir", po::value<string>(), "directory containing HiRes transform files, relative to ResultsDir")
      ("blockDir", po::value<string>(), "directory containing LoRes originals")

      // three different ways of not specifying value for flag
      // implicit_value(true) allows syntax like -H0 and --no-HiRes=0,
      // rather than just the flag e.g. -H or --no-HiRes
      ("no-LoRes,L", po::value<bool>()->zero_tokens(), "do not generate LoRes image")
      ("no-HiRes,H", po::bool_switch(), "do not generate HiRes image")
      // ("no-HiRes,H", po::value(&noHiRes)->implicit_value(true), "do not generate HiRes image")
  ;

  po::positional_options_description p;
  p.add("dataSet", 1)
   .add("outputDir", 1);

  // parse command line
  po::variables_map vm;
	try
	{
  po::store(po::command_line_parser(argc, argv)
            .options(opts)
            .positional(p)
            .run(),
            vm);
	}
	catch (std::exception& e)
	{
	  cerr << "caught command-line parsing error" << endl;
    std::cerr << e.what() << std::endl;
    exit(EXIT_FAILURE);
  }
  po::notify(vm);

  // if help is specified, or positional args aren't present
  if (vm.count("help") || !vm.count("dataSet") || !vm.count("outputDir")) {
    cerr << "Usage: "
      << argv[0] << " [--dataSet=]RatX [--outputDir=]my_dir [Options]"
      << endl << endl;
    cerr << opts << "\n";
    exit(EXIT_FAILURE);
  }

  return vm;
}
<commit_msg>Relative path bug<commit_after>// Load transforms and build RGB volumes from images

#include "itkRGBPixel.h"
#include "itkVectorResampleImageFilter.h"

// my files
#include "Stack.hpp"
#include "RegistrationBuilder.hpp"
#include "StackAligner.hpp"
#include "StackIOHelpers.hpp"
#include "IOHelpers.hpp"
#include "StackTransforms.hpp"
#include "Dirs.hpp"
#include "Parameters.hpp"
#include "Profiling.hpp"
#include "ScaleImages.hpp"

// boost
#include "boost/filesystem.hpp"
#include "boost/program_options.hpp"
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

namespace po = boost::program_options;
using namespace boost::filesystem;
using namespace boost;

po::variables_map parse_arguments(int argc, char *argv[]);

int main(int argc, char *argv[]) {
  po::variables_map vm = parse_arguments(argc, argv);

	// Process command line arguments
  Dirs::SetDataSet( vm["dataSet"].as<string>() );
  Dirs::SetOutputDirName( vm["outputDir"].as<string>() );
  string blockDir = vm.count("blockDir") ? vm["blockDir"].as<string>() + "/" : Dirs::BlockDir();
  bool LoRes = !vm.count("no-LoRes");
  bool HiRes = !vm["no-HiRes"].as<bool>();
  string roi = vm["roi"].as<string>();

  // get file names
  vector< string > basenames = getBasenames(Dirs::ImageList());
  vector< string > LoResFilePaths, HiResFilePaths;
  if(LoRes) LoResFilePaths = constructPaths(blockDir,         basenames, ".bmp");
  if(HiRes) HiResFilePaths = constructPaths(Dirs::SliceDir(), basenames, ".bmp");

  // initialise stack with correct spacings, sizes, transforms etc
  typedef itk::RGBPixel< unsigned char > PixelType;
  typedef Stack< PixelType, itk::VectorResampleImageFilter, itk::VectorLinearInterpolateImageFunction > StackType;
  StackType::SliceVectorType LoResImages, HiResImages;
  if(LoRes) LoResImages = readImages< StackType::SliceType >(LoResFilePaths);
  if(HiRes) HiResImages = readImages< StackType::SliceType >(HiResFilePaths);
  if(LoRes) scaleImages< StackType::SliceType >(LoResImages, getSpacings<2>("LoRes"));
  if(HiRes) scaleImages< StackType::SliceType >(HiResImages, getSpacings<2>("HiRes"));
  shared_ptr< StackType > LoResStack, HiResStack;
  if(LoRes) LoResStack = make_shared< StackType >(LoResImages, getSpacings<3>("LoRes"), getSize(roi));
  if(HiRes) HiResStack = make_shared< StackType >(HiResImages, getSpacings<3>("LoRes"), getSize(roi));
  if(LoRes) LoResStack->SetBasenames(basenames);
  if(HiRes) HiResStack->SetBasenames(basenames);
  if(HiRes) HiResStack->SetDefaultPixelValue( 255 );

  // prepare for possible saves
  itk::Vector< double, 2 > translation = StackTransforms::GetLoResTranslation(roi) - StackTransforms::GetLoResTranslation("whole_heart");
  create_directory( Dirs::ColourDir() );

  // save LoRes image
  if(LoRes)
  {
    // load transforms
    string loResTransformsDir = vm.count("loResTransformsDir") ? Dirs::ResultsDir() + vm["loResTransformsDir"].as<string>() : Dirs::LoResTransformsDir();
    Load(*LoResStack, loResTransformsDir);
    // move stack origins to ROI
    StackTransforms::Translate(*LoResStack, translation);
    // generate and save images
    LoResStack->updateVolumes();
    writeImage< StackType::VolumeType >( LoResStack->GetVolume(), Dirs::ColourDir() + "LoRes.mha");
  }

  // save HiRes rigid, similarity and affine image
  if(HiRes)
  {
    if(vm.count("hiResTransformsDir")) // just process single directory from command line
    {
      string dir = Dirs::ResultsDir() + vm["hiResTransformsDir"].as<string>();
      Load(*HiResStack, dir);
      // move stack origins to ROI
      StackTransforms::Translate(*HiResStack, translation);
      // generate and save images
      HiResStack->updateVolumes();
      writeImage< StackType::VolumeType >( HiResStack->GetVolume(), dir + "/HiRes.mha");

    }
    else // process all three transform optimisations
    {
      // load transforms, translate to correct ROI and save
      vector< string > HiResTransformsDirs;
      HiResTransformsDirs.push_back("CenteredRigid2DTransform");
      HiResTransformsDirs.push_back("CenteredSimilarity2DTransform");
      HiResTransformsDirs.push_back("CenteredAffineTransform");
      for(vector< string >::iterator it = HiResTransformsDirs.begin(); it != HiResTransformsDirs.end(); ++it)
      {
        Load(*HiResStack, Dirs::HiResTransformsDir() + *it);
        // move stack origins to ROI
        StackTransforms::Translate(*HiResStack, translation);
        // generate and save images
        HiResStack->updateVolumes();
        writeImage< StackType::VolumeType >( HiResStack->GetVolume(), Dirs::ColourDir() + *it + ".mha");
      }
    }

  }

  return EXIT_SUCCESS;
}

po::variables_map parse_arguments(int argc, char *argv[])
{
  // Declare the supported options.
  po::options_description opts("Options");
  opts.add_options()
      ("help,h", "produce help message")
      ("dataSet", po::value<string>(), "which rat to use")
      ("outputDir", po::value<string>(), "directory to source transforms and place results")
      ("roi", po::value<string>()->default_value("whole_heart"), "set region of interest")
      ("loResTransformsDir", po::value<string>(), "directory containing LoRes transform files, relative to ResultsDir")
      ("hiResTransformsDir", po::value<string>(), "directory containing HiRes transform files, relative to ResultsDir")
      ("blockDir", po::value<string>(), "directory containing LoRes originals")

      // three different ways of not specifying value for flag
      // implicit_value(true) allows syntax like -H0 and --no-HiRes=0,
      // rather than just the flag e.g. -H or --no-HiRes
      ("no-LoRes,L", po::value<bool>()->zero_tokens(), "do not generate LoRes image")
      ("no-HiRes,H", po::bool_switch(), "do not generate HiRes image")
      // ("no-HiRes,H", po::value(&noHiRes)->implicit_value(true), "do not generate HiRes image")
  ;

  po::positional_options_description p;
  p.add("dataSet", 1)
   .add("outputDir", 1);

  // parse command line
  po::variables_map vm;
	try
	{
  po::store(po::command_line_parser(argc, argv)
            .options(opts)
            .positional(p)
            .run(),
            vm);
	}
	catch (std::exception& e)
	{
	  cerr << "caught command-line parsing error" << endl;
    std::cerr << e.what() << std::endl;
    exit(EXIT_FAILURE);
  }
  po::notify(vm);

  // if help is specified, or positional args aren't present
  if (vm.count("help") || !vm.count("dataSet") || !vm.count("outputDir")) {
    cerr << "Usage: "
      << argv[0] << " [--dataSet=]RatX [--outputDir=]my_dir [Options]"
      << endl << endl;
    cerr << opts << "\n";
    exit(EXIT_FAILURE);
  }

  return vm;
}
<|endoftext|>


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

#include "platformsettings.h"
#include <QDir>
#include <QSettings>
#include <Quill>
#include "quillitem.h"

#define PATH "/usr/share/cameraplus/config/cameraplus.ini"

#define PREVIEW_SIZE                             QSize(854, 480)
#define THUMBNAIL_FLAVOR_NAME                    QString("screen")
#define TEMPORARY_FILE_PATH                      "%1%2.config%2quill%2tmp"
#define THUMBNAIL_EXTENSION                      QString("jpeg")
#define THUMBNAIL_CREATION_ENABLED               true
#define DBUS_THUMBNAILING_ENABLED                true
#define BACKGROUND_RENDERING_COLOR               QColor(Qt::black)

PlatformSettings::PlatformSettings(QObject *parent) :
  QObject(parent), m_settings(new QSettings(PATH, QSettings::IniFormat)) {

}

PlatformSettings::~PlatformSettings() {
  delete m_settings;
}

QSize PlatformSettings::previewSize() {
  return m_settings->value("quill/previewSize", PREVIEW_SIZE).toSize();
}

QString PlatformSettings::thumbnailFlavorName() {
  return m_settings->value("quill/thumbnailFlavorName", THUMBNAIL_FLAVOR_NAME).toString();
}

QString PlatformSettings::thumbnailExtension() {
  return m_settings->value("quill/thumbnailExtension", THUMBNAIL_EXTENSION).toString();
}

QColor PlatformSettings::backgroundRenderingColor() {
  return m_settings->value("quill/backgroundRenderingColor",
			   BACKGROUND_RENDERING_COLOR).value<QColor>();
}

bool PlatformSettings::isDBusThumbnailingEnabled() {
  return m_settings->value("quill/dbusThumbnailingEnabled", DBUS_THUMBNAILING_ENABLED).toBool();
}

bool PlatformSettings::isThumbnailCreationEnabled() {
  return m_settings->value("quill/thumbnailCreationEnabled", THUMBNAIL_CREATION_ENABLED).toBool();
}

QString PlatformSettings::temporaryFilePath() {
  QString defaultPath = QString(TEMPORARY_FILE_PATH).arg(QDir::homePath()).arg(QDir::separator());
  return m_settings->value("quill/temporaryFilePath", defaultPath).toString();
}

QSize PlatformSettings::portraitSize(const QSize& size) {
  return size.width() > size.height() ? QSize(size.height(), size.width()) : size;
}

QSize PlatformSettings::landscapeSize(const QSize& size) {
  return size.width() > size.height() ? size : QSize(size.height(), size.width());
}

void PlatformSettings::init() {
  // How we create thumbnails for portrait is really messy.
  // I am sure there is a better way to tell Quill to generate proper
  // portrait thumbnails without having 2 display levels but I don't know how.
  // The issue is we generate screen sized thumbnails for landscape
  // but we generate half screen sized thumbnails for portrait
  Quill::setPreviewLevelCount(2);
  QSize size = previewSize();

  // Landscape:
  Quill::setThumbnailFlavorName(LANDSCAPE_PREVIEW_LEVEL, thumbnailFlavorName());
  Quill::setPreviewSize(LANDSCAPE_PREVIEW_LEVEL, landscapeSize(size));

  // Portrait:
  Quill::setThumbnailFlavorName(PORTRAIT_PREVIEW_LEVEL, thumbnailFlavorName());
  Quill::setPreviewSize(PORTRAIT_PREVIEW_LEVEL, portraitSize(size));

  Quill::setThumbnailExtension(thumbnailExtension());
  Quill::setBackgroundRenderingColor(backgroundRenderingColor());
  Quill::setDBusThumbnailingEnabled(isDBusThumbnailingEnabled());
  Quill::setThumbnailCreationEnabled(isThumbnailCreationEnabled());

  QString tempPath = temporaryFilePath();
  QDir().mkpath(tempPath);
  Quill::setTemporaryFilePath(tempPath);
}

PlatformSettings::Service PlatformSettings::service(const QString& id) {
  PlatformSettings::Service service;
  m_settings->beginGroup(id);

  service.m_enabled = m_settings->value("enabled", false).toBool();
  service.m_type = m_settings->value("type").toString();
  service.m_path = m_settings->value("path").toString();
  service.m_interface = m_settings->value("interface").toString();
  service.m_dest = m_settings->value("dest").toString();
  service.m_method = m_settings->value("method").toString();

  m_settings->endGroup();

  return service;
}

QString PlatformSettings::imageCaptureStartedSound() const {
  return m_settings->value("sounds/imageCaptureStarted").toString();
}

QString PlatformSettings::imageCaptureEndedSound() const {
  return m_settings->value("sounds/imageCaptureEnded").toString();
}

QString PlatformSettings::videoRecordingStartedSound() const {
  return m_settings->value("sounds/videoRecordingStarted").toString();
}

QString PlatformSettings::videoRecordingEndedSound() const {
  return m_settings->value("sounds/videoRecordingEnded").toString();
}

QString PlatformSettings::autoFocusAcquiredSound() const {
  return m_settings->value("sounds/autoFocusAcquired").toString();
}
<commit_msg>Initialize quill only if we are building for harmattan<commit_after>/*!
 * This file is part of CameraPlus.
 *
 * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "platformsettings.h"
#include <QDir>
#include <QSettings>
#ifdef HARMATTAN
#include <Quill>
#include "quillitem.h"
#endif

#define PATH "/usr/share/cameraplus/config/cameraplus.ini"

#define PREVIEW_SIZE                             QSize(854, 480)
#define THUMBNAIL_FLAVOR_NAME                    QString("screen")
#define TEMPORARY_FILE_PATH                      "%1%2.config%2quill%2tmp"
#define THUMBNAIL_EXTENSION                      QString("jpeg")
#define THUMBNAIL_CREATION_ENABLED               true
#define DBUS_THUMBNAILING_ENABLED                true
#define BACKGROUND_RENDERING_COLOR               QColor(Qt::black)

PlatformSettings::PlatformSettings(QObject *parent) :
  QObject(parent), m_settings(new QSettings(PATH, QSettings::IniFormat)) {

}

PlatformSettings::~PlatformSettings() {
  delete m_settings;
}

QSize PlatformSettings::previewSize() {
  return m_settings->value("quill/previewSize", PREVIEW_SIZE).toSize();
}

QString PlatformSettings::thumbnailFlavorName() {
  return m_settings->value("quill/thumbnailFlavorName", THUMBNAIL_FLAVOR_NAME).toString();
}

QString PlatformSettings::thumbnailExtension() {
  return m_settings->value("quill/thumbnailExtension", THUMBNAIL_EXTENSION).toString();
}

QColor PlatformSettings::backgroundRenderingColor() {
  return m_settings->value("quill/backgroundRenderingColor",
			   BACKGROUND_RENDERING_COLOR).value<QColor>();
}

bool PlatformSettings::isDBusThumbnailingEnabled() {
  return m_settings->value("quill/dbusThumbnailingEnabled", DBUS_THUMBNAILING_ENABLED).toBool();
}

bool PlatformSettings::isThumbnailCreationEnabled() {
  return m_settings->value("quill/thumbnailCreationEnabled", THUMBNAIL_CREATION_ENABLED).toBool();
}

QString PlatformSettings::temporaryFilePath() {
  QString defaultPath = QString(TEMPORARY_FILE_PATH).arg(QDir::homePath()).arg(QDir::separator());
  return m_settings->value("quill/temporaryFilePath", defaultPath).toString();
}

QSize PlatformSettings::portraitSize(const QSize& size) {
  return size.width() > size.height() ? QSize(size.height(), size.width()) : size;
}

QSize PlatformSettings::landscapeSize(const QSize& size) {
  return size.width() > size.height() ? size : QSize(size.height(), size.width());
}

void PlatformSettings::init() {
#ifdef HARMATTAN
  // How we create thumbnails for portrait is really messy.
  // I am sure there is a better way to tell Quill to generate proper
  // portrait thumbnails without having 2 display levels but I don't know how.
  // The issue is we generate screen sized thumbnails for landscape
  // but we generate half screen sized thumbnails for portrait
  Quill::setPreviewLevelCount(2);
  QSize size = previewSize();

  // Landscape:
  Quill::setThumbnailFlavorName(LANDSCAPE_PREVIEW_LEVEL, thumbnailFlavorName());
  Quill::setPreviewSize(LANDSCAPE_PREVIEW_LEVEL, landscapeSize(size));

  // Portrait:
  Quill::setThumbnailFlavorName(PORTRAIT_PREVIEW_LEVEL, thumbnailFlavorName());
  Quill::setPreviewSize(PORTRAIT_PREVIEW_LEVEL, portraitSize(size));

  Quill::setThumbnailExtension(thumbnailExtension());
  Quill::setBackgroundRenderingColor(backgroundRenderingColor());
  Quill::setDBusThumbnailingEnabled(isDBusThumbnailingEnabled());
  Quill::setThumbnailCreationEnabled(isThumbnailCreationEnabled());

  QString tempPath = temporaryFilePath();
  QDir().mkpath(tempPath);
  Quill::setTemporaryFilePath(tempPath);
#endif
}

PlatformSettings::Service PlatformSettings::service(const QString& id) {
  PlatformSettings::Service service;
  m_settings->beginGroup(id);

  service.m_enabled = m_settings->value("enabled", false).toBool();
  service.m_type = m_settings->value("type").toString();
  service.m_path = m_settings->value("path").toString();
  service.m_interface = m_settings->value("interface").toString();
  service.m_dest = m_settings->value("dest").toString();
  service.m_method = m_settings->value("method").toString();

  m_settings->endGroup();

  return service;
}

QString PlatformSettings::imageCaptureStartedSound() const {
  return m_settings->value("sounds/imageCaptureStarted").toString();
}

QString PlatformSettings::imageCaptureEndedSound() const {
  return m_settings->value("sounds/imageCaptureEnded").toString();
}

QString PlatformSettings::videoRecordingStartedSound() const {
  return m_settings->value("sounds/videoRecordingStarted").toString();
}

QString PlatformSettings::videoRecordingEndedSound() const {
  return m_settings->value("sounds/videoRecordingEnded").toString();
}

QString PlatformSettings::autoFocusAcquiredSound() const {
  return m_settings->value("sounds/autoFocusAcquired").toString();
}
<|endoftext|>


<commit_before>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2014 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "ImageNode.h"

#include "TypeDefinition.h"
#include "OGLSurface.h"
#include "Player.h"
#include "OffscreenCanvas.h"

#include "../base/Logger.h"
#include "../base/ScopeTimer.h"
#include "../base/XMLHelper.h"
#include "../base/Exception.h"
#include "../base/ObjectCounter.h"

#include "../graphics/Filterfliprgb.h"

#include <iostream>
#include <sstream>

using namespace std;
using namespace boost;

namespace avg {

void ImageNode::registerType()
{
    TypeDefinition def = TypeDefinition("image", "rasternode",
            ExportedObject::buildObject<ImageNode>)
        .addArg(Arg<UTF8String>("href", "", false, offsetof(ImageNode, m_href)))
        .addArg(Arg<string>("compression", "none"));
    TypeRegistry::get()->registerType(def);
}

ImageNode::ImageNode(const ArgList& args)
    : m_Compression(Image::TEXTURECOMPRESSION_NONE)
{
    args.setMembers(this);
    m_pImage = ImagePtr(new Image(getSurface(), getMaterial()));
    m_Compression = Image::string2compression(args.getArgVal<string>("compression"));
    setHRef(m_href);
    ObjectCounter::get()->incRef(&typeid(*this));
}

ImageNode::~ImageNode()
{
    // XXX: The following assert checks that disconnect(true) has been called.
    // However, if connect() has been called but rendering never started,
    // disconnect isn't called either.
//    AVG_ASSERT(!m_pImage->getCanvas());
    ObjectCounter::get()->decRef(&typeid(*this));
}

void ImageNode::connectDisplay()
{
    if (m_pImage->getSource() == Image::SCENE) {
        checkCanvasValid(m_pImage->getCanvas());
    }
    m_pImage->moveToGPU();
    RasterNode::connectDisplay();
    if (m_pImage->getSource() == Image::SCENE) {
        m_pImage->getCanvas()->addDependentCanvas(getCanvas());
    }
}

void ImageNode::connect(CanvasPtr pCanvas)
{
    RasterNode::connect(pCanvas);
    checkReload();
}

void ImageNode::disconnect(bool bKill)
{
    OffscreenCanvasPtr pCanvas = m_pImage->getCanvas();
    if (pCanvas) {
        pCanvas->removeDependentCanvas(getCanvas());
    }
    if (bKill) {
        RasterNode::disconnect(bKill);
        m_pImage = ImagePtr(new Image(getSurface(), getMaterial()));
        m_href = "";
    } else {
        m_pImage->moveToCPU();
        RasterNode::disconnect(bKill);
    }
}

const UTF8String& ImageNode::getHRef() const
{
    return m_href;
}

void ImageNode::setHRef(const UTF8String& href)
{
    m_href = href;
    if (m_pImage->getSource() == Image::SCENE && getState() == Node::NS_CANRENDER)
    {
        m_pImage->getCanvas()->removeDependentCanvas(getCanvas());
    }
    try {
        if (href == "") {
            m_pImage->setEmpty();
        } else {
            checkReload();
        }
    } catch (const Exception&) {
        m_href = "";
        m_pImage->setEmpty();
        throw;
    }
}

const string ImageNode::getCompression() const
{
    return Image::compression2String(m_Compression);
}

void ImageNode::setBitmap(BitmapPtr pBmp)
{
    if (m_pImage->getSource() == Image::SCENE && getState() == Node::NS_CANRENDER) {
        m_pImage->getCanvas()->removeDependentCanvas(getCanvas());
    }
    m_pImage->setBitmap(pBmp, m_Compression);
    if (getState() == Node::NS_CANRENDER) {
        newSurface();
    }
    m_href = "";
    setViewport(-32767, -32767, -32767, -32767);
}

static ProfilingZoneID PrerenderProfilingZone("ImageNode::prerender");

void ImageNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
        float parentEffectiveOpacity)
{
    ScopeTimer timer(PrerenderProfilingZone);
    Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
    if (isVisible() && m_pImage->getSource() != Image::NONE) {
            scheduleFXRender();
        }
    }
    calcVertexArray(pVA);
}

void ImageNode::renderFX()
{
    bool bHasCanvas = bool(m_pImage->getCanvas());
    RasterNode::renderFX(getSize(), Pixel32(255, 255, 255, 255), bHasCanvas, bHasCanvas);
}

static ProfilingZoneID RenderProfilingZone("ImageNode::render");

void ImageNode::render()
{
    ScopeTimer Timer(RenderProfilingZone);
    if (m_pImage->getSource() != Image::NONE) {
        blt32(getTransform(), getSize(), getEffectiveOpacity(), getBlendMode(),
                bool(m_pImage->getCanvas()));
    }
}

IntPoint ImageNode::getMediaSize()
{
    return m_pImage->getSize();
}

void ImageNode::checkReload()
{
    if (isCanvasURL(m_href)) {
        if (m_Compression != Image::TEXTURECOMPRESSION_NONE) {
            throw Exception(AVG_ERR_UNSUPPORTED,
                    "Texture compression can't be used with canvas hrefs.");
        }
        OffscreenCanvasPtr pCanvas = Player::get()->getCanvasFromURL(m_href);
        checkCanvasValid(pCanvas);
        m_pImage->setCanvas(pCanvas);
        if (getState() == NS_CANRENDER) {
            pCanvas->addDependentCanvas(getCanvas());
        }
        newSurface();
    } else {
        bool bNewImage = Node::checkReload(m_href, m_pImage, m_Compression);
        if (bNewImage) {
            newSurface();
        }
    }
    setViewport(-32767, -32767, -32767, -32767);
    RasterNode::checkReload();
}

void ImageNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
{
    if (reactsToMouseEvents()) {
        OffscreenCanvasPtr pCanvas = m_pImage->getCanvas();
        if (pCanvas && pCanvas->getHandleEvents()) {
            glm::vec2 nodeSize(getSize());
            glm::vec2 canvasSize(pCanvas->getSize());
            glm::vec2 localPos(pos.x*(canvasSize.x/nodeSize.x),
                    pos.y*(canvasSize.y/nodeSize.y));
            pCanvas->getRootNode()->getElementsByPos(localPos, pElements);
        } else {
            RasterNode::getElementsByPos(pos, pElements);
        }
    }
}

BitmapPtr ImageNode::getBitmap()
{
    return m_pImage->getBitmap();
}

bool ImageNode::isCanvasURL(const std::string& sURL)
{
    return sURL.find("canvas:") == 0;
}

void ImageNode::checkCanvasValid(const CanvasPtr& pCanvas)
{
    if (pCanvas == getCanvas()) {
        m_href = "";
        m_pImage->setEmpty();
        throw Exception(AVG_ERR_INVALID_ARGS,
                "Circular dependency between canvases.");
    }
}

}
<commit_msg>Build fix.<commit_after>//
//  libavg - Media Playback Engine.
//  Copyright (C) 2003-2014 Ulrich von Zadow
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
//  Current versions can be found at www.libavg.de
//

#include "ImageNode.h"

#include "TypeDefinition.h"
#include "OGLSurface.h"
#include "Player.h"
#include "OffscreenCanvas.h"

#include "../base/Logger.h"
#include "../base/ScopeTimer.h"
#include "../base/XMLHelper.h"
#include "../base/Exception.h"
#include "../base/ObjectCounter.h"

#include "../graphics/Filterfliprgb.h"

#include <iostream>
#include <sstream>

using namespace std;
using namespace boost;

namespace avg {

void ImageNode::registerType()
{
    TypeDefinition def = TypeDefinition("image", "rasternode",
            ExportedObject::buildObject<ImageNode>)
        .addArg(Arg<UTF8String>("href", "", false, offsetof(ImageNode, m_href)))
        .addArg(Arg<string>("compression", "none"));
    TypeRegistry::get()->registerType(def);
}

ImageNode::ImageNode(const ArgList& args)
    : m_Compression(Image::TEXTURECOMPRESSION_NONE)
{
    args.setMembers(this);
    m_pImage = ImagePtr(new Image(getSurface(), getMaterial()));
    m_Compression = Image::string2compression(args.getArgVal<string>("compression"));
    setHRef(m_href);
    ObjectCounter::get()->incRef(&typeid(*this));
}

ImageNode::~ImageNode()
{
    // XXX: The following assert checks that disconnect(true) has been called.
    // However, if connect() has been called but rendering never started,
    // disconnect isn't called either.
//    AVG_ASSERT(!m_pImage->getCanvas());
    ObjectCounter::get()->decRef(&typeid(*this));
}

void ImageNode::connectDisplay()
{
    if (m_pImage->getSource() == Image::SCENE) {
        checkCanvasValid(m_pImage->getCanvas());
    }
    m_pImage->moveToGPU();
    RasterNode::connectDisplay();
    if (m_pImage->getSource() == Image::SCENE) {
        m_pImage->getCanvas()->addDependentCanvas(getCanvas());
    }
}

void ImageNode::connect(CanvasPtr pCanvas)
{
    RasterNode::connect(pCanvas);
    checkReload();
}

void ImageNode::disconnect(bool bKill)
{
    OffscreenCanvasPtr pCanvas = m_pImage->getCanvas();
    if (pCanvas) {
        pCanvas->removeDependentCanvas(getCanvas());
    }
    if (bKill) {
        RasterNode::disconnect(bKill);
        m_pImage = ImagePtr(new Image(getSurface(), getMaterial()));
        m_href = "";
    } else {
        m_pImage->moveToCPU();
        RasterNode::disconnect(bKill);
    }
}

const UTF8String& ImageNode::getHRef() const
{
    return m_href;
}

void ImageNode::setHRef(const UTF8String& href)
{
    m_href = href;
    if (m_pImage->getSource() == Image::SCENE && getState() == Node::NS_CANRENDER)
    {
        m_pImage->getCanvas()->removeDependentCanvas(getCanvas());
    }
    try {
        if (href == "") {
            m_pImage->setEmpty();
        } else {
            checkReload();
        }
    } catch (const Exception&) {
        m_href = "";
        m_pImage->setEmpty();
        throw;
    }
}

const string ImageNode::getCompression() const
{
    return Image::compression2String(m_Compression);
}

void ImageNode::setBitmap(BitmapPtr pBmp)
{
    if (m_pImage->getSource() == Image::SCENE && getState() == Node::NS_CANRENDER) {
        m_pImage->getCanvas()->removeDependentCanvas(getCanvas());
    }
    m_pImage->setBitmap(pBmp, m_Compression);
    if (getState() == Node::NS_CANRENDER) {
        newSurface();
    }
    m_href = "";
    setViewport(-32767, -32767, -32767, -32767);
}

static ProfilingZoneID PrerenderProfilingZone("ImageNode::prerender");

void ImageNode::preRender(const VertexArrayPtr& pVA, bool bIsParentActive,
        float parentEffectiveOpacity)
{
    ScopeTimer timer(PrerenderProfilingZone);
    Node::preRender(pVA, bIsParentActive, parentEffectiveOpacity);
    if (isVisible() && m_pImage->getSource() != Image::NONE) {
        scheduleFXRender();
    }
    calcVertexArray(pVA);
}

void ImageNode::renderFX()
{
    bool bHasCanvas = bool(m_pImage->getCanvas());
    RasterNode::renderFX(getSize(), Pixel32(255, 255, 255, 255), bHasCanvas, bHasCanvas);
}

static ProfilingZoneID RenderProfilingZone("ImageNode::render");

void ImageNode::render()
{
    ScopeTimer Timer(RenderProfilingZone);
    if (m_pImage->getSource() != Image::NONE) {
        blt32(getTransform(), getSize(), getEffectiveOpacity(), getBlendMode(),
                bool(m_pImage->getCanvas()));
    }
}

IntPoint ImageNode::getMediaSize()
{
    return m_pImage->getSize();
}

void ImageNode::checkReload()
{
    if (isCanvasURL(m_href)) {
        if (m_Compression != Image::TEXTURECOMPRESSION_NONE) {
            throw Exception(AVG_ERR_UNSUPPORTED,
                    "Texture compression can't be used with canvas hrefs.");
        }
        OffscreenCanvasPtr pCanvas = Player::get()->getCanvasFromURL(m_href);
        checkCanvasValid(pCanvas);
        m_pImage->setCanvas(pCanvas);
        if (getState() == NS_CANRENDER) {
            pCanvas->addDependentCanvas(getCanvas());
        }
        newSurface();
    } else {
        bool bNewImage = Node::checkReload(m_href, m_pImage, m_Compression);
        if (bNewImage) {
            newSurface();
        }
    }
    setViewport(-32767, -32767, -32767, -32767);
    RasterNode::checkReload();
}

void ImageNode::getElementsByPos(const glm::vec2& pos, vector<NodePtr>& pElements)
{
    if (reactsToMouseEvents()) {
        OffscreenCanvasPtr pCanvas = m_pImage->getCanvas();
        if (pCanvas && pCanvas->getHandleEvents()) {
            glm::vec2 nodeSize(getSize());
            glm::vec2 canvasSize(pCanvas->getSize());
            glm::vec2 localPos(pos.x*(canvasSize.x/nodeSize.x),
                    pos.y*(canvasSize.y/nodeSize.y));
            pCanvas->getRootNode()->getElementsByPos(localPos, pElements);
        } else {
            RasterNode::getElementsByPos(pos, pElements);
        }
    }
}

BitmapPtr ImageNode::getBitmap()
{
    return m_pImage->getBitmap();
}

bool ImageNode::isCanvasURL(const std::string& sURL)
{
    return sURL.find("canvas:") == 0;
}

void ImageNode::checkCanvasValid(const CanvasPtr& pCanvas)
{
    if (pCanvas == getCanvas()) {
        m_href = "";
        m_pImage->setEmpty();
        throw Exception(AVG_ERR_INVALID_ARGS,
                "Circular dependency between canvases.");
    }
}

}
<|endoftext|>