<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/test/browser_test_utils.h"

using content::BrowserThread;

class FastShutdown : public InProcessBrowserTest {
 protected:
  FastShutdown() {
  }

  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitch(switches::kDisablePopupBlocking);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(FastShutdown);
};

// This tests for a previous error where uninstalling an onbeforeunload handler
// would enable fast shutdown even if an onunload handler still existed.
// Flaky on all platforms, http://crbug.com/89173
#if !defined(OS_CHROMEOS)  // ChromeOS opens tabs instead of windows for popups.
IN_PROC_BROWSER_TEST_F(FastShutdown, SlowTermination) {
  // Need to run these tests on http:// since we only allow cookies on that (and
  // https obviously).
  ASSERT_TRUE(test_server()->Start());
  // This page has an unload handler.
  GURL url = test_server()->GetURL("files/fast_shutdown/on_unloader.html");
  TabContents* tab = chrome::GetActiveTabContents(browser());
  EXPECT_EQ("", content::GetCookies(tab->profile(), url));

  content::WindowedNotificationObserver window_observer(
      chrome::NOTIFICATION_BROWSER_WINDOW_READY,
      content::NotificationService::AllSources());
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), url, NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_NONE);
  window_observer.Wait();

  // Close the new window, removing the one and only beforeunload handler.
  ASSERT_EQ(2u, BrowserList::size());
  BrowserList::const_iterator i = BrowserList::begin();
  ++i;
  chrome::CloseWindow(*i);

  // Need to wait for the renderer process to shutdown to ensure that we got the
  // set cookies IPC.
  content::WindowedNotificationObserver renderer_shutdown_observer(
      content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
      content::NotificationService::AllSources());
  // Close the tab. This should launch the unload handler, which sets a cookie
  // that's stored to disk.
  chrome::CloseTab(browser());
  renderer_shutdown_observer.Wait();

  EXPECT_EQ("unloaded=ohyeah", content::GetCookies(tab->profile(), url));
}
#endif
<commit_msg>tes<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/tab_contents/tab_contents.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/test/browser_test_utils.h"

using content::BrowserThread;

class FastShutdown : public InProcessBrowserTest {
 protected:
  FastShutdown() {
  }

  virtual void SetUpCommandLine(CommandLine* command_line) {
    command_line->AppendSwitch(switches::kDisablePopupBlocking);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(FastShutdown);
};

// This tests for a previous error where uninstalling an onbeforeunload handler
// would enable fast shutdown even if an onunload handler still existed.
// Flaky on all platforms, http://crbug.com/89173
#if !defined(OS_CHROMEOS)  // ChromeOS opens tabs instead of windows for popups.
IN_PROC_BROWSER_TEST_F(FastShutdown, SlowTermination) {
  // Need to run these tests on http:// since we only allow cookies on that (and
  // https obviously).
  ASSERT_TRUE(test_server()->Start());
  // This page has an unload handler.
  GURL url = test_server()->GetURL("files/fast_shutdown/on_unloader.html");
  TabContents* tab = chrome::GetActiveTabContents(browser());
  EXPECT_EQ("", content::GetCookies(tab->profile(), url));

  content::WindowedNotificationObserver window_observer(
      chrome::NOTIFICATION_BROWSER_WINDOW_READY,
      content::NotificationService::AllSources());
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), url, NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_NONE);
  window_observer.Wait();

  // Close the new window, removing the one and only beforeunload handler.
  ASSERT_EQ(2u, BrowserList::size());
  BrowserList::const_iterator i = BrowserList::begin();
  ++i;
  chrome::CloseWindow(*i);

  // Need to wait for the renderer process to shutdown to ensure that we got the
  // set cookies IPC.
  content::WindowedNotificationObserver renderer_shutdown_observer(
      content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
      content::NotificationService::AllSources());
  // Close the tab. This should launch the unload handler, which sets a cookie
  // that's stored to disk.
  chrome::CloseTab(browser());
  renderer_shutdown_observer.Wait();

  EXPECT_EQ("unloaded=ohyeah", content::GetCookies(tab->profile(), url));
}
#endif
<|endoftext|>


<commit_before>#include "main.h"
#include "User.h"
#include "Nick.h"
#include "Modules.h"
#include "Chan.h"
#include "Utils.h"
#include "FileUtils.h"
#include <pwd.h>
#include <map>
#include <vector>

class CStickyChan : public CModule
{
public:
	MODCONSTRUCTOR(CStickyChan) {}
	virtual ~CStickyChan()
	{
	}

	virtual bool OnLoad(const CString& sArgs);

	virtual CString GetDescription()
	{
		return ( "configless sticky chans, keeps you there very stickily even" );
	}

	virtual void OnModCommand( const CString& sCommand )
	{
		CString sCmdName = sCommand.Token(0);
		CString sChannel = sCommand.Token(1);
		sChannel.MakeLower();
		if ( ( sCmdName == "stick" ) && ( !sChannel.empty() ) )
		{
			SetNV( sChannel, sCommand.Token(2) );
			PutModule( "Stuck " + sChannel );
		}
		else if ( ( sCmdName == "unstick" ) && ( !sChannel.empty() ) )
		{
			MCString::iterator it = FindNV( sChannel );
			if ( it != EndNV() )
				DelNV( it );

			PutModule( "UnStuck " + sChannel );
		}
		else
		{
			PutModule( "USAGE: [un]stick #channel [key]" );
		}
	}

	virtual void RunJob()
	{
		for( MCString::iterator it = BeginNV(); it != EndNV(); it++ )
		{
			if ( !m_pUser->FindChan( it->first ) )
			{
				CChan *pChan = new CChan( it->first, m_pUser );
				if ( !it->second.empty() )
					pChan->SetKey( it->second );
				m_pUser->AddChan( pChan );
				PutModule( "Joining [" + it->first + "]" );
			}
		}
	}
private:

};

static void RunTimer( CModule * pModule, CFPTimer *pTimer )
{
	((CStickyChan *)pModule)->RunJob();
}

bool CStickyChan::OnLoad(const CString& sArgs)
{
	AddTimer( RunTimer, "StickyChanTimer", 15 );
	return( true );
}

MODULEDEFS(CStickyChan)
<commit_msg>speed things up a bit<commit_after>#include "main.h"
#include "User.h"
#include "Nick.h"
#include "Modules.h"
#include "Chan.h"
#include "Utils.h"
#include "FileUtils.h"
#include <pwd.h>
#include <map>
#include <vector>

class CStickyChan : public CModule
{
public:
	MODCONSTRUCTOR(CStickyChan) {}
	virtual ~CStickyChan()
	{
	}

	virtual bool OnLoad(const CString& sArgs);

	virtual CString GetDescription()
	{
		return ( "configless sticky chans, keeps you there very stickily even" );
	}

	virtual void OnModCommand( const CString& sCommand )
	{
		CString sCmdName = sCommand.Token(0);
		CString sChannel = sCommand.Token(1);
		sChannel.MakeLower();
		if ( ( sCmdName == "stick" ) && ( !sChannel.empty() ) )
		{
			SetNV( sChannel, sCommand.Token(2) );
			PutModule( "Stuck " + sChannel );
		}
		else if ( ( sCmdName == "unstick" ) && ( !sChannel.empty() ) )
		{
			MCString::iterator it = FindNV( sChannel );
			if ( it != EndNV() )
				DelNV( it );

			PutModule( "UnStuck " + sChannel );
		}
		else
		{
			PutModule( "USAGE: [un]stick #channel [key]" );
		}
	}

	virtual void RunJob()
	{
		for( MCString::iterator it = BeginNV(); it != EndNV(); it++ )
		{
			if ( !m_pUser->FindChan( it->first ) )
			{
				CChan *pChan = new CChan( it->first, m_pUser );
				if ( !it->second.empty() )
					pChan->SetKey( it->second );
				m_pUser->AddChan( pChan );
				PutModule( "Joining [" + it->first + "]" );
				PutIRC( "JOIN " + it->first + ( it->second.empty() ? "" : it->second ) );
			}
		}
	}
private:

};

static void RunTimer( CModule * pModule, CFPTimer *pTimer )
{
	((CStickyChan *)pModule)->RunJob();
}

bool CStickyChan::OnLoad(const CString& sArgs)
{
	AddTimer( RunTimer, "StickyChanTimer", 15 );
	return( true );
}

MODULEDEFS(CStickyChan)
<|endoftext|>


<commit_before>#include <unistd.h>

#include "acmacs-base/argv.hh"
#include "acmacs-base/temp-file.hh"
#include "acmacs-base/string-compare.hh"
#include "acmacs-base/string-split.hh"
#include "acmacs-base/quicklook.hh"
#include "acmacs-base/filesystem.hh"
#include "acmacs-map-draw/setup-dbs.hh"
#include "acmacs-map-draw/log.hh"
#include "acmacs-map-draw/mapi-settings.hh"
#include "acmacs-map-draw/draw.hh"

// ----------------------------------------------------------------------

constexpr const std::string_view sHelpPost = R"(
one input chart: make map
two input charts: make procrustes
output /: do not generate any output
no output: generate temp pdf and open it (and then delete it)

-D <arg> --define <arg>

)";

using namespace acmacs::argv;
struct MapiOptions : public acmacs::argv::v2::argv
{
    MapiOptions(int a_argc, const char* const a_argv[], on_error on_err = on_error::exit) { parse(a_argc, a_argv, on_err); }
    // std::string_view help_pre() const override { return sHelpPost; }
    std::string_view help_post() const override { return sHelpPost; }

    option<str> db_dir{*this, "db-dir"};
    // option<str> seqdb{*this, "seqdb"};

    option<str_array> settings_files{*this, 's'};
    option<str_array> defines{*this, 'D', "define", desc{"see {ACMACSD_ROOT}/share/doc/mapi.org"}};
    option<str_array> apply{*this, 'a', "apply", dflt{str_array{"main"}}, desc{"comma separated names or json array to use as \"apply\", e.g. [\"/all-grey\",\"/egg\",\"/clades\",\"/labels\"]"}};
    option<bool>      interactive{*this, 'i', "interactive"};
    // option<str>       previous{*this, "previous"};
    option<size_t>    projection{*this, 'p', "projection", dflt{0ul}};
    option<size_t>    secondary_projection{*this, 'r', "secondary-projection", dflt{static_cast<size_t>(-1)}};

    option<bool>      open{*this, "open"};
    option<bool>      ql{*this, "ql"};
    option<str_array> verbose{*this, 'v', "verbose", desc{"comma separated list (or multiple switches) of enablers"}};

    argument<str_array> files{*this, arg_name{"input: chart.ace, chart.save, chart.acd1; output: map.pdf, /"}, mandatory};
};

    // option<str>       apply_from{*this, "apply-from", desc{"read json array to use as \"apply\" from file (or stdin if \"-\""}};
    // option<bool>      clade{*this, "clade"};
    // option<double>    point_scale{*this, "point-scale", dflt{1.0}};
    // option<double>    rotate_degrees{*this, 'r', "rotate-degrees", dflt{0.0}, desc{"counter clockwise"}};
    // option<bool>      flip_ew{*this, "flip-ew"};
    // option<bool>      flip_ns{*this, "flip-ns"};
    // option<str>       save{*this, "save", desc{"save resulting chart with modified projection and plot spec"}};

// ----------------------------------------------------------------------

static std::pair<std::vector<std::string_view>, std::vector<std::string_view>> parse_files(const argument<str_array>& files);
static void signal_handler(int sig_num);

