<commit_before>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetTaskChainExecutor.cpp
 */

#include "JPetTaskChainExecutor.h"
#include <cassert>
#include "../JPetTaskInterface/JPetTaskInterface.h"
#include "../JPetScopeLoader/JPetScopeLoader.h"
#include "../JPetTaskLoader/JPetTaskLoader.h"
#include "../JPetParamGetterAscii/JPetParamGetterAscii.h"
#include "../JPetParamGetterAscii/JPetParamSaverAscii.h"
#include "../JPetLoggerInclude.h"

JPetTaskChainExecutor::JPetTaskChainExecutor(TaskGeneratorChain* taskGeneratorChain, int processedFileId, JPetOptions opt) :
  fInputSeqId(processedFileId),
  ftaskGeneratorChain(taskGeneratorChain),
  fOptions(opt)
{
  if (fOptions.isLocalDB()) {
    fParamManager = new JPetParamManager(new JPetParamGetterAscii(fOptions.getLocalDB()));
  } else {
    fParamManager = new JPetParamManager();
  }
  if (taskGeneratorChain) {
    for (auto taskGenerator : *ftaskGeneratorChain) {
      auto task = taskGenerator();
      task->setParamManager(fParamManager); // maybe that should not be here
      fTasks.push_back(task);
    }
  } else {
    ERROR("taskGeneratorChain is null while constructing JPetTaskChainExecutor");
  }
}

bool JPetTaskChainExecutor::process()
{
  if (!processFromCmdLineArgs()) {
    ERROR("Error in processFromCmdLineArgs");
    return false;
  }
  for (auto currentTask = fTasks.begin(); currentTask != fTasks.end(); currentTask++) {
    JPetOptions::Options currOpts = fOptions.getOptions();
    if (currentTask != fTasks.begin()) {
      /// Ignore the event range options for all but the first task.
      currOpts = JPetOptions::resetEventRange(currOpts);
      /// For all but the first task,
      /// the input path must be changed if
      /// the output path argument -o was given, because the input
      /// data for them will lay in the location defined by -o.
      auto outPath  = currOpts.at("outputPath");
      if (!outPath.empty()) {
        currOpts.at("inputFile") = outPath + JPetCommonTools::extractPathFromFile(currOpts.at("inputFile")) + JPetCommonTools::extractFileNameFromFullPath(currOpts.at("inputFile"));
      }
    }
    auto taskCurr = dynamic_cast<JPetTask*> (dynamic_cast<JPetTaskLoader*>(*currentTask)->getTask());
    auto taskName = taskCurr->GetName();
    INFO(Form("Starting task: %s", taskName));
    (*currentTask)->init(currOpts);
    (*currentTask)->exec();
    (*currentTask)->terminate();
    INFO(Form("Finished task: %s", taskName));
  }
  return true;
}

void* JPetTaskChainExecutor::processProxy(void* runner)
{
  assert(runner);
  static_cast<JPetTaskChainExecutor*>(runner)->process();
  return 0;
}

TThread* JPetTaskChainExecutor::run()
{
  TThread* thread = new TThread(to_string(fInputSeqId).c_str(), processProxy, (void*)this);
  assert(thread);
  thread->Run();
  return thread;
}

bool JPetTaskChainExecutor::processFromCmdLineArgs()
{
  auto runNum = fOptions.getRunNumber();
  if (runNum >= 0) {
    try {
      fParamManager->fillParameterBank(runNum);
    } catch (...) {
      ERROR("Param bank was not generated correctly.\n The run number used:" + JPetCommonTools::intToString(runNum));
      return false;
    }
    if (fOptions.isLocalDBCreate()) {
      JPetParamSaverAscii saver;
      saver.saveParamBank(fParamManager->getParamBank(), runNum, fOptions.getLocalDBCreate());
    }
  }

  auto inputFileType = fOptions.getInputFileType();
  auto inputFile = fOptions.getInputFile();
  if (inputFileType == JPetOptions::kScope) {
    if (!createScopeTaskAndAddToTaskList()) {
      ERROR("Scope task not added correctly!!!");
      return false;
    }
  } else if (inputFileType == JPetOptions::kHld) {
    long long nevents = fOptions.getTotalEvents();
    unpackFile(inputFile, nevents);
  }
  //Assumption that only HLD files can be zipped!!!!!! - Sz.N.
  else if ( inputFileType == JPetOptions::kZip) {
    INFO( std::string("Unzipping file before unpacking") );
    if ( !JPetCommonTools::unzipFile(inputFile) )
      ERROR( std::string("Problem with unpacking file: ") + inputFile );
    long long nevents = fOptions.getTotalEvents();
    INFO( std::string("Unpacking") );
    unpackFile( JPetCommonTools::stripFileNameSuffix( std::string(inputFile) ).c_str(), nevents);
  }

  if (fOptions.getInputFileType() == JPetOptions::kUndefinedFileType)
    ERROR( Form("Unknown file type provided for file: %s", fOptions.getInputFile()) );

  return true;
}

bool JPetTaskChainExecutor::createScopeTaskAndAddToTaskList()
{
  JPetScopeLoader* module = new JPetScopeLoader(new JPetScopeTask("JPetScopeReader", "Process Oscilloscope ASCII data into JPetRecoSignal structures."));
  assert(module);
  module->setParamManager(fParamManager);
  auto scopeFile = fOptions.getScopeConfigFile();
  if (!fParamManager->getParametersFromScopeConfig(scopeFile)) {
    ERROR("Unable to generate Param Bank from Scope Config");
    return false;
  }
  fTasks.push_front(module);
  return true;
}

void JPetTaskChainExecutor::unpackFile(const char* filename, const long long nevents)
{
  if (nevents > 0) {
    fUnpacker.setParams( filename, nevents);
    WARNING(std::string("Even though the range of events was set, only the first ") + JPetCommonTools::intToString(nevents) + std::string(" will be unpacked by the unpacker. \n The unpacker always starts from the beginning of the file."));
  } else {
    fUnpacker.setParams( filename );
  }
  fUnpacker.exec();
}

JPetTaskChainExecutor::~JPetTaskChainExecutor()
{
  for (auto & task : fTasks) {
    if (task) {
      delete task;
      task = 0;
    }
  }
}
<commit_msg>Remove the inheritance of JPetTaskInterface for JPetTaskIO<commit_after>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetTaskChainExecutor.cpp
 */

#include "JPetTaskChainExecutor.h"
#include <cassert>
#include "../JPetTaskInterface/JPetTaskInterface.h"
#include "../JPetScopeLoader/JPetScopeLoader.h"
#include "../JPetTaskLoader/JPetTaskLoader.h"
#include "../JPetParamGetterAscii/JPetParamGetterAscii.h"
#include "../JPetParamGetterAscii/JPetParamSaverAscii.h"
#include "../JPetLoggerInclude.h"

JPetTaskChainExecutor::JPetTaskChainExecutor(TaskGeneratorChain* taskGeneratorChain, int processedFileId, JPetOptions opt) :
  fInputSeqId(processedFileId),
  ftaskGeneratorChain(taskGeneratorChain),
  fOptions(opt)
{
  if (fOptions.isLocalDB()) {
    fParamManager = new JPetParamManager(new JPetParamGetterAscii(fOptions.getLocalDB()));
  } else {
    fParamManager = new JPetParamManager();
  }
  if (taskGeneratorChain) {
    for (auto taskGenerator : *ftaskGeneratorChain) {
      auto task = taskGenerator();
      ///@todo change it
      (dynamic_cast<JPetTaskIO*>(task))->setParamManager(fParamManager);
      fTasks.push_back(task);
    }
  } else {
    ERROR("taskGeneratorChain is null while constructing JPetTaskChainExecutor");
  }
}

bool JPetTaskChainExecutor::process()
{
  if (!processFromCmdLineArgs()) {
    ERROR("Error in processFromCmdLineArgs");
    return false;
  }
  for (auto currentTask = fTasks.begin(); currentTask != fTasks.end(); currentTask++) {
    JPetOptions::Options currOpts = fOptions.getOptions();
    if (currentTask != fTasks.begin()) {
      /// Ignore the event range options for all but the first task.
      currOpts = JPetOptions::resetEventRange(currOpts);
      /// For all but the first task,
      /// the input path must be changed if
      /// the output path argument -o was given, because the input
      /// data for them will lay in the location defined by -o.
      auto outPath  = currOpts.at("outputPath");
      if (!outPath.empty()) {
        currOpts.at("inputFile") = outPath + JPetCommonTools::extractPathFromFile(currOpts.at("inputFile")) + JPetCommonTools::extractFileNameFromFullPath(currOpts.at("inputFile"));
      }
    }
    auto taskCurr = dynamic_cast<JPetTask*> (dynamic_cast<JPetTaskLoader*>(*currentTask)->getTask());
    auto taskName = taskCurr->GetName();
    INFO(Form("Starting task: %s", taskName));
    /// @todo fix it
    auto taskRunnerCurr =  dynamic_cast<JPetTaskIO*> (*currentTask);
    taskRunnerCurr->init(currOpts);
    taskRunnerCurr->exec();
    taskRunnerCurr->terminate();
    INFO(Form("Finished task: %s", taskName));
  }
  return true;
}

void* JPetTaskChainExecutor::processProxy(void* runner)
{
  assert(runner);
  static_cast<JPetTaskChainExecutor*>(runner)->process();
  return 0;
}

TThread* JPetTaskChainExecutor::run()
{
  TThread* thread = new TThread(to_string(fInputSeqId).c_str(), processProxy, (void*)this);
  assert(thread);
  thread->Run();
  return thread;
}

bool JPetTaskChainExecutor::processFromCmdLineArgs()
{
  auto runNum = fOptions.getRunNumber();
  if (runNum >= 0) {
    try {
      fParamManager->fillParameterBank(runNum);
    } catch (...) {
      ERROR("Param bank was not generated correctly.\n The run number used:" + JPetCommonTools::intToString(runNum));
      return false;
    }
    if (fOptions.isLocalDBCreate()) {
      JPetParamSaverAscii saver;
      saver.saveParamBank(fParamManager->getParamBank(), runNum, fOptions.getLocalDBCreate());
    }
  }

  auto inputFileType = fOptions.getInputFileType();
  auto inputFile = fOptions.getInputFile();
  if (inputFileType == JPetOptions::kScope) {
    if (!createScopeTaskAndAddToTaskList()) {
      ERROR("Scope task not added correctly!!!");
      return false;
    }
  } else if (inputFileType == JPetOptions::kHld) {
    long long nevents = fOptions.getTotalEvents();
    unpackFile(inputFile, nevents);
  }
  //Assumption that only HLD files can be zipped!!!!!! - Sz.N.
  else if ( inputFileType == JPetOptions::kZip) {
    INFO( std::string("Unzipping file before unpacking") );
    if ( !JPetCommonTools::unzipFile(inputFile) )
      ERROR( std::string("Problem with unpacking file: ") + inputFile );
    long long nevents = fOptions.getTotalEvents();
    INFO( std::string("Unpacking") );
    unpackFile( JPetCommonTools::stripFileNameSuffix( std::string(inputFile) ).c_str(), nevents);
  }

  if (fOptions.getInputFileType() == JPetOptions::kUndefinedFileType)
    ERROR( Form("Unknown file type provided for file: %s", fOptions.getInputFile()) );

  return true;
}

