<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_pcie_config.C $    */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
//-----------------------------------------------------------------------------------
///
/// @file p9_pcie_config.C
/// @brief Perform PCIE Phase2 init sequence (FAPI2)
///

// *HWP HWP Owner: Christina Graves clgraves@us.ibm.com
// *HWP FW Owner: Thi Tran thi@us.ibm.com
// *HWP Team: Nest
// *HWP Level: 1
// *HWP Consumed by: HB

//-----------------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------------
#include <p9_pcie_config.H>

//-----------------------------------------------------------------------------------
// Function definitions
//-----------------------------------------------------------------------------------
fapi2::ReturnCode p9_pcie_config(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    FAPI_INF("Start");
    FAPI_INF("End");
    return fapi2::current_err;
}
<commit_msg>PCIE phase1/phase2 initialization procedure.<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_pcie_config.C $    */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
//-----------------------------------------------------------------------------------
///
/// @file p9_pcie_config.C
/// @brief Perform PCIE Phase2 init sequence (FAPI2)
///

// *HWP HWP Owner: Christina Graves clgraves@us.ibm.com
// *HWP FW Owner: Thi Tran thi@us.ibm.com
// *HWP Team: Nest
// *HWP Level: 2
// *HWP Consumed by: HB

//-----------------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------------
#include <p9_pcie_config.H>

#include "p9_misc_scom_addresses.H"
#include "p9_misc_scom_addresses_fld.H"

//-----------------------------------------------------------------------------------
// Function definitions
//-----------------------------------------------------------------------------------
fapi2::ReturnCode p9_pcie_config(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    FAPI_INF("Start");
    // Four BARs
    const uint8_t NUM_BAR = 4;

    uint64_t l_bar_address[NUM_BAR] = {0};
    uint64_t l_bar_mask[NUM_BAR] = {0};
    uint8_t l_bar_enable[NUM_BAR] = {0};

    fapi2::buffer<uint64_t> l_buf = 0;
    auto l_pec_chiplets_vec = i_target.getChildren<fapi2::TARGET_TYPE_PEC>(fapi2::TARGET_STATE_FUNCTIONAL);
    auto l_phb_chiplets_vec = i_target.getChildren<fapi2::TARGET_TYPE_PHB>(fapi2::TARGET_STATE_FUNCTIONAL);
    FAPI_DBG("pec target vec size: %#x\n", l_pec_chiplets_vec.size());
    FAPI_DBG("phb target vec size: %#x\n", l_phb_chiplets_vec.size());
    unsigned char l_pec_id = 0;
    unsigned char l_phb_id = 0;

    for (auto l_pec_chiplets : l_pec_chiplets_vec)
    {
        // Get the pec id
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_pec_chiplets,
                               l_pec_id));

        // Phase2 init step 1
        // NestBase+0x00
        // Set bits 00:03 = 0b0001Set hang poll scale
        // Set bits             04:07 = 0b0010 Set data scale
        // Set bits 08:11 = 0b0001 Set hang pe scale
        // Set bit 22 = 0b1 Disable out-of-order store behavior
        FAPI_TRY(fapi2::getScom(l_pec_chiplets, PEC_PBCQHWCFG_REG, l_buf));
        l_buf.insertFromRight<PEC_PBCQHWCFG_REG_HANG_POLL_SCALE, PEC_PBCQHWCFG_REG_HANG_POLL_SCALE_LEN>(0x1);
        l_buf.insertFromRight<PEC_PBCQHWCFG_REG_HANG_DATA_SCALE, PEC_PBCQHWCFG_REG_HANG_DATA_SCALE_LEN>(0x2);
        l_buf.insertFromRight<PEC_PBCQHWCFG_REG_HANG_PE_SCALE, PEC_PBCQHWCFG_REG_HANG_PE_SCALE_LEN>(0x1);
        l_buf.insertFromRight<PEC_PBCQHWCFG_REG_PE_DISABLE_OOO_MODE, 1>(0x1);
        FAPI_DBG("pec%i: %#lx", l_pec_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_pec_chiplets, PEC_PBCQHWCFG_REG, l_buf));

        // Phase2 init step 2
        // NestBase+0x01
        // N/A Modify Drop Priority Control Register (DrPriCtl)

        // Phase2 init step 3
        // NestBase+0x03
        // Set bits 00:03 = 0b1001 Enable trace, and select
        // Inbound operations with addr information
        FAPI_TRY(fapi2::getScom(l_pec_chiplets, PEC_NESTTRC_REG, l_buf));
        // TODO: no register bit field defined.
        l_buf.insertFromRight<0, 4>(0x9);
        FAPI_DBG("pec%i: %#lx", l_pec_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_pec_chiplets, PEC_NESTTRC_REG, l_buf));

        // Phase2 init step 4
        // NestBase+0x05
        // N/A For use of atomics/asb_notify

        // Phase2 init step 5
        // NestBase+0x06
        // N/A To override scope prediction

        // Phase2 init step 6
        // PCIBase +0x00
        // Set bits 30 = 0b1 Enable Trace
        l_buf = 0;
        l_buf.setBit<PEC_PBAIBHWCFG_REG_PE_PCIE_CLK_TRACE_EN>();
        FAPI_DBG("pec%i: %#lx", l_pec_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_pec_chiplets, PEC_PBAIBHWCFG_REG, l_buf));
    }

    for (auto l_phb_chiplets : l_phb_chiplets_vec)
    {
        // Get the pec id
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_phb_chiplets,
                               l_phb_id));
        // Phase2 init step 7_a
        // NestBase+StackBase+0xA
        // 0x00000000_00000000
        // Clear any spurious cerr_rpt0 bits (cerr_rpt0)
        // TODO: HW363246 this step appears in the v1.0 doc but failed PCB address
        // error in model e9034
        //l_buf = (uint64_t)0x0;
        //FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        //FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_CERR_RPT0_REG, l_buf));

        // Phase2 init step 7_b
        // NestBase+StackBase+0xB
        // 0x00000000_00000000
        // Clear any spurious cerr_rpt1 bits (cerr_rpt1)
        // TODO: HW363246 this step appears in the v1.0 doc but failed PCB address
        // error in model e9034
        //l_buf = (uint64_t)0x0;
        //FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        //FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_CERR_RPT1_REG, l_buf));

        // Phase2 init step 7_c
        // NestBase+StackBase+0x0
        // 0x00000000_00000000
        // Clear any spurious FIR
        // bits (NFIR)NFIR
        l_buf = (uint64_t)0x0;
        FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_NFIR_REG, l_buf));

        // Phase2 init step 8
        // NestBase+StackBase+0x8
        // 0x00000000_00000000
        // Clear any spurious WOF
        // bits (NFIRWOF)
        FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_NFIRWOF_REG, l_buf));

        // Phase2 init step 9
        // NestBase+StackBase+0x6
        // 0x5B0F8190_00000000
        // Set the per FIR Bit Action 0 register
        l_buf = 0x5B0F819000000000;
        FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_NFIRACTION0_REG, l_buf));

        // Phase2 init step 10
        // NestBase+StackBase+0x7
        // 0x7F0F8190_00000000
        // Set the per FIR Bit Action 1 register
        l_buf = 0x7F0F819000000000;
        FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_NFIRACTION1_REG, l_buf));

        // Phase2 init step 11
        // NestBase+StackBase+0x3
        // 0x00000000_00000000
        // Set FIR Mask Bits to allow errors (NFIRMask)
        l_buf = 0x0000000000000000;
        FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_NFIRMASK_REG, l_buf));

        // Phase2 init step 12
        // NestBase+StackBase+0x15
        // 0x00000000_00000000
        // Set Data Freeze Type Register for SUE handling (DFREEZE)
        l_buf = 0x0000000000000000;
        FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_PE_DFREEZE_REG, l_buf));

        // Phase2 init step 13_a
        // PCIBase+StackBase+0xB
        // 0x00000000_00000000
        // Clear any spurious pbaib_cerr_rpt bits
        l_buf = (uint64_t)0x0;
        FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_PFIR_REG, l_buf));

        // Phase2 init step 13_b
        // PCIBase+StackBase+0x0
        // 0x00000000_00000000
        // Clear any spurious FIR
        // bits (PFIR)PFIR
        l_buf = (uint64_t)0x0;
        FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_PBAIB_CERR_RPT_REG, l_buf));

        // Phase2 init step 14
        // PCIBase+StackBase+0x8
        // 0x00000000_00000000
        // Clear any spurious WOF
        // bits (PFIRWOF)
        FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_PFIRWOF_REG, l_buf));

        // Phase2 init step 15
        // PCIBase+StackBase+0x6
        // 0x5B0F8190_00000000
        // Set the per FIR Bit Action 0 register
        l_buf = 0x5B0F819000000000;
        FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_PFIRACTION0_REG, l_buf));

        // Phase2 init step 16
        // PCIBase+StackBase+0x7
        // 0x7F0F8190_00000000
        // Set the per FIR Bit Action 1 register
        l_buf = 0x7F0F819000000000;
        FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_PFIRACTION1_REG, l_buf));

        // Phase2 init step 17
        // PCIBase+StackBase+0x3
        // 0x00000000_00000000
        // Set FIR Mask Bits to allow errors (PFIRMask)
        l_buf = 0x0000000000000000;
        FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_PFIRMASK_REG, l_buf));

        // Get the attribute for BAR address and size.
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_PCIE_BAR_BASE_ADDR, l_phb_chiplets,
                               l_bar_address));
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_PCIE_BAR_SIZE, l_phb_chiplets,
                               l_bar_mask));
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_PCIE_BAR_ENABLE, l_phb_chiplets,
                               l_bar_enable));

        // step 18: NestBase+StackBase+0xE<software programmed>Set MMIO Base
        // Address Register 0 (MMIOBAR0)
        FAPI_DBG("phb%i bar0 addr: %#lx", l_phb_id, l_bar_address[0]);
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_MMIOBAR0_REG, l_bar_address[0]));

        // step 19: NestBase+StackBase+0xF<software programmed>Set MMIO BASE
        // Address Register Mask 0 (MMIOBAR0_MASK)
        FAPI_DBG("phb%i bar0 mask: %#lx", l_phb_id, l_bar_mask[0]);
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_MMIOBAR0_MASK_REG, l_bar_mask[0]));

        // step 20: NestBase+StackBase+0x10<software programmed>Set MMIO Base
        // Address Register 1 (MMIOBAR1)
        FAPI_DBG("phb%i bar1 addr: %#lx", l_phb_id, l_bar_address[1]);
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_MMIOBAR1_REG, l_bar_address[1]));

        // step 21: NestBase+StackBase+0x11<software programmed>Set MMIO Base
        // Address Register Mask 1 (MMIOBAR1_MASK)
        FAPI_DBG("phb%i bar1 mask: %#lx", l_phb_id, l_bar_mask[1]);
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_MMIOBAR1_MASK_REG, l_bar_mask[1]));

        // step 22: NestBase+StackBase+0x12<software programmed>Set PHB
        // Regsiter Base address Register (PHBBAR)
        FAPI_DBG("phb%i phb addr: %#lx", l_phb_id, l_bar_address[2]);
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_PHBBAR_REG, l_bar_address[2]));

        // step 23: NestBase+StackBase+0x13<software programmed>Set Interrupt
        // BASEase Address Register (INTBAR)
        FAPI_DBG("phb%i int addr: %#lx", l_phb_id, l_bar_address[3]);
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_INTBAR_REG, l_bar_address[3]));

        // step 24: NestBase+StackBase+0x14<software programmed>Set Base
        // addressress Enable Register (BARE)
        l_buf = (uint64_t)0x0;
        l_buf.insertFromRight<PHB_BARE_REG_PE_MMIO_BAR0_EN, 1>(l_bar_enable[0]); // bit 0 for BAR0
        l_buf.insertFromRight<PHB_BARE_REG_PE_MMIO_BAR1_EN, 1>(l_bar_enable[1]); // bit 1 for BAR1
        l_buf.insertFromRight<PHB_BARE_REG_PE_PHB_BAR_EN, 1>(l_bar_enable[2]); // bit 2 for PHB
        l_buf.insertFromRight<PHB_BARE_REG_PE_INT_BAR_EN, 1>(l_bar_enable[3]); // bit 3 for INT
        FAPI_DBG("phb%i bar enable: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_BARE_REG, l_buf));

        // Phase2 init step 25
        // PCIBase+StackBase +0x0A
        // 0x00000000_00000000
        // Remove ETU/AIB bus from reset (PHBReset)
        l_buf = (uint64_t)0x0;
        FAPI_DBG("phb%i: %#lx", l_phb_id, l_buf());
        FAPI_TRY(fapi2::putScom(l_phb_chiplets, PHB_PHBRESET_REG, l_buf));
    }

    FAPI_INF("End");