int main(int argc, char* const argv[])
{
    using namespace std::string_view_literals;
    int exit_code = 0;
    try {
        acmacs::log::register_enabler_acmacs_base();
        MapiOptions opt(argc, argv);
        acmacs::log::enable(opt.verbose);
        setup_dbs(opt.db_dir, !opt.verbose.empty());

        const auto [inputs, outputs] = parse_files(opt.files);

        ChartDraw chart_draw{inputs, opt.projection};

        acmacs::mapi::Settings settings{chart_draw};
        settings.load(opt.settings_files, opt.defines);
        for (size_t chart_no = 0; chart_no < chart_draw.number_of_charts(); ++chart_no)
            settings.setenv_toplevel(fmt::format("chart[{}]", chart_no), chart_draw.chart(chart_no).filename());

        if (opt.interactive)
            signal(SIGHUP, signal_handler);

        for (;;) {
            for (const auto& to_apply : opt.apply) {
                if (!to_apply.empty()) {
                    if (to_apply[0] == '{' || to_apply[0] == '[') {
                        settings.apply(to_apply);
                    }
                    else {
                        for (const auto& to_apply_one : acmacs::string::split(to_apply))
                            settings.apply(to_apply_one);
                    }
                }
            }

            chart_draw.calculate_viewport();
            AD_INFO("{:.2f}", chart_draw.viewport("mapi main"));
            AD_INFO("transformation: {}", chart_draw.chart(0).modified_transformation());

            if (outputs.empty()) {
                acmacs::file::temp output{fmt::format("{}--p{}.pdf", fs::path(inputs[0]).stem(), opt.projection)};
                chart_draw.draw(output, 800, report_time::yes);
                acmacs::quicklook(output, 2);
            }
            else if (outputs[0] == "/dev/null"sv || outputs[0] == "/"sv) { // do not generate pdf
            }
            else {
                chart_draw.draw(outputs[0], 800, report_time::yes);
                acmacs::open_or_quicklook(opt.open, opt.ql, outputs[0]);
            }
            if (opt.interactive) {
                fmt::print(stderr, "mapi-i >> ");

                fd_set set;
                FD_ZERO(&set);
                FD_SET(0, &set);
                if (select(FD_SETSIZE, &set, nullptr, nullptr, nullptr) > 0) {
                    // fmt::print(stderr, " (reading)\n");
                    std::string input(20, ' ');
                    if (const auto bytes = ::read(0, input.data(), input.size()); bytes > 0) {
                        input.resize(static_cast<size_t>(bytes));
                        // fmt::print(stderr, " (read {} bytes)\n", bytes);
                    }
                }

                acmacs::run_and_detach({"tink"}, 0);
            }
            else
                break;

            chart_draw.reset();
            chart_draw.remove_legend();
            try {
                settings.reload();
            }
            catch (std::exception& err) {
                AD_ERROR("{}", err);
                acmacs::run_and_detach({"submarine"}, 0);
            }
        }
    }
    catch (std::exception& err) {
        fmt::print(stderr, "ERROR: {}\n", err);
        exit_code = 2;
    }
    return exit_code;
}

// ----------------------------------------------------------------------

std::pair<std::vector<std::string_view>, std::vector<std::string_view>> parse_files(const argument<str_array>& files)
{
    using namespace std::string_view_literals;
    std::vector<std::string_view> inputs, outputs;
    constexpr std::array input_suffixes{".ace"sv, ".acd1"sv, ".acd1.xz"sv, ".acd1.bz2"sv, ".save"sv, ".save.xz"sv, ".save.bz2"sv};
    const auto is_input = [&input_suffixes](std::string_view name) -> bool {
        return std::any_of(std::begin(input_suffixes), std::end(input_suffixes), [name](std::string_view suff) -> bool { return acmacs::string::endswith(name, suff); });
    };
    for (const auto& file : files) {
        if (is_input(file))
            inputs.push_back(file);
        else
            outputs.push_back(file);
    }
    if (inputs.empty())
        throw std::runtime_error{"no input files (charts) found in the command line"};
    if (inputs.size() > 2)
        throw std::runtime_error{fmt::format("too many input files () found in the command line", inputs)};
    return {inputs, outputs};

} // parse_files

// ----------------------------------------------------------------------

void signal_handler(int sig_num)
{
    fmt::print("SIGNAL {}\n", sig_num);

} // signal_handler

// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>porting to linux<commit_after>#include <unistd.h>
#include <signal.h>

#include "acmacs-base/argv.hh"
#include "acmacs-base/temp-file.hh"
#include "acmacs-base/string-compare.hh"
#include "acmacs-base/string-split.hh"
#include "acmacs-base/quicklook.hh"
#include "acmacs-base/filesystem.hh"
#include "acmacs-map-draw/setup-dbs.hh"
#include "acmacs-map-draw/log.hh"
#include "acmacs-map-draw/mapi-settings.hh"
#include "acmacs-map-draw/draw.hh"

// ----------------------------------------------------------------------

constexpr const std::string_view sHelpPost = R"(
one input chart: make map
two input charts: make procrustes
output /: do not generate any output
no output: generate temp pdf and open it (and then delete it)

-D <arg> --define <arg>

)";

using namespace acmacs::argv;
struct MapiOptions : public acmacs::argv::v2::argv
{
    MapiOptions(int a_argc, const char* const a_argv[], on_error on_err = on_error::exit) { parse(a_argc, a_argv, on_err); }
    // std::string_view help_pre() const override { return sHelpPost; }
    std::string_view help_post() const override { return sHelpPost; }

    option<str> db_dir{*this, "db-dir"};
    // option<str> seqdb{*this, "seqdb"};

    option<str_array> settings_files{*this, 's'};
    option<str_array> defines{*this, 'D', "define", desc{"see {ACMACSD_ROOT}/share/doc/mapi.org"}};
    option<str_array> apply{*this, 'a', "apply", dflt{str_array{"main"}}, desc{"comma separated names or json array to use as \"apply\", e.g. [\"/all-grey\",\"/egg\",\"/clades\",\"/labels\"]"}};
    option<bool>      interactive{*this, 'i', "interactive"};
    // option<str>       previous{*this, "previous"};
    option<size_t>    projection{*this, 'p', "projection", dflt{0ul}};
    option<size_t>    secondary_projection{*this, 'r', "secondary-projection", dflt{static_cast<size_t>(-1)}};

    option<bool>      open{*this, "open"};
    option<bool>      ql{*this, "ql"};
    option<str_array> verbose{*this, 'v', "verbose", desc{"comma separated list (or multiple switches) of enablers"}};

    argument<str_array> files{*this, arg_name{"input: chart.ace, chart.save, chart.acd1; output: map.pdf, /"}, mandatory};
};

    // option<str>       apply_from{*this, "apply-from", desc{"read json array to use as \"apply\" from file (or stdin if \"-\""}};
    // option<bool>      clade{*this, "clade"};
    // option<double>    point_scale{*this, "point-scale", dflt{1.0}};
    // option<double>    rotate_degrees{*this, 'r', "rotate-degrees", dflt{0.0}, desc{"counter clockwise"}};
    // option<bool>      flip_ew{*this, "flip-ew"};
    // option<bool>      flip_ns{*this, "flip-ns"};
    // option<str>       save{*this, "save", desc{"save resulting chart with modified projection and plot spec"}};

// ----------------------------------------------------------------------

static std::pair<std::vector<std::string_view>, std::vector<std::string_view>> parse_files(const argument<str_array>& files);
static void signal_handler(int sig_num);

int main(int argc, char* const argv[])
{
    using namespace std::string_view_literals;
    int exit_code = 0;
    try {
        acmacs::log::register_enabler_acmacs_base();
        MapiOptions opt(argc, argv);
        acmacs::log::enable(opt.verbose);
        setup_dbs(opt.db_dir, !opt.verbose.empty());

        const auto [inputs, outputs] = parse_files(opt.files);

        ChartDraw chart_draw{inputs, opt.projection};

        acmacs::mapi::Settings settings{chart_draw};
        settings.load(opt.settings_files, opt.defines);
        for (size_t chart_no = 0; chart_no < chart_draw.number_of_charts(); ++chart_no)
            settings.setenv_toplevel(fmt::format("chart[{}]", chart_no), chart_draw.chart(chart_no).filename());

        if (opt.interactive)
            signal(SIGHUP, signal_handler);

        for (;;) {
            for (const auto& to_apply : opt.apply) {
                if (!to_apply.empty()) {
                    if (to_apply[0] == '{' || to_apply[0] == '[') {
                        settings.apply(to_apply);
                    }
                    else {
                        for (const auto& to_apply_one : acmacs::string::split(to_apply))
                            settings.apply(to_apply_one);
                    }
                }
            }

            chart_draw.calculate_viewport();
            AD_INFO("{:.2f}", chart_draw.viewport("mapi main"));
            AD_INFO("transformation: {}", chart_draw.chart(0).modified_transformation());

            if (outputs.empty()) {
                acmacs::file::temp output{fmt::format("{}--p{}.pdf", fs::path(inputs[0]).stem(), opt.projection)};
                chart_draw.draw(output, 800, report_time::yes);
                acmacs::quicklook(output, 2);
            }
            else if (outputs[0] == "/dev/null"sv || outputs[0] == "/"sv) { // do not generate pdf
            }
            else {
                chart_draw.draw(outputs[0], 800, report_time::yes);
                acmacs::open_or_quicklook(opt.open, opt.ql, outputs[0]);
            }
            if (opt.interactive) {
                fmt::print(stderr, "mapi-i >> ");

                fd_set set;
                FD_ZERO(&set);
                FD_SET(0, &set);
                if (select(FD_SETSIZE, &set, nullptr, nullptr, nullptr) > 0) {
                    // fmt::print(stderr, " (reading)\n");
                    std::string input(20, ' ');
                    if (const auto bytes = ::read(0, input.data(), input.size()); bytes > 0) {
                        input.resize(static_cast<size_t>(bytes));
                        // fmt::print(stderr, " (read {} bytes)\n", bytes);
                    }
                }

                acmacs::run_and_detach({"tink"}, 0);
            }
            else
                break;

            chart_draw.reset();
            chart_draw.remove_legend();
            try {
                settings.reload();
            }
            catch (std::exception& err) {
                AD_ERROR("{}", err);
                acmacs::run_and_detach({"submarine"}, 0);
            }
        }
    }
    catch (std::exception& err) {
        fmt::print(stderr, "ERROR: {}\n", err);
        exit_code = 2;
    }
    return exit_code;
}

// ----------------------------------------------------------------------

std::pair<std::vector<std::string_view>, std::vector<std::string_view>> parse_files(const argument<str_array>& files)
{
    using namespace std::string_view_literals;
    std::vector<std::string_view> inputs, outputs;
    constexpr std::array input_suffixes{".ace"sv, ".acd1"sv, ".acd1.xz"sv, ".acd1.bz2"sv, ".save"sv, ".save.xz"sv, ".save.bz2"sv};
    const auto is_input = [&input_suffixes](std::string_view name) -> bool {
        return std::any_of(std::begin(input_suffixes), std::end(input_suffixes), [name](std::string_view suff) -> bool { return acmacs::string::endswith(name, suff); });
    };
    for (const auto& file : files) {
        if (is_input(file))
            inputs.push_back(file);
        else
            outputs.push_back(file);
    }
    if (inputs.empty())
        throw std::runtime_error{"no input files (charts) found in the command line"};
    if (inputs.size() > 2)
        throw std::runtime_error{fmt::format("too many input files () found in the command line", inputs)};
    return {inputs, outputs};

} // parse_files

// ----------------------------------------------------------------------

void signal_handler(int sig_num)
{
    fmt::print("SIGNAL {}\n", sig_num);

} // signal_handler

// ----------------------------------------------------------------------

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>#include <CGAL/Linear_cell_complex.h>
#include <CGAL/Delaunay_triangulation_3.h>

using namespace std;

typedef CGAL::Point_3 Point;
typedef CGAL::Delaunay_triangulation_3 Delaunay;

// PLC:
map <unsigned, Point> PLCvertices; // mapping between vertex coordinates and corresponding unique id
list <unsigned, unsigned, unsigned> PLCfaces; // contains ids of vertices/points making the triangle

// Delaunay tetrahedralization:
Delaunay DT;

// CDT: output mesh:
map <unsigned, Point> CDTvertices;
list <unsigned, unsigned, unsigned, unsigned> CDTtets; // contains ids of vertices making tetrahedron

// reads input PLC
void readPLCInput()
{
	// read PLY file(assumed to contain the PLC)
    	// initialize inputVertices
    	// initialize inputFaces

}

// computes the initial delaunay tetrahedralization
void computeInitialDelaunayTetrahedralization()
{

	list <Point> tempPointList;

	for (map<unsigned, Point>::iterator pit = PLCvertices.begin(); pit != PLCvertices.end(); pit++)
		tempPointList.push(PLCvertices.find(i)->second);

    	DT.insert(tempPointList.begin(). tempPointList.end());
}

// removes local degeneracies from Delaunay tetrahedralization
void removeLocalDegeneracies()
{
	// compute all local degeneracies in DT and add them to Q
	// repeat while Q != NULL
		// for each local degeneracy l in Q:
			// if l is removable:
				// remove l by small perturbation
			// else,
				// compute vb to break l
					// if vb encroaches upon any segment or subface,
						// push l into queue
						// call boundary protection procedure
					// else
						// insert vb to break l
					// end if
			// end if
		// end for
	// end repeat
}

// recovers the constraint faces
void recoverConstraintFaces()
{

}

// main procedure
int main()
{
	readPLCInput();
	computeInitialDelaunayTetrahedralization();
	removeLocalDegeneracies();
	recoverConstraintFaces();
        return 0;
}
<commit_msg>initialized plcVertex and plcFaces using rply library<commit_after>#include <CGAL/Linear_cell_complex.h>
#include <CGAL/Delaunay_triangulation_3.h>
#include "rply.h"

