<commit_before>/**
 * @file llnotificationsconsole.cpp
 * @brief Debugging console for unified notifications.
 *
 * $LicenseInfo:firstyear=2003&license=viewergpl$
 *
 * Copyright (c) 2003-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"
#include "llfloaternotificationsconsole.h"
#include "llnotifications.h"
#include "lluictrlfactory.h"
#include "llbutton.h"
#include "llscrolllistctrl.h"
#include "llscrolllistitem.h"
#include "llpanel.h"
#include "llcombobox.h"

const S32 NOTIFICATION_PANEL_HEADER_HEIGHT = 20;
const S32 HEADER_PADDING = 38;

class LLNotificationChannelPanel : public LLPanel
{
public:
	LLNotificationChannelPanel(const std::string& channel_name);
	BOOL postBuild();

private:
	bool update(const LLSD& payload, bool passed_filter);
	static void toggleClick(void* user_data);
	static void onClickNotification(void* user_data);
	static void onClickNotificationReject(void* user_data);
	LLNotificationChannelPtr mChannelPtr;
	LLNotificationChannelPtr mChannelRejectsPtr;
};

LLNotificationChannelPanel::LLNotificationChannelPanel(const std::string& channel_name)
	: LLPanel()
{
	mChannelPtr = LLNotifications::instance().getChannel(channel_name);
	mChannelRejectsPtr = LLNotificationChannelPtr(
		LLNotificationChannel::buildChannel(channel_name + "rejects", mChannelPtr->getParentChannelName(),
											!boost::bind(mChannelPtr->getFilter(), _1)));
	LLUICtrlFactory::instance().buildPanel(this, "panel_notifications_channel.xml");
}

BOOL LLNotificationChannelPanel::postBuild()
{
	LLButton* header_button = getChild<LLButton>("header");
	header_button->setLabel(mChannelPtr->getName());
	header_button->setClickedCallback(toggleClick, this);

	mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, true));
	mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false));

	LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list");
	scroll->setDoubleClickCallback(onClickNotification, this);
	scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
	scroll = getChild<LLScrollListCtrl>("notification_rejects_list");
	scroll->setDoubleClickCallback(onClickNotificationReject, this);
	scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
	return TRUE;
}

//static
void LLNotificationChannelPanel::toggleClick(void *user_data)
{
	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
	if (!self) return;

	LLButton* header_button = self->getChild<LLButton>("header");

	LLLayoutStack* stack = dynamic_cast<LLLayoutStack*>(self->getParent());
	if (stack)
	{
		stack->collapsePanel(self, header_button->getToggleState());
	}

	// turn off tab stop for collapsed panel
	self->getChild<LLScrollListCtrl>("notifications_list")->setTabStop(!header_button->getToggleState());
	self->getChild<LLScrollListCtrl>("notifications_list")->setVisible(!header_button->getToggleState());
	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setTabStop(!header_button->getToggleState());
	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setVisible(!header_button->getToggleState());
}

/*static*/
void LLNotificationChannelPanel::onClickNotification(void* user_data)
{
	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
	if (!self) return;
	void* data = self->getChild<LLScrollListCtrl>("notifications_list")->getFirstSelected()->getUserdata();
	if (data)
	{
		gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
	}
}

/*static*/
void LLNotificationChannelPanel::onClickNotificationReject(void* user_data)
{
	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
	if (!self) return;
	LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notification_rejects_list")->getFirstSelected();
	llassert(firstselected);
	if (firstselected)
	{
		void* data = firstselected->getUserdata();
		if (data)
		{
			gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
		}
	}
}

bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
{
	LLNotificationPtr notification = LLNotifications::instance().find(payload["id"].asUUID());
	if (notification)
	{
		LLSD row;
		row["columns"][0]["value"] = notification->getName();
		row["columns"][0]["column"] = "name";

		row["columns"][1]["value"] = notification->getMessage();
		row["columns"][1]["column"] = "content";

		row["columns"][2]["value"] = notification->getDate();
		row["columns"][2]["column"] = "date";
		row["columns"][2]["type"] = "date";

		LLScrollListItem* sli = passed_filter ?
			getChild<LLScrollListCtrl>("notifications_list")->addElement(row) :
			getChild<LLScrollListCtrl>("notification_rejects_list")->addElement(row);
		sli->setUserdata(&(*notification));
	}

	return false;
}

//
// LLFloaterNotificationConsole
//
LLFloaterNotificationConsole::LLFloaterNotificationConsole(const LLSD& key)
: LLFloater(key)
{
	mCommitCallbackRegistrar.add("ClickAdd",     boost::bind(&LLFloaterNotificationConsole::onClickAdd, this));

	//LLUICtrlFactory::instance().buildFloater(this, "floater_notifications_console.xml");
}

BOOL LLFloaterNotificationConsole::postBuild()
{
	// these are in the order of processing
	addChannel("Unexpired");
	addChannel("Ignore");
	addChannel("Visible", true);
	// all the ones below attach to the Visible channel
	addChannel("History");
	addChannel("Alerts");
	addChannel("AlertModal");
	addChannel("Group Notifications");
	addChannel("Notifications");
	addChannel("NotificationTips");

//	getChild<LLButton>("add_notification")->setClickedCallback(onClickAdd, this);

	LLComboBox* notifications = getChild<LLComboBox>("notification_types");
	LLNotifications::TemplateNames names = LLNotifications::instance().getTemplateNames();
	for (LLNotifications::TemplateNames::iterator template_it = names.begin();
		template_it != names.end();
		++template_it)
	{
		notifications->add(*template_it);
	}
	notifications->sortByName();

	return TRUE;
}

void LLFloaterNotificationConsole::addChannel(const std::string& name, bool open)
{
	LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels");
	LLNotificationChannelPanel* panelp = new LLNotificationChannelPanel(name);
	stack.addPanel(panelp, 0, NOTIFICATION_PANEL_HEADER_HEIGHT, TRUE, TRUE, LLLayoutStack::ANIMATE);

	LLButton& header_button = panelp->getChildRef<LLButton>("header");
	header_button.setToggleState(!open);
	stack.collapsePanel(panelp, !open);

	updateResizeLimits();
}

void LLFloaterNotificationConsole::removeChannel(const std::string& name)
{
	LLPanel* panelp = getChild<LLPanel>(name);
	getChildRef<LLLayoutStack>("notification_channels").removePanel(panelp);
	delete panelp;

	updateResizeLimits();
}

//static
void LLFloaterNotificationConsole::updateResizeLimits()
{
	const LLFloater::Params& floater_params = LLFloater::getDefaultParams();
	S32 floater_header_size = floater_params.header_height;

	LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels");
	setResizeLimits(getMinWidth(), floater_header_size + HEADER_PADDING + ((NOTIFICATION_PANEL_HEADER_HEIGHT + 3) * stack.getNumPanels()));
}

void LLFloaterNotificationConsole::onClickAdd()
{
	std::string message_name = getChild<LLComboBox>("notification_types")->getValue().asString();
	if (!message_name.empty())
	{
		LLNotifications::instance().add(message_name, LLSD(), LLSD());
	}
}

//=============== LLFloaterNotification ================

LLFloaterNotification::LLFloaterNotification(LLNotification* note)
:	LLFloater(LLSD()),
	mNote(note)
{
	LLUICtrlFactory::instance().buildFloater(this, "floater_notification.xml", NULL);
}

BOOL LLFloaterNotification::postBuild()
{
	setTitle(mNote->getName());
	getChild<LLUICtrl>("payload")->setValue(mNote->getMessage());

	LLComboBox* responses_combo = getChild<LLComboBox>("response");
	LLCtrlListInterface* response_list = responses_combo->getListInterface();
	LLNotificationFormPtr form(mNote->getForm());
	if(!form)
	{
		return TRUE;
	}

	responses_combo->setCommitCallback(onCommitResponse, this);

	LLSD form_sd = form->asLLSD();

	for (LLSD::array_const_iterator form_item = form_sd.beginArray(); form_item != form_sd.endArray(); ++form_item)
	{
		if ( (*form_item)["type"].asString() != "button") continue;
		std::string text = (*form_item)["text"].asString();
		response_list->addSimpleElement(text);
	}

	return TRUE;
}

void LLFloaterNotification::respond()
{
	LLComboBox* responses_combo = getChild<LLComboBox>("response");
	LLCtrlListInterface* response_list = responses_combo->getListInterface();
	const std::string& trigger = response_list->getSelectedValue().asString();
	//llinfos << trigger << llendl;

	LLSD response = mNote->getResponseTemplate();
	response[trigger] = true;
	mNote->respond(response);
}
<commit_msg>CID-146<commit_after>/**
 * @file llnotificationsconsole.cpp
 * @brief Debugging console for unified notifications.
 *
 * $LicenseInfo:firstyear=2003&license=viewergpl$
 *
 * Copyright (c) 2003-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"
#include "llfloaternotificationsconsole.h"
#include "llnotifications.h"
#include "lluictrlfactory.h"
#include "llbutton.h"
#include "llscrolllistctrl.h"
#include "llscrolllistitem.h"
#include "llpanel.h"
#include "llcombobox.h"

const S32 NOTIFICATION_PANEL_HEADER_HEIGHT = 20;
const S32 HEADER_PADDING = 38;

class LLNotificationChannelPanel : public LLPanel
{
public:
	LLNotificationChannelPanel(const std::string& channel_name);
	BOOL postBuild();

private:
	bool update(const LLSD& payload, bool passed_filter);
	static void toggleClick(void* user_data);
	static void onClickNotification(void* user_data);
	static void onClickNotificationReject(void* user_data);
	LLNotificationChannelPtr mChannelPtr;
	LLNotificationChannelPtr mChannelRejectsPtr;
};

LLNotificationChannelPanel::LLNotificationChannelPanel(const std::string& channel_name)
	: LLPanel()
{
	mChannelPtr = LLNotifications::instance().getChannel(channel_name);
	mChannelRejectsPtr = LLNotificationChannelPtr(
		LLNotificationChannel::buildChannel(channel_name + "rejects", mChannelPtr->getParentChannelName(),
											!boost::bind(mChannelPtr->getFilter(), _1)));
	LLUICtrlFactory::instance().buildPanel(this, "panel_notifications_channel.xml");
}

BOOL LLNotificationChannelPanel::postBuild()
{
	LLButton* header_button = getChild<LLButton>("header");
	header_button->setLabel(mChannelPtr->getName());
	header_button->setClickedCallback(toggleClick, this);

	mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, true));
	mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false));

	LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list");
	scroll->setDoubleClickCallback(onClickNotification, this);
	scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
	scroll = getChild<LLScrollListCtrl>("notification_rejects_list");
	scroll->setDoubleClickCallback(onClickNotificationReject, this);
	scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
	return TRUE;
}

//static
void LLNotificationChannelPanel::toggleClick(void *user_data)
{
	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
	if (!self) return;

	LLButton* header_button = self->getChild<LLButton>("header");

	LLLayoutStack* stack = dynamic_cast<LLLayoutStack*>(self->getParent());
	if (stack)
	{
		stack->collapsePanel(self, header_button->getToggleState());
	}

	// turn off tab stop for collapsed panel
	self->getChild<LLScrollListCtrl>("notifications_list")->setTabStop(!header_button->getToggleState());
	self->getChild<LLScrollListCtrl>("notifications_list")->setVisible(!header_button->getToggleState());
	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setTabStop(!header_button->getToggleState());
	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setVisible(!header_button->getToggleState());
}

/*static*/
void LLNotificationChannelPanel::onClickNotification(void* user_data)
{
	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
	if (!self) return;
	LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notifications_list")->getFirstSelected();
	llassert(firstselected);
	if (firstselected)
	{
		void* data = firstselected->getUserdata();
		if (data)
		{
			gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
		}
	}
}

