<commit_before>/* gobby - A GTKmm driven libobby client
 * Copyright (C) 2005 0x539 dev group
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "features.hpp"

#include <glibmm/pattern.h>
#include <gtkmm/textview.h>

#ifdef WITH_GTKSOURCEVIEW2
# include <gtksourceview/gtksourcebuffer.h>
#endif

#include "preferences.hpp"
#include "docwindow.hpp"

namespace
{
	GtkWrapMode wrap_mode_from_preferences(const Gobby::Preferences& pref)
	{
		if(pref.view.wrap_text)
		{
			if(pref.view.wrap_words)
				return GTK_WRAP_CHAR;
			else
				return GTK_WRAP_WORD;
		}
		else
		{
			return GTK_WRAP_NONE;
		}
	}
}

Gobby::DocWindow::DocWindow(LocalDocumentInfo& info,
                            const Preferences& preferences):
	m_view(GTK_SOURCE_VIEW(gtk_source_view_new())),
	m_info(info), m_doc(info.get_content() ),
	m_preferences(preferences), /*m_editing(false),*/
	m_title(info.get_title() ),
	m_scrolly(0.0),
	m_scroll_restore(false)
{
	if(!info.is_subscribed() )
	{
		throw std::logic_error(
			"Gobby::DocWindow::DocWindow:\n"
			"Local user is not subscribed"
		);
	}

	GtkSourceBuffer* buffer = m_doc.get_buffer();
	gtk_text_view_set_buffer(GTK_TEXT_VIEW(m_view), GTK_TEXT_BUFFER(buffer));

	Glib::RefPtr<Gtk::TextBuffer> cpp_buffer =
		Glib::wrap(GTK_TEXT_BUFFER(buffer), true);

	// Set source language by filename
	gtk_source_buffer_set_highlight_syntax(buffer, FALSE);

	for(Preferences::FileList::iterator iter = preferences.files.begin();
	    iter != preferences.files.end();
	    ++ iter)
	{
		Glib::PatternSpec spec(iter.pattern());
		if(spec.match(info.get_title()) )
		{
			gtk_source_buffer_set_language(buffer, iter.language());
			gtk_source_buffer_set_highlight_syntax(buffer, TRUE);
		}
	}

#ifdef WITH_GTKSOURCEVIEW2
	// Set a theme so we see anything.
	// TODO: This should be temporary code until gtksourceview2 sets a default
	// theme.
/*	GtkSourceStyleManager* sm = gtk_source_style_manager_new();
	GtkSourceStyleScheme* scheme = gtk_source_style_manager_get_scheme(sm, "gvim");
	gtk_source_buffer_set_style_scheme(buffer, scheme);
	g_object_unref(G_OBJECT(sm));*/
#endif

	cpp_buffer->signal_mark_set().connect(
		sigc::mem_fun(*this, &DocWindow::on_mark_set)
	);

	cpp_buffer->signal_changed().connect(
		sigc::mem_fun(*this, &DocWindow::on_changed)
	);

	m_doc.local_insert_event().connect(
		sigc::mem_fun(*this, &DocWindow::on_local_insert)
	);

	m_doc.local_erase_event().connect(
		sigc::mem_fun(*this, &DocWindow::on_local_erase)
	);

	m_doc.remote_insert_before_event().connect(
		sigc::mem_fun(*this, &DocWindow::on_remote_insert_before)
	);

	m_doc.remote_erase_before_event().connect(
		sigc::mem_fun(*this, &DocWindow::on_remote_erase_before)
	);

	m_doc.remote_insert_after_event().connect(
		sigc::mem_fun(*this, &DocWindow::on_remote_insert_after)
	);

	m_doc.remote_erase_after_event().connect(
		sigc::mem_fun(*this, &DocWindow::on_remote_erase_after)
	);

	apply_preferences();
	gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(buffer), !m_doc.empty());

	set_shadow_type(Gtk::SHADOW_IN);
	set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
	gtk_container_add(GTK_CONTAINER(gobj()), GTK_WIDGET(m_view));
}

void Gobby::DocWindow::get_cursor_position(unsigned int& row,
                                           unsigned int& col)
{
	Glib::RefPtr<Gtk::TextBuffer> cpp_buffer = Glib::wrap(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view)), true);

	Glib::RefPtr<Gtk::TextMark> mark = cpp_buffer->get_insert();

	// Gtk::TextBuffer::Mark::get_iter is not const. Why not? It prevents
	// this function from being const.
	Gtk::TextBuffer::iterator iter = mark->get_iter();

	// Row is trivial
	row = iter.get_line(); col = 0;
	int chars = iter.get_line_offset();

	// Tab characters expand to more than one column
	unsigned int tabs = m_preferences.editor.tab_width;
	for(iter.set_line_offset(0); iter.get_line_offset() < chars; ++ iter)
	{
		unsigned int width = 1;
		if(*iter == '\t')
		{
			width = (tabs - iter.get_line_offset() % tabs) % tabs;
			if(width == 0) width = tabs;
		}

		col += width;
	}
}

void Gobby::DocWindow::set_selection(const Gtk::TextIter& begin,
                                     const Gtk::TextIter& end)
{
	gtk_text_buffer_select_range(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view)),
		begin.gobj(),
		end.gobj()
		);

	gtk_text_view_scroll_to_mark(
		GTK_TEXT_VIEW(m_view),
		gtk_text_buffer_get_insert(gtk_text_view_get_buffer(
			GTK_TEXT_VIEW(m_view))),
		0.1, FALSE, 0.0, 0.0);
}

void Gobby::DocWindow::disable()
{
	gtk_widget_set_sensitive(GTK_WIDGET(m_view), FALSE);
}

Glib::ustring Gobby::DocWindow::get_selected_text() const
{
	GtkTextIter start, end;
	gtk_text_buffer_get_selection_bounds(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view)), &start, &end);

	Gtk::TextIter start_cpp(&start), end_cpp(&end);
	return start_cpp.get_slice(end_cpp);
}

const Glib::ustring& Gobby::DocWindow::get_title() const
{
	return m_title;
}

bool Gobby::DocWindow::get_modified() const
{
	return gtk_text_buffer_get_modified(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view))) == TRUE;
}

void Gobby::DocWindow::grab_focus()
{
	Gtk::ScrolledWindow::grab_focus();
	gtk_widget_grab_focus(GTK_WIDGET(m_view));
}

GtkSourceLanguage* Gobby::DocWindow::get_language() const
{
	return gtk_source_buffer_get_language(GTK_SOURCE_BUFFER(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view))));
}

void Gobby::DocWindow::set_language(GtkSourceLanguage* language)
{
	GtkSourceBuffer* buffer = GTK_SOURCE_BUFFER(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view)));

	gtk_source_buffer_set_language(buffer, language);
	gtk_source_buffer_set_highlight_syntax(buffer, language != NULL);

	m_signal_language_changed.emit();
}

const Gobby::Preferences& Gobby::DocWindow::get_preferences() const
{
	return m_preferences;
}

void Gobby::DocWindow::set_preferences(const Preferences& preferences)
{
	m_preferences = preferences;
	apply_preferences();
}

Glib::ustring Gobby::DocWindow::get_content() const
{
	Glib::RefPtr<Gtk::TextBuffer> buffer = Glib::wrap(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view)), true);

	return buffer->get_text();
}

Gobby::DocWindow::signal_cursor_moved_type
Gobby::DocWindow::cursor_moved_event() const
{
	return m_signal_cursor_moved;
}

Gobby::DocWindow::signal_content_changed_type
Gobby::DocWindow::content_changed_event() const
{
	return m_signal_content_changed;
}

Gobby::DocWindow::signal_language_changed_type
Gobby::DocWindow::language_changed_event() const
{
	return m_signal_language_changed;
}

const Gobby::LocalDocumentInfo& Gobby::DocWindow::get_info() const
{
	return m_info;
}

Gobby::LocalDocumentInfo& Gobby::DocWindow::get_info()
{
	return m_info;
}

const Gobby::Document& Gobby::DocWindow::get_document() const
{
	return m_doc;
}

void Gobby::DocWindow::on_mark_set(const Gtk::TextIter& location,
                                   const Glib::RefPtr<Gtk::TextMark>& mark)
{
	// Mark was deleted
	if(!mark) return;

	if(mark->gobj() == gtk_text_buffer_get_insert(
	   gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view))))
	{
		m_signal_cursor_moved.emit();
	}
}

void Gobby::DocWindow::on_changed()
{
	// Cursor may have moved.
	// TODO: Check if the cursor really moved
	m_signal_cursor_moved.emit();
	m_signal_content_changed.emit();
}

void Gobby::DocWindow::on_local_insert(obby::position pos,
                                       const std::string& error)
{
	m_info.insert(pos, error);
}

void Gobby::DocWindow::on_local_erase(obby::position pos,
                                      obby::position len)
{
	m_info.erase(pos, len);
}

void Gobby::DocWindow::on_remote_insert_before(obby::position,
                                               const std::string& text)
{
	store_scroll();
}

void Gobby::DocWindow::on_remote_erase_before(obby::position pos,
                                              obby::position len)
{
	store_scroll();
}

void Gobby::DocWindow::on_remote_insert_after(obby::position,
                                              const std::string& text)
{
	restore_scroll();
}

void Gobby::DocWindow::on_remote_erase_after(obby::position pos,
                                             obby::position len)
{
	restore_scroll();
}

void Gobby::DocWindow::apply_preferences()
{
	GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view));

	gtk_source_view_set_tab_width(GTK_SOURCE_VIEW(m_view),
		m_preferences.editor.tab_width);
	gtk_source_view_set_insert_spaces_instead_of_tabs(GTK_SOURCE_VIEW(m_view),
		m_preferences.editor.tab_spaces);
	gtk_source_view_set_auto_indent(GTK_SOURCE_VIEW(m_view),
		m_preferences.editor.indentation_auto);
#ifdef WITH_GTKSOURCEVIEW2
	gtk_source_view_set_smart_home_end(GTK_SOURCE_VIEW(m_view),
		m_preferences.editor.homeend_smart ?
		GTK_SOURCE_SMART_HOME_END_ALWAYS :
		GTK_SOURCE_SMART_HOME_END_DISABLED);
#else
	gtk_source_view_set_smart_home_end(GTK_SOURCE_VIEW(m_view),
		m_preferences.editor.homeend_smart);
#endif

	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(m_view),
		wrap_mode_from_preferences(m_preferences));
	gtk_source_view_set_show_line_numbers(GTK_SOURCE_VIEW(m_view),
		m_preferences.view.linenum_display);
	gtk_source_view_set_highlight_current_line(GTK_SOURCE_VIEW(m_view),
		m_preferences.view.curline_highlight);
	gtk_source_view_set_show_right_margin(GTK_SOURCE_VIEW(m_view),
		m_preferences.view.margin_display);
	gtk_source_view_set_right_margin_position(GTK_SOURCE_VIEW(m_view),
		m_preferences.view.margin_pos);
	gtk_source_buffer_set_highlight_matching_brackets(GTK_SOURCE_BUFFER(buffer),
		m_preferences.view.bracket_highlight);

	gtk_widget_modify_font(GTK_WIDGET(m_view), m_preferences.font.desc.gobj());

	// Cursor position may have changed because of new tab width
	// TODO: Only emit if the position really changed
	m_signal_cursor_moved.emit();
}

void Gobby::DocWindow::store_scroll()
{
	Gdk::Rectangle curs_rect;
	int x, y;

	Gtk::TextView* cpp_view = Glib::wrap(GTK_TEXT_VIEW(m_view));
	cpp_view->get_iter_location(cpp_view->get_buffer()->get_insert()->get_iter(), curs_rect);
	cpp_view->buffer_to_window_coords(
		Gtk::TEXT_WINDOW_WIDGET,
		curs_rect.get_x(), curs_rect.get_y(),
		x, y);

	m_scrolly = y / static_cast<double>((cpp_view->get_height() - curs_rect.get_height()));
	m_scroll_restore = true;
}