using namespace std;

typedef CGAL::Point_3 Point;
typedef CGAL::Delaunay_triangulation_3 Delaunay;

// PLC:
map <unsigned, Point> plcVertices; // mapping between vertex coordinates and corresponding unique id
list <unsigned, unsigned, unsigned> plcFaces; // contains ids of vertices/points making the triangle

// Delaunay tetrahedralization:
Delaunay DT;

// CDT: output mesh:
map <unsigned, Point> cdtVertices;
list <unsigned, unsigned, unsigned, unsigned> cdtTets; // contains ids of vertices making tetrahedron

static unsigned tempPoint[3];
unsigned int dimensionId = 0;
static unsigned pointId = 0;

static tempFace[3];

void vertex_cb(p_ply_argument argument)
{
	long eol;
	ply_get_argument_user_data(argument, NULL, &eol);
	tempPoint[dimensionId++] = ply_get_argument_value(argument);

	// insert the vertex into plcVertex
	if (strcmp(argument.element.name, 'z'))
	{
		plcVertex.push(pointId++, Point(tempPoint[0],tempPoint[1],tempPoint[2]));
		dimensionId = 0;
	}
}

void face_cb(p_ply_argument argument)
{
	long length, value_index;
	ply_get_argument_property(argument, NULL, &length, &value_index);
        switch (value_index)
	{
        	case 0:
	        case 1:
        		tempFace[pointId++] = ply_get_argument_value(argument);
	                break;
        	case 2:
                	tempFace[pointId] = ply_get_argument_value(argument);
			pointId = 0;
			plcFaces.push(tempFace[0], tempFace[1], tempFace[2]);
	                break;
        	default:
                	cout << "Invalid number of points in a face specified :(";
			break;
        }

}

// reads input PLC
void readPLCInput()
{
	// read PLY file(assumed to contain the PLC)
	string fileName;

	cout << "Please enter input filename";
	cin >> fileName;

	p_ply inputPLY = ply_open(fileName);

	if (!inputPLY) return 1;

        if (!ply_read_header(inputPLY)) return 1;

	if (!read_ply(inputPLY))
	{
		cout << "Cannot read the PLY file :(";
		exit(0);
	}

	// Initialize plcVertex and plcFaces
  	ply_set_read_cb(ply, "vertex", "x", vertex_cb, NULL, 0);
	ply_set_read_cb(ply, "vertex", "y", vertex_cb, NULL, 0);
	ply_set_read_cb(ply, "vertex", "z", vertex_cb, NULL, 0);

	ply_set_read_cb(ply, "face", "vertex_indices", face_cb, NULL, 0);

	inputPLY.close();

}

// computes the initial delaunay tetrahedralization
void computeInitialDelaunayTetrahedralization()
{

	list <Point> tempPointList;

	for (map<unsigned, Point>::iterator pit = PLCvertices.begin(); pit != PLCvertices.end(); pit++)
		tempPointList.push(PLCvertices.find(i)->second);

    	DT.insert(tempPointList.begin(), tempPointList.end());
}

// removes local degeneracies from Delaunay tetrahedralization
void removeLocalDegeneracies()
{
	// compute all local degeneracies in DT and add them to Q
	// repeat while Q != NULL
		// for each local degeneracy l in Q:
			// if l is removable:
				// remove l by small perturbation
			// else,
				// compute vb to break l
					// if vb encroaches upon any segment or subface,
						// push l into queue
						// call boundary protection procedure
					// else
						// insert vb to break l
					// end if
			// end if
		// end for
	// end repeat
}

// recovers the constraint faces
void recoverConstraintFaces()
{

}

// main procedure
int main()
{
	readPLCInput();
	computeInitialDelaunayTetrahedralization();
	removeLocalDegeneracies();
	recoverConstraintFaces();
        return 0;
}
<|endoftext|>


<commit_before>#include <assert.h>
#include <db_cxx.h>

int dbcreate(char *dbfile, char *dbname, int argc, char *argv[]) {
    int r;
#if USE_ENV
    DbEnv *env = new DbEnv(DB_CXX_NO_EXCEPTIONS);
    r = env->open(".", DB_INIT_MPOOL + DB_CREATE + DB_PRIVATE, 0777); assert(r == 0);
#else
    DbEnv *env = 0;
#endif
    Db *db = new Db(env, DB_CXX_NO_EXCEPTIONS);
    r = db->open(0, dbfile, dbname, DB_BTREE, DB_CREATE, 0777);
    assert(r == 0);

    int i = 0;
    while (i < argc) {
        char *k = argv[i++];
        if (i < argc) {
            char *v = argv[i++];
            Dbt key(k, strlen(k)); Dbt val(v, strlen(v));
            r = db->put(0, &key, &val, 0); assert(r == 0);
        }
    }

    r = db->close(0); assert(r == 0);
    if (env) {
        r = env->close(0); assert(r == 0);
        delete env;
    }
    delete db;
    return 0;
}

int usage() {
    printf("db_create [-s DBNAME] DBFILE [KEY VAL]*\n");
    return 1;
}

int main(int argc, char *argv[]) {
    char *dbname = 0;

    int i;
    for (i=1; i<argc; i++) {
        char *arg = argv[i];
        if (0 == strcmp(arg, "-h") || 0 == strcmp(arg, "--help"))
            return usage();
        if (0 == strcmp(arg, "-s")) {
            i++;
            if (i >= argc)
                return usage();
            dbname = argv[i];
            continue;
        }
        break;
    }

    if (i >= argc)
        return usage();
    char *dbfile = argv[i++];
    return dbcreate(dbfile, dbname, argc-i, &argv[i]);
}

<commit_msg>test for nodup and dupsort trees in the same file. addresses #333<commit_after>#include <assert.h>
#include <db_cxx.h>

int dbcreate(char *dbfile, char *dbname, int dbflags, int argc, char *argv[]) {
    int r;
#if USE_ENV
    DbEnv *env = new DbEnv(DB_CXX_NO_EXCEPTIONS);
    r = env->open(".", DB_INIT_MPOOL + DB_CREATE + DB_PRIVATE, 0777); assert(r == 0);
#else
    DbEnv *env = 0;
#endif
    Db *db = new Db(env, DB_CXX_NO_EXCEPTIONS);
    r = db->set_flags(dbflags);
    assert(r == 0);
    r = db->open(0, dbfile, dbname, DB_BTREE, DB_CREATE, 0777);
    assert(r == 0);

    int i = 0;
    while (i < argc) {
        char *k = argv[i++];
        if (i < argc) {
            char *v = argv[i++];
            Dbt key(k, strlen(k)); Dbt val(v, strlen(v));
            r = db->put(0, &key, &val, 0); assert(r == 0);
        }
    }

    r = db->close(0); assert(r == 0);
    if (env) {
        r = env->close(0); assert(r == 0);
        delete env;
    }
    delete db;
    return 0;
}

int usage() {
    printf("db_create [-s DBNAME] [-D] [-S] DBFILE [KEY VAL]*\n");
    return 1;
}

int main(int argc, char *argv[]) {
    char *dbname = 0;
    int dbflags = 0;

    int i;
    for (i=1; i<argc; i++) {
        char *arg = argv[i];
        if (0 == strcmp(arg, "-h") || 0 == strcmp(arg, "--help"))
            return usage();
        if (0 == strcmp(arg, "-s")) {
            if (i+1 >= argc)
                return usage();
            dbname = argv[++i];
            continue;
        }
        if (0 == strcmp(arg, "-D")) {
            dbflags += DB_DUP;
            continue;
        }
        if (0 == strcmp(arg, "-S")) {
            dbflags += DB_DUPSORT;
            continue;
        }
        break;
    }

    if (i >= argc)
        return usage();
    char *dbfile = argv[i++];
    return dbcreate(dbfile, dbname, dbflags, argc-i, &argv[i]);
}

<|endoftext|>


<commit_before>// $Id$

/***********************************************************************
Moses - factored phrase-based language decoder
Copyright (c) 2006 University of Edinburgh
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 the University of Edinburgh 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.
***********************************************************************/

// example file on how to use moses library

#ifdef WIN32
// Include Visual Leak Detector
#include <vld.h>
#endif

#include <fstream>
#include "Main.h"
#include "LatticePath.h"
#include "FactorCollection.h"
#include "Manager.h"
#include "Phrase.h"
#include "Util.h"
#include "LatticePathList.h"
#include "Timer.h"
#include "IOCommandLine.h"
#include "IOFile.h"
#include "Sentence.h"
#include "ConfusionNet.h"
#include "TranslationAnalysis.h"

#if HAVE_CONFIG_H
#include "config.h"
#else
// those not using autoconf have to build MySQL support for now
#  define USE_MYSQL 1
#endif

using namespace std;
Timer timer;

bool readInput(InputOutput *inputOutput, int inputType, InputType*& source)
{
	delete source;
	source=inputOutput->GetInput((inputType ?
																static_cast<InputType*>(new ConfusionNet) :
																static_cast<InputType*>(new Sentence(Input))));
	return (source ? true : false);
}

int main(int argc, char* argv[])
{
	// Welcome message
	TRACE_ERR( "Moses (built on " << __DATE__ << ")" << endl );
	TRACE_ERR( "a beam search decoder for phrase-based statistical machine translation models" << endl );
	TRACE_ERR( "written by Hieu Hoang, with contributions by Nicola Bertoldi, Ondrej Bojar," << endl <<
						 "Chris Callison-Burch, Alexandra Constantin, Brooke Cowan, Chris Dyer, Marcello Federico," << endl <<
						 "Evan Herbst, Philipp Koehn, Christine Moran, Wade Shen, and Richard Zens." << endl);
	TRACE_ERR( "(c) 2006 University of Edinburgh, Scotland" << endl );
	TRACE_ERR( "command: " );
	for(int i=0;i<argc;++i) TRACE_ERR( argv[i]<<" " );
	TRACE_ERR(endl);

	// load data structures
	timer.start("Starting...");
	StaticData staticData;
	if (!staticData.LoadParameters(argc, argv))
		return EXIT_FAILURE;

	// set up read/writing class
	InputOutput *inputOutput = GetInputOutput(staticData);

  std::cerr << "The score component vector looks like this:\n" << staticData.GetScoreIndexManager();
  std::cerr << "The global weight vector looks like this:\n";
	vector<float> weights = staticData.GetAllWeights();
	std::cerr << weights[0];
	for (size_t j=1; j<weights.size(); j++) { std::cerr << ", " << weights[j]; }
	std::cerr << "\n";
	// every score must have a weight!  check that here:
	assert(weights.size() == staticData.GetScoreIndexManager().GetTotalNumberOfScores());

	if (inputOutput == NULL)
		return EXIT_FAILURE;

	// read each sentence & decode
	InputType *source=0;
	size_t lineCount = 0;
	while(readInput(inputOutput,staticData.GetInputType(),source))
		{
			// note: source is only valid within this while loop!
    ResetUserTime();

    TRACE_ERR("\nTRANSLATING(" << ++lineCount << "): " << *source <<endl);

			staticData.InitializeBeforeSentenceProcessing(*source);
			Manager manager(*source, staticData);
			manager.ProcessSentence();
			inputOutput->SetOutput(manager.GetBestHypothesis(), source->GetTranslationId(),
														 staticData.GetReportSourceSpan(),
														 staticData.GetReportAllFactors()
														 );

			// n-best
			size_t nBestSize = staticData.GetNBestSize();
			if (nBestSize > 0)
				{
					TRACE_ERR("WRITING " << nBestSize << " TRANSLATION ALTERNATIVES TO " << staticData.GetNBestFilePath() << endl);
					LatticePathList nBestList;
					manager.CalcNBest(nBestSize, nBestList,staticData.OnlyDistinctNBest());
					inputOutput->SetNBest(nBestList, source->GetTranslationId());
					RemoveAllInColl(nBestList);
				}

			if (staticData.IsDetailedTranslationReportingEnabled()) {
				TranslationAnalysis::PrintTranslationAnalysis(std::cerr, manager.GetBestHypothesis());
         PrintUserTime(std::cerr, "Sentence Decoding Time:");
			}

			manager.CalcDecoderStatistics(staticData);
			staticData.CleanUpAfterSentenceProcessing();

		}

	delete inputOutput;

	timer.check("End.");
	return EXIT_SUCCESS;
}