/*static*/
void LLNotificationChannelPanel::onClickNotificationReject(void* user_data)
{
	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
	if (!self) return;
	LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notification_rejects_list")->getFirstSelected();
	llassert(firstselected);
	if (firstselected)
	{
		void* data = firstselected->getUserdata();
		if (data)
		{
			gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
		}
	}
}

bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
{
	LLNotificationPtr notification = LLNotifications::instance().find(payload["id"].asUUID());
	if (notification)
	{
		LLSD row;
		row["columns"][0]["value"] = notification->getName();
		row["columns"][0]["column"] = "name";

		row["columns"][1]["value"] = notification->getMessage();
		row["columns"][1]["column"] = "content";

		row["columns"][2]["value"] = notification->getDate();
		row["columns"][2]["column"] = "date";
		row["columns"][2]["type"] = "date";

		LLScrollListItem* sli = passed_filter ?
			getChild<LLScrollListCtrl>("notifications_list")->addElement(row) :
			getChild<LLScrollListCtrl>("notification_rejects_list")->addElement(row);
		sli->setUserdata(&(*notification));
	}

	return false;
}

//
// LLFloaterNotificationConsole
//
LLFloaterNotificationConsole::LLFloaterNotificationConsole(const LLSD& key)
: LLFloater(key)
{
	mCommitCallbackRegistrar.add("ClickAdd",     boost::bind(&LLFloaterNotificationConsole::onClickAdd, this));

	//LLUICtrlFactory::instance().buildFloater(this, "floater_notifications_console.xml");
}

BOOL LLFloaterNotificationConsole::postBuild()
{
	// these are in the order of processing
	addChannel("Unexpired");
	addChannel("Ignore");
	addChannel("Visible", true);
	// all the ones below attach to the Visible channel
	addChannel("History");
	addChannel("Alerts");
	addChannel("AlertModal");
	addChannel("Group Notifications");
	addChannel("Notifications");
	addChannel("NotificationTips");

//	getChild<LLButton>("add_notification")->setClickedCallback(onClickAdd, this);

	LLComboBox* notifications = getChild<LLComboBox>("notification_types");
	LLNotifications::TemplateNames names = LLNotifications::instance().getTemplateNames();
	for (LLNotifications::TemplateNames::iterator template_it = names.begin();
		template_it != names.end();
		++template_it)
	{
		notifications->add(*template_it);
	}
	notifications->sortByName();

	return TRUE;
}

void LLFloaterNotificationConsole::addChannel(const std::string& name, bool open)
{
	LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels");
	LLNotificationChannelPanel* panelp = new LLNotificationChannelPanel(name);
	stack.addPanel(panelp, 0, NOTIFICATION_PANEL_HEADER_HEIGHT, TRUE, TRUE, LLLayoutStack::ANIMATE);

	LLButton& header_button = panelp->getChildRef<LLButton>("header");
	header_button.setToggleState(!open);
	stack.collapsePanel(panelp, !open);

	updateResizeLimits();
}

void LLFloaterNotificationConsole::removeChannel(const std::string& name)
{
	LLPanel* panelp = getChild<LLPanel>(name);
	getChildRef<LLLayoutStack>("notification_channels").removePanel(panelp);
	delete panelp;

	updateResizeLimits();
}

//static
void LLFloaterNotificationConsole::updateResizeLimits()
{
	const LLFloater::Params& floater_params = LLFloater::getDefaultParams();
	S32 floater_header_size = floater_params.header_height;

	LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels");
	setResizeLimits(getMinWidth(), floater_header_size + HEADER_PADDING + ((NOTIFICATION_PANEL_HEADER_HEIGHT + 3) * stack.getNumPanels()));
}

void LLFloaterNotificationConsole::onClickAdd()
{
	std::string message_name = getChild<LLComboBox>("notification_types")->getValue().asString();
	if (!message_name.empty())
	{
		LLNotifications::instance().add(message_name, LLSD(), LLSD());
	}
}

//=============== LLFloaterNotification ================

LLFloaterNotification::LLFloaterNotification(LLNotification* note)
:	LLFloater(LLSD()),
	mNote(note)
{
	LLUICtrlFactory::instance().buildFloater(this, "floater_notification.xml", NULL);
}

BOOL LLFloaterNotification::postBuild()
{
	setTitle(mNote->getName());
	getChild<LLUICtrl>("payload")->setValue(mNote->getMessage());

	LLComboBox* responses_combo = getChild<LLComboBox>("response");
	LLCtrlListInterface* response_list = responses_combo->getListInterface();
	LLNotificationFormPtr form(mNote->getForm());
	if(!form)
	{
		return TRUE;
	}

	responses_combo->setCommitCallback(onCommitResponse, this);

	LLSD form_sd = form->asLLSD();

	for (LLSD::array_const_iterator form_item = form_sd.beginArray(); form_item != form_sd.endArray(); ++form_item)
	{
		if ( (*form_item)["type"].asString() != "button") continue;
		std::string text = (*form_item)["text"].asString();
		response_list->addSimpleElement(text);
	}

	return TRUE;
}

void LLFloaterNotification::respond()
{
	LLComboBox* responses_combo = getChild<LLComboBox>("response");
	LLCtrlListInterface* response_list = responses_combo->getListInterface();
	const std::string& trigger = response_list->getSelectedValue().asString();
	//llinfos << trigger << llendl;

	LLSD response = mNote->getResponseTemplate();
	response[trigger] = true;
	mNote->respond(response);
}
<|endoftext|>


<commit_before>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include "cling/Interpreter/CIFactory.h"

#include "DeclCollector.h"

#include "clang/AST/ASTContext.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Job.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Preprocessor.h"

#include "llvm/IR/LLVMContext.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"

#include <ctime>

using namespace clang;

namespace cling {
  //
  //  Dummy function so we can use dladdr to find the executable path.
  //
  void locate_cling_executable()
  {
  }

  /// \brief Retrieves the clang CC1 specific flags out of the compilation's
  /// jobs. Returns NULL on error.
  static const clang::driver::ArgStringList
  *GetCC1Arguments(clang::DiagnosticsEngine *Diagnostics,
                   clang::driver::Compilation *Compilation) {
    // We expect to get back exactly one Command job, if we didn't something
    // failed. Extract that job from the Compilation.
    const clang::driver::JobList &Jobs = Compilation->getJobs();
    if (!Jobs.size() || !isa<clang::driver::Command>(*Jobs.begin())) {
      // diagnose this...
      return NULL;
    }

    // The one job we find should be to invoke clang again.
    const clang::driver::Command *Cmd
      = cast<clang::driver::Command>(*Jobs.begin());
    if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
      // diagnose this...
      return NULL;
    }