void Gobby::DocWindow::restore_scroll()
{
	if(m_scroll_restore)
	{
		Gtk::TextView* cpp_view = Glib::wrap(GTK_TEXT_VIEW(m_view));
		if(m_scrolly >= 0.0 && m_scrolly <= 1.0)
			cpp_view->scroll_to(
				cpp_view->get_buffer()->get_insert(),
				0, 0,
				m_scrolly);

		m_scroll_restore = false;
	}
}

<commit_msg>Don't break GtkSourceVie1 build<commit_after>/* gobby - A GTKmm driven libobby client
 * Copyright (C) 2005 0x539 dev group
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "features.hpp"

#include <glibmm/pattern.h>
#include <gtkmm/textview.h>

#ifdef WITH_GTKSOURCEVIEW2
# include <gtksourceview/gtksourcebuffer.h>
#endif

#include "preferences.hpp"
#include "docwindow.hpp"

namespace
{
	GtkWrapMode wrap_mode_from_preferences(const Gobby::Preferences& pref)
	{
		if(pref.view.wrap_text)
		{
			if(pref.view.wrap_words)
				return GTK_WRAP_CHAR;
			else
				return GTK_WRAP_WORD;
		}
		else
		{
			return GTK_WRAP_NONE;
		}
	}
}

Gobby::DocWindow::DocWindow(LocalDocumentInfo& info,
                            const Preferences& preferences):
	m_view(GTK_SOURCE_VIEW(gtk_source_view_new())),
	m_info(info), m_doc(info.get_content() ),
	m_preferences(preferences), /*m_editing(false),*/
	m_title(info.get_title() ),
	m_scrolly(0.0),
	m_scroll_restore(false)
{
	if(!info.is_subscribed() )
	{
		throw std::logic_error(
			"Gobby::DocWindow::DocWindow:\n"
			"Local user is not subscribed"
		);
	}

	GtkSourceBuffer* buffer = m_doc.get_buffer();
	gtk_text_view_set_buffer(GTK_TEXT_VIEW(m_view), GTK_TEXT_BUFFER(buffer));

	Glib::RefPtr<Gtk::TextBuffer> cpp_buffer =
		Glib::wrap(GTK_TEXT_BUFFER(buffer), true);

	// Set source language by filename
	gtk_source_buffer_set_highlight_syntax(buffer, FALSE);

	for(Preferences::FileList::iterator iter = preferences.files.begin();
	    iter != preferences.files.end();
	    ++ iter)
	{
		Glib::PatternSpec spec(iter.pattern());
		if(spec.match(info.get_title()) )
		{
			gtk_source_buffer_set_language(buffer, iter.language());
			gtk_source_buffer_set_highlight_syntax(buffer, TRUE);
		}
	}

#ifdef WITH_GTKSOURCEVIEW2
	// Set a theme so we see anything.
	// TODO: This should be temporary code until gtksourceview2 sets a default
	// theme.
/*	GtkSourceStyleManager* sm = gtk_source_style_manager_new();
	GtkSourceStyleScheme* scheme = gtk_source_style_manager_get_scheme(sm, "gvim");
	gtk_source_buffer_set_style_scheme(buffer, scheme);
	g_object_unref(G_OBJECT(sm));*/
#endif

	cpp_buffer->signal_mark_set().connect(
		sigc::mem_fun(*this, &DocWindow::on_mark_set)
	);

	cpp_buffer->signal_changed().connect(
		sigc::mem_fun(*this, &DocWindow::on_changed)
	);

	m_doc.local_insert_event().connect(
		sigc::mem_fun(*this, &DocWindow::on_local_insert)
	);

	m_doc.local_erase_event().connect(
		sigc::mem_fun(*this, &DocWindow::on_local_erase)
	);

	m_doc.remote_insert_before_event().connect(
		sigc::mem_fun(*this, &DocWindow::on_remote_insert_before)
	);

	m_doc.remote_erase_before_event().connect(
		sigc::mem_fun(*this, &DocWindow::on_remote_erase_before)
	);

	m_doc.remote_insert_after_event().connect(
		sigc::mem_fun(*this, &DocWindow::on_remote_insert_after)
	);

	m_doc.remote_erase_after_event().connect(
		sigc::mem_fun(*this, &DocWindow::on_remote_erase_after)
	);

	apply_preferences();
	gtk_text_buffer_set_modified(GTK_TEXT_BUFFER(buffer), !m_doc.empty());

	set_shadow_type(Gtk::SHADOW_IN);
	set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
	gtk_container_add(GTK_CONTAINER(gobj()), GTK_WIDGET(m_view));
}

void Gobby::DocWindow::get_cursor_position(unsigned int& row,
                                           unsigned int& col)
{
	Glib::RefPtr<Gtk::TextBuffer> cpp_buffer = Glib::wrap(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view)), true);

	Glib::RefPtr<Gtk::TextMark> mark = cpp_buffer->get_insert();

	// Gtk::TextBuffer::Mark::get_iter is not const. Why not? It prevents
	// this function from being const.
	Gtk::TextBuffer::iterator iter = mark->get_iter();

	// Row is trivial
	row = iter.get_line(); col = 0;
	int chars = iter.get_line_offset();

	// Tab characters expand to more than one column
	unsigned int tabs = m_preferences.editor.tab_width;
	for(iter.set_line_offset(0); iter.get_line_offset() < chars; ++ iter)
	{
		unsigned int width = 1;
		if(*iter == '\t')
		{
			width = (tabs - iter.get_line_offset() % tabs) % tabs;
			if(width == 0) width = tabs;
		}

		col += width;
	}
}

void Gobby::DocWindow::set_selection(const Gtk::TextIter& begin,
                                     const Gtk::TextIter& end)
{
	gtk_text_buffer_select_range(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view)),
		begin.gobj(),
		end.gobj()
		);

	gtk_text_view_scroll_to_mark(
		GTK_TEXT_VIEW(m_view),
		gtk_text_buffer_get_insert(gtk_text_view_get_buffer(
			GTK_TEXT_VIEW(m_view))),
		0.1, FALSE, 0.0, 0.0);
}

void Gobby::DocWindow::disable()
{
	gtk_widget_set_sensitive(GTK_WIDGET(m_view), FALSE);
}

Glib::ustring Gobby::DocWindow::get_selected_text() const
{
	GtkTextIter start, end;
	gtk_text_buffer_get_selection_bounds(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view)), &start, &end);

	Gtk::TextIter start_cpp(&start), end_cpp(&end);
	return start_cpp.get_slice(end_cpp);
}

const Glib::ustring& Gobby::DocWindow::get_title() const
{
	return m_title;
}

bool Gobby::DocWindow::get_modified() const
{
	return gtk_text_buffer_get_modified(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view))) == TRUE;
}

void Gobby::DocWindow::grab_focus()
{
	Gtk::ScrolledWindow::grab_focus();
	gtk_widget_grab_focus(GTK_WIDGET(m_view));
}

GtkSourceLanguage* Gobby::DocWindow::get_language() const
{
	return gtk_source_buffer_get_language(GTK_SOURCE_BUFFER(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view))));
}

void Gobby::DocWindow::set_language(GtkSourceLanguage* language)
{
	GtkSourceBuffer* buffer = GTK_SOURCE_BUFFER(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view)));

	gtk_source_buffer_set_language(buffer, language);
	gtk_source_buffer_set_highlight_syntax(buffer, language != NULL);

	m_signal_language_changed.emit();
}

const Gobby::Preferences& Gobby::DocWindow::get_preferences() const
{
	return m_preferences;
}

void Gobby::DocWindow::set_preferences(const Preferences& preferences)
{
	m_preferences = preferences;
	apply_preferences();
}

Glib::ustring Gobby::DocWindow::get_content() const
{
	Glib::RefPtr<Gtk::TextBuffer> buffer = Glib::wrap(
		gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view)), true);

	return buffer->get_text();
}

Gobby::DocWindow::signal_cursor_moved_type
Gobby::DocWindow::cursor_moved_event() const
{
	return m_signal_cursor_moved;
}

Gobby::DocWindow::signal_content_changed_type
Gobby::DocWindow::content_changed_event() const
{
	return m_signal_content_changed;
}

Gobby::DocWindow::signal_language_changed_type
Gobby::DocWindow::language_changed_event() const
{
	return m_signal_language_changed;
}

const Gobby::LocalDocumentInfo& Gobby::DocWindow::get_info() const
{
	return m_info;
}

Gobby::LocalDocumentInfo& Gobby::DocWindow::get_info()
{
	return m_info;
}

const Gobby::Document& Gobby::DocWindow::get_document() const
{
	return m_doc;
}

void Gobby::DocWindow::on_mark_set(const Gtk::TextIter& location,
                                   const Glib::RefPtr<Gtk::TextMark>& mark)
{
	// Mark was deleted
	if(!mark) return;

	if(mark->gobj() == gtk_text_buffer_get_insert(
	   gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view))))
	{
		m_signal_cursor_moved.emit();
	}
}

void Gobby::DocWindow::on_changed()
{
	// Cursor may have moved.
	// TODO: Check if the cursor really moved
	m_signal_cursor_moved.emit();
	m_signal_content_changed.emit();
}

void Gobby::DocWindow::on_local_insert(obby::position pos,
                                       const std::string& error)
{
	m_info.insert(pos, error);
}

void Gobby::DocWindow::on_local_erase(obby::position pos,
                                      obby::position len)
{
	m_info.erase(pos, len);
}

void Gobby::DocWindow::on_remote_insert_before(obby::position,
                                               const std::string& text)
{
	store_scroll();
}

void Gobby::DocWindow::on_remote_erase_before(obby::position pos,
                                              obby::position len)
{
	store_scroll();
}

void Gobby::DocWindow::on_remote_insert_after(obby::position,
                                              const std::string& text)
{
	restore_scroll();
}

void Gobby::DocWindow::on_remote_erase_after(obby::position pos,
                                             obby::position len)
{
	restore_scroll();
}

void Gobby::DocWindow::apply_preferences()
{
	GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_view));

	gtk_source_view_set_tab_width(GTK_SOURCE_VIEW(m_view),
		m_preferences.editor.tab_width);
	gtk_source_view_set_insert_spaces_instead_of_tabs(GTK_SOURCE_VIEW(m_view),
		m_preferences.editor.tab_spaces);
	gtk_source_view_set_auto_indent(GTK_SOURCE_VIEW(m_view),
		m_preferences.editor.indentation_auto);
#ifdef WITH_GTKSOURCEVIEW2
	gtk_source_view_set_smart_home_end(GTK_SOURCE_VIEW(m_view),
		m_preferences.editor.homeend_smart ?
		GTK_SOURCE_SMART_HOME_END_ALWAYS :
		GTK_SOURCE_SMART_HOME_END_DISABLED);
#else
	gtk_source_view_set_smart_home_end(GTK_SOURCE_VIEW(m_view),
		m_preferences.editor.homeend_smart);
#endif

	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(m_view),
		wrap_mode_from_preferences(m_preferences));
	gtk_source_view_set_show_line_numbers(GTK_SOURCE_VIEW(m_view),
		m_preferences.view.linenum_display);
	gtk_source_view_set_highlight_current_line(GTK_SOURCE_VIEW(m_view),
		m_preferences.view.curline_highlight);
#ifdef WITH_GTKSOURCEVIEW2
	gtk_source_view_set_show_right_margin(GTK_SOURCE_VIEW(m_view),
		m_preferences.view.margin_display);
	gtk_source_view_set_right_margin_position(GTK_SOURCE_VIEW(m_view),
		m_preferences.view.margin_pos);
	gtk_source_buffer_set_highlight_matching_brackets(GTK_SOURCE_BUFFER(buffer),
		m_preferences.view.bracket_highlight);