fapi_try_exit:
    return fapi2::current_err;
}
<|endoftext|>


<commit_before>// This file is part of UDPipe <http://github.com/ufal/udpipe/>.
//
// Copyright 2016 Institute of Formal and Applied Linguistics, Faculty of
// Mathematics and Physics, Charles University in Prague, Czech Republic.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <fstream>
#include <sstream>

#include "common.h"
#include "model/evaluator.h"
#include "model/model.h"
#include "model/pipeline.h"
#include "sentence/input_format.h"
#include "sentence/output_format.h"
#include "tokenizer/detokenizer.h"
#include "trainer/trainer.h"
#include "utils/getpara.h"
#include "utils/iostreams.h"
#include "utils/options.h"
#include "utils/process_args.h"
#include "version/version.h"

using namespace ufal::udpipe;

bool append_conllu(istream& is, vector<sentence>& sentences, string& error) {
  unique_ptr<input_format> conllu_input(input_format::new_conllu_input_format());

  string block;
  while (conllu_input->read_block(is, block)) {
    conllu_input->set_text(block);
    while (sentences.emplace_back(), conllu_input->next_sentence(sentences.back(), error)) ;
    sentences.pop_back();
    if (!error.empty()) return false;
  }
  return true;
}

int main(int argc, char* argv[]) {
  iostreams_init();

  options::map options;
  if (!options::parse({{"accuracy", options::value::none},
                       {"detokenize", options::value::none},
                       {"method", options::value{"morphodita_parsito"}},
                       {"heldout", options::value::any},
                       {"input", options::value::any},
                       {"outfile", options::value::any},
                       {"output", options::value::any},
                       {"parse", options::value::none},
                       {"parser", options::value::any},
                       {"tag", options::value::none},
                       {"tagger", options::value::any},
                       {"tokenize", options::value::none},
                       {"tokenizer", options::value::any},
                       {"train", options::value::none},
                       {"version", options::value::none},
                       {"help", options::value::none}}, argc, argv, options) ||
      options.count("help") ||
      (argc < 2 && !options.count("version")))
    runtime_failure("Usage: " << argv[0] << " [running_opts] model_file [input_files]\n"
                    "       " << argv[0] << " --train [training_opts] model_file [input_files]\n"
                    "       " << argv[0] << " --detokenize [detokenize_opts] raw_text_file [input_files]\n"
                    "Running opts: --accuracy (measure accuracy only)\n"
                    "              --input=[conllu|horizontal|vertical]\n"
                    "              --outfile=output file template\n"
                    "              --output=[conllu|matxin|horizontal|vertical]\n"
                    "              --tokenize (perform tokenization)\n"
                    "              --tokenizer=tokenizer options, implies --tokenize\n"
                    "              --tag (perform tagging)\n"
                    "              --tagger=tagger options, implies --tag\n"
                    "              --parse (perform parsing)\n"
                    "              --parser=parser options, implies --parse\n"
                    "Training opts: --method=[morphodita_parsito] which method to use\n"
                    "               --heldout=heldout data file name\n"
                    "               --tokenizer=tokenizer options\n"
                    "               --tagger=tagger options\n"
                    "               --parser=parser options\n"
                    "Detokenize opts: --outfile=output file template\n"
                    "Generic opts: --version\n"
                    "              --help");
  if (options.count("version"))
    return cout << version::version_and_copyright() << endl, 0;

  // TRAINING
  if (options.count("train")) {
    string error;

    // Load training data
    cerr << "Loading training data: " << flush;
    vector<sentence> training;
    for (int i = 2; i < argc; i++) {
      ifstream input(argv[i]);
      if (!input.is_open()) runtime_failure("Cannot open input file '" << argv[i] << "'!");
      if (!append_conllu(input, training, error))
        runtime_failure("Cannot load training data from file '" << argv[i] << "': " << error);
    }
    if (argc == 2 && !append_conllu(cin, training, error)) runtime_failure("Cannot load training data: " << error);
    cerr << "done." << endl;

    // Load heldout data
    vector<sentence> heldout;
    if (options.count("heldout")) {
      ifstream input(options["heldout"]);
      if (!input.is_open()) runtime_failure("Cannot open heldout data file '" << options["heldout"] << "'!");
      if (!append_conllu(input, heldout, error))
        runtime_failure("Cannot load heldout data from file '" << options["heldout"] << "': " << error);
    }

    // Open output file
    ofstream model(argv[1], ofstream::binary);
    if (!model.is_open()) runtime_failure("Cannot open model file '" << argv[1] << "' for writing.");

    // Train the model
    cerr << "Training the UDPipe model." << endl;
    string method = options.count("method") ? options["method"] : "morphodita_parsito";
    if (!trainer::train(method, training, heldout, options["tokenizer"], options["tagger"], options["parser"], model, error))
      runtime_failure("An error occurred during model training: " << error);
    cerr << "The trained UDPipe model was saved." << endl;
  } else
  // DETOKENIZE
  if (options.count("detokenize")) {
    // Detokenize CoNLL-U files
    ifstream raw_text_file(argv[1]);
    if (!raw_text_file.is_open()) runtime_failure("Cannot load raw text from file '" << argv[1] << "'.");

    string raw_text;
    for (char c; raw_text_file.get(c); )
      raw_text.push_back(c);
    raw_text_file.close();

    detokenizer detokenizer(raw_text);
    process_args_with_output_template(2, argc, argv, options["outfile"], [&detokenizer](istream& is, ostream& os) {
      unique_ptr<input_format> conllu_input(input_format::new_conllu_input_format());
      unique_ptr<output_format> conllu_output(output_format::new_conllu_output_format());

      sentence s;
      string block, error;
      while (conllu_input->read_block(is, block)) {
        conllu_input->set_text(block);
        while (conllu_input->next_sentence(s, error)) {
          detokenizer.detokenize(s);
          conllu_output->write_sentence(s, os);
        }
        if (!error.empty()) runtime_failure("An error occurred during UDPipe execution: " << error);
      }
      conllu_output->finish_document(os);
    });
  } else
  // RUN
  {
    // Load the model if needed
    unique_ptr<model> model;
    if (options.count("tokenizer") || options.count("tokenize") ||
        options.count("tagger") || options.count("tag") ||
        options.count("parser") || options.count("parse")) {
      cerr << "Loading UDPipe model: " << flush;
      model.reset(model::load(argv[1]));
      if (!model) runtime_failure("Cannot load UDPipe model '" << argv[1] << "'!");
      cerr << "done." << endl;
    }

    if (options.count("accuracy")) {
      if (options.count("input")) runtime_failure("The --input option is unsupported when --accuracy is used!");
      if (options.count("output")) runtime_failure("The --output option is unsupported when --accuracy is used!");

      // Prepare the evaluator
      evaluator evaluator(model.get(), options.count("tokenizer") ? options["tokenizer"] : options.count("tokenize") ? pipeline::DEFAULT : pipeline::NONE,
                          options.count("tagger") ? options["tagger"] : options.count("tag") ? pipeline::DEFAULT : pipeline::NONE,
                          options.count("parser") ? options["parser"] : options.count("parse") ? pipeline::DEFAULT : pipeline::NONE);

      // Process the data
      process_args_with_output_template(2, argc, argv, options["outfile"], [&evaluator](istream& is, ostream& os) {
        string error;
        if (!evaluator.evaluate(is, os, error))
            runtime_failure("An error occurred during UDPipe execution: " << error);
      });
    } else {
      // Prepare the pipeline
      pipeline pipeline(model.get(), options.count("tokenizer") ? "tokenizer=" + options["tokenizer"] : options.count("tokenize") ? "tokenizer" : options.count("input") ? options["input"] : "conllu",
                        options.count("tagger") ? options["tagger"] : options.count("tag") ? pipeline::DEFAULT : pipeline::NONE,
                        options.count("parser") ? options["parser"] : options.count("parse") ? pipeline::DEFAULT : pipeline::NONE,
                        options.count("output") ? options["output"] : "conllu");

      // Process the data
      process_args_with_output_template(2, argc, argv, options["outfile"], [&pipeline](istream& is, ostream& os) {
        string error;
        if (!pipeline.process(is, os, error))
          runtime_failure("An error occurred during UDPipe execution: " << error);
      });
    }
  }

  return 0;
}
<commit_msg>Update to process_args_with_output_template changes.<commit_after>// This file is part of UDPipe <http://github.com/ufal/udpipe/>.
//
// Copyright 2016 Institute of Formal and Applied Linguistics, Faculty of
// Mathematics and Physics, Charles University in Prague, Czech Republic.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <fstream>
#include <sstream>

#include "common.h"
#include "model/evaluator.h"
#include "model/model.h"
#include "model/pipeline.h"
#include "sentence/input_format.h"
#include "sentence/output_format.h"
#include "tokenizer/detokenizer.h"
#include "trainer/trainer.h"
#include "utils/getpara.h"
#include "utils/iostreams.h"
#include "utils/options.h"
#include "utils/process_args.h"
#include "version/version.h"

using namespace ufal::udpipe;

bool append_conllu(istream& is, vector<sentence>& sentences, string& error) {
  unique_ptr<input_format> conllu_input(input_format::new_conllu_input_format());

  string block;
  while (conllu_input->read_block(is, block)) {
    conllu_input->set_text(block);
    while (sentences.emplace_back(), conllu_input->next_sentence(sentences.back(), error)) ;
    sentences.pop_back();
    if (!error.empty()) return false;
  }
  return true;
}