    return &Cmd->getArguments();
  }

  CompilerInstance* CIFactory::createCI(llvm::StringRef code,
                                        int argc,
                                        const char* const *argv,
                                        const char* llvmdir) {
    return createCI(llvm::MemoryBuffer::getMemBuffer(code), argc, argv,
                    llvmdir);
  }

  CompilerInstance* CIFactory::createCI(llvm::MemoryBuffer* buffer,
                                        int argc,
                                        const char* const *argv,
                                        const char* llvmdir) {
    // Create an instance builder, passing the llvmdir and arguments.
    //
    //  Initialize the llvm library.
    llvm::InitializeNativeTarget();
    llvm::InitializeAllAsmPrinters();
    llvm::sys::Path resource_path;
    if (llvmdir) {
      resource_path = llvmdir;
      resource_path.appendComponent("lib");
      resource_path.appendComponent("clang");
      resource_path.appendComponent(CLANG_VERSION_STRING);
    } else {
      // FIXME: The first arg really does need to be argv[0] on FreeBSD.
      //
      // Note: The second arg is not used for Apple, FreeBSD, Linux,
      //       or cygwin, and can only be used on systems which support
      //       the use of dladdr().
      //
      // Note: On linux and cygwin this uses /proc/self/exe to find the path.
      //
      // Note: On Apple it uses _NSGetExecutablePath().
      //
      // Note: On FreeBSD it uses getprogpath().
      //
      // Note: Otherwise it uses dladdr().
      //
      resource_path
        = CompilerInvocation::GetResourcesPath("cling",
                                       (void*)(intptr_t) locate_cling_executable
                                               );
    }
    if (!resource_path.canRead()) {
      llvm::errs()
        << "ERROR in cling::CIFactory::createCI():\n  resource directory "
        << resource_path.str() << " not found!\n";
      resource_path = "";
    }

    //______________________________________
    DiagnosticOptions* DefaultDiagnosticOptions = new DiagnosticOptions();
    DefaultDiagnosticOptions->ShowColors = llvm::sys::Process::StandardErrHasColors() ? 1 : 0;
    TextDiagnosticPrinter* DiagnosticPrinter
      = new TextDiagnosticPrinter(llvm::errs(), DefaultDiagnosticOptions);
    llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(new DiagnosticIDs());
    DiagnosticsEngine* Diagnostics
      = new DiagnosticsEngine(DiagIDs, DefaultDiagnosticOptions,
                              DiagnosticPrinter, /*Owns it*/ true); // LEAKS!

    std::vector<const char*> argvCompile(argv, argv + argc);
    // We do C++ by default; append right after argv[0] name
    // Only insert it if there is no other "-x":
    bool haveMinusX = false;
    for (const char* const* iarg = argv; !haveMinusX && iarg < argv + argc;
         ++iarg) {
      haveMinusX = !strcmp(*iarg, "-x");
    }
    if (!haveMinusX) {
      argvCompile.insert(argvCompile.begin() + 1,"-x");
      argvCompile.insert(argvCompile.begin() + 2, "c++");
    }
    argvCompile.push_back("-c");
    argvCompile.push_back("-");

    clang::driver::Driver Driver(argv[0], llvm::sys::getDefaultTargetTriple(),
                                 "cling.out",
                                 *Diagnostics);
    //Driver.setWarnMissingInput(false);
    Driver.setCheckInputsExist(false); // think foo.C(12)
    llvm::ArrayRef<const char*>RF(&(argvCompile[0]), argvCompile.size());
    llvm::OwningPtr<clang::driver::Compilation>
      Compilation(Driver.BuildCompilation(RF));
    const clang::driver::ArgStringList* CC1Args
      = GetCC1Arguments(Diagnostics, Compilation.get());
    if (CC1Args == NULL) {
      return 0;
    }
    clang::CompilerInvocation*
      Invocation = new clang::CompilerInvocation;
    clang::CompilerInvocation::CreateFromArgs(*Invocation, CC1Args->data() + 1,
                                              CC1Args->data() + CC1Args->size(),
                                              *Diagnostics);
    Invocation->getFrontendOpts().DisableFree = true;

    if (Invocation->getHeaderSearchOpts().UseBuiltinIncludes &&
        !resource_path.empty()) {
      // Update ResourceDir
      // header search opts' entry for resource_path/include isn't
      // updated by providing a new resource path; update it manually.
      clang::HeaderSearchOptions& Opts = Invocation->getHeaderSearchOpts();
      llvm::sys::Path oldResInc(Opts.ResourceDir);
      oldResInc.appendComponent("include");
      llvm::sys::Path newResInc(resource_path);
      newResInc.appendComponent("include");
      bool foundOldResInc = false;
      for (unsigned i = 0, e = Opts.UserEntries.size();
           !foundOldResInc && i != e; ++i) {
        HeaderSearchOptions::Entry &E = Opts.UserEntries[i];
        if (!E.IsFramework && E.Group == clang::frontend::System
            && E.IgnoreSysRoot && oldResInc.str() == E.Path) {
          E.Path = newResInc.str();
          foundOldResInc = true;
        }
      }

      Opts.ResourceDir = resource_path.str();
    }

    // Create and setup a compiler instance.
    CompilerInstance* CI = new CompilerInstance();
    CI->setInvocation(Invocation);

    CI->createDiagnostics(DiagnosticPrinter, /*ShouldOwnClient=*/ false,
                          /*ShouldCloneClient=*/ false);
    {
      //
      //  Buffer the error messages while we process
      //  the compiler options.
      //

      // Set the language options, which cling needs
      SetClingCustomLangOpts(CI->getLangOpts());

      CI->getInvocation().getPreprocessorOpts().addMacroDef("__CLING__");
      if (CI->getLangOpts().CPlusPlus11 == 1) {
        // http://llvm.org/bugs/show_bug.cgi?id=13530
        CI->getInvocation().getPreprocessorOpts()
          .addMacroDef("__CLING__CXX11");
      }

      if (CI->getDiagnostics().hasErrorOccurred()) {
        delete CI;
        CI = 0;
        return 0;
      }
    }
    CI->setTarget(TargetInfo::CreateTargetInfo(CI->getDiagnostics(),
                                               &Invocation->getTargetOpts()));
    if (!CI->hasTarget()) {
      delete CI;
      CI = 0;
      return 0;
    }
    CI->getTarget().setForcedLangOptions(CI->getLangOpts());
    SetClingTargetLangOpts(CI->getLangOpts(), CI->getTarget());
    if (CI->getTarget().getTriple().getOS() == llvm::Triple::Cygwin) {
      // clang "forgets" the basic arch part needed by winnt.h:
      if (CI->getTarget().getTriple().getArch() == llvm::Triple::x86) {
        CI->getInvocation().getPreprocessorOpts().addMacroDef("_X86_=1");
      } else if (CI->getTarget().getTriple().getArch()
                 == llvm::Triple::x86_64) {
        CI->getInvocation().getPreprocessorOpts().addMacroDef("__x86_64=1");
      } else {
        llvm::errs() << "Warning: unhandled target architecture "
                     << CI->getTarget().getTriple().getArchName() << '\n';
      }
    }

    // Set up source and file managers
    CI->createFileManager();
    CI->createSourceManager(CI->getFileManager());

    // Set up the memory buffer
    if (buffer)
      CI->getSourceManager().createMainFileIDForMemBuffer(buffer);
    else {
      // As main file we want
      // * a virtual file that is claiming to be huge
      // * with an empty memory buffer attached (to bring the content)
      SourceManager& SM = CI->getSourceManager();
      FileManager& FM = SM.getFileManager();
      // Build the virtual file
      const char* Filename = "InteractiveInputLineIncluder.h";
      const std::string& CGOptsMainFileName
        = CI->getInvocation().getCodeGenOpts().MainFileName;
      if (!CGOptsMainFileName.empty())
        Filename = CGOptsMainFileName.c_str();
      const FileEntry* FE
        = FM.getVirtualFile(Filename, 1U << 15U, time(0));
      FileID MainFileID = SM.createMainFileID(FE, SrcMgr::C_User);
      const SrcMgr::SLocEntry& MainFileSLocE = SM.getSLocEntry(MainFileID);
      const SrcMgr::ContentCache* MainFileCC
        = MainFileSLocE.getFile().getContentCache();
      llvm::MemoryBuffer* MainFileMB
        = llvm::MemoryBuffer::getMemBuffer("/*CLING MAIN FILE*/\n");
      const_cast<SrcMgr::ContentCache*>(MainFileCC)->setBuffer(MainFileMB);
    }

    // Set up the preprocessor
    CI->createPreprocessor();
    Preprocessor& PP = CI->getPreprocessor();
    PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                           PP.getLangOpts());

    // Set up the ASTContext
    ASTContext *Ctx = new ASTContext(CI->getLangOpts(),
                                     PP.getSourceManager(), &CI->getTarget(),
                                     PP.getIdentifierTable(),
                                     PP.getSelectorTable(), PP.getBuiltinInfo(),
                                     /*size_reserve*/0, /*DelayInit*/false);
    CI->setASTContext(Ctx);

    // Set up the ASTConsumers
    CI->setASTConsumer(new DeclCollector());

    // Set up Sema
    CodeCompleteConsumer* CCC = 0;
    CI->createSema(TU_Complete, CCC);

    // Set CodeGen options
    // CI->getCodeGenOpts().DebugInfo = 1; // want debug info
    // CI->getCodeGenOpts().EmitDeclMetadata = 1; // For unloading, for later
    CI->getCodeGenOpts().OptimizationLevel = 0; // see pure SSA, that comes out
    CI->getCodeGenOpts().CXXCtorDtorAliases = 0; // aliasing the complete
                                                 // ctor to the base ctor causes
                                                 // the JIT to crash
    // When asserts are on, TURN ON not compare the VerifyModule
    assert(CI->getCodeGenOpts().VerifyModule = 1);

    return CI;
  }

  void CIFactory::SetClingCustomLangOpts(LangOptions& Opts) {
    Opts.EmitAllDecls = 0;
    Opts.Exceptions = 1;
    Opts.CXXExceptions = 1;
    Opts.Deprecated = 1;
    //Opts.Modules = 1;

    // C++11 is turned on if cling is built with C++11: it's an interperter;
    // cross-language compilation doesn't make sense.
    // Extracted from Boost/config/compiler.
    // SunProCC has no C++11.
    // VisualC's support is not obvious to extract from Boost...
#if /*GCC*/ (defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__))   \
  || /*clang*/ (defined(__has_feature) && __has_feature(cxx_decltype))   \
  || /*ICC*/ ((!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && defined(__INTEL_COMPILER) && (__STDC_HOSTED__ && (__INTEL_COMPILER <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__))
    Opts.CPlusPlus11 = 1;
#endif

  }

  void CIFactory::SetClingTargetLangOpts(LangOptions& Opts,
                                         const TargetInfo& Target) {
    if (Target.getTriple().getOS() == llvm::Triple::Win32) {
      Opts.MicrosoftExt = 1;
      Opts.MSCVersion = 1300;
      // Should fix http://llvm.org/bugs/show_bug.cgi?id=10528
      Opts.DelayedTemplateParsing = 1;
    } else {
      Opts.MicrosoftExt = 0;
    }
  }
} // end namespace
<commit_msg>Add clarification comment.<commit_after>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include "cling/Interpreter/CIFactory.h"

#include "DeclCollector.h"

#include "clang/AST/ASTContext.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Job.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Preprocessor.h"

#include "llvm/IR/LLVMContext.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"

#include <ctime>

using namespace clang;

namespace cling {
  //
  //  Dummy function so we can use dladdr to find the executable path.
  //
  void locate_cling_executable()
  {
  }

  /// \brief Retrieves the clang CC1 specific flags out of the compilation's
  /// jobs. Returns NULL on error.
  static const clang::driver::ArgStringList
  *GetCC1Arguments(clang::DiagnosticsEngine *Diagnostics,
                   clang::driver::Compilation *Compilation) {
    // We expect to get back exactly one Command job, if we didn't something
    // failed. Extract that job from the Compilation.
    const clang::driver::JobList &Jobs = Compilation->getJobs();
    if (!Jobs.size() || !isa<clang::driver::Command>(*Jobs.begin())) {
      // diagnose this...
      return NULL;
    }

    // The one job we find should be to invoke clang again.
    const clang::driver::Command *Cmd
      = cast<clang::driver::Command>(*Jobs.begin());
    if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
      // diagnose this...
      return NULL;
    }

    return &Cmd->getArguments();
  }

  CompilerInstance* CIFactory::createCI(llvm::StringRef code,
                                        int argc,
                                        const char* const *argv,
                                        const char* llvmdir) {
    return createCI(llvm::MemoryBuffer::getMemBuffer(code), argc, argv,
                    llvmdir);
  }

  CompilerInstance* CIFactory::createCI(llvm::MemoryBuffer* buffer,
                                        int argc,
                                        const char* const *argv,
                                        const char* llvmdir) {
    // Create an instance builder, passing the llvmdir and arguments.
    //
    //  Initialize the llvm library.
    llvm::InitializeNativeTarget();
    llvm::InitializeAllAsmPrinters();
    llvm::sys::Path resource_path;
    if (llvmdir) {
      resource_path = llvmdir;
      resource_path.appendComponent("lib");
      resource_path.appendComponent("clang");
      resource_path.appendComponent(CLANG_VERSION_STRING);
    } else {
      // FIXME: The first arg really does need to be argv[0] on FreeBSD.
      //
      // Note: The second arg is not used for Apple, FreeBSD, Linux,
      //       or cygwin, and can only be used on systems which support
      //       the use of dladdr().
      //
      // Note: On linux and cygwin this uses /proc/self/exe to find the path.
      //
      // Note: On Apple it uses _NSGetExecutablePath().
      //
      // Note: On FreeBSD it uses getprogpath().
      //
      // Note: Otherwise it uses dladdr().
      //
      resource_path
        = CompilerInvocation::GetResourcesPath("cling",
                                       (void*)(intptr_t) locate_cling_executable
                                               );
    }
    if (!resource_path.canRead()) {
      llvm::errs()
        << "ERROR in cling::CIFactory::createCI():\n  resource directory "
        << resource_path.str() << " not found!\n";
      resource_path = "";
    }

    //______________________________________
    DiagnosticOptions* DefaultDiagnosticOptions = new DiagnosticOptions();
    DefaultDiagnosticOptions->ShowColors = llvm::sys::Process::StandardErrHasColors() ? 1 : 0;
    TextDiagnosticPrinter* DiagnosticPrinter
      = new TextDiagnosticPrinter(llvm::errs(), DefaultDiagnosticOptions);
    llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(new DiagnosticIDs());
    DiagnosticsEngine* Diagnostics
      = new DiagnosticsEngine(DiagIDs, DefaultDiagnosticOptions,
                              DiagnosticPrinter, /*Owns it*/ true); // LEAKS!

    std::vector<const char*> argvCompile(argv, argv + argc);
    // We do C++ by default; append right after argv[0] name
    // Only insert it if there is no other "-x":
    bool haveMinusX = false;
    for (const char* const* iarg = argv; !haveMinusX && iarg < argv + argc;
         ++iarg) {
      haveMinusX = !strcmp(*iarg, "-x");
    }
    if (!haveMinusX) {
      argvCompile.insert(argvCompile.begin() + 1,"-x");
      argvCompile.insert(argvCompile.begin() + 2, "c++");
    }
    argvCompile.push_back("-c");
    argvCompile.push_back("-");

    clang::driver::Driver Driver(argv[0], llvm::sys::getDefaultTargetTriple(),
                                 "cling.out",
                                 *Diagnostics);
    //Driver.setWarnMissingInput(false);
    Driver.setCheckInputsExist(false); // think foo.C(12)
    llvm::ArrayRef<const char*>RF(&(argvCompile[0]), argvCompile.size());
    llvm::OwningPtr<clang::driver::Compilation>
      Compilation(Driver.BuildCompilation(RF));
    const clang::driver::ArgStringList* CC1Args
      = GetCC1Arguments(Diagnostics, Compilation.get());
    if (CC1Args == NULL) {
      return 0;
    }
    clang::CompilerInvocation*
      Invocation = new clang::CompilerInvocation;
    clang::CompilerInvocation::CreateFromArgs(*Invocation, CC1Args->data() + 1,
                                              CC1Args->data() + CC1Args->size(),
                                              *Diagnostics);
    Invocation->getFrontendOpts().DisableFree = true;

    if (Invocation->getHeaderSearchOpts().UseBuiltinIncludes &&
        !resource_path.empty()) {
      // Update ResourceDir
      // header search opts' entry for resource_path/include isn't
      // updated by providing a new resource path; update it manually.
      clang::HeaderSearchOptions& Opts = Invocation->getHeaderSearchOpts();
      llvm::sys::Path oldResInc(Opts.ResourceDir);
      oldResInc.appendComponent("include");
      llvm::sys::Path newResInc(resource_path);
      newResInc.appendComponent("include");
      bool foundOldResInc = false;
      for (unsigned i = 0, e = Opts.UserEntries.size();
           !foundOldResInc && i != e; ++i) {
        HeaderSearchOptions::Entry &E = Opts.UserEntries[i];
        if (!E.IsFramework && E.Group == clang::frontend::System
            && E.IgnoreSysRoot && oldResInc.str() == E.Path) {
          E.Path = newResInc.str();
          foundOldResInc = true;
        }
      }

      Opts.ResourceDir = resource_path.str();
    }

    // Create and setup a compiler instance.
    CompilerInstance* CI = new CompilerInstance();
    CI->setInvocation(Invocation);

    CI->createDiagnostics(DiagnosticPrinter, /*ShouldOwnClient=*/ false,
                          /*ShouldCloneClient=*/ false);
    {
      //
      //  Buffer the error messages while we process
      //  the compiler options.
      //

      // Set the language options, which cling needs
      SetClingCustomLangOpts(CI->getLangOpts());

      CI->getInvocation().getPreprocessorOpts().addMacroDef("__CLING__");
      if (CI->getLangOpts().CPlusPlus11 == 1) {
        // http://llvm.org/bugs/show_bug.cgi?id=13530
        CI->getInvocation().getPreprocessorOpts()
          .addMacroDef("__CLING__CXX11");
      }

      if (CI->getDiagnostics().hasErrorOccurred()) {
        delete CI;
        CI = 0;
        return 0;
      }
    }
    CI->setTarget(TargetInfo::CreateTargetInfo(CI->getDiagnostics(),
                                               &Invocation->getTargetOpts()));
    if (!CI->hasTarget()) {
      delete CI;
      CI = 0;
      return 0;
    }
    CI->getTarget().setForcedLangOptions(CI->getLangOpts());
    SetClingTargetLangOpts(CI->getLangOpts(), CI->getTarget());
    if (CI->getTarget().getTriple().getOS() == llvm::Triple::Cygwin) {
      // clang "forgets" the basic arch part needed by winnt.h:
      if (CI->getTarget().getTriple().getArch() == llvm::Triple::x86) {
        CI->getInvocation().getPreprocessorOpts().addMacroDef("_X86_=1");
      } else if (CI->getTarget().getTriple().getArch()
                 == llvm::Triple::x86_64) {
        CI->getInvocation().getPreprocessorOpts().addMacroDef("__x86_64=1");
      } else {
        llvm::errs() << "Warning: unhandled target architecture "
                     << CI->getTarget().getTriple().getArchName() << '\n';
      }
    }

    // Set up source and file managers
    CI->createFileManager();
    CI->createSourceManager(CI->getFileManager());

    // Set up the memory buffer
    if (buffer)
      CI->getSourceManager().createMainFileIDForMemBuffer(buffer);
    else {
      // As main file we want
      // * a virtual file that is claiming to be huge
      // * with an empty memory buffer attached (to bring the content)
      SourceManager& SM = CI->getSourceManager();
      FileManager& FM = SM.getFileManager();
      // Build the virtual file
      const char* Filename = "InteractiveInputLineIncluder.h";
      const std::string& CGOptsMainFileName
        = CI->getInvocation().getCodeGenOpts().MainFileName;
      if (!CGOptsMainFileName.empty())
        Filename = CGOptsMainFileName.c_str();
      const FileEntry* FE
        = FM.getVirtualFile(Filename, 1U << 15U, time(0));
      FileID MainFileID = SM.createMainFileID(FE, SrcMgr::C_User);
      const SrcMgr::SLocEntry& MainFileSLocE = SM.getSLocEntry(MainFileID);
      const SrcMgr::ContentCache* MainFileCC
        = MainFileSLocE.getFile().getContentCache();
      llvm::MemoryBuffer* MainFileMB
        = llvm::MemoryBuffer::getMemBuffer("/*CLING MAIN FILE*/\n");
      const_cast<SrcMgr::ContentCache*>(MainFileCC)->setBuffer(MainFileMB);
    }

    // Set up the preprocessor
    CI->createPreprocessor();
    Preprocessor& PP = CI->getPreprocessor();
    PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                           PP.getLangOpts());

    // Set up the ASTContext
    ASTContext *Ctx = new ASTContext(CI->getLangOpts(),
                                     PP.getSourceManager(), &CI->getTarget(),
                                     PP.getIdentifierTable(),
                                     PP.getSelectorTable(), PP.getBuiltinInfo(),
                                     /*size_reserve*/0, /*DelayInit*/false);
    CI->setASTContext(Ctx);

    // Set up the ASTConsumers
    CI->setASTConsumer(new DeclCollector());

    // Set up Sema
    CodeCompleteConsumer* CCC = 0;
    CI->createSema(TU_Complete, CCC);

    // Set CodeGen options
    // CI->getCodeGenOpts().DebugInfo = 1; // want debug info
    // CI->getCodeGenOpts().EmitDeclMetadata = 1; // For unloading, for later
    CI->getCodeGenOpts().OptimizationLevel = 0; // see pure SSA, that comes out
    CI->getCodeGenOpts().CXXCtorDtorAliases = 0; // aliasing the complete
                                                 // ctor to the base ctor causes
                                                 // the JIT to crash
    // When asserts are on, TURN ON not compare the VerifyModule
    assert(CI->getCodeGenOpts().VerifyModule = 1);

    return CI;
  }

  void CIFactory::SetClingCustomLangOpts(LangOptions& Opts) {
    Opts.EmitAllDecls = 0; // Otherwise if PCH attached will codegen all decls.
    Opts.Exceptions = 1;
    Opts.CXXExceptions = 1;
    Opts.Deprecated = 1;
    //Opts.Modules = 1;

    // C++11 is turned on if cling is built with C++11: it's an interperter;
    // cross-language compilation doesn't make sense.
    // Extracted from Boost/config/compiler.
    // SunProCC has no C++11.
    // VisualC's support is not obvious to extract from Boost...
#if /*GCC*/ (defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__))   \
  || /*clang*/ (defined(__has_feature) && __has_feature(cxx_decltype))   \
  || /*ICC*/ ((!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && defined(__INTEL_COMPILER) && (__STDC_HOSTED__ && (__INTEL_COMPILER <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__))
    Opts.CPlusPlus11 = 1;
#endif

  }

  void CIFactory::SetClingTargetLangOpts(LangOptions& Opts,
                                         const TargetInfo& Target) {
    if (Target.getTriple().getOS() == llvm::Triple::Win32) {
      Opts.MicrosoftExt = 1;
      Opts.MSCVersion = 1300;
      // Should fix http://llvm.org/bugs/show_bug.cgi?id=10528
      Opts.DelayedTemplateParsing = 1;
    } else {
      Opts.MicrosoftExt = 0;
    }
  }
} // end namespace
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// This file contains the WebRTC suppressions for ThreadSanitizer.
// Please refer to
// http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for more info.

#if defined(THREAD_SANITIZER)

// Please make sure the code below declares a single string variable
// kTSanDefaultSuppressions contains TSan suppressions delimited by newlines.
// See http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for the instructions on writing suppressions.
char kTSanDefaultSuppressions[] =

// WebRTC specific suppressions.

// Split up suppressions covered previously by thread.cc and messagequeue.cc.
"race:rtc::MessageQueue::Quit\n"
"race:FileVideoCapturerTest::VideoCapturerListener::OnFrameCaptured\n"
"race:vp8cx_remove_encoder_threads\n"
"race:third_party/libvpx/source/libvpx/vp9/common/vp9_scan.h\n"

// Usage of trace callback and trace level is racy in libjingle_media_unittests.
// https://code.google.com/p/webrtc/issues/detail?id=3372
"race:webrtc::TraceImpl::WriteToFile\n"
"race:webrtc::VideoEngine::SetTraceFilter\n"
"race:webrtc::VoiceEngine::SetTraceFilter\n"
"race:webrtc::Trace::set_level_filter\n"
"race:webrtc::GetStaticInstance<webrtc::TraceImpl>\n"

// Audio processing
// https://code.google.com/p/webrtc/issues/detail?id=2521 for details.
"race:webrtc/modules/audio_processing/aec/aec_core.c\n"
"race:webrtc/modules/audio_processing/aec/aec_rdft.c\n"

// rtc_unittest
// https://code.google.com/p/webrtc/issues/detail?id=3911 for details.
"race:rtc::AsyncInvoker::OnMessage\n"
"race:rtc::FireAndForgetAsyncClosure<FunctorB>::Execute\n"
"race:rtc::MessageQueueManager::Clear\n"
"race:rtc::Thread::Clear\n"
// https://code.google.com/p/webrtc/issues/detail?id=2080
"race:webrtc/base/logging.cc\n"
"race:webrtc/base/sharedexclusivelock_unittest.cc\n"
"race:webrtc/base/signalthread_unittest.cc\n"
// https://code.google.com/p/webrtc/issues/detail?id=4456
"deadlock:rtc::MessageQueueManager::Clear\n"
"deadlock:rtc::MessageQueueManager::ClearInternal\n"

// libjingle_p2p_unittest
// https://code.google.com/p/webrtc/issues/detail?id=2079
"race:webrtc/base/testclient.cc\n"
"race:webrtc/base/virtualsocketserver.cc\n"
"race:talk/p2p/base/stunserver_unittest.cc\n"

// third_party/usrsctp
// TODO(jiayl): https://code.google.com/p/webrtc/issues/detail?id=3492
"race:user_sctp_timer_iterate\n"

// Potential deadlocks detected after roll in r6516.
// https://code.google.com/p/webrtc/issues/detail?id=3509
"deadlock:webrtc::ProcessThreadImpl::RegisterModule\n"
"deadlock:webrtc::RTCPReceiver::SetSsrcs\n"
"deadlock:webrtc::test::UdpSocketManagerPosixImpl::RemoveSocket\n"
"deadlock:webrtc::vcm::VideoReceiver::RegisterPacketRequestCallback\n"
"deadlock:webrtc::ViECaptureImpl::ConnectCaptureDevice\n"
"deadlock:webrtc::ViEChannel::StartSend\n"
"deadlock:webrtc::ViECodecImpl::GetSendSideDelay\n"
"deadlock:webrtc::ViEEncoder::OnLocalSsrcChanged\n"
"deadlock:webrtc::ViESender::RegisterSendTransport\n"

// TODO(pbos): Trace events are racy due to lack of proper POD atomics.
// https://code.google.com/p/webrtc/issues/detail?id=2497
"race:*trace_event_unique_catstatic*\n"

// End of suppressions.
;  // Please keep this semicolon.

#endif  // THREAD_SANITIZER
<commit_msg>Suppress data races in libjingle_peerconnection_unittest<commit_after>/*
 *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// This file contains the WebRTC suppressions for ThreadSanitizer.
// Please refer to
// http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for more info.

#if defined(THREAD_SANITIZER)

// Please make sure the code below declares a single string variable
// kTSanDefaultSuppressions contains TSan suppressions delimited by newlines.
// See http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2
// for the instructions on writing suppressions.
char kTSanDefaultSuppressions[] =

// WebRTC specific suppressions.

// Split up suppressions covered previously by thread.cc and messagequeue.cc.
"race:rtc::MessageQueue::Quit\n"
"race:FileVideoCapturerTest::VideoCapturerListener::OnFrameCaptured\n"
"race:vp8cx_remove_encoder_threads\n"
"race:third_party/libvpx/source/libvpx/vp9/common/vp9_scan.h\n"

// Usage of trace callback and trace level is racy in libjingle_media_unittests.
// https://code.google.com/p/webrtc/issues/detail?id=3372
"race:webrtc::TraceImpl::WriteToFile\n"
"race:webrtc::VideoEngine::SetTraceFilter\n"
"race:webrtc::VoiceEngine::SetTraceFilter\n"
"race:webrtc::Trace::set_level_filter\n"
"race:webrtc::GetStaticInstance<webrtc::TraceImpl>\n"

// Audio processing
// https://code.google.com/p/webrtc/issues/detail?id=2521 for details.
"race:webrtc/modules/audio_processing/aec/aec_core.c\n"
"race:webrtc/modules/audio_processing/aec/aec_rdft.c\n"

// rtc_unittest
// https://code.google.com/p/webrtc/issues/detail?id=3911 for details.
"race:rtc::AsyncInvoker::OnMessage\n"
"race:rtc::FireAndForgetAsyncClosure<FunctorB>::Execute\n"
"race:rtc::MessageQueueManager::Clear\n"
"race:rtc::Thread::Clear\n"
// https://code.google.com/p/webrtc/issues/detail?id=2080
"race:webrtc/base/logging.cc\n"
"race:webrtc/base/sharedexclusivelock_unittest.cc\n"
"race:webrtc/base/signalthread_unittest.cc\n"
// https://code.google.com/p/webrtc/issues/detail?id=4456
"deadlock:rtc::MessageQueueManager::Clear\n"
"deadlock:rtc::MessageQueueManager::ClearInternal\n"

// libjingle_peerconnection_unittest
// https://code.google.com/p/webrtc/issues/detail?id=4488
"race:webrtc::voe::ChannelOwner::~ChannelOwner\n"
"race:cricket::ChannelManager::Terminate_w()\n"

// libjingle_p2p_unittest
// https://code.google.com/p/webrtc/issues/detail?id=2079
"race:webrtc/base/testclient.cc\n"
"race:webrtc/base/virtualsocketserver.cc\n"
"race:talk/p2p/base/stunserver_unittest.cc\n"

// third_party/usrsctp
// TODO(jiayl): https://code.google.com/p/webrtc/issues/detail?id=3492
"race:user_sctp_timer_iterate\n"

// Potential deadlocks detected after roll in r6516.
// https://code.google.com/p/webrtc/issues/detail?id=3509
"deadlock:webrtc::ProcessThreadImpl::RegisterModule\n"
"deadlock:webrtc::RTCPReceiver::SetSsrcs\n"
"deadlock:webrtc::test::UdpSocketManagerPosixImpl::RemoveSocket\n"
"deadlock:webrtc::vcm::VideoReceiver::RegisterPacketRequestCallback\n"
"deadlock:webrtc::ViECaptureImpl::ConnectCaptureDevice\n"
"deadlock:webrtc::ViEChannel::StartSend\n"
"deadlock:webrtc::ViECodecImpl::GetSendSideDelay\n"
"deadlock:webrtc::ViEEncoder::OnLocalSsrcChanged\n"
"deadlock:webrtc::ViESender::RegisterSendTransport\n"

// TODO(pbos): Trace events are racy due to lack of proper POD atomics.
// https://code.google.com/p/webrtc/issues/detail?id=2497
"race:*trace_event_unique_catstatic*\n"

// End of suppressions.
;  // Please keep this semicolon.

#endif  // THREAD_SANITIZER
<|endoftext|>


<commit_before>//
// Originally written by BjÃrn Fahller (bjorn@fahller.se)
// Modified by Jeff Bush
//
// No rights claimed. The sources are released to the public domain
//
// For license information, please refer to <http://unlicense.org>
//

#include <setjmp.h>
#include <stdlib.h>
#include <iostream>
#include <ostream>
#include <forward_list>

namespace basic {
  struct stack_frame { jmp_buf buf; };
  std::forward_list<stack_frame> stack;

#define GOSUB                                                           \
  if (!(setjmp((basic::stack.emplace_front(),basic::stack.front().buf)) \
        && (basic::stack.pop_front(),true)))                            \
    goto

#define RETURN if (basic::stack.empty()) return 0; longjmp(basic::stack.front().buf, 1)

  template <typename T, typename U>
  struct separator
  {
    static char const *str() { return ""; }
  };

  template <typename T>
  struct separator<T,T>
  {
    static char const *str() { return ","; }
  };

  void type_mismatch() {
    std::cout << "Type mismatch error\n";
    exit(1);
  }

  void array_out_of_bounds() {
    std::cout << "Array out of bounds error\n";
    exit(1);
  }

  class variant
  {
  public:
    variant()
      : isnum(true),
        numval(0)
    {}

    variant(double _numval)
      : isnum(true),
        numval(_numval)
    {}

    variant(int _numval)
      : isnum(true),
        numval(_numval)
    {}

    variant(const std::string _strval)
      : isnum(false),
        strval(_strval)
    {}

    variant(const char *_strval)
      : isnum(false),
        strval(_strval)
    {}

    variant toString() const {
      if (isnum)
        return variant(std::to_string(numval));
      else
        return *this;
    }

    variant toNum() const {
      if (!isnum)
        return variant(stod(strval));
      else
        return *this;
    }

    variant &operator=(const variant &copyfrom) {
      isnum = copyfrom.isnum;
      numval = copyfrom.numval;
      strval = copyfrom.strval;
      return *this;
    }

    // Note that strings in BASIC are 1 based, so subtract 1 from the left
    // index
    variant midStr(const variant &left, const variant &right) const {
      if (isnum || !left.isnum || !right.isnum)
        type_mismatch();

      return variant(strval.substr(int(left.numval) - 1, (int(right.numval) - int(left.numval) + 1)));
    }

    variant leftStr(const variant &count) const {
      if (isnum)
        type_mismatch();

      return variant(strval.substr(0, int(count.numval)));
    }

    variant rightStr(const variant &count) const {
      if (isnum)
        type_mismatch();

      return variant(strval.substr(strval.length() - int(count.numval) - 1, int(count.numval)));
    }

    variant strlen() const {
      if (isnum)
        type_mismatch();

      return variant((int)strval.length());
    }

    variant operator+(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return variant(numval + op.numval);
      else
        return variant(strval + op.strval);
    }

    variant operator-(const variant op) const {
      if (!isnum || !op.isnum)
        type_mismatch();

      return variant(numval - op.numval);
    }

    variant operator*(const variant op) const {
      if (!isnum || !op.isnum)
        type_mismatch();

      return variant(numval * op.numval);
    }

    variant operator/(const variant op) const {
      if (!isnum || !op.isnum)
        type_mismatch();

      return variant(numval / op.numval);
    }

    bool operator>(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval > op.numval;
      else
        return strval > op.strval;
    }

    bool operator>=(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval >= op.numval;
      else
        return strval >= op.strval;
    }

    bool operator<(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval < op.numval;
      else
        return strval < op.strval;
    }

    bool operator<=(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval <= op.numval;
      else
        return strval <= op.strval;
    }

    bool operator!=(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval != op.numval;
      else
        return strval != op.strval;
    }

    bool operator==(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval == op.numval;
      else
        return strval == op.strval;
    }

    bool isnum;
    double numval;
    std::string strval;
  };

  class array
  {
  public:
    array(int _size)
      : size(_size),
        elements(new variant[_size])
    {}

    variant& operator()(const variant &indexvar) {
      if (!indexvar.isnum)
        type_mismatch();

      int index = indexvar.numval - 1;
      if (index < 0 || index >= size)
        array_out_of_bounds();

      return elements[index];
    }
  private:
    variant *elements;
    int size;
  };

  class printer
  {
    public:
    printer &operator,(const char *s) {
      std::cout  << s;
      return *this;
    }

    const printer &operator,(const variant &v) const {
      if (v.isnum)
        std::cout << v.numval;
      else
        std::cout << v.strval;

      return *this;
    }

    ~printer() { std::cout << std::endl; }
  };

  class input
  {
  public:
    input& operator,(char const *s) {
      std::cout << s << std::flush;
      return *this;
    }

    input& operator,(variant& v) {
      if (v.isnum)
        std::cin >> v.numval;
      else
        std::cin >> v.strval;

      return *this;
    }
  };

#define INPUT basic::input(),
#define PRINT basic::printer(),
#define IF if (
#define THEN )
#define LET basic::variant
#define GOTO goto
#define FOR { basic::variant& for_loop_variable =
#define TO ;                                   \
           {                                   \
             jmp_buf for_loop_top;             \
             bool for_loop_exit = false;           \
             while (!for_loop_exit)            \
             {                                 \
               if (setjmp(for_loop_top) == 0)  \
               {                               \
                 basic::variant for_loop_step=1;       \
                 basic::variant const for_loop_endval=
#define STEP ;              \
             for_loop_step=

#define NEXT for_loop_variable=for_loop_variable+for_loop_step;                           \
             for_loop_exit=(  (   for_loop_step > 0                      \
                               && for_loop_variable > for_loop_endval)   \
                            ||(   for_loop_step < 0                      \
                               && for_loop_variable < for_loop_endval)); \
             longjmp(for_loop_top, 1);                                   \
             }                                                           \
           }                                                             \
         }                                                               \
       }

#define END exit(0)
#define VAL(x) x.toNum()
#define STR(x) x.toString()
#define MID$(str, left, right) str.midStr(left, right)
#define LEFT$(str, count) str.leftStr(count)
#define RIGHT$(str, count) str.rightStr(count)
#define LEN(str) str.strlen()
#define DIM basic::array
#define RND(x) (double) (rand() & 0xffff);

} // namespace basic
<commit_msg>reimplement array with vector<commit_after>//
// Originally written by BjÃrn Fahller (bjorn@fahller.se)
// Modified by Jeff Bush
//
// No rights claimed. The sources are released to the public domain
//
// For license information, please refer to <http://unlicense.org>
//

#include <setjmp.h>
#include <stdlib.h>
#include <iostream>
#include <ostream>
#include <forward_list>
#include <vector>

namespace basic {
  struct stack_frame { jmp_buf buf; };
  std::forward_list<stack_frame> stack;

#define GOSUB                                                           \
  if (!(setjmp((basic::stack.emplace_front(),basic::stack.front().buf)) \
        && (basic::stack.pop_front(),true)))                            \
    goto

#define RETURN if (basic::stack.empty()) return 0; longjmp(basic::stack.front().buf, 1)

  template <typename T, typename U>
  struct separator
  {
    static char const *str() { return ""; }
  };

  template <typename T>
  struct separator<T,T>
  {
    static char const *str() { return ","; }
  };

  void type_mismatch() {
    std::cout << "Type mismatch error\n";
    exit(1);
  }

  void array_out_of_bounds() {
    std::cout << "Array out of bounds error\n";
    exit(1);
  }

  class variant
  {
  public:
    variant()
      : isnum(true),
        numval(0)
    {}

    variant(double _numval)
      : isnum(true),
        numval(_numval)
    {}

    variant(int _numval)
      : isnum(true),
        numval(_numval)
    {}

    variant(const std::string _strval)
      : isnum(false),
        strval(_strval)
    {}

    variant(const char *_strval)
      : isnum(false),
        strval(_strval)
    {}

    variant toString() const {
      if (isnum)
        return variant(std::to_string(numval));
      else
        return *this;
    }

    variant toNum() const {
      if (!isnum)
        return variant(stod(strval));
      else
        return *this;
    }

    variant &operator=(const variant &copyfrom) {
      isnum = copyfrom.isnum;
      numval = copyfrom.numval;
      strval = copyfrom.strval;
      return *this;
    }

    // Note that strings in BASIC are 1 based, so subtract 1 from the left
    // index
    variant midStr(const variant &left, const variant &right) const {
      if (isnum || !left.isnum || !right.isnum)
        type_mismatch();

      return variant(strval.substr(int(left.numval) - 1, (int(right.numval) - int(left.numval) + 1)));
    }

    variant leftStr(const variant &count) const {
      if (isnum)
        type_mismatch();

      return variant(strval.substr(0, int(count.numval)));
    }

    variant rightStr(const variant &count) const {
      if (isnum)
        type_mismatch();

      return variant(strval.substr(strval.length() - int(count.numval) - 1, int(count.numval)));
    }

    variant strlen() const {
      if (isnum)
        type_mismatch();

      return variant((int)strval.length());
    }

    variant operator+(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return variant(numval + op.numval);
      else
        return variant(strval + op.strval);
    }

    variant operator-(const variant op) const {
      if (!isnum || !op.isnum)
        type_mismatch();

      return variant(numval - op.numval);
    }

    variant operator*(const variant op) const {
      if (!isnum || !op.isnum)
        type_mismatch();

      return variant(numval * op.numval);
    }

    variant operator/(const variant op) const {
      if (!isnum || !op.isnum)
        type_mismatch();

      return variant(numval / op.numval);
    }

    bool operator>(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval > op.numval;
      else
        return strval > op.strval;
    }

    bool operator>=(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval >= op.numval;
      else
        return strval >= op.strval;
    }

    bool operator<(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval < op.numval;
      else
        return strval < op.strval;
    }

    bool operator<=(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval <= op.numval;
      else
        return strval <= op.strval;
    }

    bool operator!=(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval != op.numval;
      else
        return strval != op.strval;
    }

    bool operator==(const variant op) const {
      if (isnum != op.isnum)
        type_mismatch();

      if (isnum)
        return numval == op.numval;
      else
        return strval == op.strval;
    }

    bool isnum;
    double numval;
    std::string strval;
  };

  class array
  {
  public:
    array(int _size)
      : elements(_size)
    {}

    variant& operator()(const variant &indexvar) {
      if (!indexvar.isnum)
        type_mismatch();

      int index = indexvar.numval - 1;
      if (index < 0 || index >= elements.size())
        array_out_of_bounds();

      return elements[index];
    }
  private:
    std::vector<variant> elements;
  };

  class printer
  {
    public:
    printer &operator,(const char *s) {
      std::cout  << s;
      return *this;
    }

    const printer &operator,(const variant &v) const {
      if (v.isnum)
        std::cout << v.numval;
      else
        std::cout << v.strval;

      return *this;
    }

    ~printer() { std::cout << std::endl; }
  };

  class input
  {
  public:
    input& operator,(char const *s) {
      std::cout << s << std::flush;
      return *this;
    }

    input& operator,(variant& v) {
      if (v.isnum)
        std::cin >> v.numval;
      else
        std::cin >> v.strval;

      return *this;
    }
  };

#define INPUT basic::input(),
#define PRINT basic::printer(),
#define IF if (
#define THEN )
#define LET basic::variant
#define GOTO goto
#define FOR { basic::variant& for_loop_variable =
#define TO ;                                   \
           {                                   \
             jmp_buf for_loop_top;             \
             bool for_loop_exit = false;           \
             while (!for_loop_exit)            \
             {                                 \
               if (setjmp(for_loop_top) == 0)  \
               {                               \
                 basic::variant for_loop_step=1;       \
                 basic::variant const for_loop_endval=
#define STEP ;              \
             for_loop_step=

#define NEXT for_loop_variable=for_loop_variable+for_loop_step;                           \
             for_loop_exit=(  (   for_loop_step > 0                      \
                               && for_loop_variable > for_loop_endval)   \
                            ||(   for_loop_step < 0                      \
                               && for_loop_variable < for_loop_endval)); \
             longjmp(for_loop_top, 1);                                   \
             }                                                           \
           }                                                             \
         }                                                               \
       }

#define END exit(0)
#define VAL(x) x.toNum()
#define STR(x) x.toString()
#define MID$(str, left, right) str.midStr(left, right)
#define LEFT$(str, count) str.leftStr(count)
#define RIGHT$(str, count) str.rightStr(count)
#define LEN(str) str.strlen()
#define DIM basic::array
#define RND(x) (double) (rand() & 0xffff);

} // namespace basic
<|endoftext|>


<commit_before>#include "nbody.h"

Quad* BHTree::getQuad(const Body& b) {
	if(i_ == size_) {
		return nullptr;
	}
	auto& q = quads_[i_++];
	q.setPosMass(b);
	q.clearChild();
	return &q;
}

void BHTree::calcforces(Body& b, QB qb, double size) {
	Vector d, foverm;
	double h, Goverh³;

	for(;;)
		switch(qb.t) {
		case QB::empty:
			return;
		case QB::body:
			if(qb.b == &b)
				return;
			d = qb.b->p - b.p;
			h = std::hypot(std::hypot(d.x, d.y), ε_);
			Goverh³ = G_ / (h * h * h);
			foverm = d * Goverh³;
			b.newa += foverm * qb.b->mass;
			return;
		case QB::quad:
			d = qb.q->p - b.p;
			h = std::hypot(d.x, d.y);
			if(h != 0.0 && size / h < θ_) {
				h = std::hypot(h, ε_);
				Goverh³ = G_ / (h * h * h);
				foverm = d * Goverh³;
				b.newa += foverm * qb.q->mass;
				return;
			}
			size /= 2;
			calcforces(b, qb.q->c[0], size);
			calcforces(b, qb.q->c[1], size);
			calcforces(b, qb.q->c[2], size);
			qb = qb.q->c[3];
			break; /* calcforces(b, q->q[3], size); */
		}
}