#else
	gtk_source_view_set_show_margin(GTK_SOURCE_VIEW(m_view),
		m_preferences.view.margin_display);
	gtk_source_view_set_margin(GTK_SOURCE_VIEW(m_view),
		m_preferences.view.margin_pos);
	gtk_source_buffer_set_check_brackets(GTK_SOURCE_BUFFER(buffer),
		m_preferences.view.bracket_highlight);
#endif

	gtk_widget_modify_font(GTK_WIDGET(m_view), m_preferences.font.desc.gobj());

	// Cursor position may have changed because of new tab width
	// TODO: Only emit if the position really changed
	m_signal_cursor_moved.emit();
}

void Gobby::DocWindow::store_scroll()
{
	Gdk::Rectangle curs_rect;
	int x, y;

	Gtk::TextView* cpp_view = Glib::wrap(GTK_TEXT_VIEW(m_view));
	cpp_view->get_iter_location(cpp_view->get_buffer()->get_insert()->get_iter(), curs_rect);
	cpp_view->buffer_to_window_coords(
		Gtk::TEXT_WINDOW_WIDGET,
		curs_rect.get_x(), curs_rect.get_y(),
		x, y);

	m_scrolly = y / static_cast<double>((cpp_view->get_height() - curs_rect.get_height()));
	m_scroll_restore = true;
}

void Gobby::DocWindow::restore_scroll()
{
	if(m_scroll_restore)
	{
		Gtk::TextView* cpp_view = Glib::wrap(GTK_TEXT_VIEW(m_view));
		if(m_scrolly >= 0.0 && m_scrolly <= 1.0)
			cpp_view->scroll_to(
				cpp_view->get_buffer()->get_insert(),
				0, 0,
				m_scrolly);

		m_scroll_restore = false;
	}
}

<|endoftext|>


<commit_before>#include "HexagonOffload.h"
#include "IRMutator.h"
#include "Substitute.h"
#include "Closure.h"
#include "Param.h"
#include "Image.h"
#include "Output.h"
#include "LLVM_Headers.h"
#include "RemoveTrivialForLoops.h"

#include <iostream>
#include <fstream>

namespace Halide {
namespace Internal {

using std::string;
using std::vector;

namespace {

Target hexagon_remote_target(Target::NoOS, Target::Hexagon, 32);

class InjectHexagonRpc : public IRMutator {
    using IRMutator::visit;

    std::map<std::string, Expr> state_vars;

    Module device_code;

    /** Alignment info for Int(32) variables in scope, so we don't
     * lose the information when creating Hexagon kernels. */
    Scope<ModulusRemainder> alignment_info;

    Expr state_var(const std::string& name, Type type) {
        Expr& var = state_vars[name];
        if (!var.defined()) {
            Buffer storage(type, {}, nullptr, name + "_buf");
            *(void **)storage.host_ptr() = nullptr;
            var = Load::make(type_of<void*>(), name + "_buf", 0, storage, Parameter());
        }
        return var;
    }

    Expr state_var_ptr(const std::string& name, Type type) {
        Expr var = state_var(name, type);
        return Call::make(Handle(), Call::address_of, {var}, Call::Intrinsic);
    }

    Expr module_state() {
        return state_var("hexagon_module_state", type_of<void*>());
    }

    Expr module_state_ptr() {
        return state_var_ptr("hexagon_module_state", type_of<void*>());
    }

    // Create a Buffer containing the given buffer/size, and return an
    // expression for a pointer to the first element.
    Expr buffer_ptr(const uint8_t* buffer, size_t size, const char* name) {
        Buffer code(type_of<uint8_t>(), {(int)size}, nullptr, name);
        memcpy(code.host_ptr(), buffer, (int)size);

        Expr ptr_0 = Load::make(type_of<uint8_t>(), name, 0, code, Parameter());
        return Call::make(Handle(), Call::address_of, {ptr_0}, Call::Intrinsic);
    }

    Stmt call_extern_and_assert(const std::string& name, const std::vector<Expr>& args) {
        Expr call = Call::make(Int(32), name, args, Call::Extern);
        string call_result_name = unique_name(name + "_result");
        Expr call_result_var = Variable::make(Int(32), call_result_name);
        return LetStmt::make(call_result_name, call,
                             AssertStmt::make(EQ::make(call_result_var, 0), call_result_var));
    }

public:
    InjectHexagonRpc(const Target &target) : device_code("hexagon", target) {}

    void visit(const For *loop) {
        if (loop->device_api == DeviceAPI::Hexagon) {
            // Unrolling or loop partitioning might generate multiple
            // loops with the same name, so we need to unique them.
            std::string hex_name = "hex_" + loop->name;

            Stmt body = remove_trivial_for_loops(loop, true /*device_loops*/);

            // Build a closure for the device code.
            // TODO: Should this move the body of the loop to Hexagon,
            // or the loop itself? Currently, this moves the loop itself.
            Closure c(body);

            // Make an argument list, and generate a function in the
            // device_code module. The hexagon runtime code expects
            // the arguments to appear in the order of (input buffers,
            // output buffers, input scalars).  There's a huge hack
            // here, in that the scalars must be last for the scalar
            // arguments to shadow the symbols of the buffer.
            std::vector<LoweredArgument> args;
            for (const auto& i : c.buffers) {
                if (!i.second.write) {
                    Argument::Kind kind = Argument::InputBuffer;
                    args.push_back(LoweredArgument(i.first, kind, i.second.type, i.second.dimensions));
                }
            }
            for (const auto& i : c.buffers) {
                if (i.second.write) {
                    Argument::Kind kind = Argument::OutputBuffer;
                    args.push_back(LoweredArgument(i.first, kind, i.second.type, i.second.dimensions));
                }
            }
            for (const auto& i : c.vars) {
                LoweredArgument arg(i.first, Argument::InputScalar, i.second, 0);
                if (alignment_info.contains(i.first)) {
                    arg.alignment = alignment_info.get(i.first);
                }
                args.push_back(arg);
            }
            device_code.append(LoweredFunc(hex_name, args, body, LoweredFunc::External));

            // Generate a call to hexagon_device_run.
            std::vector<Expr> arg_sizes;
            std::vector<Expr> arg_ptrs;
            std::vector<Expr> arg_flags;

            for (const auto& i : c.buffers) {
                arg_sizes.push_back(Expr((size_t)sizeof(buffer_t*)));
                arg_ptrs.push_back(Variable::make(type_of<buffer_t *>(), i.first + ".buffer"));
                int flags = 0;
                if (i.second.read) flags |= 0x1;
                if (i.second.write) flags |= 0x2;
                arg_flags.push_back(flags);
            }
            for (const auto& i : c.vars) {
                Expr arg = Variable::make(i.second, i.first);
                Expr arg_ptr = Call::make(type_of<void *>(), Call::make_struct, {arg}, Call::Intrinsic);

                arg_sizes.push_back(Expr((size_t)i.second.bytes()));
                arg_ptrs.push_back(arg_ptr);
                arg_flags.push_back(0x0);
            }

            // The argument list is terminated with an argument of size 0.
            arg_sizes.push_back(Expr((size_t)0));

            std::string pipeline_name = hex_name + "_argv";
            std::vector<Expr> params;
            params.push_back(module_state());
            params.push_back(pipeline_name);
            params.push_back(state_var_ptr(hex_name, type_of<int>()));
            params.push_back(Call::make(type_of<size_t*>(), Call::make_struct, arg_sizes, Call::Intrinsic));
            params.push_back(Call::make(type_of<void**>(), Call::make_struct, arg_ptrs, Call::Intrinsic));
            params.push_back(Call::make(type_of<int*>(), Call::make_struct, arg_flags, Call::Intrinsic));

            stmt = call_extern_and_assert("halide_hexagon_run", params);

        } else {
            IRMutator::visit(loop);
        }
    }

    void visit(const Let *op) {
        if (op->value.type() == Int(32)) {
            alignment_info.push(op->name, modulus_remainder(op->value, alignment_info));
        }

        IRMutator::visit(op);

        if (op->value.type() == Int(32)) {
            alignment_info.pop(op->name);
        }
    }

    void visit(const LetStmt *op) {
        if (op->value.type() == Int(32)) {
            alignment_info.push(op->name, modulus_remainder(op->value, alignment_info));
        }

        IRMutator::visit(op);

        if (op->value.type() == Int(32)) {
            alignment_info.pop(op->name);
        }
    }

    Stmt inject(Stmt s) {
        s = mutate(s);

        // Skip if there are no device kernels.
        if (device_code.functions.empty()) {
            return s;
        }

        // Compile the device code.
        std::vector<uint8_t> object;
#if 0
        compile_module_to_shared_object(device_code, object);
        //compile_module_to_shared_object(device_code, "/tmp/hex.so");
#else
        debug(1) << "Hexagon device code module: " << device_code << "\n";
        compile_module_to_llvm_bitcode(device_code, "hex.bc");
        int result = system("${HEX_TOOLS}/bin/hexagon-clang hex.bc -fPIC -O3 -Wno-override-module -shared -o hex.so");
        internal_assert(result == 0) << "hexagon-clang failed\n";

        std::ifstream so("hex.so", std::ios::binary | std::ios::ate);
        object.resize(so.tellg());
        so.seekg(0, std::ios::beg);
        so.read(reinterpret_cast<char*>(&object[0]), object.size());
#endif

        // Put the compiled object into a buffer.
        size_t code_size = object.size();
        Expr code_ptr = buffer_ptr(&object[0], code_size, "hexagon_code");

        // Wrap the statement in calls to halide_initialize_kernels.
        Stmt init_kernels = call_extern_and_assert("halide_hexagon_initialize_kernels",
                                                   {module_state_ptr(), code_ptr, Expr(code_size)});
        s = Block::make(init_kernels, s);

        return s;
    }
};

}

Stmt inject_hexagon_rpc(Stmt s, const Target &host_target) {
    Target target = hexagon_remote_target;
    for (Target::Feature i : {Target::Debug, Target::HVX_64, Target::HVX_128}) {
        if (host_target.has_feature(i)) {
            target = target.with_feature(i);
        }
    }
    InjectHexagonRpc injector(target);
    s = injector.inject(s);
    return s;
}

}  // namespace Internal
}  // namespace Halide
<commit_msg>Replace params of offloaded code with aligned params.<commit_after>#include "HexagonOffload.h"
#include "IRMutator.h"
#include "Substitute.h"
#include "Closure.h"
#include "Param.h"
#include "Image.h"
#include "Output.h"
#include "LLVM_Headers.h"
#include "RemoveTrivialForLoops.h"

#include <iostream>
#include <fstream>

namespace Halide {
namespace Internal {

using std::string;
using std::vector;

namespace {

Target hexagon_remote_target(Target::NoOS, Target::Hexagon, 32);

// Replace the parameter objects of loads/stores witha new parameter
// object.
class ReplaceParams : public IRMutator {
    const std::map<std::string, Parameter> &replacements;

    using IRMutator::visit;

    void visit(const Load *op) {
        auto i = replacements.find(op->name);
        if (i != replacements.end()) {
            expr = Load::make(op->type, op->name, mutate(op->index), op->image, i->second);
        } else {
            IRMutator::visit(op);
        }
    }

    void visit(const Store *op) {
        auto i = replacements.find(op->name);
        if (i != replacements.end()) {
            stmt = Store::make(op->name, mutate(op->value), mutate(op->index), i->second);
        } else {
            IRMutator::visit(op);
        }
    }

public:
    ReplaceParams(const std::map<std::string, Parameter> &replacements)
        : replacements(replacements) {}
};

Stmt replace_params(Stmt s, const std::map<std::string, Parameter> &replacements) {
    return ReplaceParams(replacements).mutate(s);
}

class InjectHexagonRpc : public IRMutator {
    std::map<std::string, Expr> state_vars;

    Module device_code;

    /** Alignment info for Int(32) variables in scope, so we don't
     * lose the information when creating Hexagon kernels. */
    Scope<ModulusRemainder> alignment_info;

