<commit_before>//=======================================================================
// Copyright (c) 2013-2017 Baptiste Wicht.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <iostream>

#include "help.hpp"

void budget::help_module::handle(const std::vector<std::string>&){
    std::cout << "Usage: budget                                                     Display the overview of the current month" << std::endl << std::endl;

    std::cout << "       budget account [show]                                      Show the current accounts" << std::endl;
    std::cout << "       budget account all                                         Show all the accounts" << std::endl;
    std::cout << "       budget account add                                         Add a new account" << std::endl;
    std::cout << "       budget account delete (id)                                 Delete the given account" << std::endl;
    std::cout << "       budget account edit (id)                                   Edit the given account" << std::endl;
    std::cout << "       budget account transfer                                    Transfer money from one account to another" << std::endl << std::endl;
    std::cout << "       budget account migrate                                     Merge two accounts together" << std::endl << std::endl;
    std::cout << "       budget account archive                                     Archive the current accounts to start new accounts" << std::endl << std::endl;

    std::cout << "       budget expense [show]                                      Display the expenses of the current month" << std::endl;
    std::cout << "       budget expense show (month) (year)                         Display the expenses of the specified month of the specified year" << std::endl;
    std::cout << "       budget expense all                                         Display all the expenses" << std::endl;
    std::cout << "       budget expense add                                         Add a new expense" << std::endl;
    std::cout << "       budget expense add (template name)                         Add a new expense from a template or create a new template" << std::endl;
    std::cout << "       budget expense delete (id)                                 Remove completely the expense with the given id" << std::endl;
    std::cout << "       budget expense edit (id)                                   Modify the expense with the given id" << std::endl << std::endl;
    std::cout << "       budget expense template                                    Display the templates" << std::endl << std::endl;

    std::cout << "       budget earning [earnings]                                  Display the earnings of the current month" << std::endl;
    std::cout << "       budget earning show (month) (year)                         Display the earnings of the specified month of the specified year" << std::endl;
    std::cout << "       budget earning all                                         Display all the earnings" << std::endl;
    std::cout << "       budget earning add                                         Add a new earning" << std::endl;
    std::cout << "       budget earning delete (id)                                 Remove completely the earning with the given id" << std::endl;
    std::cout << "       budget earning edit (id)                                   Modify the earning with the given id" << std::endl << std::endl;

    std::cout << "       budget overview [month]                                    Display the overvew of the current month" << std::endl;
    std::cout << "       budget overview month (month) (year)                       Display the overvew of the specified month of the current year" << std::endl;
    std::cout << "       budget overview year (year)                                Display the overvew of the specified year" << std::endl;
    std::cout << "       budget overview aggregate                                  Display the aggregated expenses for the current year" << std::endl;
    std::cout << "       budget overview aggregate year (year)                      Display the aggregated expenses for the given year" << std::endl << std::endl;

    std::cout << "       budget recurring [show]                                    Display the recurring expenses" << std::endl;
    std::cout << "       budget recurring add                                       Add a new recurring expense" << std::endl;
    std::cout << "       budget recurring delete (id)                               Remove completely the recurring expense with the given id" << std::endl;
    std::cout << "       budget recurring edit (id)                                 Modify the recurring expense with the given id" << std::endl << std::endl;

    std::cout << "       budget fortune [status]                                    Display the status of the fortune checks" << std::endl;
    std::cout << "       budget fortune list                                        Display the list of all the fortune checks" << std::endl;
    std::cout << "       budget fortune check                                       Create a new fortune check" << std::endl;
    std::cout << "       budget fortune edit (id)                                   Edit a fortune check" << std::endl;
    std::cout << "       budget fortune delete (id)                                 Delete a fortune check" << std::endl << std::endl;

    std::cout << "       budget objective [status]                                  Show the status of the objectives for the current year" << std::endl;
    std::cout << "       budget objective list                                      List all the defined objectives" << std::endl;
    std::cout << "       budget objective add                                       Add a new objective" << std::endl;
    std::cout << "       budget objective edit (id)                                 Edit an objective" << std::endl;
    std::cout << "       budget objective delete (id)                               Delete an objective" << std::endl;

    std::cout << "       budget wish [status]                                       Show the status of the wishes" << std::endl;
    std::cout << "       budget wish list                                           List all the wishes" << std::endl;
    std::cout << "       budget wish estimate                                       Estimate the best date to buy something" << std::endl;
    std::cout << "       budget wish add                                            Add a new wish" << std::endl;
    std::cout << "       budget wish edit (id)                                      Edit a wish" << std::endl;
    std::cout << "       budget wish delete (id)                                    Delete a wish" << std::endl;

    std::cout << "       budget debt [list]                                         Display the unpaid debts" << std::endl;
    std::cout << "       budget debt all                                            Display all debts" << std::endl;
    std::cout << "       budget debt paid (id)                                      Mark the given debt as paid" << std::endl;
    std::cout << "       budget debt delete (id)                                    Delete the given debt" << std::endl;
    std::cout << "       budget debt edit (id)                                      Edit the given debt" << std::endl << std::endl;

    std::cout << "       budget versioning save                                     Commit the budget directory changes with Git" << std::endl;
    std::cout << "       budget versioning sync                                     Pull the remote changes on the budget directory with Git and push" << std::endl;

    std::cout << "       budget report [monthly]                                    Display monthly report in form of bar plot" << std::endl;
    std::cout << "       budget report account [monthly]                            Display monthly report of a specific account in form of bar plot" << std::endl;

    std::cout << "       budget gc                                                  Make sure all IDs are contiguous" << std::endl;
}
<commit_msg>Cleanup the help<commit_after>//=======================================================================
// Copyright (c) 2013-2017 Baptiste Wicht.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <iostream>

#include "help.hpp"

void budget::help_module::handle(const std::vector<std::string>&){
    std::cout << "Usage: budget                                          Display the overview of the current month\n\n";

    std::cout << "       budget account [show]                           Show the current accounts\n";
    std::cout << "       budget account all                              Show all the accounts\n";
    std::cout << "       budget account add                              Add a new account\n";
    std::cout << "       budget account delete (id)                      Delete the given account\n";
    std::cout << "       budget account edit (id)                        Edit the given account\n";
    std::cout << "       budget account transfer                         Transfer money from one account to another\n\n";
    std::cout << "       budget account migrate                          Merge two accounts together\n\n";
    std::cout << "       budget account archive                          Archive the current accounts to start new accounts\n\n";

    std::cout << "       budget expense [show]                           Display the expenses of the current month\n";
    std::cout << "       budget expense show (month) (year)              Display the expenses of the specified month of the specified year\n";
    std::cout << "       budget expense all                              Display all the expenses\n";
    std::cout << "       budget expense add                              Add a new expense\n";
    std::cout << "       budget expense add (template name)              Add a new expense from a template or create a new template\n";
    std::cout << "       budget expense delete (id)                      Remove completely the expense with the given id\n";
    std::cout << "       budget expense edit (id)                        Modify the expense with the given id\n\n";
    std::cout << "       budget expense template                         Display the templates\n\n";

    std::cout << "       budget earning [earnings]                       Display the earnings of the current month\n";
    std::cout << "       budget earning show (month) (year)              Display the earnings of the specified month of the specified year\n";
    std::cout << "       budget earning all                              Display all the earnings\n";
    std::cout << "       budget earning add                              Add a new earning\n";
    std::cout << "       budget earning delete (id)                      Remove completely the earning with the given id\n";
    std::cout << "       budget earning edit (id)                        Modify the earning with the given id\n\n";

    std::cout << "       budget overview [month]                         Display the overvew of the current month\n";
    std::cout << "       budget overview month (month) (year)            Display the overvew of the specified month of the current year\n";
    std::cout << "       budget overview year (year)                     Display the overvew of the specified year\n";
    std::cout << "       budget overview aggregate                       Display the aggregated expenses for the current year\n";
    std::cout << "       budget overview aggregate year (year)           Display the aggregated expenses for the given year\n\n";

    std::cout << "       budget recurring [show]                         Display the recurring expenses\n";
    std::cout << "       budget recurring add                            Add a new recurring expense\n";
    std::cout << "       budget recurring delete (id)                    Remove completely the recurring expense with the given id\n";
    std::cout << "       budget recurring edit (id)                      Modify the recurring expense with the given id\n\n";

    std::cout << "       budget fortune [status]                         Display the status of the fortune checks\n";
    std::cout << "       budget fortune list                             Display the list of all the fortune checks\n";
    std::cout << "       budget fortune check                            Create a new fortune check\n";
    std::cout << "       budget fortune edit (id)                        Edit a fortune check\n";
    std::cout << "       budget fortune delete (id)                      Delete a fortune check\n\n";

    std::cout << "       budget objective [status]                       Show the status of the objectives for the current year\n";
    std::cout << "       budget objective list                           List all the defined objectives\n";
    std::cout << "       budget objective add                            Add a new objective\n";
    std::cout << "       budget objective edit (id)                      Edit an objective\n";
    std::cout << "       budget objective delete (id)                    Delete an objective\n";

    std::cout << "       budget wish [status]                            Show the status of the wishes\n";
    std::cout << "       budget wish list                                List all the wishes\n";
    std::cout << "       budget wish estimate                            Estimate the best date to buy something\n";
    std::cout << "       budget wish add                                 Add a new wish\n";
    std::cout << "       budget wish edit (id)                           Edit a wish\n";
    std::cout << "       budget wish delete (id)                         Delete a wish\n";

    std::cout << "       budget debt [list]                              Display the unpaid debts\n";
    std::cout << "       budget debt all                                 Display all debts\n";
    std::cout << "       budget debt paid (id)                           Mark the given debt as paid\n";
    std::cout << "       budget debt delete (id)                         Delete the given debt\n";
    std::cout << "       budget debt edit (id)                           Edit the given debt\n\n";

    std::cout << "       budget versioning save                          Commit the budget directory changes with Git\n";
    std::cout << "       budget versioning sync                          Pull the remote changes on the budget directory with Git and push\n\n";
    std::cout << "       budget sync                                     Pull the remote changes on the budget directory with Git and push\n\n";

    std::cout << "       budget report [monthly]                         Display monthly report in form of bar plot\n";
    std::cout << "       budget report account [monthly]                 Display monthly report of a specific account in form of bar plot\n\n";

    std::cout << "       budget gc                                       Make sure all IDs are contiguous\n";
}
<|endoftext|>


<commit_before>#include "init.h"

#include <algorithm>
#include <fstream>
#include <map>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

using std::ifstream;
using std::make_unique;
using std::map;
using std::pair;
using std::size_t;
using std::stringstream;
using std::string;
using std::unique_ptr;
using std::vector;

bool CheckTokens(string &s, const unique_ptr<map<string, vector<string>>> &m_token,
                 const unique_ptr<map<string, vector<string>>> &v_token) {
  if ((s == "V") ||
      (s.at(0) == '!') ||
      (s.at(0) == '*') ||
      (s.front() == '\"' && s.back() == '\"')) {
    return true;
  }
  if (s.size() > 3 && s.substr(0, 3) == "to_") {
    for (auto &&t : *v_token) {
      if (s == t.first) {
        return true;
      }
    }
  } else {
    for (auto &&t : *m_token) {
      if (s == t.first) {
        return true;
      }
    }
  }

  return false;
}

unique_ptr<vector<vector<string>>> ParsePatterns(ifstream &input_file,
                                                 const unique_ptr<map<string, vector<string>>> &m_token,
                                                 const unique_ptr<map<string, vector<string>>> &v_token) {
  vector<vector<string>> v{};

  string buffer_line;
  for (size_t i = 0; getline(input_file, buffer_line);) {
    if (buffer_line.find("//") != string::npos) {  // read "//" as single-line comment
      continue;
    } else if (buffer_line == "") {  // do not read empty lines
      continue;
    }
    v.emplace_back(vector<string>{});
    string buffer_token{};
    stringstream ss(buffer_line);
    while (ss >> buffer_token) {
      if (CheckTokens(buffer_token, m_token, v_token)) {
        v.at(i).emplace_back(buffer_token);
      }
    }
    ++i;
  }

  auto ptr = make_unique<vector<vector<string>>>(v);
  return ptr;
}