bool JPetTaskChainExecutor::createScopeTaskAndAddToTaskList()
{
  JPetScopeLoader* module = new JPetScopeLoader(new JPetScopeTask("JPetScopeReader", "Process Oscilloscope ASCII data into JPetRecoSignal structures."));
  assert(module);
  module->setParamManager(fParamManager);
  auto scopeFile = fOptions.getScopeConfigFile();
  if (!fParamManager->getParametersFromScopeConfig(scopeFile)) {
    ERROR("Unable to generate Param Bank from Scope Config");
    return false;
  }
  fTasks.push_front(module);
  return true;
}

void JPetTaskChainExecutor::unpackFile(const char* filename, const long long nevents)
{
  if (nevents > 0) {
    fUnpacker.setParams( filename, nevents);
    WARNING(std::string("Even though the range of events was set, only the first ") + JPetCommonTools::intToString(nevents) + std::string(" will be unpacked by the unpacker. \n The unpacker always starts from the beginning of the file."));
  } else {
    fUnpacker.setParams( filename );
  }
  fUnpacker.exec();
}

JPetTaskChainExecutor::~JPetTaskChainExecutor()
{
  for (auto & task : fTasks) {
    if (task) {
      delete task;
      task = 0;
    }
  }
}
<|endoftext|>


<commit_before>#include "daemon-backend.hpp"
#include "globals.hpp"
#include "commands.hpp"
#include "utils.hpp"
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sstream>
#include <string>
#include <random>
#include <iostream>
#include <cstring>
#include <system_error>
#include <json.hpp>

using namespace std;
using json = nlohmann::json;

string Daemon::get_message() const {
    // Accept incoming connection
    struct sockaddr_un cliaddr;
    socklen_t cliaddr_size = sizeof(cliaddr);
    int csfd = accept(sfd, (struct sockaddr*) &cliaddr, &cliaddr_size);
    if (csfd == -1) throw system_error(errno, system_category(), "Could not accept incoming connection");
    // Receive request
    stringstream ss;
    while (true) {
        char buffer[256];
        int n_read = read(csfd, buffer, 255);
        if (n_read < 0) throw system_error(errno, system_category(), "Read error from client socket");
        if (n_read == 0) break;
        buffer[n_read] = '\0';
        string chunk = buffer;
        ss << chunk;
    }
    return ss.str();
}

/// Send a message to a node.
void Daemon::_send_message(const string& node_id, const string& msg) const {
    const string node_sock_path = socket_dir + node_id;

    int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sfd == -1) throw system_error(errno, system_category(), "Cannot create socket");

    struct sockaddr_un saddr;
    memset(&saddr, 0, sizeof(struct sockaddr_un));
    saddr.sun_family = AF_UNIX;
    strncpy(saddr.sun_path, node_sock_path.c_str(), sizeof(saddr.sun_path) - 1);

    int ret = connect(sfd, (struct sockaddr*) &saddr, sizeof(saddr));
    if (ret < 0) throw system_error(errno, system_category(), "Cannot connect to node socket " + node_sock_path);

    int n = write(sfd, msg.c_str(), msg.length());
    if (n < 0) throw system_error(errno, system_category(), "Cannot write message to node socket " + node_sock_path);

     shutdown(sfd, SHUT_RDWR);
}

/// Block until a notification is sent about
/// the completion of the specified task.
void Daemon::_wait_for_notify(Commands command) const try {
    while(true) {
        auto msg = get_message();
        auto vars = json::parse(msg);
        if (vars.at("cmd") == "notify-daemon" &&
            to_command_enum(vars.at("action")) == command)
            break;
    }
} catch (const exception&) {
    throw_with_nested(runtime_error("While waiting for command completion notification"));
}

/// Send message for graceful termination to a node.
void Daemon::_send_terminate(const string& node_id) const try {
    json jmsg = {
        {"cmd", "depart-cmd"},
        {"sender", "daemon-socket-id"},
        {"args", ""}
    };
    _send_message(node_id, jmsg.dump());
    _wait_for_notify(Commands::Depart);
} catch (const exception& e) {
    cerr << "Error during the termination of node " << node_id << ':' << endl;
    print_exception(e);
}

/// Select a random active node.
string Daemon::_pick_random_node() try {
    // Algorithm from http://stackoverflow.com/a/31522686
    if (node_ids.empty()) throw runtime_error("There are no active nodes");
    // Generate a random node name.
    random_device rd;
    mt19937_64 gen(rd());
    uniform_int_distribution<> dist(32, 126);
    string key(16, ' ');
    for (auto& c: key) c = static_cast<char>(dist(gen));
    // If node exists, return it, else insert it.
    auto ins = node_ids.insert(make_pair(key, 0));
    if (!ins.second) return ins.first->first;
    // Get iterator to next element (or the first, if it was the last).
    auto it = ins.first;
    it++;
    if (it == node_ids.end()) it = node_ids.begin();
    auto res = it->first;
    // Remove the inserted random node name.
    node_ids.erase(ins.first);
    // Return the element that was next to the random name.
    return res;
} catch(const exception&) {
    throw_with_nested(runtime_error("While selecting a random node"));
}

/// Select a random active node, except the one specified.
string Daemon::_pick_random_node(const string& node_id) try {
    if (node_ids.empty()) throw runtime_error("There are no active nodes");
    node_ids.at(node_id);
    node_ids.erase(node_id);
    auto res = _pick_random_node();
    node_ids[node_id] = stoi(node_id);
    return res;
} catch(const exception&) {
    throw_with_nested(runtime_error("While removing node from random selection"));
}

Daemon::Daemon() {
    int ret = daemon(0, 1);
    if (ret == -1) throw system_error(errno, system_category(), "Cannot daemonize process.");

    sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sfd == -1) throw system_error(errno, system_category(), "Cannot create initial socket.");

    struct sockaddr_un saddr;
    memset(&saddr, 0, sizeof(struct sockaddr_un));
    saddr.sun_family = AF_UNIX;
    strncpy(saddr.sun_path, socket_path.c_str(), sizeof(saddr.sun_path) - 1);

    ret = bind(sfd, (struct sockaddr*) &saddr, sizeof(struct sockaddr_un));
    if (ret == -1) throw system_error(errno, system_category(), "Cannot bind initial socket to file.");

    ret = listen(sfd, 50);
    if (ret == -1) throw system_error(errno, system_category(), "Cannot listen from initial socket.");
}

Daemon::~Daemon() {
    shutdown(sfd, SHUT_RDWR);
    unlink(socket_path.c_str());
}

/// Check whether the daemon is running,
/// and able to process requests.
bool Daemon::is_running() const {
    return _m_is_running;
}

/// Get the replica factor for this session.
unsigned Daemon::get_replica_factor() const {
    if (_m_replica_factor == 0) return 1;  // default value
    return _m_replica_factor;
}

/// Set the replica factor for this session.
void Daemon::set_replica_factor(unsigned r) {
    if (r == 0) return;  // 0 means, do not change
    if (get_replica_factor() == r) return;
    _m_replica_factor = r;
    cout << "[daemon] Replica factor set to " << get_replica_factor() << endl;
}

/// Terminate the daemon instance,
/// releasing all nodes.
void Daemon::terminate() {
    _m_is_running = false;
    // Send termination message to all nodes.
    // Termination sequence will continue regardless of
    // whether the nodes succeed to receive the message.
    for (auto&& n: node_ids) try {
        _send_terminate(n.first);
    } catch(const exception& e) {
        cerr << "Error occured while trying to terminate node " << n.first << " (id: " << n.second << "):" << endl;
        print_exception(e);
    }
    node_ids.clear();
}

/// Initialize a node.
void Daemon::init_node(const string& node_id, const string& n_replicas, const string& consistency) try {
    set_replica_factor(stoi(n_replicas));
    string replica_factor(to_string(get_replica_factor()));

    char command[31];
    strncpy(command, "/usr/local/share/dsemu/node.py", sizeof(command));

    char arg_id[node_id.length() + 1];
    strncpy(arg_id, node_id.c_str(), sizeof(arg_id));

    char arg_rep[replica_factor.length() + 1];
    strncpy(arg_rep, replica_factor.c_str(), sizeof(arg_rep));

    char arg_cons[consistency.length() + 1];
    strncpy(arg_cons, consistency.c_str(), sizeof(arg_cons));

    char * newargv[] = {
        command,
        arg_id,
        arg_rep,
        arg_cons,
        NULL
    };

    char * newenviron[] = {
        NULL
    };

    pid_t pid = fork();

    if (pid == 0) {
        execve(command, newargv, newenviron);
    }
    else if (pid > 0) {
        node_ids[node_id] = stoi(node_id);
        cout << "[daemon] Initialized node " << node_id << endl;
    }
    else
        throw system_error(errno, system_category(), "Failed to fork node process");
} catch(const exception&) {
    throw_with_nested(runtime_error("While initializing node " + node_id));
}

/// Terminate a node gracefully.
void Daemon::terminate_node(const string& node_id) try {
    node_ids.erase(node_id);
    _send_terminate(node_id);
} catch(const exception&) {
    throw_with_nested(runtime_error("While terminating node " + node_id));
}

/// Output a list of all active nodes.
void Daemon::list_nodes() try {
    cout << "Node\tID" << endl;
    for (auto&& n: node_ids)
        cout << n.first << '\t' << n.second << endl;
} catch(const exception&) {
    throw_with_nested(runtime_error("While printing node list"));
}

/// Request node ring to list itself in order.
void Daemon::list_ring(const string& node_id) try {
    json jmsg = {
        {"cmd", "list-cmd"},
        {"sender", "daemon-socket-id"},
        {"args", ""}
    };
    _send_message(node_id, jmsg.dump());
} catch(const exception&) {
    throw_with_nested(runtime_error("While requesting ring node listing"));
}

/// Request the ring to allow a new node to join.
void Daemon::join(const string& node_id) try {
    json jmsg = {
        {"cmd", "join-cmd"},
        {"sender", "daemon-socket-id"},
        {"args", {
            {"socket_fd", _pick_random_node(node_id)}
        }}
    };
    _send_message(node_id, jmsg.dump());
} catch(const exception&) {
    throw_with_nested(runtime_error("On join of node " + node_id));
}

/// Make a node depart from the ring.
void Daemon::depart(const string& node_id) {
    terminate_node(node_id);
}

/// Query the DHT for the value associated with a key.
void Daemon::query(const string& key) try {
    json jmsg = {
        {"cmd", "query-cmd"},
        {"sender", "daemon"},
        {"args", {
            {"initial_sender", "daemon"},
            {"key", key},
            {"replica_counter", get_replica_factor()}
        }}
    };
    _send_message(_pick_random_node(), jmsg.dump());
    _wait_for_notify(Commands::Query);
} catch(const exception&) {
    throw_with_nested(runtime_error("While querying key " + key));
}

// Insert a key - value pair into the DHT.
void Daemon::insert(const string& key, const string& value) try {
    json jmsg = {
        {"cmd", "insert-cmd"},
        {"sender", "daemon"},
        {"args", {
            {"key", key},
            {"value", value},
            {"initial_sender", "daemon"},
        }}
    };
    _send_message(_pick_random_node(), jmsg.dump());
    _wait_for_notify(Commands::Insert);
} catch(const exception&) {
    throw_with_nested(runtime_error("While inserting key " + key + " with value " + value));
}

/// Delete a key from the DHT.
void Daemon::remove(const string& key) try {
    json jmsg = {
        {"cmd", "delete-cmd"},
        {"sender", "daemon"},
        {"args", {
            {"initial_sender", "daemon"},
            {"key", key},
            {"replica_counter", get_replica_factor()}
        }}
    };
    _send_message(_pick_random_node(), jmsg.dump());
    _wait_for_notify(Commands::Delete);
} catch(const exception&) {
    throw_with_nested(runtime_error("While deleting key " + key));
}
<commit_msg>Fix sender on json messages<commit_after>#include "daemon-backend.hpp"
#include "globals.hpp"
#include "commands.hpp"
#include "utils.hpp"
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sstream>
#include <string>
#include <random>
#include <iostream>
#include <cstring>
#include <system_error>
#include <json.hpp>