    Expr state_var(const std::string& name, Type type) {
        Expr& var = state_vars[name];
        if (!var.defined()) {
            Buffer storage(type, {}, nullptr, name + "_buf");
            *(void **)storage.host_ptr() = nullptr;
            var = Load::make(type_of<void*>(), name + "_buf", 0, storage, Parameter());
        }
        return var;
    }

    Expr state_var_ptr(const std::string& name, Type type) {
        Expr var = state_var(name, type);
        return Call::make(Handle(), Call::address_of, {var}, Call::Intrinsic);
    }

    Expr module_state() {
        return state_var("hexagon_module_state", type_of<void*>());
    }

    Expr module_state_ptr() {
        return state_var_ptr("hexagon_module_state", type_of<void*>());
    }

    // Create a Buffer containing the given buffer/size, and return an
    // expression for a pointer to the first element.
    Expr buffer_ptr(const uint8_t* buffer, size_t size, const char* name) {
        Buffer code(type_of<uint8_t>(), {(int)size}, nullptr, name);
        memcpy(code.host_ptr(), buffer, (int)size);

        Expr ptr_0 = Load::make(type_of<uint8_t>(), name, 0, code, Parameter());
        return Call::make(Handle(), Call::address_of, {ptr_0}, Call::Intrinsic);
    }

    Stmt call_extern_and_assert(const std::string& name, const std::vector<Expr>& args) {
        Expr call = Call::make(Int(32), name, args, Call::Extern);
        string call_result_name = unique_name(name + "_result");
        Expr call_result_var = Variable::make(Int(32), call_result_name);
        return LetStmt::make(call_result_name, call,
                             AssertStmt::make(EQ::make(call_result_var, 0), call_result_var));
    }

    using IRMutator::visit;

    void visit(const For *loop) {
        if (loop->device_api == DeviceAPI::Hexagon) {
            // Unrolling or loop partitioning might generate multiple
            // loops with the same name, so we need to unique them.
            std::string hex_name = "hex_" + loop->name;

            Stmt body = remove_trivial_for_loops(loop, true /*device_loops*/);

            // Build a closure for the device code.
            // TODO: Should this move the body of the loop to Hexagon,
            // or the loop itself? Currently, this moves the loop itself.
            Closure c(body);

            // Make an argument list, and generate a function in the
            // device_code module. The hexagon runtime code expects
            // the arguments to appear in the order of (input buffers,
            // output buffers, input scalars).  There's a huge hack
            // here, in that the scalars must be last for the scalar
            // arguments to shadow the symbols of the buffer.
            std::vector<LoweredArgument> input_buffers, output_buffers;
            std::map<std::string, Parameter> replacement_params;
            for (const auto& i : c.buffers) {
                if (i.second.write) {
                    Argument::Kind kind = Argument::OutputBuffer;
                    output_buffers.push_back(LoweredArgument(i.first, kind, i.second.type, i.second.dimensions));
                } else {
                    Argument::Kind kind = Argument::InputBuffer;
                    input_buffers.push_back(LoweredArgument(i.first, kind, i.second.type, i.second.dimensions));
                }

                // Build a parameter to replace.
                Parameter p(i.second.type, true, i.second.dimensions);
                // Assert that buffers are aligned to one HVX
                // vector. Generally, they should be page aligned ION
                // buffers, so this should be a reasonable
                // requirement.
                const int alignment = 128;
                p.set_host_alignment(alignment);
                // The other parameter constraints are already
                // accounted for by the closure grabbing those
                // arguments, so we only need to provide the host
                // alignment.
                replacement_params[i.first] = p;

                // Add an assert to the body that validates the
                // alignment of the buffer.
                if (!device_code.target().has_feature(Target::NoAsserts)) {
                    Expr host_ptr = reinterpret<uint64_t>(Variable::make(Handle(), i.first + ".host"));
                    Expr error = Call::make(Int(32), "halide_error_unaligned_host_ptr",
                                            {i.first, alignment}, Call::Extern);
                    body = Block::make(AssertStmt::make(host_ptr % alignment == 0, error), body);
                }
            }
            body = replace_params(body, replacement_params);

            std::vector<LoweredArgument> args;
            args.insert(args.end(), input_buffers.begin(), input_buffers.end());
            args.insert(args.end(), output_buffers.begin(), output_buffers.end());
            for (const auto& i : c.vars) {
                LoweredArgument arg(i.first, Argument::InputScalar, i.second, 0);
                if (alignment_info.contains(i.first)) {
                    arg.alignment = alignment_info.get(i.first);
                }
                args.push_back(arg);
            }
            device_code.append(LoweredFunc(hex_name, args, body, LoweredFunc::External));

            // Generate a call to hexagon_device_run.
            std::vector<Expr> arg_sizes;
            std::vector<Expr> arg_ptrs;
            std::vector<Expr> arg_flags;

            for (const auto& i : c.buffers) {
                arg_sizes.push_back(Expr((size_t)sizeof(buffer_t*)));
                arg_ptrs.push_back(Variable::make(type_of<buffer_t *>(), i.first + ".buffer"));
                int flags = 0;
                if (i.second.read) flags |= 0x1;
                if (i.second.write) flags |= 0x2;
                arg_flags.push_back(flags);
            }
            for (const auto& i : c.vars) {
                Expr arg = Variable::make(i.second, i.first);
                Expr arg_ptr = Call::make(type_of<void *>(), Call::make_struct, {arg}, Call::Intrinsic);

                arg_sizes.push_back(Expr((size_t)i.second.bytes()));
                arg_ptrs.push_back(arg_ptr);
                arg_flags.push_back(0x0);
            }

            // The argument list is terminated with an argument of size 0.
            arg_sizes.push_back(Expr((size_t)0));

            std::string pipeline_name = hex_name + "_argv";
            std::vector<Expr> params;
            params.push_back(module_state());
            params.push_back(pipeline_name);
            params.push_back(state_var_ptr(hex_name, type_of<int>()));
            params.push_back(Call::make(type_of<size_t*>(), Call::make_struct, arg_sizes, Call::Intrinsic));
            params.push_back(Call::make(type_of<void**>(), Call::make_struct, arg_ptrs, Call::Intrinsic));
            params.push_back(Call::make(type_of<int*>(), Call::make_struct, arg_flags, Call::Intrinsic));

            stmt = call_extern_and_assert("halide_hexagon_run", params);

        } else {
            IRMutator::visit(loop);
        }
    }

    void visit(const Let *op) {
        if (op->value.type() == Int(32)) {
            alignment_info.push(op->name, modulus_remainder(op->value, alignment_info));
        }

        IRMutator::visit(op);

        if (op->value.type() == Int(32)) {
            alignment_info.pop(op->name);
        }
    }

    void visit(const LetStmt *op) {
        if (op->value.type() == Int(32)) {
            alignment_info.push(op->name, modulus_remainder(op->value, alignment_info));
        }

        IRMutator::visit(op);

        if (op->value.type() == Int(32)) {
            alignment_info.pop(op->name);
        }
    }

public:
    InjectHexagonRpc(const Target &target) : device_code("hexagon", target) {}

    Stmt inject(Stmt s) {
        s = mutate(s);

        // Skip if there are no device kernels.
        if (device_code.functions.empty()) {
            return s;
        }

        // Compile the device code.
        std::vector<uint8_t> object;
#if 0
        compile_module_to_shared_object(device_code, object);
        //compile_module_to_shared_object(device_code, "/tmp/hex.so");
#else
        debug(1) << "Hexagon device code module: " << device_code << "\n";
        compile_module_to_llvm_bitcode(device_code, "hex.bc");
        int result = system("${HEX_TOOLS}/bin/hexagon-clang hex.bc -fPIC -O3 -Wno-override-module -shared -o hex.so");
        internal_assert(result == 0) << "hexagon-clang failed\n";

        std::ifstream so("hex.so", std::ios::binary | std::ios::ate);
        object.resize(so.tellg());
        so.seekg(0, std::ios::beg);
        so.read(reinterpret_cast<char*>(&object[0]), object.size());
#endif

        // Put the compiled object into a buffer.
        size_t code_size = object.size();
        Expr code_ptr = buffer_ptr(&object[0], code_size, "hexagon_code");

        // Wrap the statement in calls to halide_initialize_kernels.
        Stmt init_kernels = call_extern_and_assert("halide_hexagon_initialize_kernels",
                                                   {module_state_ptr(), code_ptr, Expr(code_size)});
        s = Block::make(init_kernels, s);

        return s;
    }
};

}

Stmt inject_hexagon_rpc(Stmt s, const Target &host_target) {
    Target target = hexagon_remote_target;
    for (Target::Feature i : {Target::Debug, Target::NoAsserts, Target::HVX_64, Target::HVX_128}) {
        if (host_target.has_feature(i)) {
            target = target.with_feature(i);
        }
    }
    InjectHexagonRpc injector(target);
    s = injector.inject(s);
    return s;
}

}  // namespace Internal
}  // namespace Halide
<|endoftext|>


<commit_before>// Copyright 2013 the V8 project authors. 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 Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <stdlib.h>

#include "v8.h"
#include "macro-assembler.h"
#include "arm/macro-assembler-arm.h"
#include "arm/simulator-arm.h"
#include "cctest.h"

using namespace v8::internal;

typedef void* (*F)(int x, int y, int p2, int p3, int p4);

#define __ masm->

static byte to_non_zero(int n) {
  return static_cast<unsigned>(n) % 255 + 1;
}

static bool all_zeroes(const byte* beg, const byte* end) {
  CHECK(beg);
  CHECK(beg <= end);
  while (beg < end) {
    if (*beg++ != 0)
      return false;
  }
  return true;
}

TEST(CopyBytes) {
  CcTest::InitializeVM();
  Isolate* isolate = Isolate::Current();
  HandleScope handles(isolate);

  const int data_size = 1 * KB;
  size_t act_size;

  // Allocate two blocks to copy data between.
  byte* src_buffer = static_cast<byte*>(OS::Allocate(data_size, &act_size, 0));
  CHECK(src_buffer);
  CHECK(act_size >= static_cast<size_t>(data_size));
  byte* dest_buffer = static_cast<byte*>(OS::Allocate(data_size, &act_size, 0));
  CHECK(dest_buffer);
  CHECK(act_size >= static_cast<size_t>(data_size));

  // Storage for R0 and R1.
  byte* r0_;
  byte* r1_;

  MacroAssembler assembler(isolate, NULL, 0);
  MacroAssembler* masm = &assembler;

  // Code to be generated: The stuff in CopyBytes followed by a store of R0 and
  // R1, respectively.
  __ CopyBytes(r0, r1, r2, r3);
  __ mov(r2, Operand(reinterpret_cast<int>(&r0_)));
  __ mov(r3, Operand(reinterpret_cast<int>(&r1_)));
  __ str(r0, MemOperand(r2));
  __ str(r1, MemOperand(r3));
  __ bx(lr);

  CodeDesc desc;
  masm->GetCode(&desc);
  Object* code = isolate->heap()->CreateCode(
      desc,
      Code::ComputeFlags(Code::STUB),
      Handle<Code>())->ToObjectChecked();
  CHECK(code->IsCode());

  F f = FUNCTION_CAST<F>(Code::cast(code)->entry());

  // Initialise source data with non-zero bytes.
  for (int i = 0; i < data_size; i++) {
    src_buffer[i] = to_non_zero(i);
  }

  const int fuzz = 11;

  for (int size = 0; size < 600; size++) {
    for (const byte* src = src_buffer; src < src_buffer + fuzz; src++) {
      for (byte* dest = dest_buffer; dest < dest_buffer + fuzz; dest++) {
        memset(dest_buffer, 0, data_size);
        CHECK(dest + size < dest_buffer + data_size);
        (void) CALL_GENERATED_CODE(f, reinterpret_cast<int>(src),
                                      reinterpret_cast<int>(dest), size, 0, 0);
        // R0 and R1 should point at the first byte after the copied data.
        CHECK_EQ(src + size, r0_);
        CHECK_EQ(dest + size, r1_);
        // Check that we haven't written outside the target area.
        CHECK(all_zeroes(dest_buffer, dest));
        CHECK(all_zeroes(dest + size, dest_buffer + data_size));
        // Check the target area.
        CHECK_EQ(0, memcmp(src, dest, size));
      }
    }
  }

  // Check that the source data hasn't been clobbered.
  for (int i = 0; i < data_size; i++) {
    CHECK(src_buffer[i] == to_non_zero(i));
  }
}