bool BHTree::insert(const Body& nb, double size) {
	if(root_.t == QB::empty) {
		root_.t = QB::body;
		root_.b = &nb;
		return true;
	}
	double qx{0}, qy{0};
	auto qb = &root_;
	for(;;) {
		if(qb->t == QB::body) {
			auto& b = *qb->b;
			auto qxy = b.p.x < qx ? 0 : 1;
			qxy |= b.p.y < qy ? 0 : 2;
			qb->t = QB::quad;
			qb->q = getQuad(b);
			if(qb->q == nullptr)
				return false;
			qb->q->c[qxy].t = QB::body;
			qb->q->c[qxy].b = &b;
		}
		auto& q = *qb->q;
		auto mass = q.mass + nb.mass;
		q.p = (q.p * q.mass + nb.p * nb.mass) / mass;
		q.mass = mass;

		auto qxy = nb.p.x < qx ? 0 : 1;
		qxy |= nb.p.y < qy ? 0 : 1;
		if(q.c[qxy].t == QB::empty) {
			q.c[qxy].t = QB::body;
			q.c[qxy].b = &nb;
			return true;
		}
		qb = &q.c[qxy];
		size /= 2;
		qx += qxy & 1 ? size / 2 : -size / 2;
		qy += qxy & 2 ? size / 2 : -size / 2;
	}
}