unique_ptr<vector<string>> ParseTokens(ifstream &input_file) {
  vector<string> v{};  // vector of tokens

  string buffer_line;
  while (getline(input_file, buffer_line)) {  // read everything from the file
    if (buffer_line.find("//") != string::npos) {  // read "//" as single-line comment
      continue;
    } else if (buffer_line == "") {  // do not read empty lines
      continue;
    }
    v.emplace_back(buffer_line);
  }

  auto ptr = make_unique<vector<string>>(v);
  return ptr;
}

unique_ptr<vector<pair<size_t, string>>> ParseTokenCategories(const vector<string> &in) {
  vector<pair<size_t, string>> v{};  // vector of token categories

  for (size_t i = 0; i < in.size(); ++i) {
    string buffer_line{in.at(i)};
    if (buffer_line.find(":", buffer_line.size() - 1) != string::npos) {  // found a category!
      string category = buffer_line.substr(0, buffer_line.size() - 1);
      v.emplace_back(make_pair(i, category));
    }
  }

  auto ptr = make_unique<vector<pair<size_t, string>>>(v);
  return ptr;
}

unique_ptr<map<string, vector<string>>> ConstructMatchingTokens(const vector<string> &tokens,
                                                                const vector<pair<size_t, string>> &token_cat) {
  map<string, vector<string>> m{};

  for (auto &&p : token_cat) {
    if (p.second == "verb") {
      continue;
    }
    m.emplace(make_pair(p.second, vector<string>{}));
    for (size_t i = p.first + 1; tokens.at(i).find(":", tokens.at(i).size() - 1) == string::npos; ++i) {
      m.at(p.second).emplace_back(tokens.at(i));
      if (i + 1 >= tokens.size()) {
        break;
      }
    }
  }

  auto ptr = make_unique<map<string, vector<string>>>(m);
  return ptr;
}

unique_ptr<map<string, vector<string>>> ConstructVerbToken(const vector<string> &tokens, size_t start_pos) {
  map<string, vector<string>> m{};  // map of tokens

  for (size_t i = start_pos + 1; tokens.at(i).find(":", tokens.at(i).size() - 1) == string::npos; ++i) {
    string line_buffer{};
    stringstream ss_buf(tokens.at(i));
    vector<string> line_tokens{};
    while (ss_buf >> line_buffer) {
      line_tokens.emplace_back(line_buffer);
    }

    m.emplace(make_pair(line_tokens.at(0), vector<string>{}));
    for (size_t j = 1; j < line_tokens.size(); ++j) {
      m.at(line_tokens.at(0)).emplace_back(line_tokens.at(j));
    }

    if (i + 1 >= tokens.size()) {
      break;
    }
  }

  auto ptr = make_unique<map<string, vector<string>>>(m);
  return ptr;
}

string ReadTokensVersion(const vector<string> &in) {
  string version_line = in.at(0);
  if (version_line.find("VERSION") == string::npos) {
    return "";
  }
  return version_line.substr(version_line.find("=") + 1, version_line.size());
}

string ReadPatternsVersion(const vector<vector<string>> &in) {
  string version_line = in.at(0).at(0);
  if (version_line.find("VERSION") == string::npos) {
    return "";
  }
  return version_line.substr(version_line.find("=") + 1, version_line.size());
}
<commit_msg>Place CheckTokens into unnamed namespace<commit_after>#include "init.h"

#include <algorithm>
#include <fstream>
#include <map>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

using std::ifstream;
using std::make_unique;
using std::map;
using std::pair;
using std::size_t;
using std::stringstream;
using std::string;
using std::unique_ptr;
using std::vector;

namespace {
bool CheckTokens(string &s, const unique_ptr<map<string, vector<string>>> &m_token,
                 const unique_ptr<map<string, vector<string>>> &v_token) {
  if ((s == "V") ||
      (s.at(0) == '!') ||
      (s.at(0) == '*') ||
      (s.front() == '\"' && s.back() == '\"')) {
    return true;
  }
  if (s.size() > 3 && s.substr(0, 3) == "to_") {
    for (auto &&t : *v_token) {
      if (s == t.first) {
        return true;
      }
    }
  } else {
    for (auto &&t : *m_token) {
      if (s == t.first) {
        return true;
      }
    }
  }

  return false;
}
}  // namespace

unique_ptr<vector<vector<string>>> ParsePatterns(ifstream &input_file,
                                                 const unique_ptr<map<string, vector<string>>> &m_token,
                                                 const unique_ptr<map<string, vector<string>>> &v_token) {
  vector<vector<string>> v{};

  string buffer_line;
  for (size_t i = 0; getline(input_file, buffer_line);) {
    if (buffer_line.find("//") != string::npos) {  // read "//" as single-line comment
      continue;
    } else if (buffer_line == "") {  // do not read empty lines
      continue;
    }
    v.emplace_back(vector<string>{});
    string buffer_token{};
    stringstream ss(buffer_line);
    while (ss >> buffer_token) {
      if (CheckTokens(buffer_token, m_token, v_token)) {
        v.at(i).emplace_back(buffer_token);
      }
    }
    ++i;
  }

  auto ptr = make_unique<vector<vector<string>>>(v);
  return ptr;
}

unique_ptr<vector<string>> ParseTokens(ifstream &input_file) {
  vector<string> v{};  // vector of tokens

  string buffer_line;
  while (getline(input_file, buffer_line)) {  // read everything from the file
    if (buffer_line.find("//") != string::npos) {  // read "//" as single-line comment
      continue;
    } else if (buffer_line == "") {  // do not read empty lines
      continue;
    }
    v.emplace_back(buffer_line);
  }

  auto ptr = make_unique<vector<string>>(v);
  return ptr;
}

unique_ptr<vector<pair<size_t, string>>> ParseTokenCategories(const vector<string> &in) {
  vector<pair<size_t, string>> v{};  // vector of token categories

  for (size_t i = 0; i < in.size(); ++i) {
    string buffer_line{in.at(i)};
    if (buffer_line.find(":", buffer_line.size() - 1) != string::npos) {  // found a category!
      string category = buffer_line.substr(0, buffer_line.size() - 1);
      v.emplace_back(make_pair(i, category));
    }
  }

  auto ptr = make_unique<vector<pair<size_t, string>>>(v);
  return ptr;
}

unique_ptr<map<string, vector<string>>> ConstructMatchingTokens(const vector<string> &tokens,
                                                                const vector<pair<size_t, string>> &token_cat) {
  map<string, vector<string>> m{};

  for (auto &&p : token_cat) {
    if (p.second == "verb") {
      continue;
    }
    m.emplace(make_pair(p.second, vector<string>{}));
    for (size_t i = p.first + 1; tokens.at(i).find(":", tokens.at(i).size() - 1) == string::npos; ++i) {
      m.at(p.second).emplace_back(tokens.at(i));
      if (i + 1 >= tokens.size()) {
        break;
      }
    }
  }

  auto ptr = make_unique<map<string, vector<string>>>(m);
  return ptr;
}

unique_ptr<map<string, vector<string>>> ConstructVerbToken(const vector<string> &tokens, size_t start_pos) {
  map<string, vector<string>> m{};  // map of tokens

  for (size_t i = start_pos + 1; tokens.at(i).find(":", tokens.at(i).size() - 1) == string::npos; ++i) {
    string line_buffer{};
    stringstream ss_buf(tokens.at(i));
    vector<string> line_tokens{};
    while (ss_buf >> line_buffer) {
      line_tokens.emplace_back(line_buffer);
    }

    m.emplace(make_pair(line_tokens.at(0), vector<string>{}));
    for (size_t j = 1; j < line_tokens.size(); ++j) {
      m.at(line_tokens.at(0)).emplace_back(line_tokens.at(j));
    }

    if (i + 1 >= tokens.size()) {
      break;
    }
  }

  auto ptr = make_unique<map<string, vector<string>>>(m);
  return ptr;
}

string ReadTokensVersion(const vector<string> &in) {
  string version_line = in.at(0);
  if (version_line.find("VERSION") == string::npos) {
    return "";
  }
  return version_line.substr(version_line.find("=") + 1, version_line.size());
}

string ReadPatternsVersion(const vector<vector<string>> &in) {
  string version_line = in.at(0).at(0);
  if (version_line.find("VERSION") == string::npos) {
    return "";
  }
  return version_line.substr(version_line.find("=") + 1, version_line.size());
}
<|endoftext|>


<commit_before>/*
 * Justin's Awesome Game Engine
 * or *
 * Just Another Game Engine
 *
 * Copyright 2016 Justin White
 *
 * See included LICENSE file for distribution and reuse.
*/

#include <unistd.h>

#ifdef DO_DEBUG
#define LOGOG_LEVEL LOGOG_LEVEL_ALL
#else
#define LOGOG_LEVEL LOGOG_LEVEL_INFO
#endif
#include <logog/logog.hpp>

#include <Engine.h>

/*
 * Simply initializes the Logog logging system, and the Engine,
 * then transfers control to the Engine's event loop.
 */