InputOutput *GetInputOutput(StaticData &staticData)
{
	InputOutput *inputOutput;
	const std::vector<FactorType> &inputFactorOrder = staticData.GetInputFactorOrder()
																,&outputFactorOrder = staticData.GetOutputFactorOrder();
	FactorMask inputFactorUsed(inputFactorOrder);

	// io
	if (staticData.GetIOMethod() == IOMethodFile)
	{
		TRACE_ERR("IO from File" << endl);
		string					inputFileHash;
		list< Phrase >	inputPhraseList;
		string filePath = staticData.GetParam("input-file")[0];

		TRACE_ERR("About to create ioFile" << endl);
		IOFile *ioFile = new IOFile(inputFactorOrder, outputFactorOrder, inputFactorUsed
																	, staticData.GetFactorCollection()
																	, staticData.GetNBestSize()
																	, staticData.GetNBestFilePath()
																	, filePath);
		if(staticData.GetInputType())
			{
				TRACE_ERR("Do not read input phrases for confusion net translation\n");
			}
		else
			{
				TRACE_ERR("About to GetInputPhrase\n");
				ioFile->GetInputPhrase(inputPhraseList);
			}
		TRACE_ERR("After GetInputPhrase" << endl);
		inputOutput = ioFile;
		inputFileHash = GetMD5Hash(filePath);
		TRACE_ERR("About to LoadPhraseTables" << endl);
		staticData.LoadPhraseTables(true, inputFileHash, inputPhraseList);
		ioFile->ResetSentenceId();
	}
	else
	{
		TRACE_ERR("IO from STDOUT/STDIN" << endl);
		inputOutput = new IOCommandLine(inputFactorOrder, outputFactorOrder, inputFactorUsed
																	, staticData.GetFactorCollection()
																	, staticData.GetNBestSize()
																	, staticData.GetNBestFilePath());
		staticData.LoadPhraseTables();
	}
	staticData.LoadMapping();
	timer.check("Created input-output object");

	return inputOutput;
}
<commit_msg>Added decoding time computation.<commit_after>// $Id$

/***********************************************************************
Moses - factored phrase-based language decoder
Copyright (c) 2006 University of Edinburgh
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 the University of Edinburgh 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.
***********************************************************************/

// example file on how to use moses library

#ifdef WIN32
// Include Visual Leak Detector
#include <vld.h>
#endif

#include <fstream>
#include "Main.h"
#include "LatticePath.h"
#include "FactorCollection.h"
#include "Manager.h"
#include "Phrase.h"
#include "Util.h"
#include "LatticePathList.h"
#include "Timer.h"
#include "IOCommandLine.h"
#include "IOFile.h"
#include "Sentence.h"
#include "ConfusionNet.h"
#include "TranslationAnalysis.h"

#if HAVE_CONFIG_H
#include "config.h"
#else
// those not using autoconf have to build MySQL support for now
#  define USE_MYSQL 1
#endif

using namespace std;
Timer timer;

bool readInput(InputOutput *inputOutput, int inputType, InputType*& source)
{
	delete source;
	source=inputOutput->GetInput((inputType ?
																static_cast<InputType*>(new ConfusionNet) :
																static_cast<InputType*>(new Sentence(Input))));
	return (source ? true : false);
}

int main(int argc, char* argv[])
{
	// Welcome message
	TRACE_ERR( "Moses (built on " << __DATE__ << ")" << endl );
	TRACE_ERR( "a beam search decoder for phrase-based statistical machine translation models" << endl );
	TRACE_ERR( "written by Hieu Hoang, with contributions by Nicola Bertoldi, Ondrej Bojar," << endl <<
						 "Chris Callison-Burch, Alexandra Constantin, Brooke Cowan, Chris Dyer, Marcello Federico," << endl <<
						 "Evan Herbst, Philipp Koehn, Christine Moran, Wade Shen, and Richard Zens." << endl);
	TRACE_ERR( "(c) 2006 University of Edinburgh, Scotland" << endl );
	TRACE_ERR( "command: " );
	for(int i=0;i<argc;++i) TRACE_ERR( argv[i]<<" " );
	TRACE_ERR(endl);

	// load data structures
	timer.start("Starting...");
	StaticData staticData;
	if (!staticData.LoadParameters(argc, argv))
		return EXIT_FAILURE;

	// set up read/writing class
	InputOutput *inputOutput = GetInputOutput(staticData);

  std::cerr << "The score component vector looks like this:\n" << staticData.GetScoreIndexManager();
  std::cerr << "The global weight vector looks like this:\n";
	vector<float> weights = staticData.GetAllWeights();
	std::cerr << weights[0];
	for (size_t j=1; j<weights.size(); j++) { std::cerr << ", " << weights[j]; }
	std::cerr << "\n";
	// every score must have a weight!  check that here:
	assert(weights.size() == staticData.GetScoreIndexManager().GetTotalNumberOfScores());

	if (inputOutput == NULL)
		return EXIT_FAILURE;

	// read each sentence & decode
	InputType *source=0;
	size_t lineCount = 0;
	while(readInput(inputOutput,staticData.GetInputType(),source))
		{
			// note: source is only valid within this while loop!
    ResetUserTime();

    TRACE_ERR("\nTRANSLATING(" << ++lineCount << "): " << *source <<endl);

			staticData.InitializeBeforeSentenceProcessing(*source);
			Manager manager(*source, staticData);
			manager.ProcessSentence();
			inputOutput->SetOutput(manager.GetBestHypothesis(), source->GetTranslationId(),
														 staticData.GetReportSourceSpan(),
														 staticData.GetReportAllFactors()
														 );

			// n-best
			size_t nBestSize = staticData.GetNBestSize();
			if (nBestSize > 0)
				{
					TRACE_ERR("WRITING " << nBestSize << " TRANSLATION ALTERNATIVES TO " << staticData.GetNBestFilePath() << endl);
					LatticePathList nBestList;
					manager.CalcNBest(nBestSize, nBestList,staticData.OnlyDistinctNBest());
					inputOutput->SetNBest(nBestList, source->GetTranslationId());
					RemoveAllInColl(nBestList);
				}

			if (staticData.IsDetailedTranslationReportingEnabled()) {
				TranslationAnalysis::PrintTranslationAnalysis(std::cerr, manager.GetBestHypothesis());
			}

      PrintUserTime(std::cerr, "Sentence Decoding Time:");

			manager.CalcDecoderStatistics(staticData);
			staticData.CleanUpAfterSentenceProcessing();

		}

	delete inputOutput;

	timer.check("End.");
	return EXIT_SUCCESS;
}

InputOutput *GetInputOutput(StaticData &staticData)
{
	InputOutput *inputOutput;
	const std::vector<FactorType> &inputFactorOrder = staticData.GetInputFactorOrder()
																,&outputFactorOrder = staticData.GetOutputFactorOrder();
	FactorMask inputFactorUsed(inputFactorOrder);

	// io
	if (staticData.GetIOMethod() == IOMethodFile)
	{
		TRACE_ERR("IO from File" << endl);
		string					inputFileHash;
		list< Phrase >	inputPhraseList;
		string filePath = staticData.GetParam("input-file")[0];

		TRACE_ERR("About to create ioFile" << endl);
		IOFile *ioFile = new IOFile(inputFactorOrder, outputFactorOrder, inputFactorUsed
																	, staticData.GetFactorCollection()
																	, staticData.GetNBestSize()
																	, staticData.GetNBestFilePath()
																	, filePath);
		if(staticData.GetInputType())
			{
				TRACE_ERR("Do not read input phrases for confusion net translation\n");
			}
		else
			{
				TRACE_ERR("About to GetInputPhrase\n");
				ioFile->GetInputPhrase(inputPhraseList);
			}
		TRACE_ERR("After GetInputPhrase" << endl);
		inputOutput = ioFile;
		inputFileHash = GetMD5Hash(filePath);
		TRACE_ERR("About to LoadPhraseTables" << endl);
		staticData.LoadPhraseTables(true, inputFileHash, inputPhraseList);
		ioFile->ResetSentenceId();
	}
	else
	{
		TRACE_ERR("IO from STDOUT/STDIN" << endl);
		inputOutput = new IOCommandLine(inputFactorOrder, outputFactorOrder, inputFactorUsed
																	, staticData.GetFactorCollection()
																	, staticData.GetNBestSize()
																	, staticData.GetNBestFilePath());
		staticData.LoadPhraseTables();
	}
	staticData.LoadMapping();
	timer.check("Created input-output object");

	return inputOutput;
}
<|endoftext|>


<commit_before>// sdl_main.cpp

#ifdef _WIN32
#  define WINDOWS_LEAN_AND_MEAN
#  define NOMINMAX
#  include <windows.h>
#endif

#include <fstream>
#include <vector>

#include <GL/glew.h>
#include <SDL.h>
#include <SDL_syswm.h>
#undef main

#include "ShaderFunctions.h"
#include "Timer.h"
#include "g_textures.h"

Timer g_timer;
int winw = 800;
int winh = 600;

struct renderpass {
    GLuint prog;
    GLint uloc_iResolution;
    GLint uloc_iGlobalTime;
    GLint uloc_iChannelResolution;
    //iChannelTime not implemented
    GLint uloc_iChannel[4];
    GLint uloc_iMouse;
    GLint uloc_iDate;
    GLint uloc_iBlockOffset;
    GLint uloc_iSampleRate;
    GLuint texs[4];
};

struct Shadertoy {
    renderpass image;
    renderpass sound;
};

Shadertoy g_toy;

void keyboard(const SDL_Event& event, int key, int codes, int action, int mods)
{
    (void)codes;
    (void)mods;

    if (action == SDL_KEYDOWN)
    {
        switch (key)
        {
        default:
            break;

        case SDLK_ESCAPE:
            SDL_Quit();
            exit(0);
            break;
        }
    }
}

void PollEvents()
{
    SDL_Event event;
    while (SDL_PollEvent(&event))
    {
        switch(event.type)
        {
        case SDL_KEYDOWN:
        case SDL_KEYUP:
            keyboard(event, event.key.keysym.sym, 0, event.key.type, 0);
            break;

        case SDL_MOUSEBUTTONDOWN:
        case SDL_MOUSEBUTTONUP:
            break;

        case SDL_MOUSEMOTION:
            break;

        case SDL_MOUSEWHEEL:
            break;

        case SDL_WINDOWEVENT:
            break;

        case SDL_QUIT:
            exit(0);
            break;

        default:
            break;
        }
    }
}

void display()
{
    const renderpass& r = g_toy.image;
    glUseProgram(r.prog);
    if (r.uloc_iResolution > -1) glUniform3f(r.uloc_iResolution, (float)winw, (float)winh, 1.f);
    if (r.uloc_iGlobalTime > -1) glUniform1f(r.uloc_iGlobalTime, g_timer.seconds());
    if (r.uloc_iMouse > -1) glUniform4f(r.uloc_iMouse, 0.f, 0.f, 0.f, 0.f);

    SYSTEMTIME stNow;
    GetLocalTime(&stNow);
    if (r.uloc_iDate > -1) glUniform4f(r.uloc_iDate,
        (float)stNow.wYear,
        (float)stNow.wMonth - 1.f,
        (float)stNow.wDay,
        (float)stNow.wHour*60.f*60.f +
        (float)stNow.wMinute*60.f +
        (float)stNow.wSecond
        );

    for (int i=0; i<4; ++i)
    {
        glActiveTexture(GL_TEXTURE0+i);
        glBindTexture(GL_TEXTURE_2D, r.texs[i]);
        if (r.uloc_iChannel[i] > -1) glUniform1i(r.uloc_iChannel[i], i);
    }
    glRecti(-1,-1,1,1);
}

//
// Audio
//

struct
{
    SDL_AudioSpec spec;
    Uint8 *sound;               /* Pointer to wave data */
    Uint32 soundlen;            /* Length of wave data */
    int soundpos;               /* Current play position */
} wave;

void SDLCALL fillerup(void *unused, Uint8 * stream, int len)
{
    Uint8 *waveptr;
    int waveleft;

    waveptr = wave.sound + wave.soundpos;
    waveleft = wave.soundlen - wave.soundpos;

    while (waveleft <= len) { // wrap condition
        SDL_memcpy(stream, waveptr, waveleft);
        stream += waveleft;
        len -= waveleft;
        waveptr = wave.sound;
        waveleft = wave.soundlen;
        wave.soundpos = 0;
    }
    SDL_memcpy(stream, waveptr, len);
    wave.soundpos += len;
}