typedef int (*F0)();

TEST(LoadAndStoreWithRepresentation) {
  v8::internal::V8::Initialize(NULL);

  // Allocate an executable page of memory.
  size_t actual_size;
  byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
                                                 &actual_size,
                                                 true));
  CHECK(buffer);
  Isolate* isolate = CcTest::i_isolate();
  HandleScope handles(isolate);
  MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size));
  MacroAssembler* masm = &assembler;  // Create a pointer for the __ macro.
  masm->set_allow_stub_calls(false);
  __ sub(sp, sp, Operand(1 * kPointerSize));
  Label exit;

  // Test 1.
  __ mov(r0, Operand(1));  // Test number.
  __ mov(r1, Operand(0));
  __ str(r1, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(-1));
  __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::UInteger8());
  __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(255));
  __ cmp(r3, r2);
  __ b(ne, &exit);
  __ mov(r2, Operand(255));
  __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::UInteger8());
  __ cmp(r3, r2);
  __ b(ne, &exit);

  // Test 2.
  __ mov(r0, Operand(2));  // Test number.
  __ mov(r1, Operand(0));
  __ str(r1, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(-1));
  __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::Integer8());
  __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(255));
  __ cmp(r3, r2);
  __ b(ne, &exit);
  __ mov(r2, Operand(-1));
  __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::Integer8());
  __ cmp(r3, r2);
  __ b(ne, &exit);

  // Test 3.
  __ mov(r0, Operand(3));  // Test number.
  __ mov(r1, Operand(0));
  __ str(r1, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(-1));
  __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::UInteger16());
  __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(65535));
  __ cmp(r3, r2);
  __ b(ne, &exit);
  __ mov(r2, Operand(65535));
  __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::UInteger16());
  __ cmp(r3, r2);
  __ b(ne, &exit);

  // Test 4.
  __ mov(r0, Operand(4));  // Test number.
  __ mov(r1, Operand(0));
  __ str(r1, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(-1));
  __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::Integer16());
  __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(65535));
  __ cmp(r3, r2);
  __ b(ne, &exit);
  __ mov(r2, Operand(-1));
  __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::Integer16());
  __ cmp(r3, r2);
  __ b(ne, &exit);

  __ mov(r0, Operand(0));  // Success.
  __ bind(&exit);
  __ add(sp, sp, Operand(1 * kPointerSize));
  __ bx(lr);

  CodeDesc desc;
  masm->GetCode(&desc);
  // Call the function from C++.

  F0 f = FUNCTION_CAST<F0>(buffer);
  int32_t result = Simulator::current(Isolate::Current())->Call(
      FUNCTION_ADDR(f), 4, 0, 0, 0, 0);
  CHECK_EQ(0, result);
}

#undef __
<commit_msg>Fix ARM build<commit_after>// Copyright 2013 the V8 project authors. 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 Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <stdlib.h>

#include "v8.h"
#include "macro-assembler.h"
#include "arm/macro-assembler-arm.h"
#include "arm/simulator-arm.h"
#include "cctest.h"

using namespace v8::internal;

typedef void* (*F)(int x, int y, int p2, int p3, int p4);

#define __ masm->

static byte to_non_zero(int n) {
  return static_cast<unsigned>(n) % 255 + 1;
}

static bool all_zeroes(const byte* beg, const byte* end) {
  CHECK(beg);
  CHECK(beg <= end);
  while (beg < end) {
    if (*beg++ != 0)
      return false;
  }
  return true;
}

TEST(CopyBytes) {
  CcTest::InitializeVM();
  Isolate* isolate = Isolate::Current();
  HandleScope handles(isolate);

  const int data_size = 1 * KB;
  size_t act_size;

  // Allocate two blocks to copy data between.
  byte* src_buffer = static_cast<byte*>(OS::Allocate(data_size, &act_size, 0));
  CHECK(src_buffer);
  CHECK(act_size >= static_cast<size_t>(data_size));
  byte* dest_buffer = static_cast<byte*>(OS::Allocate(data_size, &act_size, 0));
  CHECK(dest_buffer);
  CHECK(act_size >= static_cast<size_t>(data_size));

  // Storage for R0 and R1.
  byte* r0_;
  byte* r1_;

  MacroAssembler assembler(isolate, NULL, 0);
  MacroAssembler* masm = &assembler;

  // Code to be generated: The stuff in CopyBytes followed by a store of R0 and
  // R1, respectively.
  __ CopyBytes(r0, r1, r2, r3);
  __ mov(r2, Operand(reinterpret_cast<int>(&r0_)));
  __ mov(r3, Operand(reinterpret_cast<int>(&r1_)));
  __ str(r0, MemOperand(r2));
  __ str(r1, MemOperand(r3));
  __ bx(lr);

  CodeDesc desc;
  masm->GetCode(&desc);
  Object* code = isolate->heap()->CreateCode(
      desc,
      Code::ComputeFlags(Code::STUB),
      Handle<Code>())->ToObjectChecked();
  CHECK(code->IsCode());

  F f = FUNCTION_CAST<F>(Code::cast(code)->entry());

  // Initialise source data with non-zero bytes.
  for (int i = 0; i < data_size; i++) {
    src_buffer[i] = to_non_zero(i);
  }

  const int fuzz = 11;

  for (int size = 0; size < 600; size++) {
    for (const byte* src = src_buffer; src < src_buffer + fuzz; src++) {
      for (byte* dest = dest_buffer; dest < dest_buffer + fuzz; dest++) {
        memset(dest_buffer, 0, data_size);
        CHECK(dest + size < dest_buffer + data_size);
        (void) CALL_GENERATED_CODE(f, reinterpret_cast<int>(src),
                                      reinterpret_cast<int>(dest), size, 0, 0);
        // R0 and R1 should point at the first byte after the copied data.
        CHECK_EQ(src + size, r0_);
        CHECK_EQ(dest + size, r1_);
        // Check that we haven't written outside the target area.
        CHECK(all_zeroes(dest_buffer, dest));
        CHECK(all_zeroes(dest + size, dest_buffer + data_size));
        // Check the target area.
        CHECK_EQ(0, memcmp(src, dest, size));
      }
    }
  }

  // Check that the source data hasn't been clobbered.
  for (int i = 0; i < data_size; i++) {
    CHECK(src_buffer[i] == to_non_zero(i));
  }
}

typedef int (*F0)();

TEST(LoadAndStoreWithRepresentation) {
  v8::internal::V8::Initialize(NULL);

  // Allocate an executable page of memory.
  size_t actual_size;
  byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
                                                 &actual_size,
                                                 true));
  CHECK(buffer);
  Isolate* isolate = CcTest::i_isolate();
  HandleScope handles(isolate);
  MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size));
  MacroAssembler* masm = &assembler;  // Create a pointer for the __ macro.
  masm->set_allow_stub_calls(false);
  __ sub(sp, sp, Operand(1 * kPointerSize));
  Label exit;

  // Test 1.
  __ mov(r0, Operand(1));  // Test number.
  __ mov(r1, Operand(0));
  __ str(r1, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(-1));
  __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::UInteger8());
  __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(255));
  __ cmp(r3, r2);
  __ b(ne, &exit);
  __ mov(r2, Operand(255));
  __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::UInteger8());
  __ cmp(r3, r2);
  __ b(ne, &exit);

  // Test 2.
  __ mov(r0, Operand(2));  // Test number.
  __ mov(r1, Operand(0));
  __ str(r1, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(-1));
  __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::Integer8());
  __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(255));
  __ cmp(r3, r2);
  __ b(ne, &exit);
  __ mov(r2, Operand(-1));
  __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::Integer8());
  __ cmp(r3, r2);
  __ b(ne, &exit);

  // Test 3.
  __ mov(r0, Operand(3));  // Test number.
  __ mov(r1, Operand(0));
  __ str(r1, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(-1));
  __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::UInteger16());
  __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(65535));
  __ cmp(r3, r2);
  __ b(ne, &exit);
  __ mov(r2, Operand(65535));
  __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::UInteger16());
  __ cmp(r3, r2);
  __ b(ne, &exit);

  // Test 4.
  __ mov(r0, Operand(4));  // Test number.
  __ mov(r1, Operand(0));
  __ str(r1, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(-1));
  __ Store(r2, MemOperand(sp, 0 * kPointerSize), Representation::Integer16());
  __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
  __ mov(r2, Operand(65535));
  __ cmp(r3, r2);
  __ b(ne, &exit);
  __ mov(r2, Operand(-1));
  __ Load(r3, MemOperand(sp, 0 * kPointerSize), Representation::Integer16());
  __ cmp(r3, r2);
  __ b(ne, &exit);

  __ mov(r0, Operand(0));  // Success.
  __ bind(&exit);
  __ add(sp, sp, Operand(1 * kPointerSize));
  __ bx(lr);

  CodeDesc desc;
  masm->GetCode(&desc);
  // Call the function from C++.

  F0 f = FUNCTION_CAST<F0>(buffer);
  intptr_t result = reinterpret_cast<intptr_t>(
      CALL_GENERATED_CODE(FUNCTION_ADDR(f), 4, 0, 0, 0, 0));

  CHECK_EQ(0, result);
}

#undef __
<|endoftext|>


<commit_before>
#include "xOpenCV.h"
#include "../QstView2D/QstView2D.h"
#undef  getT    /* 有冲突 */
#include "opencv2/opencv.hpp"
using namespace cv;

/* 全局绘制参数 */
static sint_t   s_posx;     /* 当前坐标 */
static sint_t   s_posy;     /* 当前坐标 */
static Scalar   s_color;    /* 绘制颜色 */
static sint_t   s_thick;    /* 绘制宽度 */
static sint_t   s_tline;    /* 线条类型 */

/*
---------------------------------------
    初始化参数
---------------------------------------
*/
static bool_t
qst_ocv_init (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    CR_NOUSE(parm);
    CR_NOUSE(argc);
    CR_NOUSE(argv);

    s_thick = 1;
    s_tline = 8;
    s_posx = s_posy = 0;
    s_color = Scalar(0, 0, 0, 255);
    return (TRUE);
}

/*
---------------------------------------
    设置颜色
---------------------------------------
*/
static bool_t
qst_ocv_color (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    uint_t  rr, gg, bb, aa;

    CR_NOUSE(parm);

    /* 参数解析 <Red> <Green> <Blue> [Alpha] */
    if (argc < 4)
        return (FALSE);
    rr = str2intxA(argv[1]);
    gg = str2intxA(argv[2]);
    bb = str2intxA(argv[3]);
    if (argc > 4)
        aa = str2intxA(argv[4]);
    else
        aa = 255;
    s_color = Scalar(bb, gg, rr, aa);
    return (TRUE);
}

/*
---------------------------------------
    设置宽度
---------------------------------------
*/
static bool_t
qst_ocv_width (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    CR_NOUSE(parm);

    /* 参数解析 <Width> */
    if (argc < 2)
        return (FALSE);
    s_thick = (sint_t)str2intxA(argv[1]);
    return (TRUE);
}

/*
---------------------------------------
    设置线型
---------------------------------------
*/
static bool_t
qst_ocv_tline (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    uint_t  type;

    CR_NOUSE(parm);

    /* 参数解析 <Type> */
    if (argc < 2)
        return (FALSE);
    type = str2intxA(argv[1]);  /* CV_AA = 16 */
    if (type != 8 && type != 4 && type != CV_AA)
        return (FALSE);
    s_tline = (sint_t)type;
    return (TRUE);
}