int main(const int argc, const char** argv) {
    std::string gameName;
    if (argc > 1 && argv[1] != NULL) {
        gameName = std::string(argv[1]);
    } else {
        gameName = "game";
    }

    LOGOG_INITIALIZE();
    const std::string logFilename = gameName + ".log";
    // remove existing log file
    unlink(logFilename.c_str());
    // create the log's  file sink
    logog::LogFile outFile(logFilename.c_str());
    // create the log's console sink
    logog::Cout out;
    // create custom format
    class FormatterCustom : public logog::FormatterGCC {
        virtual TOPIC_FLAGS GetTopicFlags(const logog::Topic& topic) {
            return (logog::Formatter::GetTopicFlags(topic) &
                    ~(TOPIC_FILE_NAME_FLAG | TOPIC_LINE_NUMBER_FLAG));
        }
    };
    FormatterCustom customFormat;
    customFormat.SetShowTimeOfDay(true);
    // use custom format
    out.SetFormatter(customFormat);
    outFile.SetFormatter(customFormat);

    INFO("Logging system initialized.");

    Engine theGame(argc, argv, gameName);
    if (theGame.ready()) {
        if (theGame.run()) {
        } else {
            ERR("Error running Engine, quitting.");
            return EXIT_FAILURE;
        }
    } else {
        ERR("Could not initialize Engine, quitting.");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
<commit_msg>Put the log the data files.<commit_after>/*
 * Justin's Awesome Game Engine
 * or *
 * Just Another Game Engine
 *
 * Copyright 2016 Justin White
 *
 * See included LICENSE file for distribution and reuse.
*/

#include <unistd.h>

#ifdef DO_DEBUG
#define LOGOG_LEVEL LOGOG_LEVEL_ALL
#else
#define LOGOG_LEVEL LOGOG_LEVEL_INFO
#endif
#include <logog/logog.hpp>

#include <Engine.h>

/*
 * Simply initializes the Logog logging system, and the Engine,
 * then transfers control to the Engine's event loop.
 */
int main(const int argc, const char** argv) {
    // check if a game directory is specified on the command line
    std::string gameName;
    if (argc > 1 and argv[1] != NULL) {
        gameName = std::string(argv[1]);
    } else {
        gameName = "game";
    }

    LOGOG_INITIALIZE();
    const std::string logFilename = gameName + '/' + gameName + ".log";
    // remove existing log file
    unlink(logFilename.c_str());
    // create the log's  file sink
    logog::LogFile outFile(logFilename.c_str());
    // create the log's console sink
    logog::Cout out;
    // create custom format
    class FormatterCustom : public logog::FormatterGCC {
        virtual TOPIC_FLAGS GetTopicFlags(const logog::Topic& topic) {
            return (logog::Formatter::GetTopicFlags(topic) &
                    ~(TOPIC_FILE_NAME_FLAG | TOPIC_LINE_NUMBER_FLAG));
        }
    };
    FormatterCustom customFormat;
    customFormat.SetShowTimeOfDay(true);
    // use custom format
    out.SetFormatter(customFormat);
    outFile.SetFormatter(customFormat);
    INFO("Logging system initialized.");

    Engine theGame(argc, argv, gameName);
    if (theGame.ready()) {
        if (theGame.run()) {
        } else {
            ERR("Error running Engine, quitting.");
            return EXIT_FAILURE;
        }
    } else {
        ERR("Could not initialize Engine, quitting.");
        return EXIT_FAILURE;
    }
    INFO("Done");
    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Copyright (C) 2010 - 2013 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2005 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"

#include "CEvaluationNode.h"
#include "CEvaluationTree.h"

#include "sbml/math/ASTNode.h"

CEvaluationNodeChoice::CEvaluationNodeChoice():
  CEvaluationNode(CEvaluationNode::INVALID, ""),
  mpIf(NULL),
  mpTrue(NULL),
  mpFalse(NULL)
{mPrecedence = PRECEDENCE_NUMBER;}

CEvaluationNodeChoice::CEvaluationNodeChoice(const SubType & subType,
    const Data & data):
  CEvaluationNode((Type)(CEvaluationNode::CHOICE | subType), data),
  mpIf(NULL),
  mpTrue(NULL),
  mpFalse(NULL)
{
  switch (subType)
    {
      case IF:
        break;

      default:
        fatalError();
        break;
    }

  mPrecedence = PRECEDENCE_FUNCTION;
}

CEvaluationNodeChoice::CEvaluationNodeChoice(const CEvaluationNodeChoice & src):
  CEvaluationNode(src),
  mpIf(src.mpIf),
  mpTrue(src.mpTrue),
  mpFalse(src.mpFalse)
{}

CEvaluationNodeChoice::~CEvaluationNodeChoice() {}

void CEvaluationNodeChoice::calculate()
{
  if (mpIf->getValue() > 0.5)
    {
      mValue = mpTrue->getValue();
    }
  else
    {
      mValue = mpFalse->getValue();
    }
}

bool CEvaluationNodeChoice::compile(const CEvaluationTree * /* pTree */)
{
  mpIf = static_cast<CEvaluationNode *>(getChild());

  if (mpIf == NULL) return false;

  mpTrue = static_cast<CEvaluationNode *>(mpIf->getSibling());

  if (mpTrue == NULL) return false;

  mpFalse = static_cast<CEvaluationNode *>(mpTrue->getSibling());

  if (mpFalse == NULL) return false;

  return (mpFalse->getSibling() == NULL); // We must have exactly three children
}

// virtual
std::string CEvaluationNodeChoice::getInfix(const std::vector< std::string > & children) const
{
  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
    return mData + "(" + children[0] + "," + children[1] + "," + children[2] + ")";
  else
    return "@";
}

// virtual
std::string CEvaluationNodeChoice::getDisplayString(const std::vector< std::string > & children) const
{
  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
    return mData + "(" + children[0] + "," + children[1] + "," + children[2] + ")";
  else
    return "@";
}

// virtual
std::string CEvaluationNodeChoice::getCCodeString(const std::vector< std::string > & children) const
{
  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
    return "(" + children[0] + " ? " + children[1] + " : " + children[2] + ")";
  else
    return "@";
}

// virtual
std::string CEvaluationNodeChoice::getBerkeleyMadonnaString(const std::vector< std::string > & children) const
{
  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
    return "(if " + children[0] + " then " + children[1] + " else " + children[2] + ")";
  else
    return "@";
}

// virtual
std::string CEvaluationNodeChoice::getXPPString(const std::vector< std::string > & children) const
{
  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
    return "if(" + children[0] + ")then(" + children[1] + ")else(" + children[2] + ")";
  else
    return "@"; //TODO
}

// static
CEvaluationNode * CEvaluationNodeChoice::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children)
{
  assert(pASTNode->getNumChildren() == children.size());

  size_t i = 0, iMax = children.size();

  // a piecewise function definition can have zero or more children.
  if (iMax == 0)
    {
      // create a NaN node
      return new CEvaluationNodeConstant(CEvaluationNodeConstant::_NaN, "NAN");
    }

  if (iMax == 1)
    {
      // this must be the otherwise
      // It is not clearly specified what happens if there are no pieces, but
      // an otherwise. I would assume that in this case, the otherwise always
      // takes effect

      return children[0];
    }

  SubType subType;
  std::string data = "";

  switch (pASTNode->getType())
    {
      case AST_FUNCTION_PIECEWISE:
        subType = IF;
        data = "if";
        break;

      default:
        subType = INVALID;
        break;
    }

  CEvaluationNodeChoice * pNode = new CEvaluationNodeChoice(subType, data);
  CEvaluationNode * pCurrent = pNode;

  // We have at least 2 children
  while (i < iMax - 1)
    {
      // add the condition
      pCurrent->addChild(children[i + 1]);
      // the true value
      pCurrent->addChild(children[i]);

      i += 2;

      switch (iMax - i)
        {
          case 0:
            // We are missing the false value
            pCurrent->addChild(new CEvaluationNodeConstant(CEvaluationNodeConstant::_NaN, "NAN"));
            break;

          case 1:
            // the false value
            pCurrent->addChild(children[i++]);
            break;

          default:
            // We have at least 2 more children
          {
            // create a new piecewise as the false value
            CEvaluationNode * pTmp = new CEvaluationNodeChoice(subType, data);
            pCurrent->addChild(pTmp);
            pCurrent = pTmp;
          }
          break;
        }
    }

  return pNode;
}

ASTNode* CEvaluationNodeChoice::toAST(const CCopasiDataModel* pDataModel) const
{
  ASTNode* node = new ASTNode(AST_FUNCTION_PIECEWISE);
  const CEvaluationNode* child1 = dynamic_cast<const CEvaluationNode*>(this->getChild());
  assert(child1 != NULL);
  const CEvaluationNode* child2 = dynamic_cast<const CEvaluationNode*>(child1->getSibling());
  assert(child2 != NULL);
  const CEvaluationNode* child3 = dynamic_cast<const CEvaluationNode*>(child2->getSibling());
  assert(child3 != NULL);
  // the condition is the second child to the AST node but the first child in
  // the CEvaluationNode
  node->addChild(child2->toAST(pDataModel));
  node->addChild(child1->toAST(pDataModel));
  node->addChild(child3->toAST(pDataModel));
  return node;
}

#include "utilities/copasimathml.h"

// virtual
std::string CEvaluationNodeChoice::getMMLString(const std::vector< std::string > & children,
    bool /* expand */,
    const std::vector< std::vector< std::string > > & /* variables */) const
{
  std::ostringstream out;

  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
    {
      out << "<mrow>" << std::endl;
      out << "<mo> {</mo>" << std::endl;
      out << "<mtable>" << std::endl;

      out << "<mtr>" << std::endl;

      out << "<mtd>" << std::endl;
      out << children[0];
      out << "<mo> , </mo>" << std::endl;
      out << "</mtd>" << std::endl;

      out << "<mtd>" << std::endl;
      out << children[1];

      out << "</mtd>" << std::endl;

      out << "</mtr>" << std::endl;

      out << "<mtr>" << std::endl;

      out << "<mtd>" << std::endl;
      out << children[2];
      out << "<mo> , </mo>" << std::endl;

      out << "</mtd>" << std::endl;
      out << "<mtd>" << std::endl;
      out << "<mo> else </mo>" << std::endl;
      out << "</mtd>" << std::endl;

      out << "</mtr>" << std::endl;

      out << "</mtable>" << std::endl;
      out << "</mrow>" << std::endl;
    }

  return out.str();
}
<commit_msg>Fixed Bug 2057. The order of the result expression and the else keyword is reversed.<commit_after>// Copyright (C) 2010 - 2014 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2005 - 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"

#include "CEvaluationNode.h"
#include "CEvaluationTree.h"

#include "sbml/math/ASTNode.h"

CEvaluationNodeChoice::CEvaluationNodeChoice():
  CEvaluationNode(CEvaluationNode::INVALID, ""),
  mpIf(NULL),
  mpTrue(NULL),
  mpFalse(NULL)
{mPrecedence = PRECEDENCE_NUMBER;}

CEvaluationNodeChoice::CEvaluationNodeChoice(const SubType & subType,
    const Data & data):
  CEvaluationNode((Type)(CEvaluationNode::CHOICE | subType), data),
  mpIf(NULL),
  mpTrue(NULL),
  mpFalse(NULL)
{
  switch (subType)
    {
      case IF:
        break;

      default:
        fatalError();
        break;
    }

  mPrecedence = PRECEDENCE_FUNCTION;
}

CEvaluationNodeChoice::CEvaluationNodeChoice(const CEvaluationNodeChoice & src):
  CEvaluationNode(src),
  mpIf(src.mpIf),
  mpTrue(src.mpTrue),
  mpFalse(src.mpFalse)
{}

CEvaluationNodeChoice::~CEvaluationNodeChoice() {}

void CEvaluationNodeChoice::calculate()
{
  if (mpIf->getValue() > 0.5)
    {
      mValue = mpTrue->getValue();
    }
  else
    {
      mValue = mpFalse->getValue();
    }
}

bool CEvaluationNodeChoice::compile(const CEvaluationTree * /* pTree */)
{
  mpIf = static_cast<CEvaluationNode *>(getChild());

  if (mpIf == NULL) return false;

  mpTrue = static_cast<CEvaluationNode *>(mpIf->getSibling());

  if (mpTrue == NULL) return false;

  mpFalse = static_cast<CEvaluationNode *>(mpTrue->getSibling());

  if (mpFalse == NULL) return false;

  return (mpFalse->getSibling() == NULL); // We must have exactly three children
}

// virtual
std::string CEvaluationNodeChoice::getInfix(const std::vector< std::string > & children) const
{
  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
    return mData + "(" + children[0] + "," + children[1] + "," + children[2] + ")";
  else
    return "@";
}

// virtual
std::string CEvaluationNodeChoice::getDisplayString(const std::vector< std::string > & children) const
{
  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
    return mData + "(" + children[0] + "," + children[1] + "," + children[2] + ")";
  else
    return "@";
}

// virtual
std::string CEvaluationNodeChoice::getCCodeString(const std::vector< std::string > & children) const
{
  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
    return "(" + children[0] + " ? " + children[1] + " : " + children[2] + ")";
  else
    return "@";
}

// virtual
std::string CEvaluationNodeChoice::getBerkeleyMadonnaString(const std::vector< std::string > & children) const
{
  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
    return "(if " + children[0] + " then " + children[1] + " else " + children[2] + ")";
  else
    return "@";
}

// virtual
std::string CEvaluationNodeChoice::getXPPString(const std::vector< std::string > & children) const
{
  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
    return "if(" + children[0] + ")then(" + children[1] + ")else(" + children[2] + ")";
  else
    return "@"; //TODO
}

// static
CEvaluationNode * CEvaluationNodeChoice::fromAST(const ASTNode * pASTNode, const std::vector< CEvaluationNode * > & children)
{
  assert(pASTNode->getNumChildren() == children.size());

  size_t i = 0, iMax = children.size();

  // a piecewise function definition can have zero or more children.
  if (iMax == 0)
    {
      // create a NaN node
      return new CEvaluationNodeConstant(CEvaluationNodeConstant::_NaN, "NAN");
    }

  if (iMax == 1)
    {
      // this must be the otherwise
      // It is not clearly specified what happens if there are no pieces, but
      // an otherwise. I would assume that in this case, the otherwise always
      // takes effect

      return children[0];
    }

  SubType subType;
  std::string data = "";

  switch (pASTNode->getType())
    {
      case AST_FUNCTION_PIECEWISE:
        subType = IF;
        data = "if";
        break;

      default:
        subType = INVALID;
        break;
    }

  CEvaluationNodeChoice * pNode = new CEvaluationNodeChoice(subType, data);
  CEvaluationNode * pCurrent = pNode;

  // We have at least 2 children
  while (i < iMax - 1)
    {
      // add the condition
      pCurrent->addChild(children[i + 1]);
      // the true value
      pCurrent->addChild(children[i]);

      i += 2;

      switch (iMax - i)
        {
          case 0:
            // We are missing the false value
            pCurrent->addChild(new CEvaluationNodeConstant(CEvaluationNodeConstant::_NaN, "NAN"));
            break;

          case 1:
            // the false value
            pCurrent->addChild(children[i++]);
            break;

          default:
            // We have at least 2 more children
          {
            // create a new piecewise as the false value
            CEvaluationNode * pTmp = new CEvaluationNodeChoice(subType, data);
            pCurrent->addChild(pTmp);
            pCurrent = pTmp;
          }
          break;
        }
    }

  return pNode;
}

ASTNode* CEvaluationNodeChoice::toAST(const CCopasiDataModel* pDataModel) const
{
  ASTNode* node = new ASTNode(AST_FUNCTION_PIECEWISE);
  const CEvaluationNode* child1 = dynamic_cast<const CEvaluationNode*>(this->getChild());
  assert(child1 != NULL);
  const CEvaluationNode* child2 = dynamic_cast<const CEvaluationNode*>(child1->getSibling());
  assert(child2 != NULL);
  const CEvaluationNode* child3 = dynamic_cast<const CEvaluationNode*>(child2->getSibling());
  assert(child3 != NULL);
  // the condition is the second child to the AST node but the first child in
  // the CEvaluationNode
  node->addChild(child2->toAST(pDataModel));
  node->addChild(child1->toAST(pDataModel));
  node->addChild(child3->toAST(pDataModel));
  return node;
}

#include "utilities/copasimathml.h"

// virtual
std::string CEvaluationNodeChoice::getMMLString(const std::vector< std::string > & children,
    bool /* expand */,
    const std::vector< std::vector< std::string > > & /* variables */) const
{
  std::ostringstream out;

  if (const_cast<CEvaluationNodeChoice *>(this)->compile(NULL))
    {
      out << "<mrow>" << std::endl;
      out << "<mo> {</mo>" << std::endl;
      out << "<mtable>" << std::endl;

      out << "<mtr>" << std::endl;

      out << "<mtd>" << std::endl;
      out << children[0];
      out << "<mo> , </mo>" << std::endl;
      out << "</mtd>" << std::endl;

      out << "<mtd>" << std::endl;
      out << children[1];

      out << "</mtd>" << std::endl;

      out << "</mtr>" << std::endl;

      out << "<mtr>" << std::endl;

      out << "<mtd>" << std::endl;
      out << "<mo> else, </mo>" << std::endl;

      out << "</mtd>" << std::endl;
      out << "<mtd>" << std::endl;
      out << children[2];
      out << "</mtd>" << std::endl;

      out << "</mtr>" << std::endl;

      out << "</mtable>" << std::endl;
      out << "</mrow>" << std::endl;
    }

  return out.str();
}
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * Author : Christian Potthast
 * Email  : potthast@usc.edu
 *
 */

#include <pcl/ml/densecrf.h>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pcl::DenseCrf::DenseCrf (int N, int m) :
  N_ (N), M_ (m),
  xyz_ (false), rgb_ (false), normal_ (false)
{
  current_.resize (N_ * M_, 0.0f);
  next_.resize (N_ * M_, 0.0f);
  tmp_.resize (2 * N_ * M_, 0.0f);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pcl::DenseCrf::~DenseCrf ()
{
  for(size_t i = 0; i < pairwise_potential_.size (); i++ )
    delete pairwise_potential_[i];
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::setDataVector (const std::vector<Eigen::Vector3i> data)
{
  xyz_ = true;
  data_ = data;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::setColorVector (const std::vector<Eigen::Vector3i> color)
{
  rgb_ = true;
  color_ = color;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::setUnaryEnergy (const std::vector<float> unary)
{
  unary_ = unary;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::addPairwiseEnergy (const std::vector<float> &feature, const int feature_dimension, const float w)
{
  pairwise_potential_.push_back ( new PairwisePotential (feature, feature_dimension, N_, w) );
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::addPairwiseGaussian (float sx, float sy, float sz, float w)
{
  // create feature vector
  std::vector<float> feature;
  // reserve space for the three-dimensional Gaussian kernel
  feature.resize (N_ * 3);

  // fill the feature vector
  for (size_t i = 0; i < data_.size (); i++)
  {
    feature[i * 3    ] = static_cast<float> (data_[i].x ()) / sx;
    feature[i * 3 + 1] = static_cast<float> (data_[i].y ()) / sy;
    feature[i * 3 + 2] = static_cast<float> (data_[i].z ()) / sz;
  }
  // add kernel
  addPairwiseEnergy (feature, 3, w);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::addPairwiseBilateral (float sx, float sy, float sz,
                                     float sr, float sg, float sb,
                                     float w)
{
  // create feature vector
  std::vector<float> feature;
  // reserve space for the six-dimensional Gaussian kernel
  feature.resize (N_ * 6);

  // fill the feature vector
  for (size_t i = 0; i < color_.size (); i++)
  {
    feature[i * 6    ] = static_cast<float> (data_[i].x ()) / sx;
    feature[i * 6 + 1] = static_cast<float> (data_[i].y ()) / sy;
    feature[i * 6 + 2] = static_cast<float> (data_[i].z ()) / sz;
    feature[i * 6 + 3] = static_cast<float> (color_[i].x ()) / sr;
    feature[i * 6 + 4] = static_cast<float> (color_[i].y ()) / sg;
    feature[i * 6 + 5] = static_cast<float> (color_[i].z ()) / sb;
  }
  // add kernel
  addPairwiseEnergy (feature, 6, w);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::addPairwiseNormals (std::vector<Eigen::Vector3i> &coord,
                                   std::vector<Eigen::Vector3f> &normals,
                                   float sx, float sy, float sz,
                                   float snx, float sny, float snz,
                                   float w)
{
  std::cout << coord.size () << std::endl;
  std::cout << normals.size () << std::endl;

  // create feature vector
  std::vector<float> feature;
  // reserve space for the six-dimensional Gaussian kernel
  feature.resize (N_ * 6);

  // fill the feature vector
  for (size_t i = 0; i < coord.size (); i++)
  {
    if (isnan (normals[i].x ()))
    {
      if (i > 0)
      {
        normals[i].x () = normals[i-1].x ();
        normals[i].y () = normals[i-1].y ();
        normals[i].z () = normals[i-1].z ();
      }

      //std::cout << "NaN" << std::endl;

    }

    feature[i * 6    ] = static_cast<float> (coord[i].x ()) / sx;
    feature[i * 6 + 1] = static_cast<float> (coord[i].y ()) / sy;
    feature[i * 6 + 2] = static_cast<float> (coord[i].z ()) / sz;
    feature[i * 6 + 3] = static_cast<float> (normals[i].x ()) / snx;
    feature[i * 6 + 4] = static_cast<float> (normals[i].y ()) / sny;
    feature[i * 6 + 5] = static_cast<float> (normals[i].z ()) / snz;
  }
  // add kernel

  std::cout << "TEEEEST" << std::endl;

  addPairwiseEnergy (feature, 6, w);

  std::cout << "TEEEEST2" << std::endl;

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::inference (int n_iterations, std::vector<float> &result, float relax)
{
  // Start inference
  // Initialize using the unary energies
  expAndNormalize (current_, unary_, -1);

  for (int i = 0; i < n_iterations; i++)
  {
    runInference (relax);
    std::cout << "iteration: " << i+1 << " - DONE" << std::endl;
  }

  // Copy the data into the result vector
  result = current_;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::mapInference (int n_iterations, std::vector<int> &result, float relax)
{
  // Start inference
  // Initialize using the unary energies
  expAndNormalize (current_, unary_, -1);

  for (int i = 0; i < n_iterations; i++)
  {
    runInference (relax);
    std::cout << "iteration: " << i+1 << " - DONE" << std::endl;
  }

  // Find the map
  for (int i = 0; i < N_; i++)
  {
    const int prob_idx = i * M_;
    // Find the max
    float p_label = current_[prob_idx];
    int idx = 0;
    for (int j = 1; j < M_; j++)
    {
      if (p_label < current_[prob_idx + j])
      {
        p_label = current_[prob_idx + j];
        idx = j;
      }
    }
    result[i] = idx;
  }

/*
	for( int i = 0; i < N_; i++ ){
		const float * p = prob + i*M_;
		// Find the max and subtract it so that the exp doesn't explode
		float mx = p[0];
		int imx = 0;
		for( int j=1; j<M_; j++ )
			if( mx < p[j] ){
				mx = p[j];
				imx = j;
			}
    result[i] = imx
  }
*/

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::expAndNormalize (std::vector<float> &out, const std::vector<float> &in,
                                float scale, float relax)
{
  std::vector<float> V (N_ + 10);
	for( int i = 0; i < N_; i++ ){
    int b_idx = i*M_;
		// Find the max and subtract it so that the exp doesn't explode
		float mx = scale * in[b_idx];
		for( int j = 1; j < M_; j++ )
			if( mx < scale * in[b_idx + j] )
				mx = scale * in[b_idx + j];
		float tt = 0;
		for( int  j = 0; j < M_; j++ ){
			V[j] = expf( scale * in[b_idx + j] - mx );
			tt += V[j];
		}
		// Make it a probability
		for( int j = 0; j < M_; j++ )
			V[j] /= tt;

    int a_idx = i*M_;
		for( int j = 0; j < M_; j++ )
			if (relax == 1)
				out[a_idx + j] = V[j];
			else
				out[a_idx + j] = (1-relax) * out[a_idx + j] + relax * V[j];
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::runInference (float relax)
{
  // set the unary potentials
  for (size_t i = 0; i < unary_.size (); i++)
    next_[i] = -unary_[i];

  // Add up all pairwise potentials
	for( unsigned int i = 0; i < pairwise_potential_.size(); i++ )
    pairwise_potential_[i]->compute( next_, current_, tmp_, M_ );

	// Exponentiate and normalize
	expAndNormalize( current_, next_, 1.0, relax );
}

void
pcl::DenseCrf::getBarycentric (int idx, std::vector<float> &bary)
{
  bary = pairwise_potential_[idx]->bary_;
}

void
pcl::DenseCrf::getFeatures (int idx, std::vector<float> &features)
{
  features = pairwise_potential_[idx]->features_;
}
<commit_msg>isnan -> pcl_isnan<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * Author : Christian Potthast
 * Email  : potthast@usc.edu
 *
 */

#include <pcl/ml/densecrf.h>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pcl::DenseCrf::DenseCrf (int N, int m) :
  N_ (N), M_ (m),
  xyz_ (false), rgb_ (false), normal_ (false)
{
  current_.resize (N_ * M_, 0.0f);
  next_.resize (N_ * M_, 0.0f);
  tmp_.resize (2 * N_ * M_, 0.0f);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pcl::DenseCrf::~DenseCrf ()
{
  for(size_t i = 0; i < pairwise_potential_.size (); i++ )
    delete pairwise_potential_[i];
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::setDataVector (const std::vector<Eigen::Vector3i> data)
{
  xyz_ = true;
  data_ = data;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::setColorVector (const std::vector<Eigen::Vector3i> color)
{
  rgb_ = true;
  color_ = color;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::setUnaryEnergy (const std::vector<float> unary)
{
  unary_ = unary;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::addPairwiseEnergy (const std::vector<float> &feature, const int feature_dimension, const float w)
{
  pairwise_potential_.push_back ( new PairwisePotential (feature, feature_dimension, N_, w) );
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::addPairwiseGaussian (float sx, float sy, float sz, float w)
{
  // create feature vector
  std::vector<float> feature;
  // reserve space for the three-dimensional Gaussian kernel
  feature.resize (N_ * 3);

  // fill the feature vector
  for (size_t i = 0; i < data_.size (); i++)
  {
    feature[i * 3    ] = static_cast<float> (data_[i].x ()) / sx;
    feature[i * 3 + 1] = static_cast<float> (data_[i].y ()) / sy;
    feature[i * 3 + 2] = static_cast<float> (data_[i].z ()) / sz;
  }
  // add kernel
  addPairwiseEnergy (feature, 3, w);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::addPairwiseBilateral (float sx, float sy, float sz,
                                     float sr, float sg, float sb,
                                     float w)
{
  // create feature vector
  std::vector<float> feature;
  // reserve space for the six-dimensional Gaussian kernel
  feature.resize (N_ * 6);

  // fill the feature vector
  for (size_t i = 0; i < color_.size (); i++)
  {
    feature[i * 6    ] = static_cast<float> (data_[i].x ()) / sx;
    feature[i * 6 + 1] = static_cast<float> (data_[i].y ()) / sy;
    feature[i * 6 + 2] = static_cast<float> (data_[i].z ()) / sz;
    feature[i * 6 + 3] = static_cast<float> (color_[i].x ()) / sr;
    feature[i * 6 + 4] = static_cast<float> (color_[i].y ()) / sg;
    feature[i * 6 + 5] = static_cast<float> (color_[i].z ()) / sb;
  }
  // add kernel
  addPairwiseEnergy (feature, 6, w);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::addPairwiseNormals (std::vector<Eigen::Vector3i> &coord,
                                   std::vector<Eigen::Vector3f> &normals,
                                   float sx, float sy, float sz,
                                   float snx, float sny, float snz,
                                   float w)
{
  std::cout << coord.size () << std::endl;
  std::cout << normals.size () << std::endl;

  // create feature vector
  std::vector<float> feature;
  // reserve space for the six-dimensional Gaussian kernel
  feature.resize (N_ * 6);

  // fill the feature vector
  for (size_t i = 0; i < coord.size (); i++)
  {
    if (pcl_isnan (normals[i].x ()))
    {
      if (i > 0)
      {
        normals[i].x () = normals[i-1].x ();
        normals[i].y () = normals[i-1].y ();
        normals[i].z () = normals[i-1].z ();
      }

      //std::cout << "NaN" << std::endl;

    }

    feature[i * 6    ] = static_cast<float> (coord[i].x ()) / sx;
    feature[i * 6 + 1] = static_cast<float> (coord[i].y ()) / sy;
    feature[i * 6 + 2] = static_cast<float> (coord[i].z ()) / sz;
    feature[i * 6 + 3] = static_cast<float> (normals[i].x ()) / snx;
    feature[i * 6 + 4] = static_cast<float> (normals[i].y ()) / sny;
    feature[i * 6 + 5] = static_cast<float> (normals[i].z ()) / snz;
  }
  // add kernel

  std::cout << "TEEEEST" << std::endl;

  addPairwiseEnergy (feature, 6, w);

  std::cout << "TEEEEST2" << std::endl;

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::inference (int n_iterations, std::vector<float> &result, float relax)
{
  // Start inference
  // Initialize using the unary energies
  expAndNormalize (current_, unary_, -1);

  for (int i = 0; i < n_iterations; i++)
  {
    runInference (relax);
    std::cout << "iteration: " << i+1 << " - DONE" << std::endl;
  }

  // Copy the data into the result vector
  result = current_;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::mapInference (int n_iterations, std::vector<int> &result, float relax)
{
  // Start inference
  // Initialize using the unary energies
  expAndNormalize (current_, unary_, -1);

  for (int i = 0; i < n_iterations; i++)
  {
    runInference (relax);
    std::cout << "iteration: " << i+1 << " - DONE" << std::endl;
  }

  // Find the map
  for (int i = 0; i < N_; i++)
  {
    const int prob_idx = i * M_;
    // Find the max
    float p_label = current_[prob_idx];
    int idx = 0;
    for (int j = 1; j < M_; j++)
    {
      if (p_label < current_[prob_idx + j])
      {
        p_label = current_[prob_idx + j];
        idx = j;
      }
    }
    result[i] = idx;
  }

/*
	for( int i = 0; i < N_; i++ ){
		const float * p = prob + i*M_;
		// Find the max and subtract it so that the exp doesn't explode
		float mx = p[0];
		int imx = 0;
		for( int j=1; j<M_; j++ )
			if( mx < p[j] ){
				mx = p[j];
				imx = j;
			}
    result[i] = imx
  }
*/

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::expAndNormalize (std::vector<float> &out, const std::vector<float> &in,
                                float scale, float relax)
{
  std::vector<float> V (N_ + 10);
	for( int i = 0; i < N_; i++ ){
    int b_idx = i*M_;
		// Find the max and subtract it so that the exp doesn't explode
		float mx = scale * in[b_idx];
		for( int j = 1; j < M_; j++ )
			if( mx < scale * in[b_idx + j] )
				mx = scale * in[b_idx + j];
		float tt = 0;
		for( int  j = 0; j < M_; j++ ){
			V[j] = expf( scale * in[b_idx + j] - mx );
			tt += V[j];
		}
		// Make it a probability
		for( int j = 0; j < M_; j++ )
			V[j] /= tt;

    int a_idx = i*M_;
		for( int j = 0; j < M_; j++ )
			if (relax == 1)
				out[a_idx + j] = V[j];
			else
				out[a_idx + j] = (1-relax) * out[a_idx + j] + relax * V[j];
	}
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::DenseCrf::runInference (float relax)
{
  // set the unary potentials
  for (size_t i = 0; i < unary_.size (); i++)
    next_[i] = -unary_[i];

  // Add up all pairwise potentials
	for( unsigned int i = 0; i < pairwise_potential_.size(); i++ )
    pairwise_potential_[i]->compute( next_, current_, tmp_, M_ );

	// Exponentiate and normalize
	expAndNormalize( current_, next_, 1.0, relax );
}

void
pcl::DenseCrf::getBarycentric (int idx, std::vector<float> &bary)
{
  bary = pairwise_potential_[idx]->bary_;
}

void
pcl::DenseCrf::getFeatures (int idx, std::vector<float> &features)
{
  features = pairwise_potential_[idx]->features_;
}
<|endoftext|>


<commit_before>#include <endian.h>
#include <algorithm>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
const string DATASET_PATH = "data/train-images.idx3-ubyte";
const string OUTPUT_FILE = "data/Mnist.ds";
const string OUTPUT_PATH = "data/images/";

int main() {
    uint32_t number;
    uint8_t pixel;
    int n, width, height;
    ifstream dataset(DATASET_PATH, ios::binary);
    ofstream Mnist(OUTPUT_FILE);
    if (dataset.is_open() && Mnist.is_open()) {
        dataset.read((char*)&number, sizeof(uint32_t));
        cout << "Magic number is " << be32toh(number) << " ." << endl; // magic number 2051

        dataset.read((char*)&number, sizeof(uint32_t));
        n = be32toh(number);
        cout << "There are " << n << " images." << endl; // the number of images

        dataset.read((char*)&number, sizeof(uint32_t));
        height = be32toh(number);
        cout << "Height is " << height << " pixels." << endl;

        dataset.read((char*)&number, sizeof(uint32_t));
        width = be32toh(number);
        cout << "Width is " << width << " pixels." << endl;

        for (int w = 1; w <= n; w++) {
            stringstream ss;
            ss << w;
            ofstream output(OUTPUT_PATH + ss.str() + ".txt");
            if (!output.is_open()) {
                cout << "Can't open output file!" << endl;
                return 0;
            }
            Mnist << w;
            for (int i = 1; i <= height; i++) {
                for (int j = 1; j <= width; j++) {
                    dataset.read((char*)&pixel, sizeof(pixel));
                    uint8_t t = 1;
                    int ans = 0;
                    for (int k = 1; k <= 8; k++) {
                        ans = ans << 1;
                        if ((pixel & t) == t) ans = ans + 1;
                        t = t << 1;
                    }
                    if (ans != 0) {
                        cout << '*';
                        output << 1;
                        Mnist << " " << 1;
                    } else {
                        cout << ' ';
                        output << 0;
                        Mnist << " " << 0;
                    }
                }
                cout << endl;
                output << "\n";
            }
            Mnist << "\n";
            output.close();
        }
        dataset.close();
        Mnist.close();
    } else {
        cout << "Dataset doesn't exist!" << endl;
    }
    return 0;
}
<commit_msg>save pixel into Minst<commit_after>#include <endian.h>
#include <algorithm>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
const string DATASET_PATH = "data/train-images.idx3-ubyte";
const string OUTPUT_FILE = "data/Mnist.ds";
const string OUTPUT_PATH = "data/images/";

int main() {
    uint32_t number;
    uint8_t pixel;
    int n, width, height;
    ifstream dataset(DATASET_PATH, ios::binary);
    ofstream Mnist(OUTPUT_FILE);
    if (dataset.is_open() && Mnist.is_open()) {
        dataset.read((char*)&number, sizeof(uint32_t));
        cout << "Magic number is " << be32toh(number) << " ." << endl; // magic number 2051

        dataset.read((char*)&number, sizeof(uint32_t));
        n = be32toh(number);
        cout << "There are " << n << " images." << endl; // the number of images

        dataset.read((char*)&number, sizeof(uint32_t));
        height = be32toh(number);
        cout << "Height is " << height << " pixels." << endl;

        dataset.read((char*)&number, sizeof(uint32_t));
        width = be32toh(number);
        cout << "Width is " << width << " pixels." << endl;

        for (int w = 1; w <= n; w++) {
            stringstream ss;
            ss << w;
            ofstream output(OUTPUT_PATH + ss.str() + ".txt");
            if (!output.is_open()) {
                cout << "Can't open output file!" << endl;
                return 0;
            }
            Mnist << w;
            for (int i = 1; i <= height; i++) {
                for (int j = 1; j <= width; j++) {
                    dataset.read((char*)&pixel, sizeof(pixel));
                    uint8_t t = 1;
                    int ans = 0;
                    for (int k = 1; k <= 8; k++) {
                        ans = ans << 1;
                        if ((pixel & t) == t) ans = ans + 1;
                        t = t << 1;
                    }
                    if (ans != 0) {
                        cout << "*";
                        output << '*';
                        Mnist << " " << ans;
                    } else {
                        cout << ' ';
                        output << ' ';
                        Mnist << " " << ans;
                    }
                }
                cout << endl;
                output << "\n";
            }
            Mnist << "\n";
            output.close();
        }
        dataset.close();
        Mnist.close();
    } else {
        cout << "Dataset doesn't exist!" << endl;
    }
    return 0;
}
<|endoftext|>


<commit_before>#include <tamer/driver.hh>
#include <tamer/adapter.hh>
#include <sys/select.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>

namespace tamer {

driver driver::main;

// using the "self-pipe trick" recommended by select(3) and sfslite.
namespace {

#define NSIGNALS 32
int sig_pipe[2] = { -1, -1 };
volatile unsigned sig_any_active;
volatile unsigned sig_active[NSIGNALS];
volatile int sig_installing = -1;
event<> sig_handlers[NSIGNALS];

class sigcancel_rendezvous : public rendezvous<> { public:

    sigcancel_rendezvous() {
    }

    inline void add(tamerpriv::simple_event *e) throw () {
	_nwaiting++;
	e->initialize(this, sig_installing);
    }

    void complete(uintptr_t rname, bool success) {
	if ((int) rname != sig_installing && success) {
	    struct sigaction sa;
	    sa.sa_handler = SIG_DFL;
	    sigemptyset(&sa.sa_mask);
	    sa.sa_flags = SA_RESETHAND;
	    sigaction(rname, &sa, 0);
	}
	rendezvous<>::complete(rname, success);
    }

};

sigcancel_rendezvous sigcancelr;

}

driver::driver()
    : _t(0), _nt(0),
      _fd(0), _nfds(0),
      _tcap(0), _tgroup(0), _tfree(0),
      _fdcap(0), _fdgroup(0), _fdfree(0)
{
    expand_timers();
    FD_ZERO(&_readfds);
    FD_ZERO(&_writefds);
    set_now();
}

driver::~driver()
{
    // destroy all active timers
    for (int i = 0; i < _nt; i++)
	_t[i]->~ttimer();

    // free timer groups
    while (_tgroup) {
	ttimer_group *next = _tgroup->next;
	delete[] reinterpret_cast<unsigned char *>(_tgroup);
	_tgroup = next;
    }
    delete[] _t;

    // destroy all active file descriptors
    while (_fd) {
	_fd->e.~event();
	_fd = _fd->next;
    }

    // free file descriptor groups
    while (_fdgroup) {
	tfd_group *next = _fdgroup->next;
	delete[] reinterpret_cast<unsigned char *>(_fdgroup);
	_fdgroup = next;
    }
}

void driver::expand_timers()
{
    int ncap = (_tcap ? _tcap * 2 : 16);

    ttimer_group *ngroup = reinterpret_cast<ttimer_group *>(new unsigned char[sizeof(ttimer_group) + sizeof(ttimer) * (ncap - 1)]);
    ngroup->next = _tgroup;
    _tgroup = ngroup;
    for (int i = 0; i < ncap; i++) {
	ngroup->t[i].u.next = _tfree;
	_tfree = &ngroup->t[i];
    }

    ttimer **t = new ttimer *[ncap];
    memcpy(t, _t, sizeof(ttimer *) * _nt);
    delete[] _t;
    _t = t;
    _tcap = ncap;
}

void driver::timer_reheapify_from(int pos, ttimer *t, bool /*will_delete*/)
{
    int npos;
    while (pos > 0
	   && (npos = (pos-1) >> 1, timercmp(&_t[npos]->expiry, &t->expiry, >))) {
	_t[pos] = _t[npos];
	_t[npos]->u.schedpos = pos;
	pos = npos;
    }

    while (1) {
	ttimer *smallest = t;
	npos = 2*pos + 1;
	if (npos < _nt && !timercmp(&_t[npos]->expiry, &smallest->expiry, >))
	    smallest = _t[npos];
	if (npos + 1 < _nt && !timercmp(&_t[npos+1]->expiry, &smallest->expiry, >))
	    smallest = _t[npos+1], npos++;

	smallest->u.schedpos = pos;
	_t[pos] = smallest;

	if (smallest == t)
	    break;

	pos = npos;
    }
#if 0
    if (_t + 1 < tend || !will_delete)
	_timer_expiry = tbegin[0]->expiry;
    else
	_timer_expiry = Timestamp();
#endif
}

#if 0
void driver::check_timers() const
{
    fprintf(stderr, "---");
    for (int k = 0; k < _nt; k++)
	fprintf(stderr, " %p/%d.%06d", _t[k], _t[k]->expiry.tv_sec, _t[k]->expiry.tv_usec);
    fprintf(stderr, "\n");

    for (int i = 0; i < _nt / 2; i++)
	for (int j = 2*i + 1; j < 2*i + 3; j++)
	    if (j < _nt && timercmp(&_t[i]->expiry, &_t[j]->expiry, >)) {
		fprintf(stderr, "***");
		for (int k = 0; k < _nt; k++)
		    fprintf(stderr, (k == i || k == j ? " **%d.%06d**" : " %d.%06d"), _t[k]->expiry.tv_sec, _t[k]->expiry.tv_usec);
		fprintf(stderr, "\n");
		assert(0);
	    }
}
#endif

void driver::expand_fds()
{
    int ncap = (_fdcap ? _fdcap * 2 : 16);

    tfd_group *ngroup = reinterpret_cast<tfd_group *>(new unsigned char[sizeof(tfd_group) + sizeof(tfd) * (ncap - 1)]);
    ngroup->next = _fdgroup;
    _fdgroup = ngroup;
    for (int i = 0; i < ncap; i++) {
	ngroup->t[i].next = _fdfree;
	_fdfree = &ngroup->t[i];
    }
}

void driver::at_fd(int fd, int action, const event<> &trigger)
{
    if (!_fdfree)
	expand_fds();
    if (fd >= FD_SETSIZE)
	throw tamer::tamer_error("file descriptor too large");
    if (trigger) {
	tfd *t = _fdfree;
	_fdfree = t->next;
	t->next = _fd;
	_fd = t;

	t->fd = fd;
	t->action = action;
	(void) new(static_cast<void *>(&t->e)) event<>(trigger);

	if (action <= fdwrite) {
	    fd_set *fset = (action == fdwrite ? &_writefds : &_readfds);
	    FD_SET(fd, fset);
	    if (fd >= _nfds)
		_nfds = fd + 1;
	    t->e.at_cancel(make_event(_fdcancelr));
	}
    }
}

void driver::kill_fd(int fd)
{
    assert(fd >= 0);
    if (fd < _nfds && (FD_ISSET(fd, &_readfds) || FD_ISSET(fd, &_writefds))) {
	tfd **pprev = &_fd, *t;
	while ((t = *pprev))
	    if (t->fd == fd) {
		if (t->action == fdclose)
		    t->e.trigger();
		t->e.~event();
		*pprev = t->next;
		t->next = _fdfree;
		_fdfree = t;
	    } else
		pprev = &t->next;
    }
}

void driver::at_delay(double delay, const event<> &e)
{
    if (delay <= 0)
	at_asap(e);
    else {
	timeval tv = now;
	long ldelay = (long) delay;
	tv.tv_sec += ldelay;
	tv.tv_usec += (long) ((delay - ldelay) * 1000000 + 0.5);
	if (tv.tv_usec >= 1000000) {
	    tv.tv_sec++;
	    tv.tv_usec -= 1000000;
	}
	at_time(tv, e);
    }
}

extern "C" {
static void tame_signal_handler(int signal) {
    sig_any_active = sig_active[signal] = 1;
    // ensure select wakes up, even if we get a signal in between setting the
    // timeout and calling select!
    write(sig_pipe[1], "", 1);

    // block signal until we trigger the event, giving the unblocked
    // rendezvous a chance to maybe install another handler
    sigset_t sigset;
    sigemptyset(&sigset);
    sigaddset(&sigset, signal);
    sigprocmask(SIG_BLOCK, &sigset, NULL);
}
}

void driver::at_signal(int signal, const event<> &trigger)
{
    assert(signal < NSIGNALS);

    if (!trigger)
	return;

    if (sig_pipe[0] < 0) {
	pipe(sig_pipe);
	fcntl(sig_pipe[0], F_SETFL, O_NONBLOCK);
	fcntl(sig_pipe[0], F_SETFD, FD_CLOEXEC);
	fcntl(sig_pipe[1], F_SETFD, FD_CLOEXEC);
    }

    if (sig_handlers[signal])
	sig_handlers[signal] = distribute(sig_handlers[signal], trigger);
    else {
	sig_installing = signal;

	sig_handlers[signal] = trigger;
	sig_handlers[signal].at_cancel(make_event(sigcancelr));

	struct sigaction sa;
	sa.sa_handler = tame_signal_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESETHAND;
	sigaction(signal, &sa, 0);

	sig_installing = -1;
    }
}

bool driver::empty() const
{
    if (_nt != 0 || _nfds != 0 || _asap.size() != 0
	|| sig_any_active || tamerpriv::abstract_rendezvous::unblocked)
	return false;
    for (int i = 0; i < NSIGNALS; i++)
	if (sig_handlers[i])
	    return false;
    return true;
}

void driver::once()
{
    // get rid of initial cancelled timers
    ttimer *t;
    while (_nt > 0 && (t = _t[0], !t->trigger)) {
	timer_reheapify_from(0, _t[_nt - 1], true);
	_nt--;
	t->~ttimer();
	t->u.next = _tfree;
	_tfree = t;
    }

    // determine timeout
    struct timeval to, *toptr;
    if (_asap.size()
	|| (_nt > 0 && !timercmp(&_t[0]->expiry, &now, >))
	|| sig_any_active) {
	timerclear(&to);
	toptr = &to;
    } else if (_nt == 0)
	toptr = 0;
    else {
	timersub(&_t[0]->expiry, &now, &to);
	toptr = &to;
    }

    // get rid of canceled descriptors, if any
    if (_fdcancelr.nready()) {
	while (_fdcancelr.join())
	    /* nada */;
	FD_ZERO(&_readfds);
	FD_ZERO(&_writefds);
	_nfds = 0;
	tfd **pprev = &_fd, *t;
	while ((t = *pprev))
	    if (!t->e) {
		t->e.~event();
		*pprev = t->next;
		t->next = _fdfree;
		_fdfree = t;
	    } else if (t->action <= fdwrite) {
		fd_set *fset = (t->action == fdwrite ? &_writefds : &_readfds);
		FD_SET(t->fd, fset);
		pprev = &t->next;
		if (t->fd >= _nfds)
		    _nfds = t->fd + 1;
	    }
    }

    // select!
    fd_set rfds = _readfds;
    fd_set wfds = _writefds;
    int nfds = _nfds;
    if (sig_pipe[0] >= 0) {
	FD_SET(sig_pipe[0], &rfds);
	if (sig_pipe[0] > nfds)
	    nfds = sig_pipe[0] + 1;
    }
    nfds = select(nfds, &rfds, &wfds, 0, toptr);

    // run signals
    if (sig_any_active) {
	sig_any_active = 0;
	sigset_t sigs_unblock;
	sigemptyset(&sigs_unblock);

	// check signals
	for (int sig = 0; sig < NSIGNALS; sig++)
	    if (sig_active[sig]) {
		sig_active[sig] = 0;
		sig_handlers[sig].trigger();
		sigaddset(&sigs_unblock, sig);
	    }

	// run closures activated by signals (plus maybe some others)
	while (tamerpriv::abstract_rendezvous *r = tamerpriv::abstract_rendezvous::unblocked)
	    r->run();

	// now that the signal responders have potentially reinstalled signal
	// handlers, unblock the signals
	sigprocmask(SIG_UNBLOCK, &sigs_unblock, 0);

	// kill crap data written to pipe
	char crap[64];
	while (read(sig_pipe[0], crap, 64) > 0)
	    /* do nothing */;
    }

    // run asaps
    while (event<> *e = _asap.front()) {
	e->trigger();
	_asap.pop_front();
    }

    // run file descriptors
    if (nfds >= 0) {
	tfd **pprev = &_fd, *t;
	while ((t = *pprev))
	    if ((t->action == fdread && FD_ISSET(t->fd, &rfds))
		|| (t->action == fdwrite && FD_ISSET(t->fd, &wfds))) {
		fd_set *fset = (t->action == fdwrite ? &_writefds : &_readfds);
		FD_CLR(t->fd, fset);
		t->e.trigger();
		t->e.~event();
		*pprev = t->next;
		t->next = _fdfree;
		_fdfree = t;
	    } else if (!t->e) {
		t->e.~event();
		*pprev = t->next;
		t->next = _fdfree;
		_fdfree = t;
	    } else
		pprev = &t->next;
    }

    // run the timers that worked
    set_now();
    while (_nt > 0 && (t = _t[0], !timercmp(&t->expiry, &now, >))) {
	timer_reheapify_from(0, _t[_nt - 1], true);
	_nt--;
	t->trigger.trigger();
	t->~ttimer();
	t->u.next = _tfree;
	_tfree = t;
    }

    // run active closures
    while (tamerpriv::abstract_rendezvous *r = tamerpriv::abstract_rendezvous::unblocked)
	r->run();
}

void driver::loop()
{
    while (1)
	once();
}

}
<commit_msg>make sure you remove fdclose events on kill_fd<commit_after>#include <tamer/driver.hh>
#include <tamer/adapter.hh>
#include <sys/select.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>

namespace tamer {

driver driver::main;

// using the "self-pipe trick" recommended by select(3) and sfslite.
namespace {

#define NSIGNALS 32
int sig_pipe[2] = { -1, -1 };
volatile unsigned sig_any_active;
volatile unsigned sig_active[NSIGNALS];
volatile int sig_installing = -1;
event<> sig_handlers[NSIGNALS];

class sigcancel_rendezvous : public rendezvous<> { public:

    sigcancel_rendezvous() {
    }

    inline void add(tamerpriv::simple_event *e) throw () {
	_nwaiting++;
	e->initialize(this, sig_installing);
    }

    void complete(uintptr_t rname, bool success) {
	if ((int) rname != sig_installing && success) {
	    struct sigaction sa;
	    sa.sa_handler = SIG_DFL;
	    sigemptyset(&sa.sa_mask);
	    sa.sa_flags = SA_RESETHAND;
	    sigaction(rname, &sa, 0);
	}
	rendezvous<>::complete(rname, success);
    }

};

sigcancel_rendezvous sigcancelr;

}

driver::driver()
    : _t(0), _nt(0),
      _fd(0), _nfds(0),
      _tcap(0), _tgroup(0), _tfree(0),
      _fdcap(0), _fdgroup(0), _fdfree(0)
{
    expand_timers();
    FD_ZERO(&_readfds);
    FD_ZERO(&_writefds);
    set_now();
}

driver::~driver()
{
    // destroy all active timers
    for (int i = 0; i < _nt; i++)
	_t[i]->~ttimer();

    // free timer groups
    while (_tgroup) {
	ttimer_group *next = _tgroup->next;
	delete[] reinterpret_cast<unsigned char *>(_tgroup);
	_tgroup = next;
    }
    delete[] _t;

    // destroy all active file descriptors
    while (_fd) {
	_fd->e.~event();
	_fd = _fd->next;
    }

    // free file descriptor groups
    while (_fdgroup) {
	tfd_group *next = _fdgroup->next;
	delete[] reinterpret_cast<unsigned char *>(_fdgroup);
	_fdgroup = next;
    }
}

void driver::expand_timers()
{
    int ncap = (_tcap ? _tcap * 2 : 16);

    ttimer_group *ngroup = reinterpret_cast<ttimer_group *>(new unsigned char[sizeof(ttimer_group) + sizeof(ttimer) * (ncap - 1)]);
    ngroup->next = _tgroup;
    _tgroup = ngroup;
    for (int i = 0; i < ncap; i++) {
	ngroup->t[i].u.next = _tfree;
	_tfree = &ngroup->t[i];
    }

    ttimer **t = new ttimer *[ncap];
    memcpy(t, _t, sizeof(ttimer *) * _nt);
    delete[] _t;
    _t = t;
    _tcap = ncap;
}

void driver::timer_reheapify_from(int pos, ttimer *t, bool /*will_delete*/)
{
    int npos;
    while (pos > 0
	   && (npos = (pos-1) >> 1, timercmp(&_t[npos]->expiry, &t->expiry, >))) {
	_t[pos] = _t[npos];
	_t[npos]->u.schedpos = pos;
	pos = npos;
    }

    while (1) {
	ttimer *smallest = t;
	npos = 2*pos + 1;
	if (npos < _nt && !timercmp(&_t[npos]->expiry, &smallest->expiry, >))
	    smallest = _t[npos];
	if (npos + 1 < _nt && !timercmp(&_t[npos+1]->expiry, &smallest->expiry, >))
	    smallest = _t[npos+1], npos++;

	smallest->u.schedpos = pos;
	_t[pos] = smallest;

	if (smallest == t)
	    break;

	pos = npos;
    }
#if 0
    if (_t + 1 < tend || !will_delete)
	_timer_expiry = tbegin[0]->expiry;
    else
	_timer_expiry = Timestamp();
#endif
}

#if 0
void driver::check_timers() const
{
    fprintf(stderr, "---");
    for (int k = 0; k < _nt; k++)
	fprintf(stderr, " %p/%d.%06d", _t[k], _t[k]->expiry.tv_sec, _t[k]->expiry.tv_usec);
    fprintf(stderr, "\n");

    for (int i = 0; i < _nt / 2; i++)
	for (int j = 2*i + 1; j < 2*i + 3; j++)
	    if (j < _nt && timercmp(&_t[i]->expiry, &_t[j]->expiry, >)) {
		fprintf(stderr, "***");
		for (int k = 0; k < _nt; k++)
		    fprintf(stderr, (k == i || k == j ? " **%d.%06d**" : " %d.%06d"), _t[k]->expiry.tv_sec, _t[k]->expiry.tv_usec);
		fprintf(stderr, "\n");
		assert(0);
	    }
}
#endif

void driver::expand_fds()
{
    int ncap = (_fdcap ? _fdcap * 2 : 16);

    tfd_group *ngroup = reinterpret_cast<tfd_group *>(new unsigned char[sizeof(tfd_group) + sizeof(tfd) * (ncap - 1)]);
    ngroup->next = _fdgroup;
    _fdgroup = ngroup;
    for (int i = 0; i < ncap; i++) {
	ngroup->t[i].next = _fdfree;
	_fdfree = &ngroup->t[i];
    }
}

void driver::at_fd(int fd, int action, const event<> &trigger)
{
    if (!_fdfree)
	expand_fds();
    if (fd >= FD_SETSIZE)
	throw tamer::tamer_error("file descriptor too large");
    if (trigger) {
	tfd *t = _fdfree;
	_fdfree = t->next;
	t->next = _fd;
	_fd = t;

	t->fd = fd;
	t->action = action;
	(void) new(static_cast<void *>(&t->e)) event<>(trigger);

	if (action <= fdwrite) {
	    fd_set *fset = (action == fdwrite ? &_writefds : &_readfds);
	    FD_SET(fd, fset);
	    if (fd >= _nfds)
		_nfds = fd + 1;
	    t->e.at_cancel(make_event(_fdcancelr));
	}
    }
}

void driver::kill_fd(int fd)
{
    assert(fd >= 0);
    if (fd < _nfds) {
	FD_CLR(fd, &_readfds);
	FD_CLR(fd, &_writefds);
    }
    tfd **pprev = &_fd, *t;
    while ((t = *pprev))
	if (t->fd == fd) {
	    if (t->action == fdclose)
		t->e.trigger();
	    t->e.~event();
	    *pprev = t->next;
	    t->next = _fdfree;
	    _fdfree = t;
	} else
	    pprev = &t->next;
}

void driver::at_delay(double delay, const event<> &e)
{
    if (delay <= 0)
	at_asap(e);
    else {
	timeval tv = now;
	long ldelay = (long) delay;
	tv.tv_sec += ldelay;
	tv.tv_usec += (long) ((delay - ldelay) * 1000000 + 0.5);
	if (tv.tv_usec >= 1000000) {
	    tv.tv_sec++;
	    tv.tv_usec -= 1000000;
	}
	at_time(tv, e);
    }
}

extern "C" {
static void tame_signal_handler(int signal) {
    sig_any_active = sig_active[signal] = 1;
    // ensure select wakes up, even if we get a signal in between setting the
    // timeout and calling select!
    write(sig_pipe[1], "", 1);

    // block signal until we trigger the event, giving the unblocked
    // rendezvous a chance to maybe install another handler
    sigset_t sigset;
    sigemptyset(&sigset);
    sigaddset(&sigset, signal);
    sigprocmask(SIG_BLOCK, &sigset, NULL);
}
}

void driver::at_signal(int signal, const event<> &trigger)
{
    assert(signal < NSIGNALS);

    if (!trigger)
	return;

    if (sig_pipe[0] < 0) {
	pipe(sig_pipe);
	fcntl(sig_pipe[0], F_SETFL, O_NONBLOCK);
	fcntl(sig_pipe[0], F_SETFD, FD_CLOEXEC);
	fcntl(sig_pipe[1], F_SETFD, FD_CLOEXEC);
    }

    if (sig_handlers[signal])
	sig_handlers[signal] = distribute(sig_handlers[signal], trigger);
    else {
	sig_installing = signal;

	sig_handlers[signal] = trigger;
	sig_handlers[signal].at_cancel(make_event(sigcancelr));

	struct sigaction sa;
	sa.sa_handler = tame_signal_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESETHAND;
	sigaction(signal, &sa, 0);

	sig_installing = -1;
    }
}

bool driver::empty() const
{
    if (_nt != 0 || _nfds != 0 || _asap.size() != 0
	|| sig_any_active || tamerpriv::abstract_rendezvous::unblocked)
	return false;
    for (int i = 0; i < NSIGNALS; i++)
	if (sig_handlers[i])
	    return false;
    return true;
}

void driver::once()
{
    // get rid of initial cancelled timers
    ttimer *t;
    while (_nt > 0 && (t = _t[0], !t->trigger)) {
	timer_reheapify_from(0, _t[_nt - 1], true);
	_nt--;
	t->~ttimer();
	t->u.next = _tfree;
	_tfree = t;
    }

    // determine timeout
    struct timeval to, *toptr;
    if (_asap.size()
	|| (_nt > 0 && !timercmp(&_t[0]->expiry, &now, >))
	|| sig_any_active) {
	timerclear(&to);
	toptr = &to;
    } else if (_nt == 0)
	toptr = 0;
    else {
	timersub(&_t[0]->expiry, &now, &to);
	toptr = &to;
    }

    // get rid of canceled descriptors, if any
    if (_fdcancelr.nready()) {
	while (_fdcancelr.join())
	    /* nada */;
	FD_ZERO(&_readfds);
	FD_ZERO(&_writefds);
	_nfds = 0;
	tfd **pprev = &_fd, *t;
	while ((t = *pprev))
	    if (!t->e) {
		t->e.~event();
		*pprev = t->next;
		t->next = _fdfree;
		_fdfree = t;
	    } else if (t->action <= fdwrite) {
		fd_set *fset = (t->action == fdwrite ? &_writefds : &_readfds);
		FD_SET(t->fd, fset);
		pprev = &t->next;
		if (t->fd >= _nfds)
		    _nfds = t->fd + 1;
	    }
    }

    // select!
    fd_set rfds = _readfds;
    fd_set wfds = _writefds;
    int nfds = _nfds;
    if (sig_pipe[0] >= 0) {
	FD_SET(sig_pipe[0], &rfds);
	if (sig_pipe[0] > nfds)
	    nfds = sig_pipe[0] + 1;
    }
    nfds = select(nfds, &rfds, &wfds, 0, toptr);

    // run signals
    if (sig_any_active) {
	sig_any_active = 0;
	sigset_t sigs_unblock;
	sigemptyset(&sigs_unblock);

	// check signals
	for (int sig = 0; sig < NSIGNALS; sig++)
	    if (sig_active[sig]) {
		sig_active[sig] = 0;
		sig_handlers[sig].trigger();
		sigaddset(&sigs_unblock, sig);
	    }

	// run closures activated by signals (plus maybe some others)
	while (tamerpriv::abstract_rendezvous *r = tamerpriv::abstract_rendezvous::unblocked)
	    r->run();

	// now that the signal responders have potentially reinstalled signal
	// handlers, unblock the signals
	sigprocmask(SIG_UNBLOCK, &sigs_unblock, 0);

	// kill crap data written to pipe
	char crap[64];
	while (read(sig_pipe[0], crap, 64) > 0)
	    /* do nothing */;
    }

    // run asaps
    while (event<> *e = _asap.front()) {
	e->trigger();
	_asap.pop_front();
    }

    // run file descriptors
    if (nfds >= 0) {
	tfd **pprev = &_fd, *t;
	while ((t = *pprev))
	    if ((t->action == fdread && FD_ISSET(t->fd, &rfds))
		|| (t->action == fdwrite && FD_ISSET(t->fd, &wfds))) {
		fd_set *fset = (t->action == fdwrite ? &_writefds : &_readfds);
		FD_CLR(t->fd, fset);
		t->e.trigger();
		t->e.~event();
		*pprev = t->next;
		t->next = _fdfree;
		_fdfree = t;
	    } else if (!t->e) {
		t->e.~event();
		*pprev = t->next;
		t->next = _fdfree;
		_fdfree = t;
	    } else
		pprev = &t->next;
    }

    // run the timers that worked
    set_now();
    while (_nt > 0 && (t = _t[0], !timercmp(&t->expiry, &now, >))) {
	timer_reheapify_from(0, _t[_nt - 1], true);
	_nt--;
	t->trigger.trigger();
	t->~ttimer();
	t->u.next = _tfree;
	_tfree = t;
    }

    // run active closures
    while (tamerpriv::abstract_rendezvous *r = tamerpriv::abstract_rendezvous::unblocked)
	r->run();
}

void driver::loop()
{
    while (1)
	once();
}

}
<|endoftext|>


<commit_before>
/*

    poedit, a wxWindows i18n catalogs editor

    ---------------
      edapp.cpp

      Application class

      (c) Vaclav Slavik, 1999

*/

#ifdef __GNUG__
#pragma implementation
#endif

#include <wx/wxprec.h>

#include <wx/wx.h>
#include <wx/fs_zip.h>
#include <wx/image.h>
#include <wx/xml/xmlres.h>
#include <wx/xml/xh_all.h>

#include "edapp.h"
#include "edframe.h"
#include "prefsdlg.h"

IMPLEMENT_APP(poEditApp);

wxString poEditApp::GetAppPath() const
{
#if defined(__UNIX__)
    return POEDIT_PREFIX;
#elif defined(__WXMSW__)
    wxString path = wxConfigBase::Get()->Read("application_path", "");
    if (!path)
    {
        wxLogError(_("poEdit installation is broken, cannot find application's home directory."));
        path = ".";
    }
    return path;
#else
#error "Unsupported platform!"
#endif
}

wxString poEditApp::GetAppVersion() const
{
    return "1.1.0";
}

#ifdef __UNIX__
#define CFG_FILE (home + ".poedit/config")
#else
#define CFG_FILE ""
#endif

bool poEditApp::OnInit()
{
#ifdef __UNIX__
    wxString home = wxGetHomeDir() + "/";

    // create poEdit cfg dir, move ~/.poedit to ~/.poedit/config
    // (upgrade from older versions of poEdit which used ~/.poedit file)
    if (!wxDirExists(home + ".poedit"))
    {
        if (wxFileExists(home + ".poedit"))
            wxRenameFile(home + ".poedit", home + ".poedit2");
        wxMkdir(home + ".poedit");
        if (wxFileExists(home + ".poedit2"))
            wxRenameFile(home + ".poedit2", home + ".poedit/config");
    }
#endif

    SetVendorName("Vaclav Slavik");
    SetAppName("poedit");
    wxConfigBase::Set(
        new wxConfig("", "", CFG_FILE, "",
                     wxCONFIG_USE_GLOBAL_FILE | wxCONFIG_USE_LOCAL_FILE));

#ifdef __UNIX__
    // we have to do this because otherwise xgettext might
    // speak in native language, not English, and we cannot parse
    // it correctly (not yet)
    // FIXME - better parsing of xgettext's stderr output
    putenv("LC_ALL=en");
    putenv("LC_MESSAGES=en");
    putenv("LANG=en");
#endif

    wxImage::AddHandler(new wxGIFHandler);
    wxFileSystem::AddHandler(new wxZipFSHandler);

    wxTheXmlResource->InitAllHandlers();
    wxTheXmlResource->Load(GetAppPath() + "/share/poedit/resources.zip");

    poEditFrame *frame = new poEditFrame("poEdit", argc > 1 ? argv[1] : "");

    frame->Show(true);
    SetTopWindow(frame);

    SetDefaultCfg(wxConfig::Get());

    if (wxConfig::Get()->Read("translator_name", "nothing") == "nothing")
    {
        wxMessageBox(_("This is first time you run poEdit.\n"
                       "Please fill in your name and e-mail address.\n"
                       "(This information is used only in catalogs headers)"), "Setup",
                       wxOK | wxICON_INFORMATION);

        PreferencesDialog dlg(frame);
        dlg.TransferTo(wxConfig::Get());
        if (dlg.ShowModal() == wxID_OK)
            dlg.TransferFrom(wxConfig::Get());
    }

    return true;
}

void poEditApp::SetDefaultCfg(wxConfigBase *cfg)
{
    if (cfg->Read("version", "") == GetAppVersion()) return;

    if (cfg->Read("Parsers/List", "").IsEmpty())
    {
        cfg->Write("Parsers/List", "C/C++");

        cfg->Write("Parsers/C_C++/Extensions",
                   "*.c;*.cpp;*.h;*.hpp;*.cc;*.C;*.cxx;*.hxx");
        cfg->Write("Parsers/C_C++/Command",
                   "xgettext --force-po -C -o %o %K %F");
        cfg->Write("Parsers/C_C++/KeywordItem",
                   "-k%k");
        cfg->Write("Parsers/C_C++/FileItem",
                   "%f");
    }

    if (cfg->Read("TM/database_path", "").IsEmpty())
    {
        wxString dbpath;
#if defined(__UNIX__)
        dbpath = wxGetHomeDir() + "/.poedit/tm";
#elif defined(__WXMSW__)
        dbpath = wxGetHomeDir() + "/share/poedit/tm";
#endif
        cfg->Write("TM/database_path", dbpath);
    }

    if (cfg->Read("TM/search_paths", "").IsEmpty())
    {
        wxString paths;
#if defined(__UNIX__)
        paths = wxGetHomeDir() + ":/usr/share/locale:/usr/local/share/locale";
#elif defined(__WXMSW__)
        paths = "C:";
#endif
        cfg->Write("TM/search_paths", paths);
    }

    cfg->Write("version", GetAppVersion());
}
<commit_msg>updated version to 1.1.1<commit_after>
/*

    poedit, a wxWindows i18n catalogs editor

    ---------------
      edapp.cpp

      Application class

      (c) Vaclav Slavik, 1999

*/

#ifdef __GNUG__
#pragma implementation
#endif

#include <wx/wxprec.h>

#include <wx/wx.h>
#include <wx/fs_zip.h>
#include <wx/image.h>
#include <wx/xml/xmlres.h>
#include <wx/xml/xh_all.h>

#include "edapp.h"
#include "edframe.h"
#include "prefsdlg.h"

IMPLEMENT_APP(poEditApp);

wxString poEditApp::GetAppPath() const
{
#if defined(__UNIX__)
    return POEDIT_PREFIX;
#elif defined(__WXMSW__)
    wxString path = wxConfigBase::Get()->Read("application_path", "");
    if (!path)
    {
        wxLogError(_("poEdit installation is broken, cannot find application's home directory."));
        path = ".";
    }
    return path;
#else
#error "Unsupported platform!"
#endif
}

wxString poEditApp::GetAppVersion() const
{
    return "1.1.1";
}

#ifdef __UNIX__
#define CFG_FILE (home + ".poedit/config")
#else
#define CFG_FILE ""
#endif

bool poEditApp::OnInit()
{
#ifdef __UNIX__
    wxString home = wxGetHomeDir() + "/";

    // create poEdit cfg dir, move ~/.poedit to ~/.poedit/config
    // (upgrade from older versions of poEdit which used ~/.poedit file)
    if (!wxDirExists(home + ".poedit"))
    {
        if (wxFileExists(home + ".poedit"))
            wxRenameFile(home + ".poedit", home + ".poedit2");
        wxMkdir(home + ".poedit");
        if (wxFileExists(home + ".poedit2"))
            wxRenameFile(home + ".poedit2", home + ".poedit/config");
    }
#endif

    SetVendorName("Vaclav Slavik");
    SetAppName("poedit");
    wxConfigBase::Set(
        new wxConfig("", "", CFG_FILE, "",
                     wxCONFIG_USE_GLOBAL_FILE | wxCONFIG_USE_LOCAL_FILE));

#ifdef __UNIX__
    // we have to do this because otherwise xgettext might
    // speak in native language, not English, and we cannot parse
    // it correctly (not yet)
    // FIXME - better parsing of xgettext's stderr output
    putenv("LC_ALL=en");
    putenv("LC_MESSAGES=en");
    putenv("LANG=en");
#endif

    wxImage::AddHandler(new wxGIFHandler);
    wxFileSystem::AddHandler(new wxZipFSHandler);

    wxTheXmlResource->InitAllHandlers();
    wxTheXmlResource->Load(GetAppPath() + "/share/poedit/resources.zip");

    poEditFrame *frame = new poEditFrame("poEdit", argc > 1 ? argv[1] : "");

    frame->Show(true);
    SetTopWindow(frame);

    SetDefaultCfg(wxConfig::Get());

    if (wxConfig::Get()->Read("translator_name", "nothing") == "nothing")
    {
        wxMessageBox(_("This is first time you run poEdit.\n"
                       "Please fill in your name and e-mail address.\n"
                       "(This information is used only in catalogs headers)"), "Setup",
                       wxOK | wxICON_INFORMATION);

        PreferencesDialog dlg(frame);
        dlg.TransferTo(wxConfig::Get());
        if (dlg.ShowModal() == wxID_OK)
            dlg.TransferFrom(wxConfig::Get());
    }

    return true;
}

void poEditApp::SetDefaultCfg(wxConfigBase *cfg)
{
    if (cfg->Read("version", "") == GetAppVersion()) return;

    if (cfg->Read("Parsers/List", "").IsEmpty())
    {
        cfg->Write("Parsers/List", "C/C++");

        cfg->Write("Parsers/C_C++/Extensions",
                   "*.c;*.cpp;*.h;*.hpp;*.cc;*.C;*.cxx;*.hxx");
        cfg->Write("Parsers/C_C++/Command",
                   "xgettext --force-po -C -o %o %K %F");
        cfg->Write("Parsers/C_C++/KeywordItem",
                   "-k%k");
        cfg->Write("Parsers/C_C++/FileItem",
                   "%f");
    }

    if (cfg->Read("TM/database_path", "").IsEmpty())
    {
        wxString dbpath;
#if defined(__UNIX__)
        dbpath = wxGetHomeDir() + "/.poedit/tm";
#elif defined(__WXMSW__)
        dbpath = wxGetHomeDir() + "/share/poedit/tm";
#endif
        cfg->Write("TM/database_path", dbpath);
    }

    if (cfg->Read("TM/search_paths", "").IsEmpty())
    {
        wxString paths;
#if defined(__UNIX__)
        paths = wxGetHomeDir() + ":/usr/share/locale:/usr/local/share/locale";
#elif defined(__WXMSW__)
        paths = "C:";
#endif
        cfg->Write("TM/search_paths", paths);
    }

    cfg->Write("version", GetAppVersion());
}
<|endoftext|>