int main(int argc, char* argv[]) {
  iostreams_init();

  options::map options;
  if (!options::parse({{"accuracy", options::value::none},
                       {"detokenize", options::value::none},
                       {"method", options::value{"morphodita_parsito"}},
                       {"heldout", options::value::any},
                       {"input", options::value::any},
                       {"outfile", options::value::any},
                       {"output", options::value::any},
                       {"parse", options::value::none},
                       {"parser", options::value::any},
                       {"tag", options::value::none},
                       {"tagger", options::value::any},
                       {"tokenize", options::value::none},
                       {"tokenizer", options::value::any},
                       {"train", options::value::none},
                       {"version", options::value::none},
                       {"help", options::value::none}}, argc, argv, options) ||
      options.count("help") ||
      (argc < 2 && !options.count("version")))
    runtime_failure("Usage: " << argv[0] << " [running_opts] model_file [input_files]\n"
                    "       " << argv[0] << " --train [training_opts] model_file [input_files]\n"
                    "       " << argv[0] << " --detokenize [detokenize_opts] raw_text_file [input_files]\n"
                    "Running opts: --accuracy (measure accuracy only)\n"
                    "              --input=[conllu|horizontal|vertical]\n"
                    "              --outfile=output file template\n"
                    "              --output=[conllu|matxin|horizontal|vertical]\n"
                    "              --tokenize (perform tokenization)\n"
                    "              --tokenizer=tokenizer options, implies --tokenize\n"
                    "              --tag (perform tagging)\n"
                    "              --tagger=tagger options, implies --tag\n"
                    "              --parse (perform parsing)\n"
                    "              --parser=parser options, implies --parse\n"
                    "Training opts: --method=[morphodita_parsito] which method to use\n"
                    "               --heldout=heldout data file name\n"
                    "               --tokenizer=tokenizer options\n"
                    "               --tagger=tagger options\n"
                    "               --parser=parser options\n"
                    "Detokenize opts: --outfile=output file template\n"
                    "Generic opts: --version\n"
                    "              --help");
  if (options.count("version"))
    return cout << version::version_and_copyright() << endl, 0;

  // TRAINING
  if (options.count("train")) {
    string error;

    // Load training data
    cerr << "Loading training data: " << flush;
    vector<sentence> training;
    for (int i = 2; i < argc; i++) {
      ifstream input(argv[i]);
      if (!input.is_open()) runtime_failure("Cannot open input file '" << argv[i] << "'!");
      if (!append_conllu(input, training, error))
        runtime_failure("Cannot load training data from file '" << argv[i] << "': " << error);
    }
    if (argc == 2 && !append_conllu(cin, training, error)) runtime_failure("Cannot load training data: " << error);
    cerr << "done." << endl;

    // Load heldout data
    vector<sentence> heldout;
    if (options.count("heldout")) {
      ifstream input(options["heldout"]);
      if (!input.is_open()) runtime_failure("Cannot open heldout data file '" << options["heldout"] << "'!");
      if (!append_conllu(input, heldout, error))
        runtime_failure("Cannot load heldout data from file '" << options["heldout"] << "': " << error);
    }

    // Open output file
    ofstream model(argv[1], ofstream::binary);
    if (!model.is_open()) runtime_failure("Cannot open model file '" << argv[1] << "' for writing.");

    // Train the model
    cerr << "Training the UDPipe model." << endl;
    string method = options.count("method") ? options["method"] : "morphodita_parsito";
    if (!trainer::train(method, training, heldout, options["tokenizer"], options["tagger"], options["parser"], model, error))
      runtime_failure("An error occurred during model training: " << error);
    cerr << "The trained UDPipe model was saved." << endl;
  } else
  // DETOKENIZE
  if (options.count("detokenize")) {
    // Detokenize CoNLL-U files
    ifstream raw_text_file(argv[1]);
    if (!raw_text_file.is_open()) runtime_failure("Cannot load raw text from file '" << argv[1] << "'.");

    string raw_text;
    for (char c; raw_text_file.get(c); )
      raw_text.push_back(c);
    raw_text_file.close();

    detokenizer detokenizer(raw_text);
    process_args_with_output_template(2, argc, argv, options["outfile"], [&detokenizer](istream& is, ostream& os, string, string) {
      unique_ptr<input_format> conllu_input(input_format::new_conllu_input_format());
      unique_ptr<output_format> conllu_output(output_format::new_conllu_output_format());

      sentence s;
      string block, error;
      while (conllu_input->read_block(is, block)) {
        conllu_input->set_text(block);
        while (conllu_input->next_sentence(s, error)) {
          detokenizer.detokenize(s);
          conllu_output->write_sentence(s, os);
        }
        if (!error.empty()) runtime_failure("An error occurred during UDPipe execution: " << error);
      }
      conllu_output->finish_document(os);
    });
  } else
  // RUN
  {
    // Load the model if needed
    unique_ptr<model> model;
    if (options.count("tokenizer") || options.count("tokenize") ||
        options.count("tagger") || options.count("tag") ||
        options.count("parser") || options.count("parse")) {
      cerr << "Loading UDPipe model: " << flush;
      model.reset(model::load(argv[1]));
      if (!model) runtime_failure("Cannot load UDPipe model '" << argv[1] << "'!");
      cerr << "done." << endl;
    }

    if (options.count("accuracy")) {
      if (options.count("input")) runtime_failure("The --input option is unsupported when --accuracy is used!");
      if (options.count("output")) runtime_failure("The --output option is unsupported when --accuracy is used!");

      // Prepare the evaluator
      evaluator evaluator(model.get(), options.count("tokenizer") ? options["tokenizer"] : options.count("tokenize") ? pipeline::DEFAULT : pipeline::NONE,
                          options.count("tagger") ? options["tagger"] : options.count("tag") ? pipeline::DEFAULT : pipeline::NONE,
                          options.count("parser") ? options["parser"] : options.count("parse") ? pipeline::DEFAULT : pipeline::NONE);

      // Process the data
      process_args_with_output_template(2, argc, argv, options["outfile"], [&evaluator](istream& is, ostream& os, string, string) {
        string error;
        if (!evaluator.evaluate(is, os, error))
            runtime_failure("An error occurred during UDPipe execution: " << error);
      });
    } else {
      // Prepare the pipeline
      pipeline pipeline(model.get(), options.count("tokenizer") ? "tokenizer=" + options["tokenizer"] : options.count("tokenize") ? "tokenizer" : options.count("input") ? options["input"] : "conllu",
                        options.count("tagger") ? options["tagger"] : options.count("tag") ? pipeline::DEFAULT : pipeline::NONE,
                        options.count("parser") ? options["parser"] : options.count("parse") ? pipeline::DEFAULT : pipeline::NONE,
                        options.count("output") ? options["output"] : "conllu");

      // Process the data
      process_args_with_output_template(2, argc, argv, options["outfile"], [&pipeline](istream& is, ostream& os, string, string) {
        string error;
        if (!pipeline.process(is, os, error))
          runtime_failure("An error occurred during UDPipe execution: " << error);
      });
    }
  }

  return 0;
}
<|endoftext|>