/*
---------------------------------------
    移动坐标
---------------------------------------
*/
static bool_t
qst_ocv_moveto (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    CR_NOUSE(parm);

    /* 参数解析 <X> <Y> */
    if (argc < 3)
        return (FALSE);
    s_posx = (sint_t)str2intxA(argv[1]);
    s_posy = (sint_t)str2intxA(argv[2]);
    return (TRUE);
}

/*
---------------------------------------
    移动坐标 (绘制)
---------------------------------------
*/
static bool_t
qst_ocv_lineto (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    sint_t  newx, newy;

    /* 参数解析 <X> <Y> */
    if (argc < 3)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    newx = (sint_t)str2intxA(argv[1]);
    newy = (sint_t)str2intxA(argv[2]);
    line(img, Point(s_posx, s_posy), Point(newx, newy),
                s_color, s_thick, s_tline);
    s_posx = newx;
    s_posy = newy;
    return (TRUE);
}

/*
---------------------------------------
    绘制线段
---------------------------------------
*/
static bool_t
qst_ocv_line (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    sint_t  sx, sy;
    sint_t  dx, dy;

    /* 参数解析 <X1> <Y1> <X2> <Y2> */
    if (argc < 5)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    sx = (sint_t)str2intxA(argv[1]);
    sy = (sint_t)str2intxA(argv[2]);
    dx = (sint_t)str2intxA(argv[3]);
    dy = (sint_t)str2intxA(argv[4]);
    line(img, Point(sx, sy), Point(dx, dy),
            s_color, s_thick, s_tline);
    return (TRUE);
}

/*
---------------------------------------
    绘制方框 (坐标)
---------------------------------------
*/
static bool_t
qst_ocv_rect_xy (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    sint_t  sx, sy;
    sint_t  dx, dy;

    /* 参数解析 <X1> <Y1> <X2> <Y2> */
    if (argc < 5)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    sx = (sint_t)str2intxA(argv[1]);
    sy = (sint_t)str2intxA(argv[2]);
    dx = (sint_t)str2intxA(argv[3]);
    dy = (sint_t)str2intxA(argv[4]);
    rectangle(img, Point(sx, sy), Point(dx, dy),
                s_color, s_thick, s_tline);
    return (TRUE);
}

/*
---------------------------------------
    绘制方框 (宽高)
---------------------------------------
*/
static bool_t
qst_ocv_rect_wh (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    sint_t  sx, sy;
    sint_t  ww, hh;

    /* 参数解析 <X> <Y> <Width> <Height> */
    if (argc < 5)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    sx = (sint_t)str2intxA(argv[1]);
    sy = (sint_t)str2intxA(argv[2]);
    ww = (sint_t)str2intxA(argv[3]);
    hh = (sint_t)str2intxA(argv[4]);
    rectangle(img, Point(sx, sy), Point(sx + ww - 1, sy + hh - 1),
                        s_color, s_thick, s_tline);
    return (TRUE);
}

/*
---------------------------------------
    绘制正圆
---------------------------------------
*/
static bool_t
qst_ocv_circle (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    sint_t  cx, cy, rr;

    /* 参数解析 <X> <Y> <Radius> */
    if (argc < 4)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    cx = (sint_t)str2intxA(argv[1]);
    cy = (sint_t)str2intxA(argv[2]);
    rr = (sint_t)str2intxA(argv[3]);
    circle(img, Point(cx, cy), rr, s_color, s_thick, s_tline);
    return (TRUE);
}

/*
---------------------------------------
    绘制椭圆 (圆弧)
---------------------------------------
*/
static bool_t
qst_ocv_ellipse_arc (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    fp64_t  angle;
    fp64_t  start;
    fp64_t  agend;
    sint_t  cx, cy;
    sint_t  ww, hh;

    /* 参数解析 <X> <Y> <Width> <Height> <Angle> <StartAngle> <EndAngle> */
    if (argc < 8)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    cx = (sint_t)str2intxA(argv[1]);
    cy = (sint_t)str2intxA(argv[2]);
    ww = (sint_t)str2intxA(argv[3]);
    hh = (sint_t)str2intxA(argv[4]);
    angle = str2fp64A(argv[5]);
    start = str2fp64A(argv[6]);
    agend = str2fp64A(argv[7]);
    ellipse(img, Point(cx, cy), Size(ww, hh), angle, start, agend,
                    s_color, s_thick, s_tline);
    return (TRUE);
}

/*
---------------------------------------
    绘制椭圆 (角度)
---------------------------------------
*/
static bool_t
qst_ocv_ellipse_agl (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    fp32_t  angle;
    sint_t  cx, cy;
    sint_t  ww, hh;

    /* 参数解析 <X> <Y> <Width> <Height> <Angle> */
    if (argc < 6)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    cx = (sint_t)str2intxA(argv[1]);
    cy = (sint_t)str2intxA(argv[2]);
    ww = (sint_t)str2intxA(argv[3]);
    hh = (sint_t)str2intxA(argv[4]);
    angle = str2fp32A(argv[5]);
    ellipse(img, RotatedRect(Point(cx, cy), Size(ww, hh), angle),
                    s_color, s_thick, s_tline);
    return (TRUE);
}

/*
---------------------------------------
    绘制文字 (只支持字母)
---------------------------------------
*/
static bool_t
qst_ocv_text (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    ansi_t* str;
    ansi_t* txt;
    sint_t  fface;
    fp64_t  scale;
    sint_t  sx, sy;

    /* 参数解析 <X> <Y> <FontFace> <FontScale> <EscText> */
    if (argc < 6)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);

    /* 必须使用转义字符串 */
    str = str_fmtA("\"%s\"", argv[5]);
    if (str == NULL)
        return (FALSE);
    txt = str_esc_dupU(str);
    mem_free(str);
    if (txt == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    /*  CV_FONT_HERSHEY_SIMPLEX         0
        CV_FONT_HERSHEY_PLAIN           1
        CV_FONT_HERSHEY_DUPLEX          2
        CV_FONT_HERSHEY_COMPLEX         3
        CV_FONT_HERSHEY_TRIPLEX         4
        CV_FONT_HERSHEY_COMPLEX_SMALL   5
        CV_FONT_HERSHEY_SCRIPT_SIMPLEX  6
        CV_FONT_HERSHEY_SCRIPT_COMPLEX  7
        CV_FONT_ITALIC                 +16 */
    sx = (sint_t)str2intxA(argv[1]);
    sy = (sint_t)str2intxA(argv[2]);
    fface = (sint_t)str2intxA(argv[3]);
    scale = str2fp64A(argv[4]);
    putText(img, txt, Point(sx, sy), fface, scale,
                s_color, s_thick, s_tline);
    mem_free(txt);
    return (TRUE);
}

/*
=======================================
    命令单元导出表
=======================================
*/
CR_API const sQST_CMD   qst_v2d_cmdz[] =
{
    { "ocv:init", qst_ocv_init },
    { "ocv:color", qst_ocv_color },
    { "ocv:width", qst_ocv_width },
    { "ocv:tline", qst_ocv_tline },
    { "ocv:moveto", qst_ocv_moveto },
    { "ocv:lineto", qst_ocv_lineto },
    { "ocv:line", qst_ocv_line },
    { "ocv:rect_xy", qst_ocv_rect_xy },
    { "ocv:rect_wh", qst_ocv_rect_wh },
    { "ocv:circle", qst_ocv_circle },
    { "ocv:ellipse_arc", qst_ocv_ellipse_arc },
    { "ocv:ellipse_agl", qst_ocv_ellipse_agl },
    { "ocv:text", qst_ocv_text },
    { NULL, NULL },
};
<commit_msg>OpenCV: 简化椭圆绘制命令名称<commit_after>
#include "xOpenCV.h"
#include "../QstView2D/QstView2D.h"
#undef  getT    /* 有冲突 */
#include "opencv2/opencv.hpp"
using namespace cv;

/* 全局绘制参数 */
static sint_t   s_posx;     /* 当前坐标 */
static sint_t   s_posy;     /* 当前坐标 */
static Scalar   s_color;    /* 绘制颜色 */
static sint_t   s_thick;    /* 绘制宽度 */
static sint_t   s_tline;    /* 线条类型 */

/*
---------------------------------------
    初始化参数
---------------------------------------
*/
static bool_t
qst_ocv_init (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    CR_NOUSE(parm);
    CR_NOUSE(argc);
    CR_NOUSE(argv);

    s_thick = 1;
    s_tline = 8;
    s_posx = s_posy = 0;
    s_color = Scalar(0, 0, 0, 255);
    return (TRUE);
}

/*
---------------------------------------
    设置颜色
---------------------------------------
*/
static bool_t
qst_ocv_color (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    uint_t  rr, gg, bb, aa;

    CR_NOUSE(parm);

    /* 参数解析 <Red> <Green> <Blue> [Alpha] */
    if (argc < 4)
        return (FALSE);
    rr = str2intxA(argv[1]);
    gg = str2intxA(argv[2]);
    bb = str2intxA(argv[3]);
    if (argc > 4)
        aa = str2intxA(argv[4]);
    else
        aa = 255;
    s_color = Scalar(bb, gg, rr, aa);
    return (TRUE);
}

/*
---------------------------------------
    设置宽度
---------------------------------------
*/
static bool_t
qst_ocv_width (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    CR_NOUSE(parm);

    /* 参数解析 <Width> */
    if (argc < 2)
        return (FALSE);
    s_thick = (sint_t)str2intxA(argv[1]);
    return (TRUE);
}

/*
---------------------------------------
    设置线型
---------------------------------------
*/
static bool_t
qst_ocv_tline (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    uint_t  type;

    CR_NOUSE(parm);

    /* 参数解析 <Type> */
    if (argc < 2)
        return (FALSE);
    type = str2intxA(argv[1]);  /* CV_AA = 16 */
    if (type != 8 && type != 4 && type != CV_AA)
        return (FALSE);
    s_tline = (sint_t)type;
    return (TRUE);
}

/*
---------------------------------------
    移动坐标
---------------------------------------
*/
static bool_t
qst_ocv_moveto (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    CR_NOUSE(parm);

    /* 参数解析 <X> <Y> */
    if (argc < 3)
        return (FALSE);
    s_posx = (sint_t)str2intxA(argv[1]);
    s_posy = (sint_t)str2intxA(argv[2]);
    return (TRUE);
}

/*
---------------------------------------
    移动坐标 (绘制)
---------------------------------------
*/
static bool_t
qst_ocv_lineto (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    sint_t  newx, newy;

    /* 参数解析 <X> <Y> */
    if (argc < 3)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    newx = (sint_t)str2intxA(argv[1]);
    newy = (sint_t)str2intxA(argv[2]);
    line(img, Point(s_posx, s_posy), Point(newx, newy),
                s_color, s_thick, s_tline);
    s_posx = newx;
    s_posy = newy;
    return (TRUE);
}

/*
---------------------------------------
    绘制线段
---------------------------------------
*/
static bool_t
qst_ocv_line (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    sint_t  sx, sy;
    sint_t  dx, dy;

    /* 参数解析 <X1> <Y1> <X2> <Y2> */
    if (argc < 5)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    sx = (sint_t)str2intxA(argv[1]);
    sy = (sint_t)str2intxA(argv[2]);
    dx = (sint_t)str2intxA(argv[3]);
    dy = (sint_t)str2intxA(argv[4]);
    line(img, Point(sx, sy), Point(dx, dy),
            s_color, s_thick, s_tline);
    return (TRUE);
}

/*
---------------------------------------
    绘制方框 (坐标)
---------------------------------------
*/
static bool_t
qst_ocv_rect_xy (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    sint_t  sx, sy;
    sint_t  dx, dy;

    /* 参数解析 <X1> <Y1> <X2> <Y2> */
    if (argc < 5)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    sx = (sint_t)str2intxA(argv[1]);
    sy = (sint_t)str2intxA(argv[2]);
    dx = (sint_t)str2intxA(argv[3]);
    dy = (sint_t)str2intxA(argv[4]);
    rectangle(img, Point(sx, sy), Point(dx, dy),
                s_color, s_thick, s_tline);
    return (TRUE);
}