void play_audio()
{
    wave.spec.freq = 44100;
    wave.spec.format = AUDIO_U8; //AUDIO_S16LSB;
    wave.spec.channels = 2;
    wave.spec.callback = fillerup;

    const int mPlayTime = 60; // Shadertoy gives 60 seconds of audio
    wave.soundlen = mPlayTime * wave.spec.freq;
    wave.sound = new Uint8[2*wave.soundlen];
    glViewport(0,0,512,512);
    const renderpass& r = g_toy.sound;
    glUseProgram(r.prog);

    unsigned char* mData = new unsigned char[512*512*4];
    int mTmpBufferSamples = 512*512;
    int mPlaySamples = wave.soundlen;
    int numBlocks = mPlaySamples / mTmpBufferSamples;
    for (int j=0; j<numBlocks; ++j)
    {
        int off = j * mTmpBufferSamples;
        if (r.uloc_iBlockOffset > -1) glUniform1f(r.uloc_iBlockOffset, (float)off / (float)wave.spec.freq);

        glRecti(-1,-1,1,1);
        // mData: Uint8Array[1048576]
        glReadPixels(0,0,512,512, GL_RGBA, GL_UNSIGNED_BYTE, mData);
        for (int i = 0; i<mTmpBufferSamples; ++i)
        {
            unsigned char Llo = mData[4*i+0];
            unsigned char Lhi = mData[4*i+1];
            unsigned char Rlo = mData[4*i+2];
            unsigned char Rhi = mData[4*i+3];
            const float aL = -1.0f + 2.0f*((float)Llo + 256.0f*(float)Lhi) / 65535.0f;
            const float aR = -1.0f + 2.0f*((float)Rlo + 256.0f*(float)Rhi) / 65535.0f;
            wave.sound[2*(off + i)  ] = (unsigned char)(.5f*(1.f+aL) * 255.f);
            wave.sound[2*(off + i)+1] = (unsigned char)(.5f*(1.f+aR) * 255.f);
        }
    }
    delete [] mData;

    if (SDL_OpenAudio(&wave.spec, NULL) < 0)
    {
        SDL_FreeWAV(wave.sound);
        SDL_Quit();
        exit(2);
    }

    SDL_PauseAudio(0); // Start playing
}

int main(void)
{
    ///@todo cmd line aargs

    if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    {
        return false;
    }

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8);
    int winw = 800;
    int winh = 600;

    SDL_Window* pWindow = SDL_CreateWindow(
        "kinderegg",
        100,100,
        winw, winh,
        SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);

    // thank you http://www.brandonfoltz.com/2013/12/example-using-opengl-3-0-with-sdl2-and-glew/
    SDL_GLContext glContext = SDL_GL_CreateContext(pWindow);
    if (glContext == NULL)
    {
        printf("There was an error creating the OpenGL context!\n");
        return 0;
    }

    const unsigned char *version = glGetString(GL_VERSION);
    if (version == NULL)
    {
        printf("There was an error creating the OpenGL context!\n");
        return 1;
    }

    SDL_GL_MakeCurrent(pWindow, glContext);

    // Don't forget to initialize Glew, turn glewExperimental on to
    // avoid problems fetching function pointers...
    glewExperimental = GL_TRUE;
    const GLenum l_Result = glewInit();
    if (l_Result != GLEW_OK)
    {
        exit(EXIT_FAILURE);
    }

    renderpass& r = g_toy.image;
    r.prog = makeShaderFromSource("passthru.vert", "image.frag");
    r.uloc_iResolution = glGetUniformLocation(r.prog, "iResolution");
    r.uloc_iGlobalTime = glGetUniformLocation(r.prog, "iGlobalTime");
    r.uloc_iChannelResolution = glGetUniformLocation(r.prog, "iChannelResolution");
    r.uloc_iChannel[0] = glGetUniformLocation(r.prog, "iChannel0");
    r.uloc_iChannel[1] = glGetUniformLocation(r.prog, "iChannel1");
    r.uloc_iChannel[2] = glGetUniformLocation(r.prog, "iChannel2");
    r.uloc_iChannel[3] = glGetUniformLocation(r.prog, "iChannel3");
    r.uloc_iMouse = glGetUniformLocation(r.prog, "iMouse");
    r.uloc_iDate = glGetUniformLocation(r.prog, "iDate");

    for (int i=0; i<4; ++i)
    {
        const int w = texdims[3*i];
        const int h = texdims[3*i+1];
        const int d = texdims[3*i+2];
        if (w == 0)
            continue;
        GLuint t = 0;
        glActiveTexture(GL_TEXTURE0+i);
        glGenTextures(1, &t);
        glBindTexture(GL_TEXTURE_2D, t);
        GLuint mode = 0;
        switch (d)
        {
        default:break;
        case 1: mode = GL_LUMINANCE;  break;
        case 3: mode = GL_RGB; break;
        case 4: mode = GL_RGBA; break;
        }

        char texname[6] = "tex00";
        texname[4] += i;
        std::ifstream file(texname, std::ios::binary);
        if (!file.is_open())
            continue;
        file.seekg(0, std::ios::end);
        std::streamsize size = file.tellg();
        file.seekg(0, std::ios::beg);
        std::vector<char> buffer(size);
        if (file.read(buffer.data(), size))
        {
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

            glTexImage2D(GL_TEXTURE_2D,
                0, mode,
                w, h,
                0, mode,
                GL_UNSIGNED_BYTE,
                &buffer[0]);
            r.texs[i] = t;
        }
    }

    renderpass& s = g_toy.sound;
    s.prog = makeShaderFromSource("passthru.vert", "sound.frag");
    s.uloc_iBlockOffset = glGetUniformLocation(s.prog, "iBlockOffset");
    s.uloc_iSampleRate = glGetUniformLocation(s.prog, "iSampleRate");

    play_audio();
    glViewport(0,0, winw, winh);

    int quit = 0;
    while (quit == 0)
    {
        PollEvents();
        display();
        SDL_GL_SwapWindow(pWindow);
    }

    SDL_GL_DeleteContext(glContext);
    SDL_DestroyWindow(pWindow);
    SDL_CloseAudio();
    SDL_FreeWAV(wave.sound);
    SDL_Quit();
}
<commit_msg>Play a full 60 seconds of generated audio to match shadertoy.<commit_after>// sdl_main.cpp

#ifdef _WIN32
#  define WINDOWS_LEAN_AND_MEAN
#  define NOMINMAX
#  include <windows.h>
#endif

#include <fstream>
#include <vector>

#include <GL/glew.h>
#include <SDL.h>
#include <SDL_syswm.h>
#undef main

#include "ShaderFunctions.h"
#include "Timer.h"
#include "g_textures.h"

Timer g_timer;
int winw = 800;
int winh = 600;

struct renderpass {
    GLuint prog;
    GLint uloc_iResolution;
    GLint uloc_iGlobalTime;
    GLint uloc_iChannelResolution;
    //iChannelTime not implemented
    GLint uloc_iChannel[4];
    GLint uloc_iMouse;
    GLint uloc_iDate;
    GLint uloc_iBlockOffset;
    GLint uloc_iSampleRate;
    GLuint texs[4];
};

struct Shadertoy {
    renderpass image;
    renderpass sound;
};

Shadertoy g_toy;

void keyboard(const SDL_Event& event, int key, int codes, int action, int mods)
{
    (void)codes;
    (void)mods;

    if (action == SDL_KEYDOWN)
    {
        switch (key)
        {
        default:
            break;

        case SDLK_ESCAPE:
            SDL_Quit();
            exit(0);
            break;
        }
    }
}

void PollEvents()
{
    SDL_Event event;
    while (SDL_PollEvent(&event))
    {
        switch(event.type)
        {
        case SDL_KEYDOWN:
        case SDL_KEYUP:
            keyboard(event, event.key.keysym.sym, 0, event.key.type, 0);
            break;

        case SDL_MOUSEBUTTONDOWN:
        case SDL_MOUSEBUTTONUP:
            break;

        case SDL_MOUSEMOTION:
            break;

        case SDL_MOUSEWHEEL:
            break;

        case SDL_WINDOWEVENT:
            break;

        case SDL_QUIT:
            exit(0);
            break;

        default:
            break;
        }
    }
}

void display()
{
    const renderpass& r = g_toy.image;
    glUseProgram(r.prog);
    if (r.uloc_iResolution > -1) glUniform3f(r.uloc_iResolution, (float)winw, (float)winh, 1.f);
    if (r.uloc_iGlobalTime > -1) glUniform1f(r.uloc_iGlobalTime, g_timer.seconds());
    if (r.uloc_iMouse > -1) glUniform4f(r.uloc_iMouse, 0.f, 0.f, 0.f, 0.f);

    SYSTEMTIME stNow;
    GetLocalTime(&stNow);
    if (r.uloc_iDate > -1) glUniform4f(r.uloc_iDate,
        (float)stNow.wYear,
        (float)stNow.wMonth - 1.f,
        (float)stNow.wDay,
        (float)stNow.wHour*60.f*60.f +
        (float)stNow.wMinute*60.f +
        (float)stNow.wSecond
        );

    for (int i=0; i<4; ++i)
    {
        glActiveTexture(GL_TEXTURE0+i);
        glBindTexture(GL_TEXTURE_2D, r.texs[i]);
        if (r.uloc_iChannel[i] > -1) glUniform1i(r.uloc_iChannel[i], i);
    }
    glRecti(-1,-1,1,1);
}

//
// Audio
//

struct
{
    SDL_AudioSpec spec;
    Uint8 *sound;               /* Pointer to wave data */
    Uint32 soundlen;            /* Length of wave data */
    int soundpos;               /* Current play position */
} wave;

void SDLCALL fillerup(void *unused, Uint8 * stream, int len)
{
    Uint8 *waveptr;
    int waveleft;

    waveptr = wave.sound + wave.soundpos;
    waveleft = wave.soundlen - wave.soundpos;

    while (waveleft <= len) { // wrap condition
        SDL_memcpy(stream, waveptr, waveleft);
        stream += waveleft;
        len -= waveleft;
        waveptr = wave.sound;
        waveleft = wave.soundlen;
        wave.soundpos = 0;
    }
    SDL_memcpy(stream, waveptr, len);
    wave.soundpos += len;
}

void play_audio()
{
    wave.spec.freq = 44100;
    wave.spec.format = AUDIO_U8; //AUDIO_S16LSB;
    wave.spec.channels = 2;
    wave.spec.callback = fillerup;

    const int mPlayTime = 60; // Shadertoy gives 60 seconds of audio
    wave.soundlen = mPlayTime * wave.spec.freq * 2; // interlaced stereo
    wave.sound = new Uint8[wave.soundlen];
    glViewport(0,0,512,512);
    const renderpass& r = g_toy.sound;
    glUseProgram(r.prog);

    unsigned char* mData = new unsigned char[512*512*4];
    int mTmpBufferSamples = 512*512;
    int mPlaySamples = wave.soundlen / 2;
    int numBlocks = mPlaySamples / mTmpBufferSamples;
    for (int j=0; j<numBlocks; ++j)
    {
        int off = j * mTmpBufferSamples;
        if (r.uloc_iBlockOffset > -1) glUniform1f(r.uloc_iBlockOffset, (float)off / (float)wave.spec.freq);

        glRecti(-1,-1,1,1);
        // mData: Uint8Array[1048576]
        glReadPixels(0,0,512,512, GL_RGBA, GL_UNSIGNED_BYTE, mData);
        for (int i = 0; i<mTmpBufferSamples; ++i)
        {
            unsigned char Llo = mData[4*i+0];
            unsigned char Lhi = mData[4*i+1];
            unsigned char Rlo = mData[4*i+2];
            unsigned char Rhi = mData[4*i+3];
            const float aL = -1.0f + 2.0f*((float)Llo + 256.0f*(float)Lhi) / 65535.0f;
            const float aR = -1.0f + 2.0f*((float)Rlo + 256.0f*(float)Rhi) / 65535.0f;
            wave.sound[2*(off + i)  ] = (unsigned char)(.5f*(1.f+aL) * 255.f);
            wave.sound[2*(off + i)+1] = (unsigned char)(.5f*(1.f+aR) * 255.f);
        }
    }
    delete [] mData;

    if (SDL_OpenAudio(&wave.spec, NULL) < 0)
    {
        SDL_FreeWAV(wave.sound);
        SDL_Quit();
        exit(2);
    }

    SDL_PauseAudio(0); // Start playing
}