<commit_before>/* writerperfect:
 *
 * Copyright (C) 2007 Fridrich Strba (fridrich.strba@bluewin.ch)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "OutputFileHelper.hxx"

#ifdef USE_GSF_OUTPUT
#include <gsf/gsf-utils.h>
#include <gsf/gsf-output-stdio.h>
#include <gsf/gsf-outfile.h>
#include <gsf/gsf-outfile-zip.h>
#include <gsf/gsf-input-stdio.h>
#else
#include "FemtoZip.hxx"
#endif

#include "DiskDocumentHandler.hxx"
#include "StdOutHandler.hxx"
#include <libwpd-stream/WPXStreamImplementation.h>

struct OutputFileHelperImpl
{
#ifdef USE_GSF_OUTPUT
	GsfOutfile *mpOutfile;
#else
	FemtoZip *mpOutfile;
#endif
};

OutputFileHelper::OutputFileHelper(const char* outFileName) :
#ifdef USE_GSF_OUTPUT
	m_impl(new OutputFileHelperImpl())
#else
	m_impl(new OutputFileHelperImpl())
#endif
{
	m_impl->mpOutfile = NULL;
#ifdef USE_GSF_OUTPUT
	GsfOutput  *pOutput = NULL;
	GError   *err = NULL;

	gsf_init ();

	if (!outFileName)
	        pOutput = NULL;
	else
	{
	        pOutput = GSF_OUTPUT(gsf_output_stdio_new (outFileName, &err));
	        if (pOutput == NULL) {
			if (err) {
	                	g_warning ("'%s' error: %s", outFileName, err->message);
	                        g_error_free (err);
			}
			gsf_shutdown ();
	        }
		else {
			if (err)
				g_error_free (err);
			err = NULL;
	        	m_impl->mpOutfile = GSF_OUTFILE(gsf_outfile_zip_new (pOutput, &err));
	        	if (m_impl->mpOutfile == NULL) {
				if (err) {
		                	g_warning ("'%s' error: %s",
						"gsf_outfile_zip_new", err->message);
	                        	g_error_free (err);
				}
				gsf_shutdown ();
			}
			else {
				if (err)
					g_error_free (err);
				err = NULL;
			        g_object_unref (pOutput);
			}
		}
	}
#else
	if (outFileName)
		m_impl->mpOutfile = new FemtoZip(outFileName);
#endif
}

OutputFileHelper::~OutputFileHelper()
{
#ifdef USE_GSF_OUTPUT
	if (m_impl->mpOutfile && !gsf_output_close ((GsfOutput *) m_impl->mpOutfile))
		fprintf(stderr, "ERROR : Couldn't close outfile\n");

	if (m_impl->mpOutfile)
	        g_object_unref (m_impl->mpOutfile);

	gsf_shutdown ();
#else
	if (m_impl->mpOutfile)
		delete m_impl->mpOutfile;
#endif
	if (m_impl)
		delete m_impl;
}

bool OutputFileHelper::writeChildFile(const char *childFileName, const char *str)
{
	if (!m_impl->mpOutfile)
		return true;
#ifdef USE_GSF_OUTPUT
	GsfOutput *child;
	if (NULL != (child = gsf_outfile_new_child  (m_impl->mpOutfile, childFileName, FALSE)))
	{
		bool res = gsf_output_puts (child, str) &&
			gsf_output_close (child);
		g_object_unref (child);
		return res;
	}
	return false;
#else
	m_impl->mpOutfile->createEntry(childFileName, 0);
	if (m_impl->mpOutfile->errorCode())
		return false;
	m_impl->mpOutfile->writeString(str);
	if (m_impl->mpOutfile->errorCode())
		return false;
	m_impl->mpOutfile->closeEntry();
	if (m_impl->mpOutfile->errorCode())
		return false;
	return true;
#endif
}

bool OutputFileHelper::writeChildFile(const char *childFileName, const char *str, const char compression_level)
{
	if (!m_impl->mpOutfile)
		return true;
#ifdef USE_GSF_OUTPUT
	GsfOutput *child;
#ifdef GSF_HAS_COMPRESSION_LEVEL
	if (NULL != (child = gsf_outfile_new_child_full  (m_impl->mpOutfile, childFileName, FALSE,"compression-level", compression_level, (void*)0)))
#else
	if (NULL != (child = gsf_outfile_new_child  (m_impl->mpOutfile, childFileName, FALSE)))
#endif
	{
		bool res = gsf_output_puts (child, str) &&
			gsf_output_close (child);
		g_object_unref (child);
		return res;
	}
	return false;
#else
	m_impl->mpOutfile->createEntry(childFileName, (int)compression_level);
	if (m_impl->mpOutfile->errorCode())
	    return false;
	m_impl->mpOutfile->writeString(str);
	if (m_impl->mpOutfile->errorCode())
	    return false;
	m_impl->mpOutfile->closeEntry();
	if (m_impl->mpOutfile->errorCode())
	    return false;
	return true;
#endif
}

bool OutputFileHelper::writeConvertedContent(const char *childFileName, const char *inFileName)
{
	WPXFileStream input(inFileName);

 	if (!_isSupportedFormat(&input))
 		return false;

	input.seek(0, WPX_SEEK_SET);

	DocumentHandler *pHandler;
	bool tmpIsFlatXML = true;
#ifdef USE_GSF_OUTPUT
	GsfOutput *pContentChild = NULL;
	if (m_impl->mpOutfile)
	{
	        pContentChild = gsf_outfile_new_child(m_impl->mpOutfile, childFileName, FALSE);
	        pHandler = new DiskDocumentHandler(pContentChild); // WLACH_REFACTORING: rename to DiskHandler
#else
	if (m_impl->mpOutfile)
	{
		m_impl->mpOutfile->createEntry(childFileName, 0);
		if (m_impl->mpOutfile->errorCode())
			return false;
		pHandler = new DiskDocumentHandler(m_impl->mpOutfile);
#endif
		tmpIsFlatXML = false;
	}
	else
	        pHandler = new StdOutHandler();

	bool bRetVal = _convertDocument(&input, pHandler, tmpIsFlatXML);

#ifdef USE_GSF_OUTPUT
	if (pContentChild)
	{
	        gsf_output_close(pContentChild);
	        g_object_unref(G_OBJECT (pContentChild));
	}

#else
	if (m_impl->mpOutfile)
		m_impl->mpOutfile->closeEntry();
#endif
	delete pHandler;

	return bRetVal;
}
<commit_msg>FemtoZip does not manage deflate, so use only storing<commit_after>/* writerperfect:
 *
 * Copyright (C) 2007 Fridrich Strba (fridrich.strba@bluewin.ch)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "OutputFileHelper.hxx"

#ifdef USE_GSF_OUTPUT
#include <gsf/gsf-utils.h>
#include <gsf/gsf-output-stdio.h>
#include <gsf/gsf-outfile.h>
#include <gsf/gsf-outfile-zip.h>
#include <gsf/gsf-input-stdio.h>
#else
#include "FemtoZip.hxx"
#endif

#include "DiskDocumentHandler.hxx"
#include "StdOutHandler.hxx"
#include <libwpd-stream/WPXStreamImplementation.h>

struct OutputFileHelperImpl
{
#ifdef USE_GSF_OUTPUT
	GsfOutfile *mpOutfile;
#else
	FemtoZip *mpOutfile;
#endif
};

OutputFileHelper::OutputFileHelper(const char* outFileName) :
#ifdef USE_GSF_OUTPUT
	m_impl(new OutputFileHelperImpl())
#else
	m_impl(new OutputFileHelperImpl())
#endif
{
	m_impl->mpOutfile = NULL;
#ifdef USE_GSF_OUTPUT
	GsfOutput  *pOutput = NULL;
	GError   *err = NULL;

	gsf_init ();

	if (!outFileName)
	        pOutput = NULL;
	else
	{
	        pOutput = GSF_OUTPUT(gsf_output_stdio_new (outFileName, &err));
	        if (pOutput == NULL) {
			if (err) {
	                	g_warning ("'%s' error: %s", outFileName, err->message);
	                        g_error_free (err);
			}
			gsf_shutdown ();
	        }
		else {
			if (err)
				g_error_free (err);
			err = NULL;
	        	m_impl->mpOutfile = GSF_OUTFILE(gsf_outfile_zip_new (pOutput, &err));
	        	if (m_impl->mpOutfile == NULL) {
				if (err) {
		                	g_warning ("'%s' error: %s",
						"gsf_outfile_zip_new", err->message);
	                        	g_error_free (err);
				}
				gsf_shutdown ();
			}
			else {
				if (err)
					g_error_free (err);
				err = NULL;
			        g_object_unref (pOutput);
			}
		}
	}
#else
	if (outFileName)
		m_impl->mpOutfile = new FemtoZip(outFileName);
#endif
}

OutputFileHelper::~OutputFileHelper()
{
#ifdef USE_GSF_OUTPUT
	if (m_impl->mpOutfile && !gsf_output_close ((GsfOutput *) m_impl->mpOutfile))
		fprintf(stderr, "ERROR : Couldn't close outfile\n");

	if (m_impl->mpOutfile)
	        g_object_unref (m_impl->mpOutfile);

	gsf_shutdown ();
#else
	if (m_impl->mpOutfile)
		delete m_impl->mpOutfile;
#endif
	if (m_impl)
		delete m_impl;
}

bool OutputFileHelper::writeChildFile(const char *childFileName, const char *str)
{
	if (!m_impl->mpOutfile)
		return true;
#ifdef USE_GSF_OUTPUT
	GsfOutput *child;
	if (NULL != (child = gsf_outfile_new_child  (m_impl->mpOutfile, childFileName, FALSE)))
	{
		bool res = gsf_output_puts (child, str) &&
			gsf_output_close (child);
		g_object_unref (child);
		return res;
	}
	return false;
#else
	m_impl->mpOutfile->createEntry(childFileName, 0);
	if (m_impl->mpOutfile->errorCode())
		return false;
	m_impl->mpOutfile->writeString(str);
	if (m_impl->mpOutfile->errorCode())
		return false;
	m_impl->mpOutfile->closeEntry();
	if (m_impl->mpOutfile->errorCode())
		return false;
	return true;
#endif
}

bool OutputFileHelper::writeChildFile(const char *childFileName, const char *str, const char compression_level)
{
	if (!m_impl->mpOutfile)
		return true;
#ifdef USE_GSF_OUTPUT
	GsfOutput *child;
#ifdef GSF_HAS_COMPRESSION_LEVEL
	if (NULL != (child = gsf_outfile_new_child_full  (m_impl->mpOutfile, childFileName, FALSE,"compression-level", compression_level, (void*)0)))
#else
	if (NULL != (child = gsf_outfile_new_child  (m_impl->mpOutfile, childFileName, FALSE)))
#endif
	{
		bool res = gsf_output_puts (child, str) &&
			gsf_output_close (child);
		g_object_unref (child);
		return res;
	}
	return false;
#else
	m_impl->mpOutfile->createEntry(childFileName, 0); // only storing without compressing works with FemtoZip
	if (m_impl->mpOutfile->errorCode())
	    return false;
	m_impl->mpOutfile->writeString(str);
	if (m_impl->mpOutfile->errorCode())
	    return false;
	m_impl->mpOutfile->closeEntry();
	if (m_impl->mpOutfile->errorCode())
	    return false;
	return true;
#endif
}

bool OutputFileHelper::writeConvertedContent(const char *childFileName, const char *inFileName)
{
	WPXFileStream input(inFileName);

 	if (!_isSupportedFormat(&input))
 		return false;

	input.seek(0, WPX_SEEK_SET);

	DocumentHandler *pHandler;
	bool tmpIsFlatXML = true;
#ifdef USE_GSF_OUTPUT
	GsfOutput *pContentChild = NULL;
	if (m_impl->mpOutfile)
	{
	        pContentChild = gsf_outfile_new_child(m_impl->mpOutfile, childFileName, FALSE);
	        pHandler = new DiskDocumentHandler(pContentChild); // WLACH_REFACTORING: rename to DiskHandler
#else
	if (m_impl->mpOutfile)
	{
		m_impl->mpOutfile->createEntry(childFileName, 0);
		if (m_impl->mpOutfile->errorCode())
			return false;
		pHandler = new DiskDocumentHandler(m_impl->mpOutfile);
#endif
		tmpIsFlatXML = false;
	}
	else
	        pHandler = new StdOutHandler();

	bool bRetVal = _convertDocument(&input, pHandler, tmpIsFlatXML);

#ifdef USE_GSF_OUTPUT
	if (pContentChild)
	{
	        gsf_output_close(pContentChild);
	        g_object_unref(G_OBJECT (pContentChild));
	}

#else
	if (m_impl->mpOutfile)
		m_impl->mpOutfile->closeEntry();
#endif
	delete pHandler;

	return bRetVal;
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief V8 Traverser
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014-2015 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Michael Hackstein
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "v8.h"
#include "V8/v8-conv.h"
#include "V8/v8-utils.h"
#include "V8Server/v8-vocbaseprivate.h"
#include "V8Server/v8-wrapshapedjson.h"
#include "V8Server/v8-vocindex.h"
#include "V8Server/v8-collection.h"
#include "Utils/transactions.h"
#include "Utils/V8ResolverGuard.h"
#include "Utils/CollectionNameResolver.h"
#include "VocBase/document-collection.h"
#include "Traverser.h"
#include "VocBase/key-generator.h"

using namespace std;
using namespace triagens::basics;
using namespace triagens::arango;

struct WeightInfo {
  string keyWeight;
  double defaultWeight;
  bool usesWeight;

  WeightInfo(
    string keyWeight,
    double defaultWeight
  ) :
    keyWeight(keyWeight), defaultWeight(defaultWeight), usesWeight(true)
  {
  };

  WeightInfo() : usesWeight(false) {
  };

};

class SimpleEdgeExpander {

  private:
////////////////////////////////////////////////////////////////////////////////
/// @brief direction of expansion
////////////////////////////////////////////////////////////////////////////////

    TRI_edge_direction_e direction;

////////////////////////////////////////////////////////////////////////////////
/// @brief edge collection
////////////////////////////////////////////////////////////////////////////////

    TRI_document_collection_t* edgeCollection;

////////////////////////////////////////////////////////////////////////////////
/// @brief collection name and /
////////////////////////////////////////////////////////////////////////////////

    string edgeIdPrefix;

////////////////////////////////////////////////////////////////////////////////
/// @brief the collection name resolver
////////////////////////////////////////////////////////////////////////////////

    CollectionNameResolver* resolver;

////////////////////////////////////////////////////////////////////////////////
/// @brief this is the information required to compute weight by a given
///        attribute. It contains an indicator if weight should be used.
///        Also it includes a default weight and the name of the weight
///        attribute.
////////////////////////////////////////////////////////////////////////////////

    WeightInfo weightInfo;

  public:

    SimpleEdgeExpander(TRI_edge_direction_e direction,
                       TRI_document_collection_t* edgeCollection,
                       string edgeCollectionName,
                       CollectionNameResolver* resolver)
      : direction(direction), edgeCollection(edgeCollection),
        resolver(resolver)
    {
      edgeIdPrefix = edgeCollectionName + "/";
    };

    SimpleEdgeExpander(TRI_edge_direction_e direction,
                       TRI_document_collection_t* edgeCollection,
                       string edgeCollectionName,
                       CollectionNameResolver* resolver,
                       WeightInfo weightInfo)
      : direction(direction), edgeCollection(edgeCollection),
        resolver(resolver), weightInfo(weightInfo)
    {
      edgeIdPrefix = edgeCollectionName + "/";
    };

    Traverser::VertexId extractFromId(TRI_doc_mptr_copy_t& ptr) {
      char const* key = TRI_EXTRACT_MARKER_FROM_KEY(&ptr);
      TRI_voc_cid_t cid = TRI_EXTRACT_MARKER_FROM_CID(&ptr);
      string col = resolver->getCollectionName(cid);
      col.append("/");
      col.append(key);
      return col;
    };

    Traverser::VertexId extractToId(TRI_doc_mptr_copy_t& ptr) {
      char const* key = TRI_EXTRACT_MARKER_TO_KEY(&ptr);
      TRI_voc_cid_t cid = TRI_EXTRACT_MARKER_TO_CID(&ptr);
      string col = resolver->getCollectionName(cid);
      col.append("/");
      col.append(key);
      return col;
    };

    Traverser::EdgeId extractEdgeId(TRI_doc_mptr_copy_t ptr) {
      char const* key = TRI_EXTRACT_MARKER_KEY(ptr);
      // AppendAndCopy
      return edgeIdPrefix.append(key);
    };

    void operator() (Traverser::VertexId source,
                     vector<Traverser::Step>& result) {
      std::vector<TRI_doc_mptr_copy_t> edges;
      TransactionBase fake(true); // Fake a transaction to please checks.
                                  // This is due to multi-threading

      // Process Vertex Id!
      size_t split;
      char const* str = source.c_str();
      if (!TRI_ValidateDocumentIdKeyGenerator(str, &split)) {
        // TODO Error Handling
        return;
      }
      string collectionName = source.substr(0, split);

      auto col = resolver->getCollectionStruct(collectionName);
      if (col == nullptr) {
        // collection not found
        throw TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
      }
      auto collectionCId = col->_cid;
      edges = TRI_LookupEdgesDocumentCollection(edgeCollection, direction, collectionCId, const_cast<char*>(str + split + 1));

      unordered_map<Traverser::VertexId, size_t> candidates;
      Traverser::VertexId from;
      Traverser::VertexId to;
      if (weightInfo.usesWeight) {
        for (size_t j = 0;  j < edges.size(); ++j) {
          from = extractFromId(edges[j]);
          to = extractToId(edges[j]);
          double currentWeight = weightInfo.defaultWeight;
          if (from != source) {
            auto cand = candidates.find(from);
            if (cand == candidates.end()) {
              // Add weight
              result.emplace_back(to, from, currentWeight, extractEdgeId(edges[j]));
              candidates.emplace(from, result.size() - 1);
            } else {
              // Compare weight
              auto oldWeight = result[cand->second].weight();
              if (currentWeight < oldWeight) {
                result[cand->second].setWeight(currentWeight);
              }
            }
          }
          else if (to != source) {
            auto cand = candidates.find(to);
            if (cand == candidates.end()) {
              // Add weight
              result.emplace_back(to, from, currentWeight, extractEdgeId(edges[j]));
              candidates.emplace(to, result.size() - 1);
            } else {
              auto oldWeight = result[cand->second].weight();
              if (currentWeight < oldWeight) {
                result[cand->second].setWeight(currentWeight);
              }
            }
          }
        }
      }
      else {
        for (size_t j = 0;  j < edges.size();  ++j) {
          from = extractFromId(edges[j]);
          to = extractFromId(edges[j]);
          if (from != source) {
            auto cand = candidates.find(from);
            if (cand == candidates.end()) {
              result.emplace_back(from, to, 1, extractEdgeId(edges[j]));
              candidates.emplace(from, result.size()-1);
            }
          }
          else if (to != source) {
            auto cand = candidates.find(to);
            if (cand == candidates.end()) {
              result.emplace_back(to, from, 1, extractEdgeId(edges[j]));
              candidates.emplace(to, result.size()-1);
            }
          }
        }
      }
    }
};

static v8::Handle<v8::Value> pathIdsToV8(v8::Isolate* isolate, Traverser::Path& p) {
  v8::EscapableHandleScope scope(isolate);
  v8::Handle<v8::Object> result = v8::Object::New(isolate);

  uint32_t const vn = static_cast<uint32_t>(p.vertices.size());
  v8::Handle<v8::Array> vertices = v8::Array::New(isolate, static_cast<int>(vn));

  for (size_t j = 0;  j < vn;  ++j) {
    vertices->Set(static_cast<uint32_t>(j), TRI_V8_ASCII_STRING(p.vertices[j]));
  }
  result->Set("vertices", vertices);

  uint32_t const en = static_cast<uint32_t>(p.edges.size());
  v8::Handle<v8::Array> edges = v8::Array::New(isolate, static_cast<int>(en));

  for (size_t j = 0;  j < en;  ++j) {
    edges->Set(static_cast<uint32_t>(j), TRI_V8_ASCII_STRING(p.edges[j]));
  }
  result->Set(TRI_V8_STRING("edges"), edges);
  result->Set(TRI_V8_STRING("distance"), v8::Number::New(isolate, p.weight));

  return result;
};

struct LocalCollectionGuard {
  LocalCollectionGuard (TRI_vocbase_col_t* collection)
    : _collection(collection) {
  }

  ~LocalCollectionGuard () {
    if (_collection != nullptr && ! _collection->_isLocal) {
      FreeCoordinatorCollection(_collection);
    }
  }

  TRI_vocbase_col_t* _collection;
};

void TRI_RunDijkstraSearch (const v8::FunctionCallbackInfo<v8::Value>& args) {
  v8::Isolate* isolate = args.GetIsolate();
  v8::HandleScope scope(isolate);

  if (args.Length() < 4 || args.Length() > 5) {
    TRI_V8_THROW_EXCEPTION_USAGE("AQL_SHORTEST_PATH(<vertexcollection>, <edgecollection>, <start>, <end>, <options>)");
  }

  std::unique_ptr<char[]> key;
  TRI_vocbase_t* vocbase;
  TRI_vocbase_col_t const* col = nullptr;

  vocbase = GetContextVocBase(isolate);

  vector<string> readCollections;
  vector<string> writeCollections;
  TRI_voc_cid_t vertexCollectionCId;
  TRI_voc_cid_t edgeCollectionCId;
  TRI_voc_rid_t rid;

  double lockTimeout = (double) (TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT / 1000000ULL);
  bool embed = false;
  bool waitForSync = false;

  // get the vertex collection
  if (! args[0]->IsString()) {
    TRI_V8_THROW_TYPE_ERROR("expecting string for <vertexcollection>");
  }
  string vertexCollectionName = TRI_ObjectToString(args[0]);

  // get the edge collection
  if (! args[1]->IsString()) {
    TRI_V8_THROW_TYPE_ERROR("expecting string for <edgecollection>");
  }
  string const edgeCollectionName = TRI_ObjectToString(args[1]);

  vocbase = GetContextVocBase(isolate);

  if (vocbase == nullptr) {
    TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
  }
  V8ResolverGuard resolver(vocbase);

  readCollections.push_back(vertexCollectionName);
  readCollections.push_back(edgeCollectionName);

  if (! args[2]->IsString()) {
    TRI_V8_THROW_TYPE_ERROR("expecting string for <startVertex>");
  }

  string direction = "outbound";
  bool useWeight = false;
  string weightAttribute = "";
  double defaultWeight = 1;
  bool bidirectional = true;

  if (args.Length() == 5) {
    if (! args[4]->IsObject()) {
      TRI_V8_THROW_TYPE_ERROR("expecting json for <options>");
    }
    v8::Handle<v8::Object> options = args[4]->ToObject();
    v8::Local<v8::String> keyDirection = TRI_V8_ASCII_STRING("direction");
    v8::Local<v8::String> keyWeight= TRI_V8_ASCII_STRING("distance");
    v8::Local<v8::String> keyDefaultWeight= TRI_V8_ASCII_STRING("defaultDistance");

    if (options->Has(keyDirection) ) {
      direction = TRI_ObjectToString(options->Get(keyDirection));
      if (   direction != "outbound"
          && direction != "inbound"
          && direction != "any"
         ) {
        TRI_V8_THROW_TYPE_ERROR("expecting direction to be 'outbound', 'inbound' or 'any'");
      }
    }
    if (options->Has(keyWeight) && options->Has(keyDefaultWeight) ) {
      useWeight = true;
      weightAttribute = TRI_ObjectToString(options->Get(keyWeight));
      defaultWeight = TRI_ObjectToDouble(options->Get(keyDefaultWeight));
    }
    v8::Local<v8::String> keyBidirectional = TRI_V8_ASCII_STRING("bidirectional");
    if (options->Has(keyBidirectional)) {
      bidirectional = TRI_ObjectToBoolean(options->Get(keyBidirectional));
    }
  }

  // IHHF isCoordinator

  // Start Transaction to collect all parts of the path
  ExplicitTransaction trx(
    vocbase,
    readCollections,
    writeCollections,
    lockTimeout,
    waitForSync,
    embed
  );

  int res = trx.begin();

  if (res != TRI_ERROR_NO_ERROR) {
    TRI_V8_THROW_EXCEPTION(res);
  }

  col = resolver.getResolver()->getCollectionStruct(vertexCollectionName);
  if (col == nullptr) {
    // collection not found
    TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
  }
  vertexCollectionCId = col->_cid;
  if (trx.orderBarrier(trx.trxCollection(col->_cid)) == nullptr) {
    TRI_V8_THROW_EXCEPTION_MEMORY();
  }

  col = resolver.getResolver()->getCollectionStruct(edgeCollectionName);
  if (col == nullptr) {
    // collection not found
    TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
  }
  edgeCollectionCId = col->_cid;
  if (trx.orderBarrier(trx.trxCollection(col->_cid)) == nullptr) {
    TRI_V8_THROW_EXCEPTION_MEMORY();
  }

  TRI_document_collection_t* ecol = trx.trxCollection(col->_cid)->_collection->_collection;
  CollectionNameResolver resolver1(vocbase);
  CollectionNameResolver resolver2(vocbase);
  TRI_edge_direction_e forward;
  TRI_edge_direction_e backward;
  if (direction == "outbound") {
    forward = TRI_EDGE_OUT;
    backward = TRI_EDGE_IN;
  } else if (direction == "inbound") {
    forward = TRI_EDGE_IN;
    backward = TRI_EDGE_OUT;
  } else {
    forward = TRI_EDGE_ANY;
    backward = TRI_EDGE_ANY;
  }

  unique_ptr<SimpleEdgeExpander> forwardExpander;
  unique_ptr<SimpleEdgeExpander> backwardExpander;
  if (useWeight) {
    forwardExpander.reset(new SimpleEdgeExpander(forward, ecol, edgeCollectionName,
                                                 &resolver1, WeightInfo(weightAttribute, defaultWeight)));
    backwardExpander.reset(new SimpleEdgeExpander(backward, ecol, edgeCollectionName,
                                                 &resolver2, WeightInfo(weightAttribute, defaultWeight)));
  } else {
    forwardExpander.reset(new SimpleEdgeExpander(forward, ecol, edgeCollectionName, &resolver1));
    backwardExpander.reset(new SimpleEdgeExpander(backward, ecol, edgeCollectionName, &resolver2));
  }

  Traverser traverser(*forwardExpander, *backwardExpander, bidirectional);
  unique_ptr<Traverser::Path> path(traverser.shortestPath(startVertex, targetVertex));
  if (path.get() == nullptr) {
    res = trx.finish(res);
    v8::EscapableHandleScope scope(isolate);
    TRI_V8_RETURN(scope.Escape<v8::Value>(v8::Object::New(isolate)));
  }
  auto result = pathIdsToV8(isolate, *path);
  res = trx.finish(res);

  TRI_V8_RETURN(result);
}
<commit_msg>Rebase cleanup<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief V8 Traverser
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014-2015 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Michael Hackstein
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "v8.h"
#include "V8/v8-conv.h"
#include "V8/v8-utils.h"
#include "V8Server/v8-vocbaseprivate.h"
#include "V8Server/v8-wrapshapedjson.h"
#include "V8Server/v8-vocindex.h"
#include "V8Server/v8-collection.h"
#include "Utils/transactions.h"
#include "Utils/V8ResolverGuard.h"
#include "Utils/CollectionNameResolver.h"
#include "VocBase/document-collection.h"
#include "Traverser.h"
#include "VocBase/key-generator.h"

using namespace std;
using namespace triagens::basics;
using namespace triagens::arango;

struct WeightInfo {
  string keyWeight;
  double defaultWeight;
  bool usesWeight;

  WeightInfo(
    string keyWeight,
    double defaultWeight
  ) :
    keyWeight(keyWeight), defaultWeight(defaultWeight), usesWeight(true)
  {
  };

  WeightInfo() : usesWeight(false) {
  };

};

class SimpleEdgeExpander {

////////////////////////////////////////////////////////////////////////////////
/// @brief direction of expansion
////////////////////////////////////////////////////////////////////////////////

    TRI_edge_direction_e direction;

////////////////////////////////////////////////////////////////////////////////
/// @brief edge collection
////////////////////////////////////////////////////////////////////////////////

    TRI_document_collection_t* edgeCollection;

////////////////////////////////////////////////////////////////////////////////
/// @brief collection name and /
////////////////////////////////////////////////////////////////////////////////

    string edgeIdPrefix;

////////////////////////////////////////////////////////////////////////////////
/// @brief the collection name resolver
////////////////////////////////////////////////////////////////////////////////

    CollectionNameResolver* resolver;

////////////////////////////////////////////////////////////////////////////////
/// @brief this is the information required to compute weight by a given
///        attribute. It contains an indicator if weight should be used.
///        Also it includes a default weight and the name of the weight
///        attribute.
////////////////////////////////////////////////////////////////////////////////

    WeightInfo weightInfo;

  public:

    SimpleEdgeExpander(TRI_edge_direction_e direction,
                       TRI_document_collection_t* edgeCollection,
                       string edgeCollectionName,
                       CollectionNameResolver* resolver)
      : direction(direction), edgeCollection(edgeCollection),
        resolver(resolver)
    {
      edgeIdPrefix = edgeCollectionName + "/";
    };

    SimpleEdgeExpander(TRI_edge_direction_e direction,
                       TRI_document_collection_t* edgeCollection,
                       string edgeCollectionName,
                       CollectionNameResolver* resolver,
                       WeightInfo weightInfo)
      : direction(direction), edgeCollection(edgeCollection),
        resolver(resolver), weightInfo(weightInfo)
    {
      edgeIdPrefix = edgeCollectionName + "/";
    };

    Traverser::VertexId extractFromId(TRI_doc_mptr_copy_t& ptr) {
      char const* key = TRI_EXTRACT_MARKER_FROM_KEY(&ptr);
      TRI_voc_cid_t cid = TRI_EXTRACT_MARKER_FROM_CID(&ptr);
      string col = resolver->getCollectionName(cid);
      col.append("/");
      col.append(key);
      return col;
    };

    Traverser::VertexId extractToId(TRI_doc_mptr_copy_t& ptr) {
      char const* key = TRI_EXTRACT_MARKER_TO_KEY(&ptr);
      TRI_voc_cid_t cid = TRI_EXTRACT_MARKER_TO_CID(&ptr);
      string col = resolver->getCollectionName(cid);
      col.append("/");
      col.append(key);
      return col;
    };

    Traverser::EdgeId extractEdgeId(TRI_doc_mptr_copy_t& ptr) {
      char const* key = TRI_EXTRACT_MARKER_KEY(&ptr);
      return edgeIdPrefix + key;
    };

    void operator() (Traverser::VertexId source,
                     vector<Traverser::Step>& result) {
      std::vector<TRI_doc_mptr_copy_t> edges;
      TransactionBase fake(true); // Fake a transaction to please checks.
                                  // This is due to multi-threading

      // Process Vertex Id!
      size_t split;
      char const* str = source.c_str();
      if (!TRI_ValidateDocumentIdKeyGenerator(str, &split)) {
        // TODO Error Handling
        return;
      }
      string collectionName = source.substr(0, split);

      auto col = resolver->getCollectionStruct(collectionName);
      if (col == nullptr) {
        // collection not found
        throw TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND;
      }
      auto collectionCId = col->_cid;
      edges = TRI_LookupEdgesDocumentCollection(edgeCollection, direction, collectionCId, const_cast<char*>(str + split + 1));

      unordered_map<Traverser::VertexId, size_t> candidates;
      Traverser::VertexId from;
      Traverser::VertexId to;
      if (weightInfo.usesWeight) {
        for (size_t j = 0;  j < edges.size(); ++j) {
          from = extractFromId(edges[j]);
          to = extractToId(edges[j]);
          double currentWeight = weightInfo.defaultWeight;
          if (from != source) {
            auto cand = candidates.find(from);
            if (cand == candidates.end()) {
              // Add weight
              result.emplace_back(to, from, currentWeight, extractEdgeId(edges[j]));
              candidates.emplace(from, result.size() - 1);
            } else {
              // Compare weight
              auto oldWeight = result[cand->second].weight();
              if (currentWeight < oldWeight) {
                result[cand->second].setWeight(currentWeight);
              }
            }
          }
          else if (to != source) {
            auto cand = candidates.find(to);
            if (cand == candidates.end()) {
              // Add weight
              result.emplace_back(to, from, currentWeight, extractEdgeId(edges[j]));
              candidates.emplace(to, result.size() - 1);
            } else {
              auto oldWeight = result[cand->second].weight();
              if (currentWeight < oldWeight) {
                result[cand->second].setWeight(currentWeight);
              }
            }
          }
        }
      }
      else {
        for (size_t j = 0;  j < edges.size();  ++j) {
          from = extractFromId(edges[j]);
          to = extractToId(edges[j]);
          if (from != source) {
            auto cand = candidates.find(from);
            if (cand == candidates.end()) {
              result.emplace_back(from, to, 1, extractEdgeId(edges[j]));
              candidates.emplace(from, result.size()-1);
            }
          }
          else if (to != source) {
            auto cand = candidates.find(to);
            if (cand == candidates.end()) {
              result.emplace_back(to, from, 1, extractEdgeId(edges[j]));
              candidates.emplace(to, result.size()-1);
            }
          }
        }
      }
    }
};

static v8::Handle<v8::Value> pathIdsToV8(v8::Isolate* isolate, Traverser::Path& p) {
  v8::EscapableHandleScope scope(isolate);
  v8::Handle<v8::Object> result = v8::Object::New(isolate);

  uint32_t const vn = static_cast<uint32_t>(p.vertices.size());
  v8::Handle<v8::Array> vertices = v8::Array::New(isolate, static_cast<int>(vn));

  for (size_t j = 0;  j < vn;  ++j) {
    vertices->Set(static_cast<uint32_t>(j), TRI_V8_STRING(p.vertices[j].c_str()));
  }
  result->Set(TRI_V8_STRING("vertices"), vertices);

  uint32_t const en = static_cast<uint32_t>(p.edges.size());
  v8::Handle<v8::Array> edges = v8::Array::New(isolate, static_cast<int>(en));

  for (size_t j = 0;  j < en;  ++j) {
    edges->Set(static_cast<uint32_t>(j), TRI_V8_STRING(p.edges[j].c_str()));
  }
  result->Set(TRI_V8_STRING("edges"), edges);
  result->Set(TRI_V8_STRING("distance"), v8::Number::New(isolate, p.weight));

  return scope.Escape<v8::Value>(result);
};

struct LocalCollectionGuard {
  LocalCollectionGuard (TRI_vocbase_col_t* collection)
    : _collection(collection) {
  }

  ~LocalCollectionGuard () {
    if (_collection != nullptr && ! _collection->_isLocal) {
      FreeCoordinatorCollection(_collection);
    }
  }

  TRI_vocbase_col_t* _collection;
};

void TRI_RunDijkstraSearch (const v8::FunctionCallbackInfo<v8::Value>& args) {
  v8::Isolate* isolate = args.GetIsolate();
  v8::HandleScope scope(isolate);

  if (args.Length() < 4 || args.Length() > 5) {
    TRI_V8_THROW_EXCEPTION_USAGE("AQL_SHORTEST_PATH(<vertexcollection>, <edgecollection>, <start>, <end>, <options>)");
  }

  std::unique_ptr<char[]> key;
  TRI_vocbase_t* vocbase;
  TRI_vocbase_col_t const* col = nullptr;

  vocbase = GetContextVocBase(isolate);

  vector<string> readCollections;
  vector<string> writeCollections;

  double lockTimeout = (double) (TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT / 1000000ULL);
  bool embed = false;
  bool waitForSync = false;

  // get the vertex collection
  if (! args[0]->IsString()) {
    TRI_V8_THROW_TYPE_ERROR("expecting string for <vertexcollection>");
  }
  string vertexCollectionName = TRI_ObjectToString(args[0]);

  // get the edge collection
  if (! args[1]->IsString()) {
    TRI_V8_THROW_TYPE_ERROR("expecting string for <edgecollection>");
  }
  string const edgeCollectionName = TRI_ObjectToString(args[1]);

  vocbase = GetContextVocBase(isolate);

  if (vocbase == nullptr) {
    TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_DATABASE_NOT_FOUND);
  }
  V8ResolverGuard resolver(vocbase);

  readCollections.push_back(vertexCollectionName);
  readCollections.push_back(edgeCollectionName);

  if (! args[2]->IsString()) {
    TRI_V8_THROW_TYPE_ERROR("expecting string for <startVertex>");
  }
  string const startVertex = TRI_ObjectToString(args[2]);

  if (! args[3]->IsString()) {
    TRI_V8_THROW_TYPE_ERROR("expecting string for <targetVertex>");
  }
  string const targetVertex = TRI_ObjectToString(args[3]);

  string direction = "outbound";
  bool useWeight = false;
  string weightAttribute = "";
  double defaultWeight = 1;
  bool bidirectional = true;

  if (args.Length() == 5) {
    if (! args[4]->IsObject()) {
      TRI_V8_THROW_TYPE_ERROR("expecting json for <options>");
    }
    v8::Handle<v8::Object> options = args[4]->ToObject();
    v8::Local<v8::String> keyDirection = TRI_V8_ASCII_STRING("direction");
    v8::Local<v8::String> keyWeight= TRI_V8_ASCII_STRING("distance");
    v8::Local<v8::String> keyDefaultWeight= TRI_V8_ASCII_STRING("defaultDistance");

    if (options->Has(keyDirection) ) {
      direction = TRI_ObjectToString(options->Get(keyDirection));
      if (   direction != "outbound"
          && direction != "inbound"
          && direction != "any"
         ) {
        TRI_V8_THROW_TYPE_ERROR("expecting direction to be 'outbound', 'inbound' or 'any'");
      }
    }
    if (options->Has(keyWeight) && options->Has(keyDefaultWeight) ) {
      useWeight = true;
      weightAttribute = TRI_ObjectToString(options->Get(keyWeight));
      defaultWeight = TRI_ObjectToDouble(options->Get(keyDefaultWeight));
    }
    v8::Local<v8::String> keyBidirectional = TRI_V8_ASCII_STRING("bidirectional");
    if (options->Has(keyBidirectional)) {
      bidirectional = TRI_ObjectToBoolean(options->Get(keyBidirectional));
    }
  }

  // IHHF isCoordinator

  // Start Transaction to collect all parts of the path
  ExplicitTransaction trx(
    vocbase,
    readCollections,
    writeCollections,
    lockTimeout,
    waitForSync,
    embed
  );

  int res = trx.begin();

  if (res != TRI_ERROR_NO_ERROR) {
    TRI_V8_THROW_EXCEPTION(res);
  }

  col = resolver.getResolver()->getCollectionStruct(vertexCollectionName);
  if (col == nullptr) {
    // collection not found
    TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
  }

  if (trx.orderBarrier(trx.trxCollection(col->_cid)) == nullptr) {
    TRI_V8_THROW_EXCEPTION_MEMORY();
  }

  col = resolver.getResolver()->getCollectionStruct(edgeCollectionName);
  if (col == nullptr) {
    // collection not found
    TRI_V8_THROW_EXCEPTION(TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND);
  }

  if (trx.orderBarrier(trx.trxCollection(col->_cid)) == nullptr) {
    TRI_V8_THROW_EXCEPTION_MEMORY();
  }

  TRI_document_collection_t* ecol = trx.trxCollection(col->_cid)->_collection->_collection;
  CollectionNameResolver resolver1(vocbase);
  CollectionNameResolver resolver2(vocbase);
  TRI_edge_direction_e forward;
  TRI_edge_direction_e backward;
  if (direction == "outbound") {
    forward = TRI_EDGE_OUT;
    backward = TRI_EDGE_IN;
  } else if (direction == "inbound") {
    forward = TRI_EDGE_IN;
    backward = TRI_EDGE_OUT;
  } else {
    forward = TRI_EDGE_ANY;
    backward = TRI_EDGE_ANY;
  }

  unique_ptr<SimpleEdgeExpander> forwardExpander;
  unique_ptr<SimpleEdgeExpander> backwardExpander;
  if (useWeight) {
    forwardExpander.reset(new SimpleEdgeExpander(forward, ecol, edgeCollectionName,
                                                 &resolver1, WeightInfo(weightAttribute, defaultWeight)));
    backwardExpander.reset(new SimpleEdgeExpander(backward, ecol, edgeCollectionName,
                                                 &resolver2, WeightInfo(weightAttribute, defaultWeight)));
  } else {
    forwardExpander.reset(new SimpleEdgeExpander(forward, ecol, edgeCollectionName, &resolver1));
    backwardExpander.reset(new SimpleEdgeExpander(backward, ecol, edgeCollectionName, &resolver2));
  }

  Traverser traverser(*forwardExpander, *backwardExpander, bidirectional);
  unique_ptr<Traverser::Path> path(traverser.shortestPath(startVertex, targetVertex));
  if (path.get() == nullptr) {
    res = trx.finish(res);
    v8::EscapableHandleScope scope(isolate);
    TRI_V8_RETURN(scope.Escape<v8::Value>(v8::Object::New(isolate)));
  }
  auto result = pathIdsToV8(isolate, *path);
  res = trx.finish(res);

  TRI_V8_RETURN(result);
}
<|endoftext|>


<commit_before>#include "uiTags.h"

uiTags::uiTags(Gtk::Window *parent)
{
	m_parent = parent;
    this->signal_expose_event().connect(sigc::mem_fun(*this, &uiTags::on_uiTags_expose_event) );
    m_AddNew.signal_clicked().connect(sigc::mem_fun(*this, &uiTags::on_addnew_clicked) );
	m_AddNew.set_label("+Tag");
	this->put(m_AddNew, 5, 10);
	m_AddNew.set_sensitive(false);
}

uiTags::~uiTags() {}

void uiTags::set_parent(Gtk::Window* parent)
{
	m_parent = parent;
}

std::vector<Glib::ustring> uiTags::tags()
{
	return m_tags;
}

void uiTags::tags(std::vector<Glib::ustring> tags)
{
	m_tags = tags;
	m_AddNew.set_sensitive(true);

	for(unsigned int i = 0; i < m_tag_widgets.size(); i++)
		delete m_tag_widgets[i];

	m_tag_widgets.clear();

	for(unsigned int i = 0; i < m_tags.size(); i++)
		m_tag_widgets.push_back(new Tag(m_tags[i]));

	for(unsigned int i = 0; i < m_tag_widgets.size(); i++)
		m_tag_widgets[i]->signal_deleted().connect(sigc::mem_fun(*this, &uiTags::on_tag_deleted) );

	needput = true;
	active = true;
	redraw();
}

void uiTags::clear()
{
	for(unsigned int i = 0; i < m_tag_widgets.size(); i++)
		delete m_tag_widgets[i];

	m_tag_widgets.clear();
	m_tags.clear();
	m_AddNew.set_sensitive(false);
}

uiTags::type_signal_added uiTags::signal_added()
{
	return m_signal_added;
}

uiTags::type_signal_deleted uiTags::signal_deleted()
{
	return m_signal_deleted;
}

void uiTags::on_tag_deleted(Glib::ustring tag)
{
	Gtk::Dialog dialog("Are you sure?", true);
	dialog.set_transient_for(*m_parent);
	dialog.set_resizable(false);
	dialog.add_button(Gtk::Stock::NO, Gtk::RESPONSE_CANCEL);
	dialog.add_button(Gtk::Stock::YES, Gtk::RESPONSE_OK);
	Gtk::Label label("Are you sure you want to delete this tag?");
	dialog.get_vbox()->pack_start(label,true,true);
	Gtk::Label label_tag(""+tag+"");
	label_tag.set_use_markup(true);
	dialog.get_vbox()->pack_start(label_tag,true,true);
	dialog.show_all_children();
	int result = dialog.run();

	switch (result) {
		case (Gtk::RESPONSE_OK):
			m_signal_deleted.emit(tag);
			break;
	}

}

void uiTags::on_addnew_clicked()
{
	if (m_parent == NULL) {
		return;
	}

	Gtk::Dialog dialog("Add Tag", true);
	dialog.set_transient_for(*m_parent);
	dialog.set_resizable(false);
	dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
	dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
	Gtk::Label label("Enter the new tag:");
	dialog.get_vbox()->pack_start(label,true,true);
	Gtk::Entry entry;
	dialog.get_vbox()->pack_start(entry,true,true);
	dialog.show_all_children();
	int result = dialog.run();

	switch (result) {
		case (Gtk::RESPONSE_OK):
			Glib::ustring t = entry.get_text();
			if (t != "") {
				if (m_signal_added.emit(t)) {
					m_tags.push_back(t);
					tags(m_tags);
					redraw();
				}
			}
			break;
	}

}

bool uiTags::on_uiTags_expose_event(GdkEventExpose* /*e*/)
{
	redraw();
	return false;
}