void BHTree::insert(Galaxy& g) {
Again:
	root_.t = QB::empty;
	i_ = 0;
	for(auto& b : g.bodies) {
		if(!insert(b, g.limit)) {
			resize();
			goto Again;
		}
	}
}

void BHTree::calcforces(Galaxy& g) {
	insert(g);
	for(auto& b : g.bodies) {
		b.a = b.newa;
		b.newa = {0, 0};
		calcforces(b, root_, g.limit);
	}
}
<commit_msg>clean up force calculation<commit_after>#include "nbody.h"

Quad* BHTree::getQuad(const Body& b) {
	if(i_ == size_) {
		return nullptr;
	}
	auto& q = quads_[i_++];
	q.setPosMass(b);
	q.clearChild();
	return &q;
}

void BHTree::calcforces(Body& b, QB qb, double size) {
	for(;;) {
		Vector d;
		double h;
		switch(qb.t) {
		case QB::empty:
			return;
		case QB::body:
			if(qb.b == &b)
				return;
			d = qb.b->p - b.p;
			h = std::hypot(std::hypot(d.x, d.y), ε_);
			b.newa += d * G_ / (h * h * h) * qb.b->mass;
			return;
		case QB::quad:
			d = qb.q->p - b.p;
			h = std::hypot(d.x, d.y);
			if(h != 0.0 && size / h < θ_) {
				h = std::hypot(h, ε_);
				b.newa += d * G_ / (h * h * h) * qb.q->mass;
				return;
			}
			size /= 2;
			calcforces(b, qb.q->c[0], size);
			calcforces(b, qb.q->c[1], size);
			calcforces(b, qb.q->c[2], size);
			qb = qb.q->c[3];
			break; /* calcforces(b, q->q[3], size); */
		}
	}
}