int main(void)
{
    ///@todo cmd line aargs

    if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    {
        return false;
    }

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8);
    int winw = 800;
    int winh = 600;

    SDL_Window* pWindow = SDL_CreateWindow(
        "kinderegg",
        100,100,
        winw, winh,
        SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);

    // thank you http://www.brandonfoltz.com/2013/12/example-using-opengl-3-0-with-sdl2-and-glew/
    SDL_GLContext glContext = SDL_GL_CreateContext(pWindow);
    if (glContext == NULL)
    {
        printf("There was an error creating the OpenGL context!\n");
        return 0;
    }

    const unsigned char *version = glGetString(GL_VERSION);
    if (version == NULL)
    {
        printf("There was an error creating the OpenGL context!\n");
        return 1;
    }

    SDL_GL_MakeCurrent(pWindow, glContext);

    // Don't forget to initialize Glew, turn glewExperimental on to
    // avoid problems fetching function pointers...
    glewExperimental = GL_TRUE;
    const GLenum l_Result = glewInit();
    if (l_Result != GLEW_OK)
    {
        exit(EXIT_FAILURE);
    }

    renderpass& r = g_toy.image;
    r.prog = makeShaderFromSource("passthru.vert", "image.frag");
    r.uloc_iResolution = glGetUniformLocation(r.prog, "iResolution");
    r.uloc_iGlobalTime = glGetUniformLocation(r.prog, "iGlobalTime");
    r.uloc_iChannelResolution = glGetUniformLocation(r.prog, "iChannelResolution");
    r.uloc_iChannel[0] = glGetUniformLocation(r.prog, "iChannel0");
    r.uloc_iChannel[1] = glGetUniformLocation(r.prog, "iChannel1");
    r.uloc_iChannel[2] = glGetUniformLocation(r.prog, "iChannel2");
    r.uloc_iChannel[3] = glGetUniformLocation(r.prog, "iChannel3");
    r.uloc_iMouse = glGetUniformLocation(r.prog, "iMouse");
    r.uloc_iDate = glGetUniformLocation(r.prog, "iDate");

    for (int i=0; i<4; ++i)
    {
        const int w = texdims[3*i];
        const int h = texdims[3*i+1];
        const int d = texdims[3*i+2];
        if (w == 0)
            continue;
        GLuint t = 0;
        glActiveTexture(GL_TEXTURE0+i);
        glGenTextures(1, &t);
        glBindTexture(GL_TEXTURE_2D, t);
        GLuint mode = 0;
        switch (d)
        {
        default:break;
        case 1: mode = GL_LUMINANCE;  break;
        case 3: mode = GL_RGB; break;
        case 4: mode = GL_RGBA; break;
        }

        char texname[6] = "tex00";
        texname[4] += i;
        std::ifstream file(texname, std::ios::binary);
        if (!file.is_open())
            continue;
        file.seekg(0, std::ios::end);
        std::streamsize size = file.tellg();
        file.seekg(0, std::ios::beg);
        std::vector<char> buffer(size);
        if (file.read(buffer.data(), size))
        {
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

            glTexImage2D(GL_TEXTURE_2D,
                0, mode,
                w, h,
                0, mode,
                GL_UNSIGNED_BYTE,
                &buffer[0]);
            r.texs[i] = t;
        }
    }

    renderpass& s = g_toy.sound;
    s.prog = makeShaderFromSource("passthru.vert", "sound.frag");
    s.uloc_iBlockOffset = glGetUniformLocation(s.prog, "iBlockOffset");
    s.uloc_iSampleRate = glGetUniformLocation(s.prog, "iSampleRate");

    play_audio();
    glViewport(0,0, winw, winh);

    int quit = 0;
    while (quit == 0)
    {
        PollEvents();
        display();
        SDL_GL_SwapWindow(pWindow);
    }

    SDL_GL_DeleteContext(glContext);
    SDL_DestroyWindow(pWindow);
    SDL_CloseAudio();
    SDL_FreeWAV(wave.sound);
    SDL_Quit();
}
<|endoftext|>


<commit_before>/*
 * Launch WAS child processes.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "was_launch.hxx"
#include "system/fd_util.h"
#include "system/fd-util.h"
#include "spawn/Interface.hxx"
#include "spawn/Prepared.hxx"
#include "spawn/ChildOptions.hxx"
#include "gerrno.h"
#include "util/ConstBuffer.hxx"

#include <daemon/log.h>
#include <inline/compiler.h>

#include <sys/socket.h>
#include <unistd.h>

void
WasProcess::Close()
{
    if (control_fd >= 0) {
        close(control_fd);
        control_fd = -1;
    }

    if (input_fd >= 0) {
        close(input_fd);
        input_fd = -1;
    }

    if (output_fd >= 0) {
        close(output_fd);
        output_fd = -1;
    }
}

bool
was_launch(SpawnService &spawn_service,
           WasProcess *process,
           const char *name,
           const char *executable_path,
           ConstBuffer<const char *> args,
           const ChildOptions &options,
           ExitListener *listener,
           GError **error_r)
{
    int control_fds[2], input_fds[2], output_fds[2];

    if (socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, control_fds) < 0) {
        set_error_errno_msg(error_r, "failed to create socket pair");
        return false;
    }

    if (pipe_cloexec(input_fds) < 0) {
        set_error_errno_msg(error_r, "failed to create first pipe");
        close(control_fds[0]);
        close(control_fds[1]);
        return false;
    }

    if (pipe_cloexec(output_fds) < 0) {
        set_error_errno_msg(error_r, "failed to create second pipe");
        close(control_fds[0]);
        close(control_fds[1]);
        close(input_fds[0]);
        close(input_fds[1]);
        return false;
    }

    PreparedChildProcess p;

    p.stdin_fd = output_fds[0];
    p.stdout_fd = input_fds[1];
    /* fd2 is retained */
    p.control_fd = control_fds[1];

    p.Append(executable_path);
    for (auto i : args)
        p.Append(i);

    if (!options.CopyTo(p, true, nullptr, error_r)) {
        close(control_fds[0]);
        close(input_fds[0]);
        close(output_fds[1]);
        return false;
    }

    int pid = spawn_service.SpawnChildProcess(name, std::move(p), listener,
                                              error_r);
    if (pid < 0) {
        close(control_fds[0]);
        close(input_fds[0]);
        close(output_fds[1]);
        return false;
    }

    fd_set_nonblock(input_fds[0], true);
    fd_set_nonblock(output_fds[1], true);

    process->pid = pid;
    process->control_fd = control_fds[0];
    process->input_fd = input_fds[0];
    process->output_fd = output_fds[1];
    return true;
}
<commit_msg>was/launch: move PreparedChildProcess declaration up<commit_after>/*
 * Launch WAS child processes.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "was_launch.hxx"
#include "system/fd_util.h"
#include "system/fd-util.h"
#include "spawn/Interface.hxx"
#include "spawn/Prepared.hxx"
#include "spawn/ChildOptions.hxx"
#include "gerrno.h"
#include "util/ConstBuffer.hxx"

#include <daemon/log.h>
#include <inline/compiler.h>

#include <sys/socket.h>
#include <unistd.h>

void
WasProcess::Close()
{
    if (control_fd >= 0) {
        close(control_fd);
        control_fd = -1;
    }

    if (input_fd >= 0) {
        close(input_fd);
        input_fd = -1;
    }

    if (output_fd >= 0) {
        close(output_fd);
        output_fd = -1;
    }
}

bool
was_launch(SpawnService &spawn_service,
           WasProcess *process,
           const char *name,
           const char *executable_path,
           ConstBuffer<const char *> args,
           const ChildOptions &options,
           ExitListener *listener,
           GError **error_r)
{
    int control_fds[2], input_fds[2], output_fds[2];

    PreparedChildProcess p;

    if (socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, control_fds) < 0) {
        set_error_errno_msg(error_r, "failed to create socket pair");
        return false;
    }

    p.control_fd = control_fds[1];

    if (pipe_cloexec(input_fds) < 0) {
        set_error_errno_msg(error_r, "failed to create first pipe");
        close(control_fds[0]);
        return false;
    }

    p.stdout_fd = input_fds[1];

    if (pipe_cloexec(output_fds) < 0) {
        set_error_errno_msg(error_r, "failed to create second pipe");
        close(control_fds[0]);
        close(input_fds[0]);
        return false;
    }

    p.stdin_fd = output_fds[0];

    p.Append(executable_path);
    for (auto i : args)
        p.Append(i);

    if (!options.CopyTo(p, true, nullptr, error_r)) {
        close(control_fds[0]);
        close(input_fds[0]);
        close(output_fds[1]);
        return false;
    }

    int pid = spawn_service.SpawnChildProcess(name, std::move(p), listener,
                                              error_r);
    if (pid < 0) {
        close(control_fds[0]);
        close(input_fds[0]);
        close(output_fds[1]);
        return false;
    }

    fd_set_nonblock(input_fds[0], true);
    fd_set_nonblock(output_fds[1], true);

    process->pid = pid;
    process->control_fd = control_fds[0];
    process->input_fd = input_fds[0];
    process->output_fd = output_fds[1];
    return true;
}
<|endoftext|>


<commit_before>#include "bvs/bvs.h"

BVS::BVS* bvs;
BVS::Logger logger("Daemon");

int testLogger();
int testConfig();

/** BVSD namespace, contains only the bvs daemon. */
namespace BVSD
{
/** BVS framework's command line daemon.
 * This is a simple command line daemon. It serves as a client to the BVS
 * framework. It is also intended as a sample client.
 *
 * It is interactive, you can use the following commands by just entering them
 * on the command line and then pressing enter (short versions are also
 * available, enter 'help<enter>' to see them):
 *
 * @li \c run run system until paused.
 * @li \c continue same as run
 * @li \c step advance system by one step.
 * @li \c pause pause(stop) system.
 * @li \c test call test functions.
 * @li \c quit shutdown system and quit.
 * @li \c help show help.
 */
	class BVSD
	{
	};
}

/** Main function, creates interactive loop. */
int main(int argc, char** argv)
{
	LOG(2, "starting!");
	bvs = new BVS::BVS(argc, argv);

	LOG(2, "loading modules!");
	bvs->loadModules();

	LOG(2, "connecting modules!");
	bvs->connectAllModules();

	LOG(2, "starting!");
	bvs->start();

	bvs->run();

	std::string input;
	while (input != "q" && input != "quit")
	{
		std::getline(std::cin, input);

		if (input == "r" || input == "run" || input == "c" || input == "continue")
		{
			LOG(2, "RUN!!!");
			bvs->run();
		}
		else if (input.empty() || input == "s" || input == "step")
		{
			LOG(2, "STEP!!!");
			bvs->step();
		}
		else if (input == "p" || input == "pause")
		{
			LOG(2, "PAUSING!!!");
			bvs->pause();
		}
		else if (input == "t" || input == "test")
		{
			testLogger();
			testConfig();
		}
		else if (input == "q" || input == "quit")
		{
			LOG(2, "quitting...");
			bvs->quit();
			LOG(2, "finished!");
		}
		else if (input == "h" || input == "help")
		{
			std::cout << "usage:" << std::endl;
			std::cout << "   r|run        run system until paused" << std::endl;
			std::cout << "   c|continue   same as run" << std::endl;
			std::cout << "   s|step       advance system by one step" << std::endl;
			std::cout << "   p|pause      pause(stop) system" << std::endl;
			std::cout << "   t|test       call test functions" << std::endl;
			std::cout << "   q|quit       shutdown system and quit" << std::endl;
			std::cout << "   h|help       show help" << std::endl;
		}
	}

	delete bvs;

	return 0;
}

/** Performs some logger tests.
 * This functions performs some tests on the logger system. Nothing fancy, can
 * be studied to gain some insight into using the logger system.
 */
int testLogger()
{
	LOG(0, "to CLI FILE");
	bvs->disableLogConsole();
	LOG(0, "to FILE only");

	BVS::Logger file("FILE LOG", 3, BVS::Logger::TO_FILE);
	file.out(0) << "FILE ONLY" << std::endl;

	bvs->enableLogConsole();
	BVS::Logger cli("CLI LOG", 3, BVS::Logger::TO_CLI);
	cli.out(0) << "CLI ONLY" << std::endl;

	bvs->disableLogConsole();
	bvs->disableLogFile();
	LOG(0, "NOOP");

	bvs->enableLogConsole();
	LOG(0, "to CLI");

	bvs->disableLogConsole();
	bvs->enableLogFile("BVSLog.txt", true);
	LOG(0, "to FILE AGAIN");

	bvs->enableLogConsole();
	BVS::Logger both("to BOTH", 0, BVS::Logger::TO_CLI_AND_FILE);
	both.out(0) << "to CLI AND FILE" << std::endl;

	return 0;
}

/** Performs some config tests.
 * This functions performs some tests on the config system. Nothing fancy, can
 * be studied to gain some insight into using the config system.
 */