void uiTags::redraw()
{
	if (active) m_AddNew.show();

	if (m_tags.empty()) return;
	const int spacing = 5;
	int x=spacing;
	int y=spacing;
	int w,h;
	int width = this->get_width();
	Gtk::Requisition rec = m_AddNew.size_request();
	x += rec.width;
	for(unsigned int i = 0; i < m_tag_widgets.size(); i++)
	{
		m_tag_widgets[i]->show();
		rec = m_tag_widgets[i]->size_request();
		w = rec.width;
		h = rec.height;
		if (x > 0 && x+w > width) { x = spacing; y += h+spacing; }
		if (needput) this->put(*m_tag_widgets[i],x,y);
		else this->move(*m_tag_widgets[i],x,y);
		x += w+spacing;
	}
	needput = false;
}

uiTags::Tag::Tag(Glib::ustring tag)
{
	this->add(m_frame);
	m_Value.set_text(tag);
	m_Close.set_label("X");
	m_Close.set_relief(Gtk::RELIEF_NONE);
    m_Close.signal_clicked().connect(sigc::mem_fun(*this, &uiTags::Tag::on_delete_clicked) );

	m_hbox.pack_start(m_Close, false, false);
	m_hbox.pack_start(m_Value, false, false);
	m_frame.add(m_hbox);
	m_frame.set_shadow_type(Gtk::SHADOW_NONE);
	m_frame.set_border_width(2);
	show_all_children();
}