using namespace std;
using json = nlohmann::json;

string Daemon::get_message() const {
    // Accept incoming connection
    struct sockaddr_un cliaddr;
    socklen_t cliaddr_size = sizeof(cliaddr);
    int csfd = accept(sfd, (struct sockaddr*) &cliaddr, &cliaddr_size);
    if (csfd == -1) throw system_error(errno, system_category(), "Could not accept incoming connection");
    // Receive request
    stringstream ss;
    while (true) {
        char buffer[256];
        int n_read = read(csfd, buffer, 255);
        if (n_read < 0) throw system_error(errno, system_category(), "Read error from client socket");
        if (n_read == 0) break;
        buffer[n_read] = '\0';
        string chunk = buffer;
        ss << chunk;
    }
    return ss.str();
}

/// Send a message to a node.
void Daemon::_send_message(const string& node_id, const string& msg) const {
    const string node_sock_path = socket_dir + node_id;

    int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sfd == -1) throw system_error(errno, system_category(), "Cannot create socket");

    struct sockaddr_un saddr;
    memset(&saddr, 0, sizeof(struct sockaddr_un));
    saddr.sun_family = AF_UNIX;
    strncpy(saddr.sun_path, node_sock_path.c_str(), sizeof(saddr.sun_path) - 1);

    int ret = connect(sfd, (struct sockaddr*) &saddr, sizeof(saddr));
    if (ret < 0) throw system_error(errno, system_category(), "Cannot connect to node socket " + node_sock_path);

    int n = write(sfd, msg.c_str(), msg.length());
    if (n < 0) throw system_error(errno, system_category(), "Cannot write message to node socket " + node_sock_path);

     shutdown(sfd, SHUT_RDWR);
}

/// Block until a notification is sent about
/// the completion of the specified task.
void Daemon::_wait_for_notify(Commands command) const try {
    while(true) {
        auto msg = get_message();
        auto vars = json::parse(msg);
        if (vars.at("cmd") == "notify-daemon" &&
            to_command_enum(vars.at("action")) == command)
            break;
    }
} catch (const exception&) {
    throw_with_nested(runtime_error("While waiting for command completion notification"));
}

/// Send message for graceful termination to a node.
void Daemon::_send_terminate(const string& node_id) const try {
    json jmsg = {
        {"cmd", "depart-cmd"},
        {"sender", "daemon"},
        {"args", ""}
    };
    _send_message(node_id, jmsg.dump());
    _wait_for_notify(Commands::Depart);
} catch (const exception& e) {
    cerr << "Error during the termination of node " << node_id << ':' << endl;
    print_exception(e);
}

/// Select a random active node.
string Daemon::_pick_random_node() try {
    // Algorithm from http://stackoverflow.com/a/31522686
    if (node_ids.empty()) throw runtime_error("There are no active nodes");
    // Generate a random node name.
    random_device rd;
    mt19937_64 gen(rd());
    uniform_int_distribution<> dist(32, 126);
    string key(16, ' ');
    for (auto& c: key) c = static_cast<char>(dist(gen));
    // If node exists, return it, else insert it.
    auto ins = node_ids.insert(make_pair(key, 0));
    if (!ins.second) return ins.first->first;
    // Get iterator to next element (or the first, if it was the last).
    auto it = ins.first;
    it++;
    if (it == node_ids.end()) it = node_ids.begin();
    auto res = it->first;
    // Remove the inserted random node name.
    node_ids.erase(ins.first);
    // Return the element that was next to the random name.
    return res;
} catch(const exception&) {
    throw_with_nested(runtime_error("While selecting a random node"));
}

/// Select a random active node, except the one specified.
string Daemon::_pick_random_node(const string& node_id) try {
    if (node_ids.empty()) throw runtime_error("There are no active nodes");
    node_ids.at(node_id);
    node_ids.erase(node_id);
    auto res = _pick_random_node();
    node_ids[node_id] = stoi(node_id);
    return res;
} catch(const exception&) {
    throw_with_nested(runtime_error("While removing node from random selection"));
}

Daemon::Daemon() {
    int ret = daemon(0, 1);
    if (ret == -1) throw system_error(errno, system_category(), "Cannot daemonize process.");

    sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sfd == -1) throw system_error(errno, system_category(), "Cannot create initial socket.");

    struct sockaddr_un saddr;
    memset(&saddr, 0, sizeof(struct sockaddr_un));
    saddr.sun_family = AF_UNIX;
    strncpy(saddr.sun_path, socket_path.c_str(), sizeof(saddr.sun_path) - 1);

    ret = bind(sfd, (struct sockaddr*) &saddr, sizeof(struct sockaddr_un));
    if (ret == -1) throw system_error(errno, system_category(), "Cannot bind initial socket to file.");

    ret = listen(sfd, 50);
    if (ret == -1) throw system_error(errno, system_category(), "Cannot listen from initial socket.");
}

Daemon::~Daemon() {
    shutdown(sfd, SHUT_RDWR);
    unlink(socket_path.c_str());
}

/// Check whether the daemon is running,
/// and able to process requests.
bool Daemon::is_running() const {
    return _m_is_running;
}

/// Get the replica factor for this session.
unsigned Daemon::get_replica_factor() const {
    if (_m_replica_factor == 0) return 1;  // default value
    return _m_replica_factor;
}

/// Set the replica factor for this session.
void Daemon::set_replica_factor(unsigned r) {
    if (r == 0) return;  // 0 means, do not change
    if (get_replica_factor() == r) return;
    _m_replica_factor = r;
    cout << "[daemon] Replica factor set to " << get_replica_factor() << endl;
}

/// Terminate the daemon instance,
/// releasing all nodes.
void Daemon::terminate() {
    _m_is_running = false;
    // Send termination message to all nodes.
    // Termination sequence will continue regardless of
    // whether the nodes succeed to receive the message.
    for (auto&& n: node_ids) try {
        _send_terminate(n.first);
    } catch(const exception& e) {
        cerr << "Error occured while trying to terminate node " << n.first << " (id: " << n.second << "):" << endl;
        print_exception(e);
    }
    node_ids.clear();
}

/// Initialize a node.
void Daemon::init_node(const string& node_id, const string& n_replicas, const string& consistency) try {
    set_replica_factor(stoi(n_replicas));
    string replica_factor(to_string(get_replica_factor()));

    char command[31];
    strncpy(command, "/usr/local/share/dsemu/node.py", sizeof(command));

    char arg_id[node_id.length() + 1];
    strncpy(arg_id, node_id.c_str(), sizeof(arg_id));

    char arg_rep[replica_factor.length() + 1];
    strncpy(arg_rep, replica_factor.c_str(), sizeof(arg_rep));

    char arg_cons[consistency.length() + 1];
    strncpy(arg_cons, consistency.c_str(), sizeof(arg_cons));

    char * newargv[] = {
        command,
        arg_id,
        arg_rep,
        arg_cons,
        NULL
    };

    char * newenviron[] = {
        NULL
    };

    pid_t pid = fork();

    if (pid == 0) {
        execve(command, newargv, newenviron);
    }
    else if (pid > 0) {
        node_ids[node_id] = stoi(node_id);
        cout << "[daemon] Initialized node " << node_id << endl;
    }
    else
        throw system_error(errno, system_category(), "Failed to fork node process");
} catch(const exception&) {
    throw_with_nested(runtime_error("While initializing node " + node_id));
}

/// Terminate a node gracefully.
void Daemon::terminate_node(const string& node_id) try {
    node_ids.erase(node_id);
    _send_terminate(node_id);
} catch(const exception&) {
    throw_with_nested(runtime_error("While terminating node " + node_id));
}

/// Output a list of all active nodes.
void Daemon::list_nodes() try {
    cout << "Node\tID" << endl;
    for (auto&& n: node_ids)
        cout << n.first << '\t' << n.second << endl;
} catch(const exception&) {
    throw_with_nested(runtime_error("While printing node list"));
}

/// Request node ring to list itself in order.
void Daemon::list_ring(const string& node_id) try {
    json jmsg = {
        {"cmd", "list-cmd"},
        {"sender", "daemon"},
        {"args", ""}
    };
    _send_message(node_id, jmsg.dump());
} catch(const exception&) {
    throw_with_nested(runtime_error("While requesting ring node listing"));
}

/// Request the ring to allow a new node to join.
void Daemon::join(const string& node_id) try {
    json jmsg = {
        {"cmd", "join-cmd"},
        {"sender", "daemon"},
        {"args", {
            {"socket_fd", _pick_random_node(node_id)}
        }}
    };
    _send_message(node_id, jmsg.dump());
} catch(const exception&) {
    throw_with_nested(runtime_error("On join of node " + node_id));
}

/// Make a node depart from the ring.
void Daemon::depart(const string& node_id) {
    terminate_node(node_id);
}

/// Query the DHT for the value associated with a key.
void Daemon::query(const string& key) try {
    json jmsg = {
        {"cmd", "query-cmd"},
        {"sender", "daemon"},
        {"args", {
            {"initial_sender", "daemon"},
            {"key", key},
            {"replica_counter", get_replica_factor()}
        }}
    };
    _send_message(_pick_random_node(), jmsg.dump());
    _wait_for_notify(Commands::Query);
} catch(const exception&) {
    throw_with_nested(runtime_error("While querying key " + key));
}

// Insert a key - value pair into the DHT.
void Daemon::insert(const string& key, const string& value) try {
    json jmsg = {
        {"cmd", "insert-cmd"},
        {"sender", "daemon"},
        {"args", {
            {"key", key},
            {"value", value},
            {"initial_sender", "daemon"},
        }}
    };
    _send_message(_pick_random_node(), jmsg.dump());
    _wait_for_notify(Commands::Insert);
} catch(const exception&) {
    throw_with_nested(runtime_error("While inserting key " + key + " with value " + value));
}