int testConfig()
{
	LOG(0, "testing...");

	int i;
	std::string s;
	bool b;

	bvs->config.getValue("BVS.logVerbosity", i, 0)
		.getValue("BVS.logFile", s, std::string("default"))
		.getValue("BVS.logSystem", b, false);

	LOG(0, "Getting int: " << i);
	LOG(0, "Getting string: " << s);
	LOG(0, "Getting bool: " << b);

	i = bvs->config.getValue<int>("BVS.logVerbosity", 0);
	s = bvs->config.getValue<std::string>("BVS.logFile", std::string("default"));
	b = bvs->config.getValue<bool>("BVS.logSystem", false);

	LOG(0, "Getting int directly: " << i);
	LOG(0, "Getting string directly: " << s);
	LOG(0, "Getting bool directly: " << b);

	std::string empty;
	bvs->config.getValue("this.option.does.not.exist", empty, std::string("empty"));
	LOG(0, "This should be 'empty': " << empty);

	std::vector<std::string> list;
	bvs->config.getValue("BVS.modules", list);
	LOG(0, "List: BVS.modules");
	int count = 0;
	for (auto& it : list)
	{
		(void) it;
		(void) count;
		LOG(0, count++ << ": " << it);
	}

	return 0;
}

<commit_msg>run: add hotswap call<commit_after>#include "bvs/bvs.h"

BVS::BVS* bvs;
BVS::Logger logger("Daemon");

int testLogger();
int testConfig();

/** BVSD namespace, contains only the bvs daemon. */
namespace BVSD
{
/** BVS framework's command line daemon.
 * This is a simple command line daemon. It serves as a client to the BVS
 * framework. It is also intended as a sample client.
 *
 * It is interactive, you can use the following commands by just entering them
 * on the command line and then pressing enter (short versions are also
 * available, enter 'help<enter>' to see them):
 *
 * @li \c run run system until paused.
 * @li \c continue same as run
 * @li \c step advance system by one step.
 * @li \c pause pause(stop) system.
 * @li \c test call test functions.
 * @li \c quit shutdown system and quit.
 * @li \c help show help.
 */
	class BVSD
	{
	};
}

/** Main function, creates interactive loop. */
int main(int argc, char** argv)
{
	LOG(2, "starting!");
	bvs = new BVS::BVS(argc, argv);

	LOG(2, "loading modules!");
	bvs->loadModules();

	LOG(2, "connecting modules!");
	bvs->connectAllModules();

	LOG(2, "starting!");
	bvs->start();

	//bvs->run();

	std::string input;
	while (input != "q" && input != "quit")
	{
		std::getline(std::cin, input);

		if (input == "r" || input == "run" || input == "c" || input == "continue")
		{
			LOG(2, "RUN!!!");
			bvs->run();
		}
		else if (input.empty() || input == "s" || input == "step")
		{
			LOG(2, "STEP!!!");
			bvs->step();
		}
		else if (input == "p" || input == "pause")
		{
			LOG(2, "PAUSING!!!");
			bvs->pause();
		}
		else if (input == "t" || input == "test")
		{
			testLogger();
			testConfig();
		}
		else if (input.substr(0,2) == "hs" || input.substr(0, 7) == "hotswap")
		{
			size_t delimiter = input.find_first_of(" ");
			input.erase(0, delimiter+1);
			if (input.empty() || delimiter==std::string::npos) std::cout << "ERROR: no module ID given!" << std::endl;
			else bvs->hotSwap(input);
		}
		else if (input == "q" || input == "quit")
		{
			LOG(2, "quitting...");
			bvs->quit();
			LOG(2, "finished!");
		}
		else if (input == "h" || input == "help")
		{
			std::cout << "usage:" << std::endl;
			std::cout << "   r|run            run system until paused" << std::endl;
			std::cout << "   c|continue       same as run" << std::endl;
			std::cout << "   s|step           advance system by one step" << std::endl;
			std::cout << "   p|pause          pause(stop) system" << std::endl;
			std::cout << "   hs|hotswap <arg> HotSwap(TM) <moduleID>" << std::endl;
			std::cout << "   t|test           call test functions" << std::endl;
			std::cout << "   q|quit           shutdown system and quit" << std::endl;
			std::cout << "   h|help           show help" << std::endl;
		}
	}

	delete bvs;

	return 0;
}

/** Performs some logger tests.
 * This functions performs some tests on the logger system. Nothing fancy, can
 * be studied to gain some insight into using the logger system.
 */
int testLogger()
{
	LOG(0, "to CLI FILE");
	bvs->disableLogConsole();
	LOG(0, "to FILE only");

	BVS::Logger file("FILE LOG", 3, BVS::Logger::TO_FILE);
	file.out(0) << "FILE ONLY" << std::endl;

	bvs->enableLogConsole();
	BVS::Logger cli("CLI LOG", 3, BVS::Logger::TO_CLI);
	cli.out(0) << "CLI ONLY" << std::endl;

	bvs->disableLogConsole();
	bvs->disableLogFile();
	LOG(0, "NOOP");

	bvs->enableLogConsole();
	LOG(0, "to CLI");

	bvs->disableLogConsole();
	bvs->enableLogFile("BVSLog.txt", true);
	LOG(0, "to FILE AGAIN");

	bvs->enableLogConsole();
	BVS::Logger both("to BOTH", 0, BVS::Logger::TO_CLI_AND_FILE);
	both.out(0) << "to CLI AND FILE" << std::endl;

	return 0;
}

/** Performs some config tests.
 * This functions performs some tests on the config system. Nothing fancy, can
 * be studied to gain some insight into using the config system.
 */
int testConfig()
{
	LOG(0, "testing...");

	int i;
	std::string s;
	bool b;

	bvs->config.getValue("BVS.logVerbosity", i, 0)
		.getValue("BVS.logFile", s, std::string("default"))
		.getValue("BVS.logSystem", b, false);

	LOG(0, "Getting int: " << i);
	LOG(0, "Getting string: " << s);
	LOG(0, "Getting bool: " << b);

	i = bvs->config.getValue<int>("BVS.logVerbosity", 0);
	s = bvs->config.getValue<std::string>("BVS.logFile", std::string("default"));
	b = bvs->config.getValue<bool>("BVS.logSystem", false);

	LOG(0, "Getting int directly: " << i);
	LOG(0, "Getting string directly: " << s);
	LOG(0, "Getting bool directly: " << b);

	std::string empty;
	bvs->config.getValue("this.option.does.not.exist", empty, std::string("empty"));
	LOG(0, "This should be 'empty': " << empty);

	std::vector<std::string> list;
	bvs->config.getValue("BVS.modules", list);
	LOG(0, "List: BVS.modules");
	int count = 0;
	for (auto& it : list)
	{
		(void) it;
		(void) count;
		LOG(0, count++ << ": " << it);
	}

	return 0;
}

<|endoftext|>


<commit_before>#ifdef WINDOWS

#include <windows.h>
#include <fstream>
#include "util/system.h"

namespace System{

bool isDirectory(const std::string & path){
    return GetFileAttributes(path.c_str()) & FILE_ATTRIBUTE_DIRECTORY;
}

bool readableFile(const std::string & path){
    return !isDirectory(path) && readable(path);
}

bool readable(const std::string & path){
	std::ifstream stream(path.c_str());
    bool ok = stream.good();
    if (stream.is_open()){
        stream.close();
    }
    return ok;
}

}

#endif
<commit_msg>directories are readable in windows<commit_after>#ifdef WINDOWS

#include <windows.h>
#include <fstream>
#include "util/system.h"

namespace System{

bool isDirectory(const std::string & path){
    return GetFileAttributes(path.c_str()) & FILE_ATTRIBUTE_DIRECTORY;
}

bool readableFile(const std::string & path){
    return !isDirectory(path) && readable(path);
}

bool readable(const std::string & path){
    if (isDirectory(path)){
        return true;
    }

	std::ifstream stream(path.c_str());
    bool ok = stream.good();
    if (stream.is_open()){
        stream.close();
    }
    return ok;
}

}

#endif
<|endoftext|>


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

/***********************************************************
*
*  omxFitFunction.cc
*
*  Created: Timothy R. Brick 	Date: 2008-11-13 12:33:06
*
*	FitFunction objects are a subclass of data matrix that evaluates
*   itself anew at each iteration, so that any changes to
*   free parameters can be incorporated into the update.
*   // Question: Should FitFunction be a ``subtype'' of
*   // omxAlgebra or a separate beast entirely?
*
**********************************************************/

#include "omxFitFunction.h"
#include "fitMultigroup.h"

typedef struct omxFitFunctionTableEntry omxFitFunctionTableEntry;

struct omxFitFunctionTableEntry {

	char name[32];
	void (*initFun)(omxFitFunction*);
	void (*setVarGroup)(omxFitFunction*, FreeVarGroup *);  // TODO ugh, just convert to C++

};

static void defaultSetFreeVarGroup(omxFitFunction *ff, FreeVarGroup *fvg)
{
	if (ff->freeVarGroup && ff->freeVarGroup != fvg) {
		Rf_warning("%s: setFreeVarGroup called with different group (%d vs %d)",
			ff->matrix->name, ff->freeVarGroup->id[0], fvg->id[0]);
	}
	ff->freeVarGroup = fvg;
}

static const omxFitFunctionTableEntry omxFitFunctionSymbolTable[] = {
	{"MxFitFunctionAlgebra", 			&omxInitAlgebraFitFunction, defaultSetFreeVarGroup},
	{"MxFitFunctionWLS",				&omxInitWLSFitFunction, defaultSetFreeVarGroup},
	{"MxFitFunctionRow", 				&omxInitRowFitFunction, defaultSetFreeVarGroup},
	{"MxFitFunctionML", 				&omxInitMLFitFunction, defaultSetFreeVarGroup},
	{"imxFitFunctionFIML", &omxInitFIMLFitFunction, defaultSetFreeVarGroup},
	{"MxFitFunctionR",					&omxInitRFitFunction, defaultSetFreeVarGroup},
	{"MxFitFunctionMultigroup", &initFitMultigroup, mgSetFreeVarGroup},
};

void omxFreeFitFunctionArgs(omxFitFunction *off) {
	if(off==NULL) return;

	/* Completely destroy the fit function structures */
	if(off->matrix != NULL) {
		if (off->destructFun) off->destructFun(off);
		off->matrix = NULL;
	}
}

void omxFitFunctionCreateChildren(omxState *globalState)
{
	if (Global->numThreads <= 1) return;

	for(size_t j = 0; j < globalState->expectationList.size(); j++) {
		if (!globalState->expectationList[j]->canDuplicate) return;
	}

	if (globalState->childList.size()) Rf_error("Children already created");

	int numThreads = Global->numThreads;

	globalState->childList.resize(numThreads);

	for(int ii = 0; ii < numThreads; ii++) {
		globalState->childList[ii] = new omxState;
		omxInitState(globalState->childList[ii]);
		omxDuplicateState(globalState->childList[ii], globalState);
	}
}

void omxDuplicateFitMatrix(omxMatrix *tgt, const omxMatrix *src, omxState* newState) {

	if(tgt == NULL || src == NULL) return;

	omxFitFunction *ff = src->fitFunction;
	if(ff == NULL) return;

	omxFillMatrixFromMxFitFunction(tgt, ff->fitType, src->matrixNumber);
	setFreeVarGroup(tgt->fitFunction, src->fitFunction->freeVarGroup);
	tgt->fitFunction->rObj = ff->rObj;
	omxCompleteFitFunction(tgt);
}

void omxFitFunctionCompute(omxFitFunction *off, int want, FitContext *fc)
{
	if (!off->initialized) Rf_error("FitFunction not initialized");

	off->computeFun(off, want, fc);
	if (fc) fc->wanted |= want;

	if (want & FF_COMPUTE_FIT) {
		omxMarkClean(off->matrix);
	}
}

void ComputeFit(omxMatrix *fitMat, int want, FitContext *fc)
{
	bool doFit = want & FF_COMPUTE_FIT;
	// R_CheckUserInterrupt(); add here? TODO

#pragma omp atomic
	++Global->computeCount; // could avoid lock by keeping in FitContext

	if (doFit) Global->checkpointPrefit(fc, fc->est, false);
	omxFitFunction *ff = fitMat->fitFunction;
	if (ff) {
		omxFitFunctionCompute(ff, want, fc);
	} else {
		if (want != FF_COMPUTE_FIT) Rf_error("Only fit is available");
		omxForceCompute(fitMat);
	}
	if (doFit) {
		if (fitMat->rows != 1) {
			if (strEQ(ff->fitType, "MxFitFunctionML") || strEQ(ff->fitType, "imxFitFunctionFIML")) {
				// NOTE: Floating-point addition is not
				// associative. If we compute this in parallel
				// then we introduce non-determinancy.
				double sum = 0;
				for(int i = 0; i < fitMat->rows; i++) {
					sum += log(omxVectorElement(fitMat, i));
				}
				fc->fit = sum * Global->llScale;
				if (!Global->rowLikelihoodsWarning) {
					Rf_warning("%s does not evaluate to a 1x1 matrix. Fixing model by adding "
						   "mxAlgebra(-2*sum(log(%s)), 'm2ll'), mxFitFunctionAlgebra('m2ll')",
						   fitMat->name, fitMat->name);
					Global->rowLikelihoodsWarning = true;
				}
			} else {
				omxRaiseErrorf("%s of type %s returned %d values instead of 1, not sure how to proceed",
					       fitMat->name, ff->fitType, fitMat->rows);
				fc->fit = nan("unknown");
			}
		} else {
			fc->fit = fitMat->data[0];
		}
		if (std::isfinite(fc->fit)) {
			fc->resetIterationError();
		}
		Global->checkpointPostfit(fc);
	}
}