void uiTags::Tag::on_delete_clicked()
{
	m_signal_deleted.emit(m_Value.get_text());
}

uiTags::Tag::type_signal_deleted uiTags::Tag::signal_deleted()
{
	return m_signal_deleted;
}
<commit_msg>Tag updates<commit_after>#include "uiTags.h"

uiTags::uiTags(Gtk::Window *parent)
{
	m_parent = parent;
    this->signal_expose_event().connect(sigc::mem_fun(*this, &uiTags::on_uiTags_expose_event) );
    m_AddNew.signal_clicked().connect(sigc::mem_fun(*this, &uiTags::on_addnew_clicked) );
	m_AddNew.set_label("+Tag");
	this->put(m_AddNew, 5, 10);
	m_AddNew.set_sensitive(false);
}

uiTags::~uiTags() {}

void uiTags::set_parent(Gtk::Window* parent)
{
	m_parent = parent;
}

std::vector<Glib::ustring> uiTags::tags()
{
	return m_tags;
}

void uiTags::tags(std::vector<Glib::ustring> tags)
{
	m_tags = tags;
	m_AddNew.set_sensitive(true);

	for(unsigned int i = 0; i < m_tag_widgets.size(); i++)
		delete m_tag_widgets[i];

	m_tag_widgets.clear();

	for(unsigned int i = 0; i < m_tags.size(); i++)
		m_tag_widgets.push_back(new Tag(m_tags[i]));

	for(unsigned int i = 0; i < m_tag_widgets.size(); i++)
		m_tag_widgets[i]->signal_deleted().connect(sigc::mem_fun(*this, &uiTags::on_tag_deleted) );

	needput = true;
	active = true;
	redraw();
}