bool BHTree::insert(const Body& nb, double size) {
	if(root_.t == QB::empty) {
		root_.t = QB::body;
		root_.b = &nb;
		return true;
	}
	double qx{0}, qy{0};
	auto qb = &root_;
	for(;;) {
		if(qb->t == QB::body) {
			auto& b = *qb->b;
			auto qxy = b.p.x < qx ? 0 : 1;
			qxy |= b.p.y < qy ? 0 : 2;
			qb->t = QB::quad;
			qb->q = getQuad(b);
			if(qb->q == nullptr)
				return false;
			qb->q->c[qxy].t = QB::body;
			qb->q->c[qxy].b = &b;
		}
		auto& q = *qb->q;
		auto mass = q.mass + nb.mass;
		q.p = (q.p * q.mass + nb.p * nb.mass) / mass;
		q.mass = mass;

		auto qxy = nb.p.x < qx ? 0 : 1;
		qxy |= nb.p.y < qy ? 0 : 1;
		if(q.c[qxy].t == QB::empty) {
			q.c[qxy].t = QB::body;
			q.c[qxy].b = &nb;
			return true;
		}
		qb = &q.c[qxy];
		size /= 2;
		qx += qxy & 1 ? size / 2 : -size / 2;
		qy += qxy & 2 ? size / 2 : -size / 2;
	}
}

void BHTree::insert(Galaxy& g) {
Again:
	root_.t = QB::empty;
	i_ = 0;
	for(auto& b : g.bodies) {
		if(!insert(b, g.limit)) {
			resize();
			goto Again;
		}
	}
}

void BHTree::calcforces(Galaxy& g) {
	insert(g);
	for(auto& b : g.bodies) {
		b.a = b.newa;
		b.newa = {0, 0};
		calcforces(b, root_, g.limit);
	}
}
<|endoftext|>