/// Delete a key from the DHT.
void Daemon::remove(const string& key) try {
    json jmsg = {
        {"cmd", "delete-cmd"},
        {"sender", "daemon"},
        {"args", {
            {"initial_sender", "daemon"},
            {"key", key},
            {"replica_counter", get_replica_factor()}
        }}
    };
    _send_message(_pick_random_node(), jmsg.dump());
    _wait_for_notify(Commands::Delete);
} catch(const exception&) {
    throw_with_nested(runtime_error("While deleting key " + key));
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: hyphdsp.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2006-03-07 10:17:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _LINGUISTIC_HYPHDSP_HXX_
#define _LINGUISTIC_HYPHDSP_HXX_

#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEDISPLAYNAME_HPP_
#include <com/sun/star/lang/XServiceDisplayName.hpp>
#endif
#include <com/sun/star/linguistic2/XHyphenator.hpp>
#include <com/sun/star/linguistic2/XPossibleHyphens.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
#include <com/sun/star/linguistic2/XLinguServiceEventBroadcaster.hpp>

#ifndef _TOOLS_TABLE_HXX
#include <tools/table.hxx>
#endif

#include <uno/lbnames.h>            // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type
#include <cppuhelper/implbase1.hxx> // helper for implementations

#include "lngopt.hxx"
#include "misc.hxx"
#include "defs.hxx"

class LngSvcMgr;

///////////////////////////////////////////////////////////////////////////

class LangSvcEntry_Hyph
{
    friend class HyphenatorDispatcher;

    ::rtl::OUString                                     aSvcImplName;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XHyphenator >    aSvcRef;

//  INT16           nLang;     //used as key in the table
    SvcFlags        aFlags;

public:
    LangSvcEntry_Hyph() {}
    LangSvcEntry_Hyph( const ::rtl::OUString &rSvcImplName );
    ~LangSvcEntry_Hyph();

    BOOL    IsAlreadyWarned() const     { return aFlags.bAlreadyWarned != 0; }
    void    SetAlreadyWarned(BOOL bVal) { aFlags.bAlreadyWarned = 0 != bVal; }
    BOOL    IsDoWarnAgain() const       { return aFlags.bDoWarnAgain != 0; }
    void    SetDoWarnAgain(BOOL bVal)   { aFlags.bDoWarnAgain = 0 != bVal; }
};

DECLARE_TABLE( HyphSvcList, LangSvcEntry_Hyph * );

class HyphenatorDispatcher :
    public cppu::WeakImplHelper1
    <
        ::com::sun::star::linguistic2::XHyphenator
    >,
    public LinguDispatcher
{
    HyphSvcList     aSvcList;

    ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet >                     xPropSet;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSearchableDictionaryList >  xDicList;

    LngSvcMgr      &rMgr;

    // disallow copy-constructor and assignment-operator for now
    HyphenatorDispatcher(const HyphenatorDispatcher &);
    HyphenatorDispatcher & operator = (const HyphenatorDispatcher &);

    inline ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet >
            GetPropSet();
    inline ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSearchableDictionaryList >
            GetDicList();

    void    ClearSvcList();

    com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XHyphenatedWord>
            buildHyphWord( const rtl::OUString rOrigWord,
                const ::com::sun::star::uno::Reference<
                    ::com::sun::star::linguistic2::XDictionaryEntry> &xEntry,
                INT16 nLang, INT16 nMaxLeading );

    com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XPossibleHyphens >
            buildPossHyphens( const ::com::sun::star::uno::Reference<
                    ::com::sun::star::linguistic2::XDictionaryEntry > &xEntry,
                    INT16 nLanguage );

public:
    HyphenatorDispatcher( LngSvcMgr &rLngSvcMgr );
    virtual ~HyphenatorDispatcher();

    // XSupportedLocales
    virtual ::com::sun::star::uno::Sequence<
            ::com::sun::star::lang::Locale > SAL_CALL
        getLocales()
            throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL
        hasLocale( const ::com::sun::star::lang::Locale& aLocale )
            throw(::com::sun::star::uno::RuntimeException);

    // XHyphenator
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL
        hyphenate( const ::rtl::OUString& aWord,
                const ::com::sun::star::lang::Locale& aLocale,
                sal_Int16 nMaxLeading,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL
        queryAlternativeSpelling( const ::rtl::OUString& aWord,
                const ::com::sun::star::lang::Locale& aLocale,
                sal_Int16 nIndex,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XPossibleHyphens > SAL_CALL
        createPossibleHyphens(
                const ::rtl::OUString& aWord,
                const ::com::sun::star::lang::Locale& aLocale,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);

    // LinguDispatcher
    virtual void
        SetServiceList( const ::com::sun::star::lang::Locale &rLocale,
                const ::com::sun::star::uno::Sequence<
                    rtl::OUString > &rSvcImplNames );
    virtual ::com::sun::star::uno::Sequence< rtl::OUString >
        GetServiceList( const ::com::sun::star::lang::Locale &rLocale ) const;
    virtual DspType
        GetDspType() const;
};

inline ::com::sun::star::uno::Reference<
    ::com::sun::star::beans::XPropertySet >
        HyphenatorDispatcher::GetPropSet()
{
    return xPropSet.is() ?
                xPropSet : xPropSet = ::linguistic::GetLinguProperties();
}

inline ::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XSearchableDictionaryList >
        HyphenatorDispatcher::GetDicList()
{
    return xDicList.is() ?
                xDicList : xDicList = ::linguistic::GetSearchableDictionaryList();
}

///////////////////////////////////////////////////////////////////////////

#endif

<commit_msg>INTEGRATION: CWS tl32 (1.4.34); FILE MERGED 2006/11/02 15:42:37 tl 1.4.34.1: #140479# warning-free code for unxsols4(.pro)<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: hyphdsp.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-25 12:22:52 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _LINGUISTIC_HYPHDSP_HXX_
#define _LINGUISTIC_HYPHDSP_HXX_

#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEDISPLAYNAME_HPP_
#include <com/sun/star/lang/XServiceDisplayName.hpp>
#endif
#include <com/sun/star/linguistic2/XHyphenator.hpp>
#include <com/sun/star/linguistic2/XPossibleHyphens.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
#include <com/sun/star/linguistic2/XLinguServiceEventBroadcaster.hpp>

#ifndef _TOOLS_TABLE_HXX
#include <tools/table.hxx>
#endif

#include <uno/lbnames.h>            // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type
#include <cppuhelper/implbase1.hxx> // helper for implementations

#include "lngopt.hxx"
#include "misc.hxx"
#include "defs.hxx"

class LngSvcMgr;

///////////////////////////////////////////////////////////////////////////

class LangSvcEntry_Hyph
{
    friend class HyphenatorDispatcher;

    ::rtl::OUString                                     aSvcImplName;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XHyphenator >    aSvcRef;

//  INT16           nLang;     //used as key in the table
    SvcFlags        aFlags;

public:
    LangSvcEntry_Hyph() {}
    LangSvcEntry_Hyph( const ::rtl::OUString &rSvcImplName );
    ~LangSvcEntry_Hyph();

    BOOL    IsAlreadyWarned() const     { return aFlags.bAlreadyWarned != 0; }
    void    SetAlreadyWarned(BOOL bVal) { aFlags.bAlreadyWarned = 0 != bVal; }
    BOOL    IsDoWarnAgain() const       { return aFlags.bDoWarnAgain != 0; }
    void    SetDoWarnAgain(BOOL bVal)   { aFlags.bDoWarnAgain = 0 != bVal; }
};

DECLARE_TABLE( HyphSvcList, LangSvcEntry_Hyph * )

class HyphenatorDispatcher :
    public cppu::WeakImplHelper1
    <
        ::com::sun::star::linguistic2::XHyphenator
    >,
    public LinguDispatcher
{
    HyphSvcList     aSvcList;

    ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet >                     xPropSet;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSearchableDictionaryList >  xDicList;

    LngSvcMgr      &rMgr;

    // disallow copy-constructor and assignment-operator for now
    HyphenatorDispatcher(const HyphenatorDispatcher &);
    HyphenatorDispatcher & operator = (const HyphenatorDispatcher &);

    inline ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet >
            GetPropSet();
    inline ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSearchableDictionaryList >
            GetDicList();

    void    ClearSvcList();

    com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XHyphenatedWord>
            buildHyphWord( const rtl::OUString rOrigWord,
                const ::com::sun::star::uno::Reference<
                    ::com::sun::star::linguistic2::XDictionaryEntry> &xEntry,
                INT16 nLang, INT16 nMaxLeading );

    com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XPossibleHyphens >
            buildPossHyphens( const ::com::sun::star::uno::Reference<
                    ::com::sun::star::linguistic2::XDictionaryEntry > &xEntry,
                    INT16 nLanguage );

public:
    HyphenatorDispatcher( LngSvcMgr &rLngSvcMgr );
    virtual ~HyphenatorDispatcher();

    // XSupportedLocales
    virtual ::com::sun::star::uno::Sequence<
            ::com::sun::star::lang::Locale > SAL_CALL
        getLocales()
            throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL
        hasLocale( const ::com::sun::star::lang::Locale& aLocale )
            throw(::com::sun::star::uno::RuntimeException);

    // XHyphenator
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL
        hyphenate( const ::rtl::OUString& aWord,
                const ::com::sun::star::lang::Locale& aLocale,
                sal_Int16 nMaxLeading,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL
        queryAlternativeSpelling( const ::rtl::OUString& aWord,
                const ::com::sun::star::lang::Locale& aLocale,
                sal_Int16 nIndex,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XPossibleHyphens > SAL_CALL
        createPossibleHyphens(
                const ::rtl::OUString& aWord,
                const ::com::sun::star::lang::Locale& aLocale,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);

    // LinguDispatcher
    virtual void
        SetServiceList( const ::com::sun::star::lang::Locale &rLocale,
                const ::com::sun::star::uno::Sequence<
                    rtl::OUString > &rSvcImplNames );
    virtual ::com::sun::star::uno::Sequence< rtl::OUString >
        GetServiceList( const ::com::sun::star::lang::Locale &rLocale ) const;
    virtual DspType
        GetDspType() const;
};

inline ::com::sun::star::uno::Reference<
    ::com::sun::star::beans::XPropertySet >
        HyphenatorDispatcher::GetPropSet()
{
    return xPropSet.is() ?
                xPropSet : xPropSet = ::linguistic::GetLinguProperties();
}

inline ::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XSearchableDictionaryList >
        HyphenatorDispatcher::GetDicList()
{
    return xDicList.is() ?
                xDicList : xDicList = ::linguistic::GetSearchableDictionaryList();
}

///////////////////////////////////////////////////////////////////////////

#endif

<|endoftext|>


<commit_before>#include "../../core_include/api.h"
#include "../../core_include/msg.h"
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <windows.h>
#include <assert.h>

#define MAX_TIMER_CNT 10
#define TIMER_UNIT 50//ms

static void(*do_assert)(const char* file, int line);
static void(*do_log_out)(const char* log);
void register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log))
{
	do_assert = my_assert;
	do_log_out = my_log_out;
}

void _assert(const char* file, int line)
{
	static char s_buf[192];
	if (do_assert)
	{
		do_assert(file, line);
	}
	else
	{
		memset(s_buf, 0, sizeof(s_buf));
		sprintf_s(s_buf, sizeof(s_buf), "vvvvvvvvvvvvvvvvvvvvvvvvvvvv\n\nAssert@ file = %s, line = %d\n\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", file, line);
		OutputDebugStringA(s_buf);
		printf("%s", s_buf);
		fflush(stdout);
		assert(false);
	}
}

void log_out(const char* log)
{
	if (do_log_out)
	{
		do_log_out(log);
	}
	else
	{
		printf("%s", log);
		fflush(stdout);
		OutputDebugStringA(log);
	}
}

typedef struct _timer_manage
{
    struct  _timer_info
    {
        int state; /* on or off */
        int interval;
        int elapse; /* 0~interval */
        void (* timer_proc) (void* ptmr, void* parg);
    }timer_info[MAX_TIMER_CNT];

    void (* old_sigfunc)(int);
    void (* new_sigfunc)(int);
}_timer_manage_t;
static struct _timer_manage timer_manage;

DWORD WINAPI timer_routine(LPVOID lpParam)
{
    int i;
    while(true)
    {
    	for(i = 0; i < MAX_TIMER_CNT; i++)
		{
			if(timer_manage.timer_info[i].state == 0)
			{
				continue;
			}
			timer_manage.timer_info[i].elapse++;
			if(timer_manage.timer_info[i].elapse == timer_manage.timer_info[i].interval)
			{
				timer_manage.timer_info[i].elapse = 0;
				timer_manage.timer_info[i].timer_proc(0, 0);
			}
		}
		Sleep(TIMER_UNIT);
    }
    return 0;
}

static int init_mul_timer()
{
	static bool s_is_init = false;
	if(s_is_init == true)
	{
		return 0;
	}
    memset(&timer_manage, 0, sizeof(struct _timer_manage));
    DWORD pid;
	CreateThread(0, 0, timer_routine, 0, 0, &pid);
    s_is_init = true;
    return 1;
}

static int set_a_timer(int interval, void (* timer_proc) (void* ptmr, void* parg))
{
	init_mul_timer();

	int i;
    if(timer_proc == 0 || interval <= 0)
    {
        return (-1);
    }

    for(i = 0; i < MAX_TIMER_CNT; i++)
    {
        if(timer_manage.timer_info[i].state == 1)
        {
            continue;
        }
        memset(&timer_manage.timer_info[i], 0, sizeof(timer_manage.timer_info[i]));
        timer_manage.timer_info[i].timer_proc = timer_proc;
        timer_manage.timer_info[i].interval = interval;
        timer_manage.timer_info[i].elapse = 0;
        timer_manage.timer_info[i].state = 1;
        break;
    }

    if(i >= MAX_TIMER_CNT)
    {
		ASSERT(false);
        return (-1);
    }
    return (i);
}

typedef void (*EXPIRE_ROUTINE)(void* arg);
EXPIRE_ROUTINE s_expire_function;
static c_fifo s_real_timer_fifo;

static DWORD WINAPI fire_real_timer(LPVOID lpParam)
{
	char dummy;
	while(1)
	{
		if(s_real_timer_fifo.read(&dummy, 1) > 0)
		{
			if(s_expire_function)s_expire_function(0);
		}
		else
		{
			ASSERT(false);
		}
	}
	return 0;
}

/*Win32 desktop only
static void CALLBACK trigger_real_timer(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR)
{
	char dummy = 0x33;
	s_real_timer_fifo.write(&dummy, 1);
}
*/

static DWORD WINAPI trigger_real_timer(LPVOID lpParam)
{
	char dummy = 0x33;
	while (1)
	{
		s_real_timer_fifo.write(&dummy, 1);
		Sleep(REAL_TIME_TASK_CYCLE_MS);
	}
	return 0;
}

void start_real_timer(void (*func)(void* arg))
{
	if(0 == func)
	{
		return;
	}

	s_expire_function = func;
	//timeSetEvent(REAL_TIME_TASK_CYCLE_MS, 0, trigger_real_timer, 0, TIME_PERIODIC);//Win32 desktop only

	static DWORD s_pid;
	if(s_pid == 0)
	{
		CreateThread(0, 0, trigger_real_timer, 0, 0, &s_pid);
		CreateThread(0, 0, fire_real_timer, 0, 0, &s_pid);
	}
}

unsigned int get_cur_thread_id()
{
	return GetCurrentThreadId();
}

void register_timer(int milli_second,void func(void* ptmr, void* parg))
{
	set_a_timer(milli_second/TIMER_UNIT,func);
}

long get_time_in_second()
{
	return time(0);
}

T_TIME get_time()
{
	T_TIME ret = {0};

	SYSTEMTIME time;
	GetLocalTime(&time);
	ret.year = time.wYear;
	ret.month = time.wMonth;
	ret.day = time.wDay;
	ret.hour = time.wHour;
	ret.minute = time.wMinute;
	ret.second = time.wSecond;
	return ret;
}

T_TIME second_to_day(long second)
{
	T_TIME ret;
	ret.year = 1999;
	ret.month = 10;
	ret.date = 1;

	ret.second = second % 60;
	second /= 60;
	ret.minute = second % 60;
	second /= 60;
	ret.hour = (second + 8) % 24;//China time zone.
	return ret;
}

void create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg)
{
	DWORD pid = 0;
	CreateThread(0, 0, LPTHREAD_START_ROUTINE(start_routine), arg, 0, &pid);
	*thread_id = pid;
}

void thread_sleep(unsigned int milli_seconds)
{
	Sleep(milli_seconds);
}

#pragma pack(push,1)
typedef struct {
	unsigned short	bfType;
	unsigned int   	bfSize;
	unsigned short  bfReserved1;
	unsigned short  bfReserved2;
	unsigned int   	bfOffBits;
}FileHead;

typedef struct {
	unsigned int  	biSize;
	int 			biWidth;
	int       		biHeight;
	unsigned short	biPlanes;
	unsigned short  biBitCount;
	unsigned int    biCompress;
	unsigned int    biSizeImage;
	int       		biXPelsPerMeter;
	int       		biYPelsPerMeter;
	unsigned int 	biClrUsed;
	unsigned int    biClrImportant;
	unsigned int 	biRedMask;
	unsigned int 	biGreenMask;
	unsigned int 	biBlueMask;
}Infohead;
#pragma pack(pop)

int build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data)
{
	FileHead bmp_head;
	Infohead bmp_info;
	int size = width * height * 2;

	//initialize bmp head.
	bmp_head.bfType = 0x4d42;
	bmp_head.bfSize = size + sizeof(FileHead) + sizeof(Infohead);
	bmp_head.bfReserved1 = bmp_head.bfReserved2 = 0;
	bmp_head.bfOffBits = bmp_head.bfSize - size;

	//initialize bmp info.
	bmp_info.biSize = 40;
	bmp_info.biWidth = width;
	bmp_info.biHeight = height;
	bmp_info.biPlanes = 1;
	bmp_info.biBitCount = 16;
	bmp_info.biCompress = 3;
	bmp_info.biSizeImage = size;
	bmp_info.biXPelsPerMeter = 0;
	bmp_info.biYPelsPerMeter = 0;
	bmp_info.biClrUsed = 0;
	bmp_info.biClrImportant = 0;

	//RGB565
	bmp_info.biRedMask = 0xF800;
	bmp_info.biGreenMask = 0x07E0;
	bmp_info.biBlueMask = 0x001F;

	//copy the data
	FILE *fp;
	if (!(fp = fopen(filename, "wb")))
	{
		return -1;
	}

	fwrite(&bmp_head, 1, sizeof(FileHead), fp);
	fwrite(&bmp_info, 1, sizeof(Infohead), fp);

	//fwrite(data, 1, size, fp);//top <-> bottom
	for (int i = (height - 1); i >= 0; --i)
	{
		fwrite(&data[i * width * 2], 1, width * 2, fp);
	}

	fclose(fp);
	return 0;
}<commit_msg>add newline at end of file<commit_after>#include "../../core_include/api.h"
#include "../../core_include/msg.h"
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <windows.h>
#include <assert.h>

#define MAX_TIMER_CNT 10
#define TIMER_UNIT 50//ms

static void(*do_assert)(const char* file, int line);
static void(*do_log_out)(const char* log);
void register_debug_function(void(*my_assert)(const char* file, int line), void(*my_log_out)(const char* log))
{
	do_assert = my_assert;
	do_log_out = my_log_out;
}

void _assert(const char* file, int line)
{
	static char s_buf[192];
	if (do_assert)
	{
		do_assert(file, line);
	}
	else
	{
		memset(s_buf, 0, sizeof(s_buf));
		sprintf_s(s_buf, sizeof(s_buf), "vvvvvvvvvvvvvvvvvvvvvvvvvvvv\n\nAssert@ file = %s, line = %d\n\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", file, line);
		OutputDebugStringA(s_buf);
		printf("%s", s_buf);
		fflush(stdout);
		assert(false);
	}
}

void log_out(const char* log)
{
	if (do_log_out)
	{
		do_log_out(log);
	}
	else
	{
		printf("%s", log);
		fflush(stdout);
		OutputDebugStringA(log);
	}
}

typedef struct _timer_manage
{
    struct  _timer_info
    {
        int state; /* on or off */
        int interval;
        int elapse; /* 0~interval */
        void (* timer_proc) (void* ptmr, void* parg);
    }timer_info[MAX_TIMER_CNT];

    void (* old_sigfunc)(int);
    void (* new_sigfunc)(int);
}_timer_manage_t;
static struct _timer_manage timer_manage;

DWORD WINAPI timer_routine(LPVOID lpParam)
{
    int i;
    while(true)
    {
    	for(i = 0; i < MAX_TIMER_CNT; i++)
		{
			if(timer_manage.timer_info[i].state == 0)
			{
				continue;
			}
			timer_manage.timer_info[i].elapse++;
			if(timer_manage.timer_info[i].elapse == timer_manage.timer_info[i].interval)
			{
				timer_manage.timer_info[i].elapse = 0;
				timer_manage.timer_info[i].timer_proc(0, 0);
			}
		}
		Sleep(TIMER_UNIT);
    }
    return 0;
}

static int init_mul_timer()
{
	static bool s_is_init = false;
	if(s_is_init == true)
	{
		return 0;
	}
    memset(&timer_manage, 0, sizeof(struct _timer_manage));
    DWORD pid;
	CreateThread(0, 0, timer_routine, 0, 0, &pid);
    s_is_init = true;
    return 1;
}

static int set_a_timer(int interval, void (* timer_proc) (void* ptmr, void* parg))
{
	init_mul_timer();

	int i;
    if(timer_proc == 0 || interval <= 0)
    {
        return (-1);
    }

    for(i = 0; i < MAX_TIMER_CNT; i++)
    {
        if(timer_manage.timer_info[i].state == 1)
        {
            continue;
        }
        memset(&timer_manage.timer_info[i], 0, sizeof(timer_manage.timer_info[i]));
        timer_manage.timer_info[i].timer_proc = timer_proc;
        timer_manage.timer_info[i].interval = interval;
        timer_manage.timer_info[i].elapse = 0;
        timer_manage.timer_info[i].state = 1;
        break;
    }

    if(i >= MAX_TIMER_CNT)
    {
		ASSERT(false);
        return (-1);
    }
    return (i);
}

typedef void (*EXPIRE_ROUTINE)(void* arg);
EXPIRE_ROUTINE s_expire_function;
static c_fifo s_real_timer_fifo;

static DWORD WINAPI fire_real_timer(LPVOID lpParam)
{
	char dummy;
	while(1)
	{
		if(s_real_timer_fifo.read(&dummy, 1) > 0)
		{
			if(s_expire_function)s_expire_function(0);
		}
		else
		{
			ASSERT(false);
		}
	}
	return 0;
}

/*Win32 desktop only
static void CALLBACK trigger_real_timer(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR)
{
	char dummy = 0x33;
	s_real_timer_fifo.write(&dummy, 1);
}
*/

static DWORD WINAPI trigger_real_timer(LPVOID lpParam)
{
	char dummy = 0x33;
	while (1)
	{
		s_real_timer_fifo.write(&dummy, 1);
		Sleep(REAL_TIME_TASK_CYCLE_MS);
	}
	return 0;
}

void start_real_timer(void (*func)(void* arg))
{
	if(0 == func)
	{
		return;
	}

	s_expire_function = func;
	//timeSetEvent(REAL_TIME_TASK_CYCLE_MS, 0, trigger_real_timer, 0, TIME_PERIODIC);//Win32 desktop only

	static DWORD s_pid;
	if(s_pid == 0)
	{
		CreateThread(0, 0, trigger_real_timer, 0, 0, &s_pid);
		CreateThread(0, 0, fire_real_timer, 0, 0, &s_pid);
	}
}

unsigned int get_cur_thread_id()
{
	return GetCurrentThreadId();
}

void register_timer(int milli_second,void func(void* ptmr, void* parg))
{
	set_a_timer(milli_second/TIMER_UNIT,func);
}

long get_time_in_second()
{
	return time(0);
}

T_TIME get_time()
{
	T_TIME ret = {0};

	SYSTEMTIME time;
	GetLocalTime(&time);
	ret.year = time.wYear;
	ret.month = time.wMonth;
	ret.day = time.wDay;
	ret.hour = time.wHour;
	ret.minute = time.wMinute;
	ret.second = time.wSecond;
	return ret;
}

T_TIME second_to_day(long second)
{
	T_TIME ret;
	ret.year = 1999;
	ret.month = 10;
	ret.date = 1;

	ret.second = second % 60;
	second /= 60;
	ret.minute = second % 60;
	second /= 60;
	ret.hour = (second + 8) % 24;//China time zone.
	return ret;
}

void create_thread(unsigned long* thread_id, void* attr, void *(*start_routine) (void *), void* arg)
{
	DWORD pid = 0;
	CreateThread(0, 0, LPTHREAD_START_ROUTINE(start_routine), arg, 0, &pid);
	*thread_id = pid;
}

void thread_sleep(unsigned int milli_seconds)
{
	Sleep(milli_seconds);
}

#pragma pack(push,1)
typedef struct {
	unsigned short	bfType;
	unsigned int   	bfSize;
	unsigned short  bfReserved1;
	unsigned short  bfReserved2;
	unsigned int   	bfOffBits;
}FileHead;

typedef struct {
	unsigned int  	biSize;
	int 			biWidth;
	int       		biHeight;
	unsigned short	biPlanes;
	unsigned short  biBitCount;
	unsigned int    biCompress;
	unsigned int    biSizeImage;
	int       		biXPelsPerMeter;
	int       		biYPelsPerMeter;
	unsigned int 	biClrUsed;
	unsigned int    biClrImportant;
	unsigned int 	biRedMask;
	unsigned int 	biGreenMask;
	unsigned int 	biBlueMask;
}Infohead;
#pragma pack(pop)

int build_bmp(const char *filename, unsigned int width, unsigned int height, unsigned char *data)
{
	FileHead bmp_head;
	Infohead bmp_info;
	int size = width * height * 2;

	//initialize bmp head.
	bmp_head.bfType = 0x4d42;
	bmp_head.bfSize = size + sizeof(FileHead) + sizeof(Infohead);
	bmp_head.bfReserved1 = bmp_head.bfReserved2 = 0;
	bmp_head.bfOffBits = bmp_head.bfSize - size;

	//initialize bmp info.
	bmp_info.biSize = 40;
	bmp_info.biWidth = width;
	bmp_info.biHeight = height;
	bmp_info.biPlanes = 1;
	bmp_info.biBitCount = 16;
	bmp_info.biCompress = 3;
	bmp_info.biSizeImage = size;
	bmp_info.biXPelsPerMeter = 0;
	bmp_info.biYPelsPerMeter = 0;
	bmp_info.biClrUsed = 0;
	bmp_info.biClrImportant = 0;

	//RGB565
	bmp_info.biRedMask = 0xF800;
	bmp_info.biGreenMask = 0x07E0;
	bmp_info.biBlueMask = 0x001F;

	//copy the data
	FILE *fp;
	if (!(fp = fopen(filename, "wb")))
	{
		return -1;
	}

	fwrite(&bmp_head, 1, sizeof(FileHead), fp);
	fwrite(&bmp_info, 1, sizeof(Infohead), fp);

	//fwrite(data, 1, size, fp);//top <-> bottom
	for (int i = (height - 1); i >= 0; --i)
	{
		fwrite(&data[i * width * 2], 1, width * 2, fp);
	}

	fclose(fp);
	return 0;
}
<|endoftext|>


<commit_before>/**************************************************************************
** This file is part of LiteIDE
**
** Copyright (c) 2011-2014 LiteIDE Team. All rights reserved.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
**
** In addition, as a special exception,  that plugins developed for LiteIDE,
** are allowed to remain closed sourced and can be distributed under any license .
** These rights are included in the file LGPL_EXCEPTION.txt in this package.
**
**************************************************************************/
// Module: main.cpp
// Creator: visualfc <visualfc@gmail.com>

#include <QApplication>
#include <QTranslator>
#include <QLocale>
#include <QLibraryInfo>
#include <QDir>
#include <QSettings>
#include <QSplashScreen>
#include <QTextCodec>
#if QT_VERSION >= 0x050000
#include <QStandardPaths>
#endif
#include <QDebug>
#include "mainwindow.h"
#include "liteapp.h"
#include "goproxy.h"
#include "cdrv.h"
//lite_memory_check_begin
#if defined(WIN32) && defined(_MSC_VER) &&  defined(_DEBUG)
     #define _CRTDBG_MAP_ALLOC
     #include <stdlib.h>
     #include <crtdbg.h>
     #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
     #define new DEBUG_NEW
#endif
//lite_memory_check_end

#ifdef LITEAPP_LIBRARY
int liteapp_main(int argc, char *argv[])
#else
int main(int argc, char *argv[])
#endif
{
#ifndef LITEAPP_LIBRARY
    #if defined(_MSC_VER) && defined(_DEBUG)
        _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
    #endif
#endif
    QApplication app(argc, argv);

#if QT_VERSION >= 0x050100
    app.setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif

    QTranslator translator;
    QTranslator qtTranslator;
    const QSettings settings(QSettings::IniFormat,QSettings::UserScope,"liteide","liteide");
    QString locale = QLocale::system().name();
    locale = settings.value(LITEAPP_LANGUAGE,locale).toString();
    QString resPath = LiteApp::getResoucePath();
    if (!locale.isEmpty()) {
        const QString &liteideTrPath = resPath+"/translations";
        if (translator.load(QLatin1String("liteide_") + locale, liteideTrPath)) {
            const QString &qtTrPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
            const QString &qtTrFile = QLatin1String("qt_") + locale;
            // Binary installer puts Qt tr files into creatorTrPath
            app.installTranslator(&translator);
            if (qtTranslator.load(qtTrFile, qtTrPath) || qtTranslator.load(qtTrFile, liteideTrPath)) {
                app.installTranslator(&qtTranslator);
            }
            app.setProperty("liteide_locale", locale);
        }
    }
    QString qss = settings.value(LITEAPP_QSS,"default.qss").toString();
    if (!qss.isEmpty()) {
        QFile f(resPath+"/liteapp/qss/"+qss);
        if (f.open(QFile::ReadOnly)) {
            QString styleSheet = QLatin1String(f.readAll());
            app.setStyleSheet(styleSheet);
        }
    }

    QDir::addSearchPath("icon",resPath);
    QDir::addSearchPath("icon",resPath+"/liteapp");
    QDir::addSearchPath("icon",":/");
#if QT_VERSION >= 0x050000
    QString storage = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
#else
    QString storage = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
#endif
    QDir dir(storage);
    dir.mkdir("liteide");

    QStringList argList;
    QStringList fileList;
    if (argc >= 2) {
        for (int i = 1; i < argc; i++) {
            QString arg = argv[i];
            if (arg.startsWith("-")) {
                argList.append(arg);
                continue;
            } else {
                fileList.append(arg);
            }
        }
    }

    IApplication *liteApp = LiteApp::NewApplication(true,0);

    if (fileList.size() == 1) {
        QString file = fileList.at(0);
        QFileInfo f(file);
        if (f.isFile()) {
            liteApp->fileManager()->openFolderEx(f.path());
            liteApp->fileManager()->openEditor(file);
        } else if (f.isDir()) {
            liteApp->fileManager()->openFolderEx(file);
        }
    } else {
        foreach(QString file, fileList) {
            QFileInfo f(file);
            if (f.isFile()) {
                liteApp->fileManager()->openEditor(file);
            } else if (f.isDir()) {
                liteApp->fileManager()->openFolderEx(file);
            }
        }
    }
    int ret = app.exec();
    return ret;
}

int cdrv_main(int argc, char **argv)
{
    return liteapp_main(argc,argv);
}
<commit_msg>update<commit_after>/**************************************************************************
** This file is part of LiteIDE
**
** Copyright (c) 2011-2014 LiteIDE Team. All rights reserved.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
** Lesser General Public License for more details.
**
** In addition, as a special exception,  that plugins developed for LiteIDE,
** are allowed to remain closed sourced and can be distributed under any license .
** These rights are included in the file LGPL_EXCEPTION.txt in this package.
**
**************************************************************************/
// Module: main.cpp
// Creator: visualfc <visualfc@gmail.com>

#include <QApplication>
#include <QTranslator>
#include <QLocale>
#include <QLibraryInfo>
#include <QDir>
#include <QSettings>
#include <QSplashScreen>
#include <QTextCodec>
#if QT_VERSION >= 0x050000
#include <QStandardPaths>
#endif
#include <QDebug>
#include "mainwindow.h"
#include "liteapp.h"
#include "goproxy.h"
#include "cdrv.h"
//lite_memory_check_begin
#if defined(WIN32) && defined(_MSC_VER) &&  defined(_DEBUG)
     #define _CRTDBG_MAP_ALLOC
     #include <stdlib.h>
     #include <crtdbg.h>
     #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
     #define new DEBUG_NEW
#endif
//lite_memory_check_end

#ifdef LITEAPP_LIBRARY
int liteapp_main(int argc, char *argv[])
#else
int main(int argc, char *argv[])
#endif
{
#ifndef LITEAPP_LIBRARY
    #if defined(_MSC_VER) && defined(_DEBUG)
        _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
    #endif
#endif
    QApplication app(argc, argv);

#if QT_VERSION >= 0x050100
    app.setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif

    QTranslator translator;
    QTranslator qtTranslator;

    QString resPath = LiteApp::getResoucePath();
    QString locale = QLocale::system().name();
    QString qss;
    QSettings global(resPath+"/liteapp/config/global.ini",QSettings::IniFormat);
    bool storeLocal = global.value(LITEIDE_STORELOCAL,false).toBool();
    if (storeLocal) {
        const QSettings settings(resPath+"/liteapp/config/liteide.ini", QSettings::IniFormat);
        locale = settings.value(LITEAPP_LANGUAGE,locale).toString();
        qss = settings.value(LITEAPP_QSS,"default.qss").toString();
    } else {
        const QSettings settings(QSettings::IniFormat,QSettings::UserScope,"liteide","liteide");
        locale = settings.value(LITEAPP_LANGUAGE,locale).toString();
        qss = settings.value(LITEAPP_QSS,"default.qss").toString();
    }

    if (!locale.isEmpty()) {
        const QString &liteideTrPath = resPath+"/translations";
        if (translator.load(QLatin1String("liteide_") + locale, liteideTrPath)) {
            const QString &qtTrPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
            const QString &qtTrFile = QLatin1String("qt_") + locale;
            // Binary installer puts Qt tr files into creatorTrPath
            app.installTranslator(&translator);
            if (qtTranslator.load(qtTrFile, qtTrPath) || qtTranslator.load(qtTrFile, liteideTrPath)) {
                app.installTranslator(&qtTranslator);
            }
            app.setProperty("liteide_locale", locale);
        }
    }
    if (!qss.isEmpty()) {
        QFile f(resPath+"/liteapp/qss/"+qss);
        if (f.open(QFile::ReadOnly)) {
            QString styleSheet = QLatin1String(f.readAll());
            app.setStyleSheet(styleSheet);
        }
    }

    QDir::addSearchPath("icon",resPath);
    QDir::addSearchPath("icon",resPath+"/liteapp");
    QDir::addSearchPath("icon",":/");
#if QT_VERSION >= 0x050000
    QString storage = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
#else
    QString storage = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
#endif
    QDir dir(storage);
    dir.mkdir("liteide");

    QStringList argList;
    QStringList fileList;
    if (argc >= 2) {
        for (int i = 1; i < argc; i++) {
            QString arg = argv[i];
            if (arg.startsWith("-")) {
                argList.append(arg);
                continue;
            } else {
                fileList.append(arg);
            }
        }
    }

    IApplication *liteApp = LiteApp::NewApplication(true,0);

    if (fileList.size() == 1) {
        QString file = fileList.at(0);
        QFileInfo f(file);
        if (f.isFile()) {
            liteApp->fileManager()->openFolderEx(f.path());
            liteApp->fileManager()->openEditor(file);
        } else if (f.isDir()) {
            liteApp->fileManager()->openFolderEx(file);
        }
    } else {
        foreach(QString file, fileList) {
            QFileInfo f(file);
            if (f.isFile()) {
                liteApp->fileManager()->openEditor(file);
            } else if (f.isDir()) {
                liteApp->fileManager()->openFolderEx(file);
            }
        }
    }
    int ret = app.exec();
    return ret;
}

int cdrv_main(int argc, char **argv)
{
    return liteapp_main(argc,argv);
}
<|endoftext|>


<commit_before>// -*- C++ -*-
//
//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//                               Charles A. Williams
//                        Rensselaer Polytechnic Institute
//                        (C) 2004 All Rights Reserved
//
//  Copyright 2004 Rensselaer Polytechnic Institute.
//  All worldwide rights reserved.  A license to use, copy, modify and
//  distribute this software for non-commercial research purposes only
//  is hereby granted, provided that this copyright notice and
//  accompanying disclaimer is not modified or removed from the software.
//
//  DISCLAIMER:  The software is distributed "AS IS" without any express
//  or implied warranty, including but not limited to, any implied
//  warranties of merchantability or fitness for a particular purpose
//  or any warranty of non-infringement of any current or pending patent
//  rights.  The authors of the software make no representations about
//  the suitability of this software for any particular purpose.  The
//  entire risk as to the quality and performance of the software is with
//  the user.  Should the software prove defective, the user assumes the
//  cost of all necessary servicing, repair or correction.  In
//  particular, neither Rensselaer Polytechnic Institute, nor the authors
//  of the software are liable for any indirect, special, consequential,
//  or incidental damages related to the software, to the maximum extent
//  the law permits.
//
//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

#include <portinfo>
#include <Python.h>

#include "bindings.h"

#include "array.h"         // array allocation and conversion functions
#include "elastc.h"        // elastic solution driver
#include "input_misc.h"    // miscellaneous input and indexing routines
#include "parser.h"        // parsers
#include "scanner.h"       // scanners
#include "sparse.h"        // sparse matrix routines
#include "viscos.h"        // time-dependent solution driver
#include "misc.h"          // miscellaneous methods

// the method table

struct PyMethodDef pylithomop3d_methods[] = {

    // adjust id array for slippery nodes
    {pylithomop3d_adjid__name__, pylithomop3d_adjid,
     METH_VARARGS, pylithomop3d_adjid__doc__},

    // allocate an integer array
    {pylithomop3d_allocateInt__name__, pylithomop3d_allocateInt,
     METH_VARARGS, pylithomop3d_allocateInt__doc__},

    // allocate a double array
    {pylithomop3d_allocateDouble__name__, pylithomop3d_allocateDouble,
     METH_VARARGS, pylithomop3d_allocateDouble__doc__},

    // convert a double list to an array
    {pylithomop3d_doubleListToArray__name__, pylithomop3d_doubleListToArray,
     METH_VARARGS, pylithomop3d_doubleListToArray__doc__},

    // drive elastic solution
    {pylithomop3d_elastc__name__, pylithomop3d_elastc,
     METH_VARARGS, pylithomop3d_elastc__doc__},

    // form id array for split nodes
    {pylithomop3d_id_split__name__, pylithomop3d_id_split,
     METH_VARARGS, pylithomop3d_id_split__doc__},

    // convert an integer list to an array
    {pylithomop3d_intListToArray__name__, pylithomop3d_intListToArray,
     METH_VARARGS, pylithomop3d_intListToArray__doc__},

    // create linked list for sparse matrix
    {pylithomop3d_lnklst__name__, pylithomop3d_lnklst,
     METH_VARARGS, pylithomop3d_lnklst__doc__},

    // localize id array
    {pylithomop3d_local__name__, pylithomop3d_local,
     METH_VARARGS, pylithomop3d_local__doc__},

    // localize id array for split nodes
    {pylithomop3d_localf__name__, pylithomop3d_localf,
     METH_VARARGS, pylithomop3d_localf__doc__},

    // localize id array for slippery nodes
    {pylithomop3d_localx__name__, pylithomop3d_localx,
     METH_VARARGS, pylithomop3d_localx__doc__},

    // create sparse matrix in modified sparse row format
    {pylithomop3d_makemsr__name__, pylithomop3d_makemsr,
     METH_VARARGS, pylithomop3d_makemsr__doc__},

    // find closest fault neignbors for slippery nodes
    {pylithomop3d_nfind__name__, pylithomop3d_nfind,
     METH_VARARGS, pylithomop3d_nfind__doc__},

    // read boundary conditions
    {pylithomop3d_read_bc__name__, pylithomop3d_read_bc,
     METH_VARARGS, pylithomop3d_read_bc__doc__},

    // read connectivities
    {pylithomop3d_read_connect__name__, pylithomop3d_read_connect,
     METH_VARARGS, pylithomop3d_read_connect__doc__},

    // read coordinates
    {pylithomop3d_read_coords__name__, pylithomop3d_read_coords,
     METH_VARARGS, pylithomop3d_read_coords__doc__},

    // read differential forces
    {pylithomop3d_read_diff__name__, pylithomop3d_read_diff,
     METH_VARARGS, pylithomop3d_read_diff__doc__},

    // read time steps at which full output is desired
    {pylithomop3d_read_fuldat__name__, pylithomop3d_read_fuldat,
     METH_VARARGS, pylithomop3d_read_fuldat__doc__},

    // read time history info
    {pylithomop3d_read_hist__name__, pylithomop3d_read_hist,
     METH_VARARGS, pylithomop3d_read_hist__doc__},

    // read prestresses
    {pylithomop3d_read_prestr__name__, pylithomop3d_read_prestr,
     METH_VARARGS, pylithomop3d_read_prestr__doc__},

    // read material properties
    {pylithomop3d_read_prop__name__, pylithomop3d_read_prop,
     METH_VARARGS, pylithomop3d_read_prop__doc__},

    // read local coordinate rotations
    {pylithomop3d_read_skew__name__, pylithomop3d_read_skew,
     METH_VARARGS, pylithomop3d_read_skew__doc__},

    // read slippery node definitions
    {pylithomop3d_read_slip__name__, pylithomop3d_read_slip,
     METH_VARARGS, pylithomop3d_read_slip__doc__},

    // read split node definitions
    {pylithomop3d_read_split__name__, pylithomop3d_read_split,
     METH_VARARGS, pylithomop3d_read_split__doc__},

    // read time step group information
    {pylithomop3d_read_timdat__name__, pylithomop3d_read_timdat,
     METH_VARARGS, pylithomop3d_read_timdat__doc__},

    // read traction boundary conditions
    {pylithomop3d_read_traction__name__, pylithomop3d_read_traction,
     METH_VARARGS, pylithomop3d_read_traction__doc__},

    // read winkler force information
    {pylithomop3d_read_wink__name__, pylithomop3d_read_wink,
     METH_VARARGS, pylithomop3d_read_wink__doc__},

    // read winkler force information for slippery nodes
    {pylithomop3d_read_winkx__name__, pylithomop3d_read_winkx,
     METH_VARARGS, pylithomop3d_read_winkx__doc__},

    // scan boundary condition file
    {pylithomop3d_scan_bc__name__, pylithomop3d_scan_bc,
     METH_VARARGS, pylithomop3d_scan_bc__doc__},

    // scan connectivity file
    {pylithomop3d_scan_connect__name__, pylithomop3d_scan_connect,
     METH_VARARGS, pylithomop3d_scan_connect__doc__},

    // scan coordinates file
    {pylithomop3d_scan_coords__name__, pylithomop3d_scan_coords,
     METH_VARARGS, pylithomop3d_scan_coords__doc__},

    // scan differential forces file
    {pylithomop3d_scan_diff__name__, pylithomop3d_scan_diff,
     METH_VARARGS, pylithomop3d_scan_diff__doc__},

    // scan time step output info file
    {pylithomop3d_scan_fuldat__name__, pylithomop3d_scan_fuldat,
     METH_VARARGS, pylithomop3d_scan_fuldat__doc__},

    // scan time history definition file
    {pylithomop3d_scan_hist__name__, pylithomop3d_scan_hist,
     METH_VARARGS, pylithomop3d_scan_hist__doc__},

    // scan prestress file
    {pylithomop3d_scan_prestr__name__, pylithomop3d_scan_prestr,
     METH_VARARGS, pylithomop3d_scan_prestr__doc__},

    // scan material properties file
    {pylithomop3d_scan_prop__name__, pylithomop3d_scan_prop,
     METH_VARARGS, pylithomop3d_scan_prop__doc__},

    // scan local coordinate rotations file
    {pylithomop3d_scan_skew__name__, pylithomop3d_scan_skew,
     METH_VARARGS, pylithomop3d_scan_skew__doc__},

    // scan slippery node definitions file
    {pylithomop3d_scan_slip__name__, pylithomop3d_scan_slip,
     METH_VARARGS, pylithomop3d_scan_slip__doc__},

    // scan split node definitions file
    {pylithomop3d_scan_split__name__, pylithomop3d_scan_split,
     METH_VARARGS, pylithomop3d_scan_split__doc__},

    // scan time step group info file
    {pylithomop3d_scan_timdat__name__, pylithomop3d_scan_timdat,
     METH_VARARGS, pylithomop3d_scan_timdat__doc__},

    // scan traction boundary conditions file
    {pylithomop3d_scan_traction__name__, pylithomop3d_scan_traction,
     METH_VARARGS, pylithomop3d_scan_traction__doc__},

    // scan winkler forces info file
    {pylithomop3d_scan_wink__name__, pylithomop3d_scan_wink,
     METH_VARARGS, pylithomop3d_scan_wink__doc__},

    // scan winkler forces info file for slippery nodes
    {pylithomop3d_scan_winkx__name__, pylithomop3d_scan_winkx,
     METH_VARARGS, pylithomop3d_scan_winkx__doc__},

    // drive time-dependent solution
    {pylithomop3d_viscos__name__, pylithomop3d_viscos,
     METH_VARARGS, pylithomop3d_viscos__doc__},

    // write out element and prestress information
    {pylithomop3d_write_element_info__name__, pylithomop3d_write_element_info,
     METH_VARARGS, pylithomop3d_write_element_info__doc__},

    // write out global control information
    {pylithomop3d_write_global_info__name__, pylithomop3d_write_global_info,
     METH_VARARGS, pylithomop3d_write_global_info__doc__},

    // write out sparse matrix information
    {pylithomop3d_write_sparse_info__name__, pylithomop3d_write_sparse_info,
     METH_VARARGS, pylithomop3d_write_sparse_info__doc__},

    // write out stress computation information
    {pylithomop3d_write_strscomp__name__, pylithomop3d_write_strscomp,
     METH_VARARGS, pylithomop3d_write_strscomp__doc__},

    // write out subiteration convergence information
    {pylithomop3d_write_subiter__name__, pylithomop3d_write_subiter,
     METH_VARARGS, pylithomop3d_write_subiter__doc__},

    // copyright note
    {pylithomop3d_copyright__name__, pylithomop3d_copyright,
     METH_VARARGS, pylithomop3d_copyright__doc__},

// Sentinel
    {0, 0}
};

// version
// $Id: bindings.cc,v 1.1 2004/04/14 21:24:47 willic3 Exp $

// End of file
<commit_msg>Updated methods table for new and unused routines.<commit_after>// -*- C++ -*-
//
//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//                               Charles A. Williams
//                        Rensselaer Polytechnic Institute
//                        (C) 2004 All Rights Reserved
//
//  Copyright 2004 Rensselaer Polytechnic Institute.
//  All worldwide rights reserved.  A license to use, copy, modify and
//  distribute this software for non-commercial research purposes only
//  is hereby granted, provided that this copyright notice and
//  accompanying disclaimer is not modified or removed from the software.
//
//  DISCLAIMER:  The software is distributed "AS IS" without any express
//  or implied warranty, including but not limited to, any implied
//  warranties of merchantability or fitness for a particular purpose
//  or any warranty of non-infringement of any current or pending patent
//  rights.  The authors of the software make no representations about
//  the suitability of this software for any particular purpose.  The
//  entire risk as to the quality and performance of the software is with
//  the user.  Should the software prove defective, the user assumes the
//  cost of all necessary servicing, repair or correction.  In
//  particular, neither Rensselaer Polytechnic Institute, nor the authors
//  of the software are liable for any indirect, special, consequential,
//  or incidental damages related to the software, to the maximum extent
//  the law permits.
//
//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

#include <portinfo>
#include <Python.h>

#include "bindings.h"

#include "array.h"         // array allocation and conversion functions
#include "elastc.h"        // elastic solution driver
#include "input_misc.h"    // miscellaneous input and indexing routines
#include "parser.h"        // parsers
#include "scanner.h"       // scanners
#include "setup.h"         // initialization/setup routines
#include "sparse.h"        // sparse matrix routines
#include "viscos.h"        // time-dependent solution driver
#include "misc.h"          // miscellaneous methods

// the method table

struct PyMethodDef pylithomop3d_methods[] = {

    // adjust id array for slippery nodes
    {pylithomop3d_adjid__name__, pylithomop3d_adjid,
     METH_VARARGS, pylithomop3d_adjid__doc__},

    // allocate an integer array
    {pylithomop3d_allocateInt__name__, pylithomop3d_allocateInt,
     METH_VARARGS, pylithomop3d_allocateInt__doc__},

    // allocate a double array
    {pylithomop3d_allocateDouble__name__, pylithomop3d_allocateDouble,
     METH_VARARGS, pylithomop3d_allocateDouble__doc__},

    // convert a double list to an array
    {pylithomop3d_doubleListToArray__name__, pylithomop3d_doubleListToArray,
     METH_VARARGS, pylithomop3d_doubleListToArray__doc__},

    // drive elastic solution
    {pylithomop3d_elastc__name__, pylithomop3d_elastc,
     METH_VARARGS, pylithomop3d_elastc__doc__},

    // form id array for split nodes
    {pylithomop3d_id_split__name__, pylithomop3d_id_split,
     METH_VARARGS, pylithomop3d_id_split__doc__},

    // convert an integer list to an array
    {pylithomop3d_intListToArray__name__, pylithomop3d_intListToArray,
     METH_VARARGS, pylithomop3d_intListToArray__doc__},

    // create linked list for sparse matrix
    {pylithomop3d_lnklst__name__, pylithomop3d_lnklst,
     METH_VARARGS, pylithomop3d_lnklst__doc__},

    // localize id array
    {pylithomop3d_local__name__, pylithomop3d_local,
     METH_VARARGS, pylithomop3d_local__doc__},

    // localize id array for split nodes
    {pylithomop3d_localf__name__, pylithomop3d_localf,
     METH_VARARGS, pylithomop3d_localf__doc__},

    // localize id array for slippery nodes
    {pylithomop3d_localx__name__, pylithomop3d_localx,
     METH_VARARGS, pylithomop3d_localx__doc__},

    // create sparse matrix in modified sparse row format
    {pylithomop3d_makemsr__name__, pylithomop3d_makemsr,
     METH_VARARGS, pylithomop3d_makemsr__doc__},

    // initialize material model information
    {pylithomop3d_matmod_def__name__, pylithomop3d_matmod_def,
     METH_VARARGS, pylithomop3d_matmod_def__doc__},

    // find closest fault neignbors for slippery nodes
    {pylithomop3d_nfind__name__, pylithomop3d_nfind,
     METH_VARARGS, pylithomop3d_nfind__doc__},

    // precompute shape function information
    {pylithomop3d_preshape__name__, pylithomop3d_preshape,
     METH_VARARGS, pylithomop3d_preshape__doc__},

    // read boundary conditions
    {pylithomop3d_read_bc__name__, pylithomop3d_read_bc,
     METH_VARARGS, pylithomop3d_read_bc__doc__},

    // read connectivities
    {pylithomop3d_read_connect__name__, pylithomop3d_read_connect,
     METH_VARARGS, pylithomop3d_read_connect__doc__},

    // read coordinates
    {pylithomop3d_read_coords__name__, pylithomop3d_read_coords,
     METH_VARARGS, pylithomop3d_read_coords__doc__},

    // read differential forces
    {pylithomop3d_read_diff__name__, pylithomop3d_read_diff,
     METH_VARARGS, pylithomop3d_read_diff__doc__},

    // read time steps at which full output is desired
    {pylithomop3d_read_fuldat__name__, pylithomop3d_read_fuldat,
     METH_VARARGS, pylithomop3d_read_fuldat__doc__},

    // read time history info
    {pylithomop3d_read_hist__name__, pylithomop3d_read_hist,
     METH_VARARGS, pylithomop3d_read_hist__doc__},

    // read material history info
    {pylithomop3d_read_mathist__name__, pylithomop3d_read_mathist,
     METH_VARARGS, pylithomop3d_read_mathist__doc__},

    // read prestresses
    // {pylithomop3d_read_prestr__name__, pylithomop3d_read_prestr,
     // METH_VARARGS, pylithomop3d_read_prestr__doc__},

    // read local coordinate rotations
    {pylithomop3d_read_skew__name__, pylithomop3d_read_skew,
     METH_VARARGS, pylithomop3d_read_skew__doc__},

    // read slippery node definitions
    {pylithomop3d_read_slip__name__, pylithomop3d_read_slip,
     METH_VARARGS, pylithomop3d_read_slip__doc__},

    // read split node definitions
    {pylithomop3d_read_split__name__, pylithomop3d_read_split,
     METH_VARARGS, pylithomop3d_read_split__doc__},

    // read state output information
    {pylithomop3d_read_stateout__name__, pylithomop3d_read_stateout,
     METH_VARARGS, pylithomop3d_read_stateout__doc__},

    // read time step group information
    {pylithomop3d_read_timdat__name__, pylithomop3d_read_timdat,
     METH_VARARGS, pylithomop3d_read_timdat__doc__},

    // read traction boundary conditions
    // {pylithomop3d_read_traction__name__, pylithomop3d_read_traction,
     // METH_VARARGS, pylithomop3d_read_traction__doc__},

    // read winkler force information
    {pylithomop3d_read_wink__name__, pylithomop3d_read_wink,
     METH_VARARGS, pylithomop3d_read_wink__doc__},

    // read winkler force information for slippery nodes
    {pylithomop3d_read_winkx__name__, pylithomop3d_read_winkx,
     METH_VARARGS, pylithomop3d_read_winkx__doc__},

    // scan boundary condition file
    {pylithomop3d_scan_bc__name__, pylithomop3d_scan_bc,
     METH_VARARGS, pylithomop3d_scan_bc__doc__},

    // scan connectivity file
    {pylithomop3d_scan_connect__name__, pylithomop3d_scan_connect,
     METH_VARARGS, pylithomop3d_scan_connect__doc__},

    // scan coordinates file
    {pylithomop3d_scan_coords__name__, pylithomop3d_scan_coords,
     METH_VARARGS, pylithomop3d_scan_coords__doc__},

    // scan differential forces file
    {pylithomop3d_scan_diff__name__, pylithomop3d_scan_diff,
     METH_VARARGS, pylithomop3d_scan_diff__doc__},

    // scan time step output info file
    {pylithomop3d_scan_fuldat__name__, pylithomop3d_scan_fuldat,
     METH_VARARGS, pylithomop3d_scan_fuldat__doc__},

    // scan time history definition file
    {pylithomop3d_scan_hist__name__, pylithomop3d_scan_hist,
     METH_VARARGS, pylithomop3d_scan_hist__doc__},

    // scan prestress file
    // {pylithomop3d_scan_prestr__name__, pylithomop3d_scan_prestr,
     // METH_VARARGS, pylithomop3d_scan_prestr__doc__},

    // scan local coordinate rotations file
    {pylithomop3d_scan_skew__name__, pylithomop3d_scan_skew,
     METH_VARARGS, pylithomop3d_scan_skew__doc__},

    // scan slippery node definitions file
    {pylithomop3d_scan_slip__name__, pylithomop3d_scan_slip,
     METH_VARARGS, pylithomop3d_scan_slip__doc__},

    // scan split node definitions file
    {pylithomop3d_scan_split__name__, pylithomop3d_scan_split,
     METH_VARARGS, pylithomop3d_scan_split__doc__},

    // scan time step group info file
    {pylithomop3d_scan_timdat__name__, pylithomop3d_scan_timdat,
     METH_VARARGS, pylithomop3d_scan_timdat__doc__},

    // scan traction boundary conditions file
    // {pylithomop3d_scan_traction__name__, pylithomop3d_scan_traction,
     // METH_VARARGS, pylithomop3d_scan_traction__doc__},

    // scan winkler forces info file
    {pylithomop3d_scan_wink__name__, pylithomop3d_scan_wink,
     METH_VARARGS, pylithomop3d_scan_wink__doc__},

    // scan winkler forces info file for slippery nodes
    {pylithomop3d_scan_winkx__name__, pylithomop3d_scan_winkx,
     METH_VARARGS, pylithomop3d_scan_winkx__doc__},

    // drive time-dependent solution
    {pylithomop3d_viscos__name__, pylithomop3d_viscos,
     METH_VARARGS, pylithomop3d_viscos__doc__},

    // write out element and prestress information
    {pylithomop3d_write_element_info__name__, pylithomop3d_write_element_info,
     METH_VARARGS, pylithomop3d_write_element_info__doc__},

    // write out global control information
    {pylithomop3d_write_global_info__name__, pylithomop3d_write_global_info,
     METH_VARARGS, pylithomop3d_write_global_info__doc__},

    // write out material property information
    {pylithomop3d_write_props__name__, pylithomop3d_write_props,
     METH_VARARGS, pylithomop3d_write_props__doc__},

    // write out sparse matrix information
    {pylithomop3d_write_sparse_info__name__, pylithomop3d_write_sparse_info,
     METH_VARARGS, pylithomop3d_write_sparse_info__doc__},

    // write out stress computation information
    {pylithomop3d_write_strscomp__name__, pylithomop3d_write_strscomp,
     METH_VARARGS, pylithomop3d_write_strscomp__doc__},

    // write out subiteration convergence information
    {pylithomop3d_write_subiter__name__, pylithomop3d_write_subiter,
     METH_VARARGS, pylithomop3d_write_subiter__doc__},

    // copyright note
    {pylithomop3d_copyright__name__, pylithomop3d_copyright,
     METH_VARARGS, pylithomop3d_copyright__doc__},

// Sentinel
    {0, 0}
};

// version
// $Id: bindings.cc,v 1.2 2004/07/20 14:57:47 willic3 Exp $

// End of file
<|endoftext|>