void uiTags::clear()
{
	for(unsigned int i = 0; i < m_tag_widgets.size(); i++)
		delete m_tag_widgets[i];

	m_tag_widgets.clear();
	m_tags.clear();
	m_AddNew.set_sensitive(false);
}

uiTags::type_signal_added uiTags::signal_added()
{
	return m_signal_added;
}

uiTags::type_signal_deleted uiTags::signal_deleted()
{
	return m_signal_deleted;
}

void uiTags::on_tag_deleted(Glib::ustring tag)
{
	Gtk::Dialog dialog("Are you sure?", true);
	dialog.set_transient_for(*m_parent);
	dialog.set_resizable(false);
	dialog.add_button(Gtk::Stock::NO, Gtk::RESPONSE_CANCEL);
	dialog.add_button(Gtk::Stock::YES, Gtk::RESPONSE_OK);
	Gtk::Label label("Are you sure you want to delete this tag?");
	dialog.get_vbox()->pack_start(label,true,true);
	Gtk::Label label_tag(""+tag+"");
	label_tag.set_use_markup(true);
	dialog.get_vbox()->pack_start(label_tag,true,true);
	dialog.show_all_children();
	int result = dialog.run();

	switch (result) {
		case (Gtk::RESPONSE_OK):
			m_signal_deleted.emit(tag);
			break;
	}

}