/*
---------------------------------------
    绘制方框 (宽高)
---------------------------------------
*/
static bool_t
qst_ocv_rect_wh (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    sint_t  sx, sy;
    sint_t  ww, hh;

    /* 参数解析 <X> <Y> <Width> <Height> */
    if (argc < 5)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    sx = (sint_t)str2intxA(argv[1]);
    sy = (sint_t)str2intxA(argv[2]);
    ww = (sint_t)str2intxA(argv[3]);
    hh = (sint_t)str2intxA(argv[4]);
    rectangle(img, Point(sx, sy), Point(sx + ww - 1, sy + hh - 1),
                        s_color, s_thick, s_tline);
    return (TRUE);
}

/*
---------------------------------------
    绘制正圆
---------------------------------------
*/
static bool_t
qst_ocv_circle (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    sint_t  cx, cy, rr;

    /* 参数解析 <X> <Y> <Radius> */
    if (argc < 4)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    cx = (sint_t)str2intxA(argv[1]);
    cy = (sint_t)str2intxA(argv[2]);
    rr = (sint_t)str2intxA(argv[3]);
    circle(img, Point(cx, cy), rr, s_color, s_thick, s_tline);
    return (TRUE);
}

/*
---------------------------------------
    绘制椭圆 (圆弧)
---------------------------------------
*/
static bool_t
qst_ocv_ellps_arc (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    fp64_t  angle;
    fp64_t  start;
    fp64_t  agend;
    sint_t  cx, cy;
    sint_t  ww, hh;

    /* 参数解析 <X> <Y> <Width> <Height> <Angle> <StartAngle> <EndAngle> */
    if (argc < 8)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    cx = (sint_t)str2intxA(argv[1]);
    cy = (sint_t)str2intxA(argv[2]);
    ww = (sint_t)str2intxA(argv[3]);
    hh = (sint_t)str2intxA(argv[4]);
    angle = str2fp64A(argv[5]);
    start = str2fp64A(argv[6]);
    agend = str2fp64A(argv[7]);
    ellipse(img, Point(cx, cy), Size(ww, hh), angle, start, agend,
                    s_color, s_thick, s_tline);
    return (TRUE);
}

/*
---------------------------------------
    绘制椭圆 (角度)
---------------------------------------
*/
static bool_t
qst_ocv_ellps_agl (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    fp32_t  angle;
    sint_t  cx, cy;
    sint_t  ww, hh;

    /* 参数解析 <X> <Y> <Width> <Height> <Angle> */
    if (argc < 6)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    cx = (sint_t)str2intxA(argv[1]);
    cy = (sint_t)str2intxA(argv[2]);
    ww = (sint_t)str2intxA(argv[3]);
    hh = (sint_t)str2intxA(argv[4]);
    angle = str2fp32A(argv[5]);
    ellipse(img, RotatedRect(Point(cx, cy), Size(ww, hh), angle),
                    s_color, s_thick, s_tline);
    return (TRUE);
}

/*
---------------------------------------
    绘制文字 (只支持字母)
---------------------------------------
*/
static bool_t
qst_ocv_text (
  __CR_IN__ void_t*     parm,
  __CR_IN__ uint_t      argc,
  __CR_IN__ ansi_t**    argv
    )
{
    ansi_t* str;
    ansi_t* txt;
    sint_t  fface;
    fp64_t  scale;
    sint_t  sx, sy;

    /* 参数解析 <X> <Y> <FontFace> <FontScale> <EscText> */
    if (argc < 6)
        return (FALSE);

    sIMAGE*     draw;
    IplImage    image;

    draw = ((sQstView2D*)parm)->paint;
    if (draw == NULL)
        return (FALSE);

    /* 必须使用转义字符串 */
    str = str_fmtA("\"%s\"", argv[5]);
    if (str == NULL)
        return (FALSE);
    txt = str_esc_dupU(str);
    mem_free(str);
    if (txt == NULL)
        return (FALSE);
    ilab_img2ipl_set(&image, draw);

    Mat img(&image, false);

    /*  CV_FONT_HERSHEY_SIMPLEX         0
        CV_FONT_HERSHEY_PLAIN           1
        CV_FONT_HERSHEY_DUPLEX          2
        CV_FONT_HERSHEY_COMPLEX         3
        CV_FONT_HERSHEY_TRIPLEX         4
        CV_FONT_HERSHEY_COMPLEX_SMALL   5
        CV_FONT_HERSHEY_SCRIPT_SIMPLEX  6
        CV_FONT_HERSHEY_SCRIPT_COMPLEX  7
        CV_FONT_ITALIC                 +16 */
    sx = (sint_t)str2intxA(argv[1]);
    sy = (sint_t)str2intxA(argv[2]);
    fface = (sint_t)str2intxA(argv[3]);
    scale = str2fp64A(argv[4]);
    putText(img, txt, Point(sx, sy), fface, scale,
                s_color, s_thick, s_tline);
    mem_free(txt);
    return (TRUE);
}

/*
=======================================
    命令单元导出表
=======================================
*/
CR_API const sQST_CMD   qst_v2d_cmdz[] =
{
    { "ocv:init", qst_ocv_init },
    { "ocv:color", qst_ocv_color },
    { "ocv:width", qst_ocv_width },
    { "ocv:tline", qst_ocv_tline },
    { "ocv:moveto", qst_ocv_moveto },
    { "ocv:lineto", qst_ocv_lineto },
    { "ocv:line", qst_ocv_line },
    { "ocv:rect_xy", qst_ocv_rect_xy },
    { "ocv:rect_wh", qst_ocv_rect_wh },
    { "ocv:circle", qst_ocv_circle },
    { "ocv:ellps_arc", qst_ocv_ellps_arc },
    { "ocv:ellps_agl", qst_ocv_ellps_agl },
    { "ocv:text", qst_ocv_text },
    { NULL, NULL },
};
<|endoftext|>


<commit_before>#include "DateTime.h"
#include "ArraySort.h"
#include <iostream>
#include <string>
#include <list>
using namespace std;
using namespace NP_DATETIME;
using namespace NP_ARRAYSORT;

// .h

int main();
void sortDateTimesShow();
void sortDatesShow();
void sortDateTimesShow();

// .cpp

void sortDateTimesShow() {
	cout << "For our first act, we're going to sort some times in our very own DateTime class!" << endl;
	cout << "How many DateTimes would you like to sort? ";

	short items;

	cin >> items;
	if (items <= 1) {
		cout << "Well it wouldn't be much of a show if I didn't sort at least 2 things, right? We'll sort 2 things for now." << endl;
		items = 2;
	}
	else {
		cout << items << " DateTimes it is!" << endl;
	}

	cout << "Now if you could type these times in yourself..." << endl;

	Comparable ** timesToSort = nullptr;
	timesToSort = new Comparable * [items];

	for (short index = 0; index < items; index++)
		timesToSort[index] = nullptr;

	for (short tIndex = 0; tIndex < items; tIndex++) {
		cout << "DateTime " << tIndex + 1 << " [dd/mm/yyyy hh:mm:ss]: ";
		DateTime thisTime;
		Comparable * thisTimeComparable = &thisTime;
		cin >> thisTime;
		cout << "You entered: " << thisTime << endl;
		timesToSort[tIndex] = new DateTime(dynamic_cast<DateTime&>(*thisTimeComparable));
	}

	cout << "Awesome! Now that we have " << items << " different DateTimes, let me present them in the order you entered..." << endl << endl;

	printArray(cout, timesToSort, items);

	cout << endl << endl << " ... and that's all of them! Now abracadraba, quicksort away! Here's the sorted list!" << endl << endl;

	quickSort(timesToSort, 0, items - 1);
	// insertionSort(timesToSort, 0, items - 1);

	printArray(cout, timesToSort, items);
	cout << endl << endl;
}

int main()
{
	string name;
	cout << "Hello! Welcome the magic sorting show! Please enter your name: ";
	cin >> name;

	if (name.length() <= 1) {
		cout << "no name, huh? I'll just call you Bill!" << endl;
		name = "Bill";
	}
	else {
		cout << "Hello, " << name << "!" << endl;
	}

	cout << "We have quite a treat for you today! We're going to sort things for you in C++!" << endl;

	sortDateTimesShow();

	cout << "Thank you Seattle, you have been an amazing audience!" << endl;
	cout << "I have been your host, Norton Pengra and I will see you later!" << endl;

	char tmp;
	cin >> tmp;
}<commit_msg>clean up memory<commit_after>#include "DateTime.h"
#include "ArraySort.h"
#include <iostream>
#include <string>
#include <list>
using namespace std;
using namespace NP_DATETIME;
using namespace NP_ARRAYSORT;

// .h

int main();
void sortDateTimesShow();
void sortDatesShow();
void sortDateTimesShow();

// .cpp

void sortDateTimesShow() {
	cout << "For our first act, we're going to sort some times in our very own DateTime class!" << endl;
	cout << "How many DateTimes would you like to sort? ";

	short items;

	cin >> items;
	if (items <= 1) {
		cout << "Well it wouldn't be much of a show if I didn't sort at least 2 things, right? We'll sort 2 things for now." << endl;
		items = 2;
	}
	else {
		cout << items << " DateTimes it is!" << endl;
	}

	cout << "Now if you could type these times in yourself..." << endl;

	Comparable ** timesToSort = nullptr;
	timesToSort = new Comparable * [items];

	for (short index = 0; index < items; index++)
		timesToSort[index] = nullptr;

	for (short tIndex = 0; tIndex < items; tIndex++) {
		cout << "DateTime " << tIndex + 1 << " [dd/mm/yyyy hh:mm:ss]: ";
		DateTime thisTime;
		Comparable * thisTimeComparable = &thisTime;
		cin >> thisTime;
		cout << "You entered: " << thisTime << endl;
		timesToSort[tIndex] = new DateTime(dynamic_cast<DateTime&>(*thisTimeComparable));
	}

	cout << "Awesome! Now that we have " << items << " different DateTimes, let me present them in the order you entered..." << endl << endl;

	printArray(cout, timesToSort, items);

	cout << endl << endl << " ... and that's all of them! Now abracadraba, quicksort away! Here's the sorted list!" << endl << endl;

	quickSort(timesToSort, 0, items - 1);
	// insertionSort(timesToSort, 0, items - 1);

	printArray(cout, timesToSort, items);
	cout << endl << endl;

	// clean up memory
	delete[] timesToSort;
	timesToSort = nullptr;
}

int main()
{
	string name;
	cout << "Hello! Welcome the magic sorting show! Please enter your name: ";
	cin >> name;

	if (name.length() <= 1) {
		cout << "no name, huh? I'll just call you Bill!" << endl;
		name = "Bill";
	}
	else {
		cout << "Hello, " << name << "!" << endl;
	}

	cout << "We have quite a treat for you today! We're going to sort things for you in C++!" << endl;

	sortDateTimesShow();

	cout << "Thank you Seattle, you have been an amazing audience!" << endl;
	cout << "I have been your host, Norton Pengra and I will see you later!" << endl;

	char tmp;
	cin >> tmp;
}<|endoftext|>


<commit_before>#include "p3DFFT_to_iR.hpp"
#include "Morton_shuffler.hpp"
#include <iostream>

int myrank, nprocs;

const int iter0 = 138000;

int get_RMHD_names(
        int iteration,
        bool velocity,
        char **fname)
{
    if (velocity)
    {
        sprintf(fname[0], "K%.6dQNP002", iteration);
        sprintf(fname[1], "K%.6dQNP003", iteration);
    }
    else
    {
        sprintf(fname[0], "K%.6dQNP005", iteration);
        sprintf(fname[1], "K%.6dQNP006", iteration);
    }
    return EXIT_SUCCESS;
}