<commit_before>/*
 * Jamoma DSP Soundfile Recorder
 * Copyright © 2010, Tim Place
 *
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTSoundfileRecorder.h"

#define thisTTClass			TTSoundfileRecorder
#define thisTTClassName		"soundfile.recorder"
#define thisTTClassTags		"audio, soundfile, record"

TT_AUDIO_CONSTRUCTOR,
mFilePath(kTTSymEmpty),
mFormat(kTTSymEmpty),
mSoundFile(NULL),
mRecord(false),
mNumChannels(0),
mNumBufferFrames(0),
mLength(0),
mLengthInSamples(0),
mCycles(0)
{
	addAttributeWithSetter(	FilePath,		kTypeSymbol);
	addAttribute(			Format,			kTypeSymbol);
	addAttributeWithSetter(	Record,			kTypeBoolean);
	addAttribute(			NumChannels,	kTypeUInt16);
		addAttributeProperty(	NumChannels,	readOnly, kTTBoolYes);
	addAttributeWithSetter(	Length,			kTypeFloat64);
		addAttributeProperty(Length,			range,			TTValue(0, 60000));
		addAttributeProperty(Length,			rangeChecking,	TT("clip"));

}

TTSoundfileRecorder::~TTSoundfileRecorder()
{
	setAttributeValue(TT("record"), kTTBoolNo);
	if (mSoundFile)
		sf_close(mSoundFile);
}

TTErr TTSoundfileRecorder::setRecord(const TTValue& newValue)
{
	TTBoolean	newRecordState = newValue;
	TTErr		err = kTTErrNone;

	if (newRecordState == 1){
		if (mLength <= 0)
			setProcessMethod(processAudioRecording);
		else
			setProcessMethod(processTimedAudioRecording);
		}
	else
		setProcessMethod(processAudioBypass);

	if (mRecord != newRecordState) {
		mRecord = newRecordState;
		if (mRecord) {			// start recording
			mLengthInSamples = mLength * sr * 0.001; // reset the Sample counter
			mCycles = 0;
			//mNumChannels = 0;	// set to zero so that the process method will set the num channels and trigger an open
		}
		else {					// stop recording -- close the file
			if (mSoundFile){
				sf_close(mSoundFile);
			mSoundFile = NULL;
			}
		}
	}
	return err;
}

TTErr TTSoundfileRecorder::setLength(const TTValue& newValue)
{	TTFloat64	newLength = newValue;
	if (newLength != mLength){
		mLength = newLength;
		mNumBufferFrames = 0; //hack to force a resize of mBuffer in the process method
	}
	return kTTErrNone;
}

// "FLAC-24bit" -> SF_FORMAT_FLAC | SF_FORMAT_PCM_24

int TTSoundfileRecorder::translateFormatFromName(TTSymbolPtr name)
{
	int		format = 0;
	char	cname[64];
	char*	s;

	if (name)
		strncpy(cname, name->getCString(), 64);
	else
		strncpy(cname, "CAF", 64);

	s = strrchr(cname, '-'); // look for subtype
	if (s) {
		*s = 0;
		s++;
		if (s) {
			if (strstr(s, "16bit"))
				format |= SF_FORMAT_PCM_16;
			else if (strstr(s, "24bit"))
				format |= SF_FORMAT_PCM_24;
			else if (strstr(s, "32bit"))
				format |= SF_FORMAT_PCM_32;
			else
				format |= SF_FORMAT_PCM_24;
		}
	}
	else { // no subtype, set default
		format |= SF_FORMAT_PCM_24;
	}

	// now look at the primary type
	if (strstr(cname, "FLAC"))
		format |= SF_FORMAT_FLAC;
	else if (strstr(cname, "AIFF"))
		format |= SF_FORMAT_AIFF;
	else if (strstr(cname, "WAV"))
		format |= SF_FORMAT_WAV;
	else if (strstr(cname, "Matlab"))
		format |= SF_FORMAT_MAT5;
	else
		format |= SF_FORMAT_CAF;

	return format;
}

TTErr TTSoundfileRecorder::setFilePath(const TTValue& newValue)
{
	mFilePath = newValue;
	/*if ((mNumChannels) && (mFormat))
		return openFile();
	else */
		return kTTErrNone;
}

TTErr TTSoundfileRecorder::openFile()
{
	memset(&mSoundFileInfo, 0, sizeof(mSoundFileInfo));
	mSoundFileInfo.channels = mNumChannels;
	mSoundFileInfo.format = translateFormatFromName(mFormat);
	mSoundFileInfo.samplerate = sr;

	mSoundFile = sf_open(mFilePath->getCString(), SFM_WRITE, &mSoundFileInfo);

	if (!mSoundFile) {
		TTLogMessage("Can't create soundfile.\n");
		return kTTErrGeneric;
	}
	return kTTErrNone;
}