void defaultAddOutput(omxFitFunction* oo, MxRList *out)
{}

void omxFillMatrixFromMxFitFunction(omxMatrix* om, const char *fitType, int matrixNumber)
{
	omxFitFunction *obj = (omxFitFunction*) R_alloc(1, sizeof(omxFitFunction));
	memset(obj, 0, sizeof(omxFitFunction));

	/* Register FitFunction and Matrix with each other */
	obj->matrix = om;
	omxResizeMatrix(om, 1, 1);					// FitFunction matrices MUST be 1x1.
	om->fitFunction = obj;
	om->hasMatrixNumber = TRUE;
	om->matrixNumber = matrixNumber;

	for (size_t fx=0; fx < OMX_STATIC_ARRAY_SIZE(omxFitFunctionSymbolTable); fx++) {
		const omxFitFunctionTableEntry *entry = omxFitFunctionSymbolTable + fx;
		if(strcmp(fitType, entry->name) == 0) {
			obj->fitType = entry->name;
			obj->initFun = entry->initFun;

			// We need to set up the FreeVarGroup before calling initFun
			// because older fit functions expect to know the number of
			// free variables during initFun.
			obj->setVarGroup = entry->setVarGroup; // ugh!
			obj->addOutput = defaultAddOutput;
			break;
		}
	}

	if (obj->initFun == NULL) Rf_error("Fit function %s not implemented", fitType);
}

void omxCompleteFitFunction(omxMatrix *om)
{
	omxFitFunction *obj = om->fitFunction;
	if (obj->initialized) return;
	SEXP rObj = obj->rObj;

	SEXP slotValue;
	Rf_protect(slotValue = R_do_slot(rObj, Rf_install("expectation")));
	if (LENGTH(slotValue) == 1) {
		int expNumber = INTEGER(slotValue)[0];
		if(expNumber != NA_INTEGER) {
			obj->expectation = omxExpectationFromIndex(expNumber, om->currentState);
			setFreeVarGroup(obj->expectation, obj->freeVarGroup);
			omxCompleteExpectation(obj->expectation);
		}
	}
	Rf_unprotect(1);	/* slotValue */

	obj->initFun(obj);

	if(obj->computeFun == NULL) Rf_error("Failed to initialize fit function %s", obj->fitType);

	obj->matrix->data[0] = NA_REAL;
	omxMarkDirty(obj->matrix);
	obj->initialized = TRUE;
}

void setFreeVarGroup(omxFitFunction *ff, FreeVarGroup *fvg)
{
	(*ff->setVarGroup)(ff, fvg);
}

void omxFitFunctionPrint(omxFitFunction* off, const char* d) {
	mxLog("(FitFunction, type %s)", off->fitType);
	omxPrintMatrix(off->matrix, d);
}

/* Helper functions */
omxMatrix* omxNewMatrixFromSlot(SEXP rObj, omxState* currentState, const char* slotName) {
	SEXP slotValue;
	Rf_protect(slotValue = R_do_slot(rObj, Rf_install(slotName)));
	omxMatrix* newMatrix = omxMatrixLookupFromState1(slotValue, currentState);
	Rf_unprotect(1);
	return newMatrix;
}

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

/***********************************************************
*
*  omxFitFunction.cc
*
*  Created: Timothy R. Brick 	Date: 2008-11-13 12:33:06
*
*	FitFunction objects are a subclass of data matrix that evaluates
*   itself anew at each iteration, so that any changes to
*   free parameters can be incorporated into the update.
*   // Question: Should FitFunction be a ``subtype'' of
*   // omxAlgebra or a separate beast entirely?
*
**********************************************************/

#include "omxFitFunction.h"
#include "fitMultigroup.h"

typedef struct omxFitFunctionTableEntry omxFitFunctionTableEntry;

struct omxFitFunctionTableEntry {

	char name[32];
	void (*initFun)(omxFitFunction*);
	void (*setVarGroup)(omxFitFunction*, FreeVarGroup *);  // TODO ugh, just convert to C++

};

static void defaultSetFreeVarGroup(omxFitFunction *ff, FreeVarGroup *fvg)
{
	if (ff->freeVarGroup && ff->freeVarGroup != fvg) {
		Rf_warning("%s: setFreeVarGroup called with different group (%d vs %d)",
			ff->matrix->name, ff->freeVarGroup->id[0], fvg->id[0]);
	}
	ff->freeVarGroup = fvg;
}

static const omxFitFunctionTableEntry omxFitFunctionSymbolTable[] = {
	{"MxFitFunctionAlgebra", 			&omxInitAlgebraFitFunction, defaultSetFreeVarGroup},
	{"MxFitFunctionWLS",				&omxInitWLSFitFunction, defaultSetFreeVarGroup},
	{"MxFitFunctionRow", 				&omxInitRowFitFunction, defaultSetFreeVarGroup},
	{"MxFitFunctionML", 				&omxInitMLFitFunction, defaultSetFreeVarGroup},
	{"imxFitFunctionFIML", &omxInitFIMLFitFunction, defaultSetFreeVarGroup},
	{"MxFitFunctionR",					&omxInitRFitFunction, defaultSetFreeVarGroup},
	{"MxFitFunctionMultigroup", &initFitMultigroup, mgSetFreeVarGroup},
};

void omxFreeFitFunctionArgs(omxFitFunction *off) {
	if(off==NULL) return;

	/* Completely destroy the fit function structures */
	if(off->matrix != NULL) {
		if (off->destructFun) off->destructFun(off);
		off->matrix = NULL;
	}
}

void omxFitFunctionCreateChildren(omxState *globalState)
{
	if (Global->numThreads <= 1) return;

	for(size_t j = 0; j < globalState->expectationList.size(); j++) {
		if (!globalState->expectationList[j]->canDuplicate) return;
	}

	if (globalState->childList.size()) Rf_error("Children already created");

	int numThreads = Global->numThreads;

	globalState->childList.resize(numThreads);

	for(int ii = 0; ii < numThreads; ii++) {
		globalState->childList[ii] = new omxState;
		omxInitState(globalState->childList[ii]);
		omxDuplicateState(globalState->childList[ii], globalState);
	}
}

void omxDuplicateFitMatrix(omxMatrix *tgt, const omxMatrix *src, omxState* newState) {

	if(tgt == NULL || src == NULL) return;

	omxFitFunction *ff = src->fitFunction;
	if(ff == NULL) return;

	omxFillMatrixFromMxFitFunction(tgt, ff->fitType, src->matrixNumber);
	setFreeVarGroup(tgt->fitFunction, src->fitFunction->freeVarGroup);
	tgt->fitFunction->rObj = ff->rObj;
	omxCompleteFitFunction(tgt);
}

void omxFitFunctionCompute(omxFitFunction *off, int want, FitContext *fc)
{
	if (!off->initialized) Rf_error("FitFunction not initialized");

	off->computeFun(off, want, fc);
	if (fc) fc->wanted |= want;

	if (want & FF_COMPUTE_FIT) {
		omxMarkClean(off->matrix);
	}
}

void ComputeFit(omxMatrix *fitMat, int want, FitContext *fc)
{
	bool doFit = want & FF_COMPUTE_FIT;
	R_CheckUserInterrupt();

#pragma omp atomic
	++Global->computeCount; // could avoid lock by keeping in FitContext

	if (doFit) Global->checkpointPrefit(fc, fc->est, false);
	omxFitFunction *ff = fitMat->fitFunction;
	if (ff) {
		omxFitFunctionCompute(ff, want, fc);
	} else {
		if (want != FF_COMPUTE_FIT) Rf_error("Only fit is available");
		omxForceCompute(fitMat);
	}
	if (doFit) {
		if (fitMat->rows != 1) {
			if (strEQ(ff->fitType, "MxFitFunctionML") || strEQ(ff->fitType, "imxFitFunctionFIML")) {
				// NOTE: Floating-point addition is not
				// associative. If we compute this in parallel
				// then we introduce non-determinancy.
				double sum = 0;
				for(int i = 0; i < fitMat->rows; i++) {
					sum += log(omxVectorElement(fitMat, i));
				}
				fc->fit = sum * Global->llScale;
				if (!Global->rowLikelihoodsWarning) {
					Rf_warning("%s does not evaluate to a 1x1 matrix. Fixing model by adding "
						   "mxAlgebra(-2*sum(log(%s)), 'm2ll'), mxFitFunctionAlgebra('m2ll')",
						   fitMat->name, fitMat->name);
					Global->rowLikelihoodsWarning = true;
				}
			} else {
				omxRaiseErrorf("%s of type %s returned %d values instead of 1, not sure how to proceed",
					       fitMat->name, ff->fitType, fitMat->rows);
				fc->fit = nan("unknown");
			}
		} else {
			fc->fit = fitMat->data[0];
		}
		if (std::isfinite(fc->fit)) {
			fc->resetIterationError();
		}
		Global->checkpointPostfit(fc);
	}
}

void defaultAddOutput(omxFitFunction* oo, MxRList *out)
{}

void omxFillMatrixFromMxFitFunction(omxMatrix* om, const char *fitType, int matrixNumber)
{
	omxFitFunction *obj = (omxFitFunction*) R_alloc(1, sizeof(omxFitFunction));
	memset(obj, 0, sizeof(omxFitFunction));

	/* Register FitFunction and Matrix with each other */
	obj->matrix = om;
	omxResizeMatrix(om, 1, 1);					// FitFunction matrices MUST be 1x1.
	om->fitFunction = obj;
	om->hasMatrixNumber = TRUE;
	om->matrixNumber = matrixNumber;

	for (size_t fx=0; fx < OMX_STATIC_ARRAY_SIZE(omxFitFunctionSymbolTable); fx++) {
		const omxFitFunctionTableEntry *entry = omxFitFunctionSymbolTable + fx;
		if(strcmp(fitType, entry->name) == 0) {
			obj->fitType = entry->name;
			obj->initFun = entry->initFun;

			// We need to set up the FreeVarGroup before calling initFun
			// because older fit functions expect to know the number of
			// free variables during initFun.
			obj->setVarGroup = entry->setVarGroup; // ugh!
			obj->addOutput = defaultAddOutput;
			break;
		}
	}

	if (obj->initFun == NULL) Rf_error("Fit function %s not implemented", fitType);
}

void omxCompleteFitFunction(omxMatrix *om)
{
	omxFitFunction *obj = om->fitFunction;
	if (obj->initialized) return;
	SEXP rObj = obj->rObj;

	SEXP slotValue;
	Rf_protect(slotValue = R_do_slot(rObj, Rf_install("expectation")));
	if (LENGTH(slotValue) == 1) {
		int expNumber = INTEGER(slotValue)[0];
		if(expNumber != NA_INTEGER) {
			obj->expectation = omxExpectationFromIndex(expNumber, om->currentState);
			setFreeVarGroup(obj->expectation, obj->freeVarGroup);
			omxCompleteExpectation(obj->expectation);
		}
	}
	Rf_unprotect(1);	/* slotValue */

	obj->initFun(obj);

	if(obj->computeFun == NULL) Rf_error("Failed to initialize fit function %s", obj->fitType);

	obj->matrix->data[0] = NA_REAL;
	omxMarkDirty(obj->matrix);
	obj->initialized = TRUE;
}

void setFreeVarGroup(omxFitFunction *ff, FreeVarGroup *fvg)
{
	(*ff->setVarGroup)(ff, fvg);
}

void omxFitFunctionPrint(omxFitFunction* off, const char* d) {
	mxLog("(FitFunction, type %s)", off->fitType);
	omxPrintMatrix(off->matrix, d);
}

/* Helper functions */
omxMatrix* omxNewMatrixFromSlot(SEXP rObj, omxState* currentState, const char* slotName) {
	SEXP slotValue;
	Rf_protect(slotValue = R_do_slot(rObj, Rf_install(slotName)));
	omxMatrix* newMatrix = omxMatrixLookupFromState1(slotValue, currentState);
	Rf_unprotect(1);
	return newMatrix;
}

<|endoftext|>