void uiTags::on_addnew_clicked()
{
	if (m_parent == NULL) {
		return;
	}

	Gtk::Dialog dialog("Add Tag", true);
	dialog.set_transient_for(*m_parent);
	dialog.set_resizable(false);
	dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
	dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
	Gtk::Label label("Enter the new tag:");
	dialog.get_vbox()->pack_start(label,true,true);
	Gtk::Entry entry;
	entry.set_activates_default(true);
	dialog.get_vbox()->pack_start(entry,true,true);
	dialog.show_all_children();
	int result = dialog.run();

	switch (result) {
		case (Gtk::RESPONSE_OK):
			Glib::ustring t = entry.get_text();
			if (t != "") {
				if (m_signal_added.emit(t)) {
					m_tags.push_back(t);
					tags(m_tags);
					redraw();
				}
			}
			break;
	}

}

bool uiTags::on_uiTags_expose_event(GdkEventExpose* /*e*/)
{
	redraw();
	return false;
}

void uiTags::redraw()
{
	if (active) m_AddNew.show();

	if (m_tags.empty()) return;
	const int spacing = 5;
	int x=spacing;
	int y=spacing;
	int w,h;
	int width = this->get_width();
	Gtk::Requisition rec = m_AddNew.size_request();
	x += rec.width;
	for(unsigned int i = 0; i < m_tag_widgets.size(); i++)
	{
		m_tag_widgets[i]->show();
		rec = m_tag_widgets[i]->size_request();
		w = rec.width;
		h = rec.height;
		if (x > 0 && x+w > width) { x = spacing; y += h+spacing; }
		if (needput) this->put(*m_tag_widgets[i],x,y);
		else this->move(*m_tag_widgets[i],x,y);
		x += w+spacing;
	}
	needput = false;
}

uiTags::Tag::Tag(Glib::ustring tag)
{
	this->add(m_frame);
	m_Value.set_text(tag);
	m_Close.set_label("X");
	m_Close.set_relief(Gtk::RELIEF_NONE);
    m_Close.signal_clicked().connect(sigc::mem_fun(*this, &uiTags::Tag::on_delete_clicked) );

	m_hbox.pack_start(m_Close, false, false);
	m_hbox.pack_start(m_Value, false, false);
	m_frame.add(m_hbox);
	m_frame.set_shadow_type(Gtk::SHADOW_NONE);
	m_frame.set_border_width(2);
	show_all_children();
}

void uiTags::Tag::on_delete_clicked()
{
	m_signal_deleted.emit(m_Value.get_text());
}

uiTags::Tag::type_signal_deleted uiTags::Tag::signal_deleted()
{
	return m_signal_deleted;
}
<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include <QmitkFunctionalityTesting.h>

#include <QmitkFctMediator.h>

#include <qapplication.h>
#include <qtimer.h>
#include <qwidgetlist.h>
#include <qobjectlist.h>
#include <qmessagebox.h>

#include <stdlib.h>
#include <iostream>

QmitkFunctionalityTesting::QmitkFunctionalityTesting( QmitkFctMediator* qfm, QObject * parent, const char * name )
  : QObject(parent, name), m_QmitkFctMediator(qfm)
{
  QObject::connect( &m_ActivateTimer, SIGNAL(timeout()), this, SLOT(ActivateNextFunctionality()) );
  QObject::connect( &m_CloseMessagesTimer, SIGNAL(timeout()), this, SLOT(CloseFirstMessageBox()) );
}

QmitkFunctionalityTesting::~QmitkFunctionalityTesting()
{

}

void QmitkFunctionalityTesting::CloseFirstMessageBox() {
    bool boxClosed = false;
    QWidgetList* topWidgets = QApplication::topLevelWidgets();
    QWidgetListIt topWidgetsIt(*topWidgets);
    QWidget* widget;
    while ( ( widget = topWidgetsIt.current()) != 0 ) {
       ++topWidgetsIt;
       if (widget->isA("QMessageBox")) {
        std::cout << "Found a toplevel message box! Give it a parent! Closing it ..." << std::endl;
         ((QMessageBox*)widget)->close();
         boxClosed=true;
         break;
       }
    QObjectList *l = widget->queryList( "QMessageBox" );
    QObjectListIt it( *l );
    QObject *obj;
    while ( (obj = it.current()) != 0 ) {
        ++it;
        std::cout << "Found a message box! Closing it ..." << std::endl;
        ((QMessageBox*)obj)->close();
        boxClosed = true;
        break;
    }
    delete l; // delete the list, not the objects
    if (boxClosed) {
      break;
    }
  }
  delete topWidgets;
  if (boxClosed) {
    // let everything redraw and call self
    m_CloseMessagesTimer.start(5000,true);
  } else {
    std::cout << "No message box closed" << std::endl;
  }
}

void QmitkFunctionalityTesting::ActivateNextFunctionality()
{
  std::cout<<"[PASSED]"<<std::endl;
  int nextId = m_QmitkFctMediator->GetActiveFunctionalityId()+1;
  QmitkFunctionality * nextFunctionality = m_QmitkFctMediator->GetFunctionalityById(nextId);
  if(nextFunctionality != NULL)
  {
    std::cout << "Testing Functionality \"" << nextFunctionality->className() <<"\" "<< std::flush;
    m_CloseMessagesTimer.start(10000,true); // close message boxes if RaiseFunctionality doesn't return
    m_QmitkFctMediator->RaiseFunctionality(nextId);
    m_CloseMessagesTimer.stop();
    m_ActivateTimer.start(5000,true); // after redraw activate next
  }
  else
  {
    qApp->quit();
  }
}

int StartQmitkFunctionalityTesting(QmitkFctMediator* qfm)
{
  QmitkFunctionalityTesting *testing = new QmitkFunctionalityTesting(qfm);

  QTimer::singleShot(2000,testing,SLOT(ActivateNextFunctionality())); // 2 seconds single-shot timer

  std::cout << "Starting QmitkFunctionalityTesting ... " << std::endl;
  if (qfm->GetActiveFunctionality()) {
    std::cout << "Testing Functionality \"" << qfm->GetActiveFunctionality()->className() <<"\": "<< std::flush;
  }
  else
  {
    std::cout << "No active functionality yet ..." << std::endl << std::flush;
  }
  qApp->exec();
  std::cout<<"[PASSED]"<<std::endl;

  std::cout<<"[TEST DONE]"<<std::endl;
  return EXIT_SUCCESS;
}
<commit_msg>CHG: activate close message box timer<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include <QmitkFunctionalityTesting.h>

#include <QmitkFctMediator.h>

#include <qapplication.h>
#include <qtimer.h>
#include <qwidgetlist.h>
#include <qobjectlist.h>
#include <qmessagebox.h>

#include <stdlib.h>
#include <iostream>

QmitkFunctionalityTesting::QmitkFunctionalityTesting( QmitkFctMediator* qfm, QObject * parent, const char * name )
  : QObject(parent, name), m_QmitkFctMediator(qfm)
{
  QObject::connect( &m_ActivateTimer, SIGNAL(timeout()), this, SLOT(ActivateNextFunctionality()) );
  QObject::connect( &m_CloseMessagesTimer, SIGNAL(timeout()), this, SLOT(CloseFirstMessageBox()) );
}

QmitkFunctionalityTesting::~QmitkFunctionalityTesting()
{

}

void QmitkFunctionalityTesting::CloseFirstMessageBox() {
    bool boxClosed = false;
    QWidgetList* topWidgets = QApplication::topLevelWidgets();
    QWidgetListIt topWidgetsIt(*topWidgets);
    QWidget* widget;
    while ( ( widget = topWidgetsIt.current()) != 0 ) {
       ++topWidgetsIt;
       if (widget->isA("QMessageBox")) {
        std::cout << "Found a toplevel message box! Give it a parent! Closing it ..." << std::endl;
         ((QMessageBox*)widget)->close();
         boxClosed=true;
         break;
       }
    QObjectList *l = widget->queryList( "QMessageBox" );
    QObjectListIt it( *l );
    QObject *obj;
    while ( (obj = it.current()) != 0 ) {
        ++it;
        std::cout << "Found a message box! Closing it ..." << std::endl;
        ((QMessageBox*)obj)->close();
        boxClosed = true;
        break;
    }
    delete l; // delete the list, not the objects
    if (boxClosed) {
      break;
    }
  }
  delete topWidgets;
  if (boxClosed) {
    // let everything redraw and call self
    m_CloseMessagesTimer.start(5000,true);
  } else {
    std::cout << "No message box closed" << std::endl;
  }
}

void QmitkFunctionalityTesting::ActivateNextFunctionality()
{
  std::cout<<"[PASSED]"<<std::endl;
  int nextId = m_QmitkFctMediator->GetActiveFunctionalityId()+1;
  QmitkFunctionality * nextFunctionality = m_QmitkFctMediator->GetFunctionalityById(nextId);
  if(nextFunctionality != NULL)
  {
    std::cout << "Testing Functionality \"" << nextFunctionality->className() <<"\" "<< std::flush;
    m_CloseMessagesTimer.start(10000,true); // close message boxes if RaiseFunctionality doesn't return
    m_QmitkFctMediator->RaiseFunctionality(nextId);
    m_CloseMessagesTimer.stop();
    m_ActivateTimer.start(5000,true); // after redraw activate next
  }
  else
  {
    qApp->quit();
  }
}

int StartQmitkFunctionalityTesting(QmitkFctMediator* qfm)
{
  QmitkFunctionalityTesting *testing = new QmitkFunctionalityTesting(qfm);

  QTimer::singleShot(2000,testing,SLOT(ActivateNextFunctionality())); // 2 seconds single-shot timer
  testing->m_CloseMessagesTimer.start(10000,true); // close message boxes if RaiseFunctionality doesn't return

  std::cout << "Starting QmitkFunctionalityTesting ... " << std::endl;
  if (qfm->GetActiveFunctionality()) {
    std::cout << "Testing Functionality \"" << qfm->GetActiveFunctionality()->className() <<"\": "<< std::flush;
  }
  else
  {
    std::cout << "No active functionality yet ..." << std::endl << std::flush;
  }
  qApp->exec();
  std::cout<<"[PASSED]"<<std::endl;

  std::cout<<"[TEST DONE]"<<std::endl;
  return EXIT_SUCCESS;
}
<|endoftext|>