int main(int argc, char *argv[])
{
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

    const int n = 1364;
    const int N = 2048;
    int nfiles = nprocs % 64;
    int iteration;
    if (argc == 2)
    {
        iteration = atoi(argv[1]);
    }
    else
    {
        std::cerr <<
            "not enough (or too many) parameters.\naborting." <<
            std::endl;
        MPI_Finalize();
        return EXIT_SUCCESS;
    }
    p3DFFT_to_iR *r = new p3DFFT_to_iR(
            (n/2+1), n, n,
            N, N, N,
            2);
    Morton_shuffler *s = new Morton_shuffler(
            N, N, N, 2, nfiles);

    // initialize file names
    char *ifile[2];
    for (int i=0; i<2; i++)
        ifile[i] = (char*)malloc(sizeof(char)*100);

    // velocity
    get_RMHD_names(iteration, true, ifile);
    r->read(ifile);
    sprintf(ifile[0], "u_t%.3x", iteration - iter0);
    s->shuffle(r->r3, ifile[0]);
    // magnetic
    get_RMHD_names(iteration, false, ifile);
    r->read(ifile);
    sprintf(ifile[0], "b_t%.3x", iteration - iter0);
    s->shuffle(r->r3, ifile[0]);

    //free file names
    for (int i=0; i<2; i++)
        free(ifile[i]);

    delete s;
    delete r;

    // clean up
    fftwf_mpi_cleanup();
    MPI_Finalize();
    return EXIT_SUCCESS;
}

<commit_msg>fix nfiles computation<commit_after>#include "p3DFFT_to_iR.hpp"
#include "Morton_shuffler.hpp"
#include <iostream>

int myrank, nprocs;

const int iter0 = 138000;

int get_RMHD_names(
        int iteration,
        bool velocity,
        char **fname)
{
    if (velocity)
    {
        sprintf(fname[0], "K%.6dQNP002", iteration);
        sprintf(fname[1], "K%.6dQNP003", iteration);
    }
    else
    {
        sprintf(fname[0], "K%.6dQNP005", iteration);
        sprintf(fname[1], "K%.6dQNP006", iteration);
    }
    return EXIT_SUCCESS;
}

int main(int argc, char *argv[])
{
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

    const int n = 1364;
    const int N = 2048;
    int nfiles;
    if (nprocs % 64 == 0)
    {
        nfiles = 64;
    }
    else
    {
        nfiles = nprocs;
    }
    int iteration;
    if (argc == 2)
    {
        iteration = atoi(argv[1]);
    }
    else
    {
        std::cerr <<
            "not enough (or too many) parameters.\naborting." <<
            std::endl;
        MPI_Finalize();
        return EXIT_SUCCESS;
    }
    p3DFFT_to_iR *r = new p3DFFT_to_iR(
            (n/2+1), n, n,
            N, N, N,
            2);
    Morton_shuffler *s = new Morton_shuffler(
            N, N, N, 2, nfiles);

    // initialize file names
    char *ifile[2];
    for (int i=0; i<2; i++)
        ifile[i] = (char*)malloc(sizeof(char)*100);

    // velocity
    get_RMHD_names(iteration, true, ifile);
    r->read(ifile);
    sprintf(ifile[0], "u_t%.3x", iteration - iter0);
    s->shuffle(r->r3, ifile[0]);
    // magnetic
    get_RMHD_names(iteration, false, ifile);
    r->read(ifile);
    sprintf(ifile[0], "b_t%.3x", iteration - iter0);
    s->shuffle(r->r3, ifile[0]);

    //free file names
    for (int i=0; i<2; i++)
        free(ifile[i]);

    delete s;
    delete r;

    // clean up
    fftwf_mpi_cleanup();
    MPI_Finalize();
    return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>// --------------------------------------------------------
// Code generated by Papyrus C++
// --------------------------------------------------------

#define Annotator_AnnotatorLib_Object_BODY

/************************************************************
 Object class body
 ************************************************************/

// include associated header file
#include <algorithm>
#include <assert.h>
#include "AnnotatorLib/Object.h"
#include "AnnotatorLib/Annotation.h"

// Derived includes directives

namespace AnnotatorLib {

// static attributes (if any)

static long lastId = 10000;

/**
 *
 * @return id
 */
Object::Object() : id(genId()) { }

Object::Object(unsigned long id) : id(id) { }

unsigned long Object::genId() {
    lastId += 3;
    return lastId;
}

unsigned long Object::getId() const
{
    return id;
}

std::string Object::getName()
{
    return name;
}

void Object::setName(std::string name)
{
    this->name = name;
}

Class *Object::getClass() const
{
    return objectClass;
}

void Object::setClass(Class *c)
{
    this->objectClass = c;
}

std::vector<Attribute *> Object::getAttributes() const
{
    return attributes;
}

bool Object::addAttribute(Attribute *attribute)
{
    if (attribute != nullptr && std::find(attributes.begin(), attributes.end(), attribute) == attributes.end()) {
        attributes.push_back(attribute);
        return true;
    }
    return false;
}

bool Object::removeAttribute(Attribute *attribute)
{
    std::vector<Attribute *>::const_iterator position = std::find(attributes.begin(), attributes.end(), attribute);
    if (position != attributes.end()){
        attributes.erase(position);
        return true;
    }
    return false;
}

Annotation *Object::getFirstAnnotation() const
{
    if(annotations.size() == 0)
        return nullptr;
    return annotations[0]->getFirst();
}

Annotation *Object::getFirstAnnotation(Frame *frame) const
{
    Annotation *annotation = this->getFirstAnnotation();
    while(annotation != nullptr && !annotation->isLast()){

        if(annotation->getFrame()->getNumber() < frame->getNumber()){
            annotation = annotation->getNext();

        } else if (annotation->getFrame()->getNumber() == frame->getNumber()){
            return annotation;

        } else if (annotation->getFrame()->getNumber() > frame->getNumber()){
            if(annotation->isFirst())
                return nullptr;
            else
                return annotation->getPrevious();
        }
    }
    return nullptr;
}

std::vector<Annotation *> Object::getAnnotations() const
{
    return annotations;
}

bool Object::addAnnotation(Annotation *annotation)
{
    if (annotation != nullptr && std::find(annotations.begin(), annotations.end(), annotation) == annotations.end()) {
        annotations.push_back(annotation);
        annotation->setObject(this);
        return true;
    }
    return false;
}

bool Object::removeAnnotation(Annotation *annotation)
{
    std::vector<Annotation *>::const_iterator position = std::find(annotations.begin(), annotations.end(), annotation);
    if (position != annotations.end()){
        annotations.erase(position);
        return true;
    }
    return false;
}

std::vector<Frame *> Object::getFrames() const
{
    return frames;
}

bool Object::addFrame(Frame *frame)
{
    if (frame != nullptr && std::find(frames.begin(), frames.end(), frame) == frames.end()) {
        frames.push_back(frame);
        return true;
    }
    return false;
}

bool Object::removeFrame(Frame *frame)
{
    std::vector<Frame *>::const_iterator position = std::find(frames.begin(), frames.end(), frame);
    if (position != frames.end()){
        frames.erase(position);
        return true;
    }
    return false;
}

bool Object::appearsInFrame(Frame *frame) const
{
    if(annotations.size() > 0)
    {
        Annotation *annotation = annotations[0];
        Annotation *first = annotation->getFirst();
        assert(first);
        Annotation *last = annotation->getLast();
        assert(last);
        if(first->getFrame()->getNumber() <= frame->getNumber()
                && last->getFrame()->getNumber() >= frame->getNumber())
            return true;
        if(first->getFrame()->getNumber() <= frame->getNumber()
                && !last->isFinished())
            return true;
    }
    return false;
}

} // of namespace AnnotatorLib

/************************************************************
 End of Object class body
 ************************************************************/
<commit_msg>remove frame from Object if it doesn't contain any annotations<commit_after>// --------------------------------------------------------
// Code generated by Papyrus C++
// --------------------------------------------------------

#define Annotator_AnnotatorLib_Object_BODY

/************************************************************
 Object class body
 ************************************************************/

// include associated header file
#include <algorithm>
#include <assert.h>
#include "AnnotatorLib/Object.h"
#include "AnnotatorLib/Annotation.h"

// Derived includes directives

namespace AnnotatorLib {

// static attributes (if any)

static long lastId = 10000;

/**
 *
 * @return id
 */
Object::Object() : id(genId()) { }

Object::Object(unsigned long id) : id(id) { }

unsigned long Object::genId() {
    lastId += 3;
    return lastId;
}

unsigned long Object::getId() const
{
    return id;
}

std::string Object::getName()
{
    return name;
}

void Object::setName(std::string name)
{
    this->name = name;
}

Class *Object::getClass() const
{
    return objectClass;
}

void Object::setClass(Class *c)
{
    this->objectClass = c;
}

std::vector<Attribute *> Object::getAttributes() const
{
    return attributes;
}

bool Object::addAttribute(Attribute *attribute)
{
    if (attribute != nullptr && std::find(attributes.begin(), attributes.end(), attribute) == attributes.end()) {
        attributes.push_back(attribute);
        return true;
    }
    return false;
}

bool Object::removeAttribute(Attribute *attribute)
{
    std::vector<Attribute *>::const_iterator position = std::find(attributes.begin(), attributes.end(), attribute);
    if (position != attributes.end()){
        attributes.erase(position);
        return true;
    }
    return false;
}

Annotation *Object::getFirstAnnotation() const
{
    if(annotations.size() == 0)
        return nullptr;
    return annotations[0]->getFirst();
}

Annotation *Object::getFirstAnnotation(Frame *frame) const
{
    Annotation *annotation = this->getFirstAnnotation();
    while(annotation != nullptr && !annotation->isLast()){

        if(annotation->getFrame()->getFrameNumber() < frame->getFrameNumber()){
            annotation = annotation->getNext();

        } else if (annotation->getFrame()->getFrameNumber() == frame->getFrameNumber()){
            return annotation;

        } else if (annotation->getFrame()->getFrameNumber() > frame->getFrameNumber()){
            if(annotation->isFirst())
                return nullptr;
            else
                return annotation->getPrevious();
        }
    }
    return nullptr;
}

std::vector<Annotation *> Object::getAnnotations() const
{
    return annotations;
}

bool Object::addAnnotation(Annotation *annotation)
{
    if (annotation != nullptr && std::find(annotations.begin(), annotations.end(), annotation) == annotations.end()) {
        annotations.push_back(annotation);
        annotation->setObject(this);
        return true;
    }
    return false;
}

bool Object::removeAnnotation(Annotation *annotation)
{
    std::vector<Annotation *>::const_iterator position = std::find(annotations.begin(), annotations.end(), annotation);
    if (position != annotations.end()){
        Frame* frame = annotation->getFrame();
        if (frame) {
            frame->removeAnnotation(annotation);
            if (!frame->hasAnnotations()) this->removeFrame(frame);
        }
        annotations.erase(position);
        return true;
    }
    return false;
}

std::vector<Frame *> Object::getFrames() const
{
    return frames;
}

bool Object::addFrame(Frame *frame)
{
    if (frame != nullptr && std::find(frames.begin(), frames.end(), frame) == frames.end()) {
        frames.push_back(frame);
        return true;
    }
    return false;
}

bool Object::removeFrame(Frame *frame)
{
    std::vector<Frame *>::const_iterator position = std::find(frames.begin(), frames.end(), frame);
    if (position != frames.end()){
        frames.erase(position);
        return true;
    }
    return false;
}

bool Object::appearsInFrame(Frame *frame) const
{
    if(annotations.size() > 0)
    {
        Annotation *annotation = annotations[0];
        Annotation *first = annotation->getFirst();
        assert(first);
        Annotation *last = annotation->getLast();
        assert(last);
        if(first->getFrame()->getFrameNumber() <= frame->getFrameNumber()
                && last->getFrame()->getFrameNumber() >= frame->getFrameNumber())
            return true;
        if(first->getFrame()->getFrameNumber() <= frame->getFrameNumber()
                && !last->isFinished())
            return true;
    }
    return false;
}

} // of namespace AnnotatorLib

/************************************************************
 End of Object class body
 ************************************************************/
<|endoftext|>