TTErr TTSoundfileRecorder::processAudioRecording(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
{
	TTAudioSignal&		out = outputs->getSignal(0);
	TTAudioSignal&		in  = inputs->getSignal(0);
	TTSampleValuePtr	outSample, inSample;
	TTUInt16			channelCount = in.getNumChannelsAsInt();
	TTUInt16			vs = in.getVectorSizeAsInt();
	TTUInt16			n, channel;
	TTBoolean			bufferNeedsResize = NO;
	//sf_count_t			numSamplesWritten;
	//TTUInt64			progress = mCycles*vs*channelCount;

	if (mNumChannels != channelCount) {		// input channel number has changed, we need to set up the buffer
		mNumChannels = channelCount;
		bufferNeedsResize = YES;
	}

	if (mNumBufferFrames != vs) {   //vector size has changed, we need to set up the buffer
		mNumBufferFrames = vs;
		bufferNeedsResize = YES;
	}
	if (bufferNeedsResize){
		TTUInt64 buffersize = mNumChannels * mNumBufferFrames;
		mBuffer.resize(buffersize);
	}

	if (!mSoundFile) //if we don't have already a file open, do it now.
		openFile();

	for (channel=0; channel<channelCount; channel++) {
		inSample = in.mSampleVectors[channel];
		outSample = out.mSampleVectors[channel]; // sending audio out
		for (n=0; n<vs; n++){
			//mBuffer[progress+(n * channelCount + channel)] = inSample[n]; //sending audio to recording buffer
			mBuffer[(n * channelCount + channel)] = inSample[n]; //sending audio to recording buffer
			outSample[n] = inSample[n];  // sending audio out
		}
	}
    //mCycles++;
	//if (mCycles == 100){

	if (sf_writef_double(mSoundFile, &mBuffer[0], vs) != vs) {
		char errorStr[256];
        sf_error_str(mSoundFile, errorStr, 256);
		TTLogError("Error while writing file: %s \n",errorStr);
	}

	//	mCycles = 0;
	//}

	return kTTErrNone;
}

TTErr TTSoundfileRecorder::processTimedAudioRecording(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
{
	TTAudioSignal&		out = outputs->getSignal(0);
	TTAudioSignal&		in  = inputs->getSignal(0);
	TTSampleValuePtr	outSample, inSample;
	TTUInt16			channelCount = in.getNumChannelsAsInt();
	TTUInt16			vs = in.getVectorSizeAsInt();
	TTUInt16			n, channel;
	TTBoolean			bufferNeedsResize = NO;
	//sf_count_t			numSamplesWritten;
	TTUInt64			progress = mCycles*vs*channelCount;

	if (mNumChannels != channelCount) {		// input channel number has changed, we need to set up the buffer
		mNumChannels = channelCount;
		bufferNeedsResize = YES;
	}

	if (mNumBufferFrames != vs) {   //vector size has changed, we need to set up the buffer
		mNumBufferFrames = vs;
		bufferNeedsResize = YES;
	}
	if (bufferNeedsResize){
		TTUInt64 buffersize = mNumChannels * mNumBufferFrames * ceil((double)mLengthInSamples/(double)mNumBufferFrames);
		mBuffer.resize(buffersize);
	}

	if (!mSoundFile) //if we don't have already a file open, do it now.
		openFile();

	for (channel=0; channel<channelCount; channel++) {
		inSample = in.mSampleVectors[channel];
		outSample = out.mSampleVectors[channel]; // sending audio out
		for (n=0; n<vs; n++){
			mBuffer[progress+(n * channelCount + channel)] = inSample[n]; //sending audio to recording buffer
			outSample[n] = inSample[n];  // sending audio out
		}
	}

	mCycles++;
	mLengthInSamples -= vs; // decreasing the samplecounter by a vs
	if (mLengthInSamples <= 0){ //TODO: we might want to chop of the samples that were recorded too long
		if (sf_writef_double(mSoundFile, &mBuffer[0], mCycles*vs) != mCycles*vs) {
			char errorStr[256];
			sf_error_str(mSoundFile, errorStr, 256);
			TTLogError("Error while writing file: %s \n",errorStr);
		}
		return setRecord(0);
	}
	else return kTTErrNone;
}

TTErr TTSoundfileRecorder::processAudioBypass(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
{
	TTAudioSignal&		out = outputs->getSignal(0);
	TTAudioSignal&		in  = inputs->getSignal(0);
	TTSampleValuePtr	outSample, inSample;
	TTUInt16			channelCount = in.getNumChannelsAsInt();
	TTUInt16			vs = in.getVectorSizeAsInt();
	TTUInt16			n, channel;

	// not recording, just bypassing audio and return
	 for (channel=0; channel<channelCount; channel++) {
		 inSample = in.mSampleVectors[channel];
		 outSample = out.mSampleVectors[channel]; // sending audio out
		 for (n=0; n<vs; n++)
			 outSample[n] = inSample[n];  // sending audio out
	}
	return kTTErrNone;
}

<commit_msg>adding a comment<commit_after>/*
 * Jamoma DSP Soundfile Recorder
 * Copyright © 2010, Tim Place
 *
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTSoundfileRecorder.h"

#define thisTTClass			TTSoundfileRecorder
#define thisTTClassName		"soundfile.recorder"
#define thisTTClassTags		"audio, soundfile, record"

TT_AUDIO_CONSTRUCTOR,
mFilePath(kTTSymEmpty),
mFormat(kTTSymEmpty),
mSoundFile(NULL),
mRecord(false),
mNumChannels(0),
mNumBufferFrames(0),
mLength(0),
mLengthInSamples(0),
mCycles(0)
{
	addAttributeWithSetter(	FilePath,		kTypeSymbol);
	addAttribute(			Format,			kTypeSymbol);
	addAttributeWithSetter(	Record,			kTypeBoolean);
	addAttribute(			NumChannels,	kTypeUInt16);
		addAttributeProperty(	NumChannels,	readOnly, kTTBoolYes);
	addAttributeWithSetter(	Length,			kTypeFloat64);
		addAttributeProperty(Length,			range,			TTValue(0, 60000));
		addAttributeProperty(Length,			rangeChecking,	TT("clip"));

}

TTSoundfileRecorder::~TTSoundfileRecorder()
{
	setAttributeValue(TT("record"), kTTBoolNo);
	if (mSoundFile)
		sf_close(mSoundFile);
}

TTErr TTSoundfileRecorder::setRecord(const TTValue& newValue)
{
	TTBoolean	newRecordState = newValue;
	TTErr		err = kTTErrNone;

	if (newRecordState == 1){
		if (mLength <= 0)
			setProcessMethod(processAudioRecording);
		else
			setProcessMethod(processTimedAudioRecording);
		}
	else
		setProcessMethod(processAudioBypass);

	if (mRecord != newRecordState) {
		mRecord = newRecordState;
		if (mRecord) {			// start recording
			mLengthInSamples = mLength * sr * 0.001; // reset the Sample counter
			mCycles = 0;
			//mNumChannels = 0;	// set to zero so that the process method will set the num channels and trigger an open
		}
		else {					// stop recording -- close the file
			if (mSoundFile){
				sf_close(mSoundFile);
			mSoundFile = NULL;
			}
		}
	}
	return err;
}

TTErr TTSoundfileRecorder::setLength(const TTValue& newValue)
{	TTFloat64	newLength = newValue;
	if (newLength != mLength){
		mLength = newLength;
		mNumBufferFrames = 0; //hack to force a resize of mBuffer in the process method
	}
	return kTTErrNone;
}

// "FLAC-24bit" -> SF_FORMAT_FLAC | SF_FORMAT_PCM_24
// something to consider when you want to write large amount of data as fast as possible: http://www.mega-nerd.com/libsndfile/FAQ.html#Q006
int TTSoundfileRecorder::translateFormatFromName(TTSymbolPtr name)
{
	int		format = 0;
	char	cname[64];
	char*	s;

	if (name)
		strncpy(cname, name->getCString(), 64);
	else
		strncpy(cname, "CAF", 64);

	s = strrchr(cname, '-'); // look for subtype
	if (s) {
		*s = 0;
		s++;
		if (s) {
			if (strstr(s, "16bit"))
				format |= SF_FORMAT_PCM_16;
			else if (strstr(s, "24bit"))
				format |= SF_FORMAT_PCM_24;
			else if (strstr(s, "32bit"))
				format |= SF_FORMAT_PCM_32;
			else
				format |= SF_FORMAT_PCM_24;
		}
	}
	else { // no subtype, set default
		format |= SF_FORMAT_PCM_24;
	}

	// now look at the primary type
	if (strstr(cname, "FLAC"))
		format |= SF_FORMAT_FLAC;
	else if (strstr(cname, "AIFF"))
		format |= SF_FORMAT_AIFF;
	else if (strstr(cname, "WAV"))
		format |= SF_FORMAT_WAV;
	else if (strstr(cname, "Matlab"))
		format |= SF_FORMAT_MAT5;
	else
		format |= SF_FORMAT_CAF;

	return format;
}

TTErr TTSoundfileRecorder::setFilePath(const TTValue& newValue)
{
	mFilePath = newValue;
	/*if ((mNumChannels) && (mFormat))
		return openFile();
	else */
		return kTTErrNone;
}

TTErr TTSoundfileRecorder::openFile()
{
	memset(&mSoundFileInfo, 0, sizeof(mSoundFileInfo));
	mSoundFileInfo.channels = mNumChannels;
	mSoundFileInfo.format = translateFormatFromName(mFormat);
	mSoundFileInfo.samplerate = sr;

	mSoundFile = sf_open(mFilePath->getCString(), SFM_WRITE, &mSoundFileInfo);

	if (!mSoundFile) {
		TTLogMessage("Can't create soundfile.\n");
		return kTTErrGeneric;
	}
	return kTTErrNone;
}

TTErr TTSoundfileRecorder::processAudioRecording(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
{
	TTAudioSignal&		out = outputs->getSignal(0);
	TTAudioSignal&		in  = inputs->getSignal(0);
	TTSampleValuePtr	outSample, inSample;
	TTUInt16			channelCount = in.getNumChannelsAsInt();
	TTUInt16			vs = in.getVectorSizeAsInt();
	TTUInt16			n, channel;
	TTBoolean			bufferNeedsResize = NO;
	//sf_count_t			numSamplesWritten;
	//TTUInt64			progress = mCycles*vs*channelCount;

	if (mNumChannels != channelCount) {		// input channel number has changed, we need to set up the buffer
		mNumChannels = channelCount;
		bufferNeedsResize = YES;
	}

	if (mNumBufferFrames != vs) {   //vector size has changed, we need to set up the buffer
		mNumBufferFrames = vs;
		bufferNeedsResize = YES;
	}
	if (bufferNeedsResize){
		TTUInt64 buffersize = mNumChannels * mNumBufferFrames;
		mBuffer.resize(buffersize);
	}

	if (!mSoundFile) //if we don't have already a file open, do it now.
		openFile();

	for (channel=0; channel<channelCount; channel++) {
		inSample = in.mSampleVectors[channel];
		outSample = out.mSampleVectors[channel]; // sending audio out
		for (n=0; n<vs; n++){
			//mBuffer[progress+(n * channelCount + channel)] = inSample[n]; //sending audio to recording buffer
			mBuffer[(n * channelCount + channel)] = inSample[n]; //sending audio to recording buffer
			outSample[n] = inSample[n];  // sending audio out
		}
	}
    //mCycles++;
	//if (mCycles == 100){

	if (sf_writef_double(mSoundFile, &mBuffer[0], vs) != vs) {
		char errorStr[256];
        sf_error_str(mSoundFile, errorStr, 256);
		TTLogError("Error while writing file: %s \n",errorStr);
	}

	//	mCycles = 0;
	//}

	return kTTErrNone;
}

TTErr TTSoundfileRecorder::processTimedAudioRecording(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
{
	TTAudioSignal&		out = outputs->getSignal(0);
	TTAudioSignal&		in  = inputs->getSignal(0);
	TTSampleValuePtr	outSample, inSample;
	TTUInt16			channelCount = in.getNumChannelsAsInt();
	TTUInt16			vs = in.getVectorSizeAsInt();
	TTUInt16			n, channel;
	TTBoolean			bufferNeedsResize = NO;
	//sf_count_t			numSamplesWritten;
	TTUInt64			progress = mCycles*vs*channelCount;

	if (mNumChannels != channelCount) {		// input channel number has changed, we need to set up the buffer
		mNumChannels = channelCount;
		bufferNeedsResize = YES;
	}

	if (mNumBufferFrames != vs) {   //vector size has changed, we need to set up the buffer
		mNumBufferFrames = vs;
		bufferNeedsResize = YES;
	}
	if (bufferNeedsResize){
		TTUInt64 buffersize = mNumChannels * mNumBufferFrames * ceil((double)mLengthInSamples/(double)mNumBufferFrames);
		mBuffer.resize(buffersize);
	}

	if (!mSoundFile) //if we don't have already a file open, do it now.
		openFile();

	for (channel=0; channel<channelCount; channel++) {
		inSample = in.mSampleVectors[channel];
		outSample = out.mSampleVectors[channel]; // sending audio out
		for (n=0; n<vs; n++){
			mBuffer[progress+(n * channelCount + channel)] = inSample[n]; //sending audio to recording buffer
			outSample[n] = inSample[n];  // sending audio out
		}
	}

	mCycles++;
	mLengthInSamples -= vs; // decreasing the samplecounter by a vs
	if (mLengthInSamples <= 0){ //TODO: we might want to chop of the samples that were recorded too long
		if (sf_writef_double(mSoundFile, &mBuffer[0], mCycles*vs) != mCycles*vs) {
			char errorStr[256];
			sf_error_str(mSoundFile, errorStr, 256);
			TTLogError("Error while writing file: %s \n",errorStr);
		}
		return setRecord(0);
	}
	else return kTTErrNone;
}

TTErr TTSoundfileRecorder::processAudioBypass(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
{
	TTAudioSignal&		out = outputs->getSignal(0);
	TTAudioSignal&		in  = inputs->getSignal(0);
	TTSampleValuePtr	outSample, inSample;
	TTUInt16			channelCount = in.getNumChannelsAsInt();
	TTUInt16			vs = in.getVectorSizeAsInt();
	TTUInt16			n, channel;

	// not recording, just bypassing audio and return
	 for (channel=0; channel<channelCount; channel++) {
		 inSample = in.mSampleVectors[channel];
		 outSample = out.mSampleVectors[channel]; // sending audio out
		 for (n=0; n<vs; n++)
			 outSample[n] = inSample[n];  // sending audio out
	}
	return kTTErrNone;
}

<|endoftext|>


<commit_before>#pragma once

#include <libekb.H>

#include <cstdarg>
#include <nlohmann/json.hpp>

namespace openpower
{
namespace pels
{
namespace phal
{

using json = nlohmann::json;
using FFDCData = std::vector<std::pair<std::string, std::string>>;

/**
 * @brief Used to convert  processed SBE FFDC FAPI format packets into
 *        PEL expected format.
 *
 * @param[out] pelJSONFmtCalloutDataList used to store collected callout
 *             data into pel expected format
 * @param[out] ffdcUserData used to store additional ffdc user data to
 *             provided by the SBE FFDC packet.
 *
 * @return NULL
 *
 */
void convertFAPItoPELformat(FFDC& ffdc, json& pelJSONFmtCalloutDataList,
                            FFDCData& ffdcUserData);
} // namespace phal
} // namespace pels
} // namespace openpower
<commit_msg>PEL: convertFAPItoPELformat function description updates<commit_after>#pragma once

#include <libekb.H>

#include <cstdarg>
#include <nlohmann/json.hpp>

namespace openpower
{
namespace pels
{
namespace phal
{

using json = nlohmann::json;
using FFDCData = std::vector<std::pair<std::string, std::string>>;

/**
 * @brief Used to convert  processed SBE FFDC FAPI format packets into
 *        PEL expected format.
 *
 * @param[in]  ffdc FFDC data capturd by the HWP
 * @param[out] pelJSONFmtCalloutDataList used to store collected callout
 *             data into pel expected format
 * @param[out] ffdcUserData used to store additional ffdc user data to
 *             provided by the SBE FFDC packet.
 *
 * @return NULL
 *
 */
void convertFAPItoPELformat(FFDC& ffdc, json& pelJSONFmtCalloutDataList,
                            FFDCData& ffdcUserData);
} // namespace phal
} // namespace pels
} // namespace openpower
<|endoftext|>


<commit_before>/**
 * @file TextPlot.cpp
 *
 * A simple console-based data plotter.
 *
 * This file is part of the Aquila DSP library.
 * Aquila is free software, licensed under the MIT/X11 License. A copy of
 * the license is provided with the library in the LICENSE file.
 *
 * @package Aquila
 * @version 3.0.0-dev
 * @author Zbigniew Siciarz
 * @date 2007-2013
 * @license http://www.opensource.org/licenses/mit-license.php MIT
 * @since 3.0.0
 */

#include "TextPlot.h"
#include <memory>

namespace Aquila
{
    /**
     * Creates the plot object.
     *
     * @param title plot title (optional, default is "Data plot")
     * @param out where to output the plot data (default is std::cout)
     */
    TextPlot::TextPlot(const std::string &title, std::ostream &out):
        m_title(title), m_out(out), m_width(64), m_height(16)
    {
    }

    /**
     * "Draws" the plot to the output stream.
     *
     * @param plot internal plot data
     */
    void TextPlot::drawPlotMatrix(const PlotMatrixType &plot)
    {
        const std::size_t length = plot.size();

        m_out << "\n" << m_title << "\n";
        // output the plot data, flushing only at the end
        for (unsigned int y = 0; y < m_height; ++y)
        {
            for (unsigned int x = 0; x < length; ++x)
            {
                m_out << plot[x][y];
            }
            m_out << "\n";
        }
        m_out.flush();
    }

    /**
     * A shorthand for plotting only the first half of magnitude spectrum.
     *
     * @param spectrum a vector of complex numbers
     */
    void TextPlot::plotSpectrum(Aquila::SpectrumType spectrum)
    {
        std::size_t halfLength = spectrum.size() / 2;
        std::unique_ptr<double[]> absSpectrum(new double[halfLength]);
        for (std::size_t i = 0; i < halfLength; ++i)
        {
            absSpectrum[i] = std::abs(spectrum[i]);
        }
        plot(absSpectrum.get(), halfLength);
    }
}
<commit_msg>TextPlot::plotSpectrum() using a vector instead of heap memory.<commit_after>/**
 * @file TextPlot.cpp
 *
 * A simple console-based data plotter.
 *
 * This file is part of the Aquila DSP library.
 * Aquila is free software, licensed under the MIT/X11 License. A copy of
 * the license is provided with the library in the LICENSE file.
 *
 * @package Aquila
 * @version 3.0.0-dev
 * @author Zbigniew Siciarz
 * @date 2007-2013
 * @license http://www.opensource.org/licenses/mit-license.php MIT
 * @since 3.0.0
 */

#include "TextPlot.h"

namespace Aquila
{
    /**
     * Creates the plot object.
     *
     * @param title plot title (optional, default is "Data plot")
     * @param out where to output the plot data (default is std::cout)
     */
    TextPlot::TextPlot(const std::string &title, std::ostream &out):
        m_title(title), m_out(out), m_width(64), m_height(16)
    {
    }

    /**
     * "Draws" the plot to the output stream.
     *
     * @param plot internal plot data
     */
    void TextPlot::drawPlotMatrix(const PlotMatrixType &plot)
    {
        const std::size_t length = plot.size();

        m_out << "\n" << m_title << "\n";
        // output the plot data, flushing only at the end
        for (unsigned int y = 0; y < m_height; ++y)
        {
            for (unsigned int x = 0; x < length; ++x)
            {
                m_out << plot[x][y];
            }
            m_out << "\n";
        }
        m_out.flush();
    }

    /**
     * A shorthand for plotting only the first half of magnitude spectrum.
     *
     * @param spectrum a vector of complex numbers
     */
    void TextPlot::plotSpectrum(Aquila::SpectrumType spectrum)
    {
        std::size_t halfLength = spectrum.size() / 2;
        std::vector<double> absSpectrum(halfLength);
        for (std::size_t i = 0; i < halfLength; ++i)
        {
            absSpectrum[i] = std::abs(spectrum[i]);
        }
        plot(absSpectrum);
    }
}
<|endoftext|>


<commit_before><commit_msg>refactor PseudoRubyText to use RenderContext<commit_after><|endoftext|>