<commit_before>#include <unordered_map>

#include <QString>

#include "lirch_plugin.h"
#include "QString_hash.h"
#include "edict_messages.h"
#include "notify_messages.h"
#include "grinder_messages.h"
#include "core/core_messages.h"
#include "blocker_messages.h"
#include "notify_messages.h"
#include "channel_messages.h"
#include "parser.h"

using namespace std;

QString prefix(const QString &s)
{
	if (s.isEmpty() || s[0]!='/')
		return "";
	return s.left(s.indexOf(' '));
}

QString run_replacers(const unordered_multimap<QString, pair<QRegExp, QString>> &replacements, QString message)
{
	auto range=replacements.equal_range(prefix(message));
	for (auto &i=range.first; i!=range.second; ++i)
		message.replace(i->second.first, i->second.second);
	return message;
}

message handle_me(QString text, QString channel)
{
	if (text=="/me")
		return empty_message::create();
	//Remove the leading "/me "
	return edict_message::create(edict_message_subtype::ME, channel, text.remove(0,4));
}

message handle_quit(QString, QString)
{
	return core_quit_message::create();
}

message handle_normal(QString text, QString channel)
{
	if (text.startsWith("/say "))
		text.remove(0,5);
	return edict_message::create(edict_message_subtype::NORMAL, channel, text);
}

message handle_channel_change(QString text, QString)
{
	if (!text.startsWith("/channel"))
		return empty_message::create();
	return set_channel::create(text.remove(0, 9));
}

message handle_commands(QString text, QString channel)
{
	if (!text.startsWith("/commands"))
		return empty_message::create();
	QStringList parsed = parse(text);
	parsed.removeFirst();
	return display_commands_message::create(channel, parsed);
}

message handle_erase_command(QString text, QString)
{
	if(!text.startsWith("/macro_erase "))
		return empty_message::create();
	QStringList parsed = parse(text);
	parsed.removeFirst();
	QString command = parsed.at(0);
	if (command.size()!=0 && command[0]!='/')
		command.push_front("/");
	if(parsed.size() < 1)
		return empty_message::create();
	while(parsed.size() < 3)
		parsed += "";
	return register_replacer::create(command, QRegExp(parsed.at(1), Qt::CaseSensitive, QRegExp::RegExp2), parsed.at(2), register_replacer_subtype::REMOVE);
}

message handle_channel_leave(QString text, QString)
{
	if (!text.startsWith("/leave"))
		return empty_message::create();
	return leave_channel::create(text.remove(0, 7));
}

message handle_user_command(QString text, QString)
{
	if (!text.startsWith("/macro "))
		return empty_message::create();
	QStringList parsed = parse(text);
	parsed.removeFirst();
	QString command = parsed.at(0);
	if (command.size()!=0 && command[0]!='/')
		command.push_front("/");
	if(parsed.size() < 3)
		return empty_message::create();
	return register_replacer::create(command, QRegExp(parsed.at(1), Qt::CaseSensitive, QRegExp::RegExp2), parsed.at(2));
}

void run(plugin_pipe p, string name)
{
	p.write(registration_message::create(-30000, name, "raw_edict"));
	p.write(registration_message::create(-30000, name, "register_replacer"));
	p.write(registration_message::create(-30000, name, "register_handler"));
	p.write(registration_message::create(-30000, name, "display commands"));
	unordered_multimap<QString, pair<QRegExp, QString>> text_replacements;
	unordered_map<QString, function<message (QString, QString)>> handlers;
	while (true)
	{
		message m=p.blocking_read();
		if (m.type=="shutdown")
		{
			//We don't have any cleanup to do, so just return
			return;
		}
		else if (m.type=="registration_status")
		{
			auto s=dynamic_cast<registration_status *>(m.getdata());
			if (!s)
				continue;
			//Retry 2000 times until we succeed
			if (!s->status)
			{
				if (s->priority>-32000)
					p.write(registration_message::create(s->priority-1, name, s->type));
			}
			else
			{
				if (s->type=="register_handler")
				{
					p.write(handler_ready::create());
					p.write(register_handler::create("", handle_normal));
					p.write(register_handler::create("/say", handle_normal));
					p.write(register_handler::create("/me", handle_me));
					p.write(register_handler::create("/q", handle_quit));
					p.write(register_handler::create("/quit", handle_quit));
					p.write(register_handler::create("/channel", handle_channel_change));
					p.write(register_handler::create("/commands", handle_commands));
					p.write(register_handler::create("/leave", handle_channel_leave));
					p.write(register_handler::create("/macro", handle_user_command));
					p.write(register_handler::create("/macro_erase", handle_erase_command));
				}
				else if (s->type=="register_replacer")
				{
					p.write(replacer_ready::create());
					p.write(register_replacer::create("/slap", QRegExp("/slap\\b( ?) *(.*)", Qt::CaseSensitive, QRegExp::RegExp2), "/me slaps\\1\\2 with an optimistic biologist"));
				}
			}
		}
		else if (m.type=="register_replacer")
		{
			auto i=dynamic_cast<register_replacer *>(m.getdata());
			if (!i)
				continue;
			if(i->subtype == register_replacer_subtype::ADD)
				text_replacements.insert({i->command, {i->pattern, i->replacement}});
			else if(i->subtype == register_replacer_subtype::REMOVE)
			{
				if(i->pattern.pattern() == "")
					text_replacements.erase(text_replacements.find(i->command));
				else if(text_replacements.count(i->command) > 0)
					for(unordered_multimap<QString, pair<QRegExp, QString> >::iterator iter = text_replacements.find(i->command); iter!=text_replacements.end(); iter++)
					{
						if(i->command == iter->first && i->pattern == iter->second.first && (i->replacement == "" || i->replacement == iter->second.second))
						{
							text_replacements.erase(iter);
							break;
						}
					}
			}
		}
		else if (m.type=="register_handler")
		{
			auto i=dynamic_cast<register_handler *>(m.getdata());
			if (!i)
				continue;
			handlers.insert({i->command, i->handler});
		}
		else if (m.type=="raw_edict")
		{
			auto e=dynamic_cast<raw_edict_message *>(m.getdata());
			if (!e)
				continue;
			//Ensure that characters with multiple representations
			//are normalized so we can compare strings directly by
			//character.
			auto str=e->contents.normalized(QString::NormalizationForm_C);
			if (str.isEmpty())
				//We don't propagate empty messages (on principle)
				continue;
			auto pre=prefix(str);
			auto mod=run_replacers(text_replacements, str);
			if (prefix(mod)!=pre)
			{
				//Recurse if the type of the message has been changed
				p.write(raw_edict_message::create(mod, e->channel));
				continue;
			}
			if (handlers.count(pre)==0)
				//Nothing can handle this type of message, so complain
				//We should be using tr here since this is a
				//message to be displayed, but I'm not sure
				//which tr to use.
				p.write(notify_message::create(e->channel, QString("Unknown message type \"%1\"").arg(pre)));
			else
				p.write(handlers[pre](str, e->channel));
		}
		else if (m.type == "display commands")
		{
			auto internals=dynamic_cast<display_commands_message *>(m.getdata());
			if (!internals)
				continue;
			QString output;
			if(internals->arguments.size() == 0)
			{
				output = "commands:";
				for(unordered_map<QString, function<message (QString, QString)>>::iterator i = handlers.begin(); i != handlers.end(); i++)
				{
					if(i->first != "")
					{
						output += "\n";
						output += i->first;
					}
				}
				for(unordered_multimap<QString, pair<QRegExp, QString>>::iterator i = text_replacements.begin(); i != text_replacements.end(); i++)
				{
					if(i->first != "")
					{
						output += "\n";
						output += i->first;
					}
				}
			}
			for(int argument = 0; argument < internals->arguments.size(); argument++)
			{
				if(internals->arguments[argument] == "macros")
				{
					output = "macros:";
					for(unordered_multimap<QString, pair<QRegExp, QString>>::iterator i = text_replacements.begin(); i != text_replacements.end(); i++)
						if(i->first != "")
							output.append("\n").append(i->first).append(" \"").append(i->second.first.pattern()).append("\" \"").append(i->second.second).append("\"");
				}
			}
			p.write(notify_message::create(internals->channel, output));
		}
		else if (m.type == "query commands")
		{

		}
		else
		{
			p.write(m.decrement_priority());
		}
	}
}
<commit_msg>Sorted commands, prevented duplicate listings, and added a way to list replacements<commit_after>#include <unordered_map>
#include <set>

#include <QString>

#include "lirch_plugin.h"
#include "QString_hash.h"
#include "edict_messages.h"
#include "notify_messages.h"
#include "grinder_messages.h"
#include "core/core_messages.h"
#include "blocker_messages.h"
#include "notify_messages.h"
#include "channel_messages.h"
#include "parser.h"

using namespace std;

QString prefix(const QString &s)
{
	if (s.isEmpty() || s[0]!='/')
		return "";
	return s.left(s.indexOf(' '));
}

QString run_replacers(const unordered_multimap<QString, pair<QRegExp, QString>> &replacements, QString message)
{
	auto range=replacements.equal_range(prefix(message));
	for (auto &i=range.first; i!=range.second; ++i)
		message.replace(i->second.first, i->second.second);
	return message;
}

message handle_me(QString text, QString channel)
{
	if (text=="/me")
		return empty_message::create();
	//Remove the leading "/me "
	return edict_message::create(edict_message_subtype::ME, channel, text.remove(0,4));
}

message handle_quit(QString, QString)
{
	return core_quit_message::create();
}

message handle_normal(QString text, QString channel)
{
	if (text.startsWith("/say "))
		text.remove(0,5);
	return edict_message::create(edict_message_subtype::NORMAL, channel, text);
}

message handle_channel_change(QString text, QString)
{
	if (!text.startsWith("/channel"))
		return empty_message::create();
	return set_channel::create(text.remove(0, 9));
}

message handle_commands(QString text, QString channel)
{
	if (!text.startsWith("/commands"))
		return empty_message::create();
	QStringList parsed = parse(text);
	parsed.removeFirst();
	return display_commands_message::create(channel, parsed);
}

message handle_erase_command(QString text, QString)
{
	if(!text.startsWith("/macro_erase "))
		return empty_message::create();
	QStringList parsed = parse(text);
	parsed.removeFirst();
	QString command = parsed.at(0);
	if (command.size()!=0 && command[0]!='/')
		command.push_front("/");
	if(parsed.size() < 1)
		return empty_message::create();
	while(parsed.size() < 3)
		parsed += "";
	return register_replacer::create(command, QRegExp(parsed.at(1), Qt::CaseSensitive, QRegExp::RegExp2), parsed.at(2), register_replacer_subtype::REMOVE);
}

message handle_channel_leave(QString text, QString)
{
	if (!text.startsWith("/leave"))
		return empty_message::create();
	return leave_channel::create(text.remove(0, 7));
}

message handle_user_command(QString text, QString)
{
	if (!text.startsWith("/macro "))
		return empty_message::create();
	QStringList parsed = parse(text);
	parsed.removeFirst();
	QString command = parsed.at(0);
	if (command.size()!=0 && command[0]!='/')
		command.push_front("/");
	if(parsed.size() < 3)
		return empty_message::create();
	return register_replacer::create(command, QRegExp(parsed.at(1), Qt::CaseSensitive, QRegExp::RegExp2), parsed.at(2));
}

void run(plugin_pipe p, string name)
{
	p.write(registration_message::create(-30000, name, "raw_edict"));
	p.write(registration_message::create(-30000, name, "register_replacer"));
	p.write(registration_message::create(-30000, name, "register_handler"));
	p.write(registration_message::create(-30000, name, "display commands"));
	unordered_multimap<QString, pair<QRegExp, QString>> text_replacements;
	unordered_map<QString, function<message (QString, QString)>> handlers;
	while (true)
	{
		message m=p.blocking_read();
		if (m.type=="shutdown")
		{
			//We don't have any cleanup to do, so just return
			return;
		}
		else if (m.type=="registration_status")
		{
			auto s=dynamic_cast<registration_status *>(m.getdata());
			if (!s)
				continue;
			//Retry 2000 times until we succeed
			if (!s->status)
			{
				if (s->priority>-32000)
					p.write(registration_message::create(s->priority-1, name, s->type));
			}
			else
			{
				if (s->type=="register_handler")
				{
					p.write(handler_ready::create());
					p.write(register_handler::create("", handle_normal));
					p.write(register_handler::create("/say", handle_normal));
					p.write(register_handler::create("/me", handle_me));
					p.write(register_handler::create("/q", handle_quit));
					p.write(register_handler::create("/quit", handle_quit));
					p.write(register_handler::create("/channel", handle_channel_change));
					p.write(register_handler::create("/commands", handle_commands));
					p.write(register_handler::create("/leave", handle_channel_leave));
					p.write(register_handler::create("/macro", handle_user_command));
					p.write(register_handler::create("/macro_erase", handle_erase_command));
				}
				else if (s->type=="register_replacer")
				{
					p.write(replacer_ready::create());
					p.write(register_replacer::create("/slap", QRegExp("/slap\\b( ?) *(.*)", Qt::CaseSensitive, QRegExp::RegExp2), "/me slaps\\1\\2 with an optimistic biologist"));
				}
			}
		}
		else if (m.type=="register_replacer")
		{
			auto i=dynamic_cast<register_replacer *>(m.getdata());
			if (!i)
				continue;
			if(i->subtype == register_replacer_subtype::ADD)
				text_replacements.insert({i->command, {i->pattern, i->replacement}});
			else if(i->subtype == register_replacer_subtype::REMOVE)
			{
				if(i->pattern.pattern() == "")
					text_replacements.erase(text_replacements.find(i->command));
				else if(text_replacements.count(i->command) > 0)
					for(unordered_multimap<QString, pair<QRegExp, QString> >::iterator iter = text_replacements.find(i->command); iter!=text_replacements.end(); iter++)
					{
						if(i->command == iter->first && i->pattern == iter->second.first && (i->replacement == "" || i->replacement == iter->second.second))
						{
							text_replacements.erase(iter);
							break;
						}
					}
			}
		}
		else if (m.type=="register_handler")
		{
			auto i=dynamic_cast<register_handler *>(m.getdata());
			if (!i)
				continue;
			handlers.insert({i->command, i->handler});
		}
		else if (m.type=="raw_edict")
		{
			auto e=dynamic_cast<raw_edict_message *>(m.getdata());
			if (!e)
				continue;
			//Ensure that characters with multiple representations
			//are normalized so we can compare strings directly by
			//character.
			auto str=e->contents.normalized(QString::NormalizationForm_C);
			if (str.isEmpty())
				//We don't propagate empty messages (on principle)
				continue;
			auto pre=prefix(str);
			auto mod=run_replacers(text_replacements, str);
			if (prefix(mod)!=pre)
			{
				//Recurse if the type of the message has been changed
				p.write(raw_edict_message::create(mod, e->channel));
				continue;
			}
			if (handlers.count(pre)==0)
				//Nothing can handle this type of message, so complain
				//We should be using tr here since this is a
				//message to be displayed, but I'm not sure
				//which tr to use.
				p.write(notify_message::create(e->channel, QObject::tr("Unknown message type \"%1\"").arg(pre)));
			else
				p.write(handlers[pre](mod, e->channel));
		}
		else if (m.type == "display commands")
		{
			auto internals=dynamic_cast<display_commands_message *>(m.getdata());
			if (!internals)
				continue;
			QString output;
			if(internals->arguments.size() == 0)
			{
				output = "\ncommands:";
				set<QString> commands;
				for(const auto &p : handlers)
					commands.insert(p.first);
				for(const auto &p : text_replacements)
					commands.insert(p.first);
				commands.erase("");
				for (const auto &s : commands)
					output+="\n"+s;
			}
			//Should this be put into a "/macros" command?
			if (internals->arguments.count("macros")!=0)
			{
				output += "\nmacros:";
				for(const auto &p : text_replacements)
					if (p.first!="")
						output+="\n"+p.first+" \'"+p.second.first.pattern()+"\' \'"+p.second.second+"\'";
			}
			//Same for this
			if (internals->arguments.count("replacements")!=0)
			{
				output += "\nreplacements:";
				auto range=text_replacements.equal_range("");
				for_each(range.first, range.second, [&output](const decltype(text_replacements)::value_type &p)
				{
					output+="\n\'"+p.second.first.pattern()+"\' \'"+p.second.second+"\'";
				});
			}
			output.remove(0,1);
			p.write(notify_message::create(internals->channel, output));
		}
		else if (m.type == "query commands")
		{

		}
		else
		{
			p.write(m.decrement_priority());
		}
	}
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2015, Project OSRM contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef BASE_PLUGIN_HPP
#define BASE_PLUGIN_HPP

#include <osrm/coordinate.hpp>
#include <osrm/json_container.hpp>
#include <osrm/route_parameters.hpp>

#include <string>
#include <vector>
#include <algorithm>

class BasePlugin
{
  public:
    BasePlugin() {}
    // Maybe someone can explain the pure virtual destructor thing to me (dennis)
    virtual ~BasePlugin() {}
    virtual const std::string GetDescriptor() const = 0;
    virtual int HandleRequest(const RouteParameters &, osrm::json::Object &) = 0;
    virtual bool
    check_all_coordinates(const std::vector<FixedPointCoordinate> &coordinates) const final
    {
        if (2 > coordinates.size() || std::any_of(std::begin(coordinates), std::end(coordinates),
                                                  [](const FixedPointCoordinate &coordinate)
                                                  {
                                                      return !coordinate.is_valid();
                                                  }))
        {
            return false;
        }
        return true;
    }
};

#endif /* BASE_PLUGIN_HPP */
<commit_msg>reorder includes, fixes style regression from commit fdf2e59.<commit_after>/*

Copyright (c) 2015, Project OSRM contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef BASE_PLUGIN_HPP
#define BASE_PLUGIN_HPP

#include <osrm/coordinate.hpp>
#include <osrm/json_container.hpp>
#include <osrm/route_parameters.hpp>

#include <algorithm>
#include <string>
#include <vector>

class BasePlugin
{
  public:
    BasePlugin() {}
    // Maybe someone can explain the pure virtual destructor thing to me (dennis)
    virtual ~BasePlugin() {}
    virtual const std::string GetDescriptor() const = 0;
    virtual int HandleRequest(const RouteParameters &, osrm::json::Object &) = 0;
    virtual bool
    check_all_coordinates(const std::vector<FixedPointCoordinate> &coordinates) const final
    {
        if (2 > coordinates.size() || std::any_of(std::begin(coordinates), std::end(coordinates),
                                                  [](const FixedPointCoordinate &coordinate)
                                                  {
                                                      return !coordinate.is_valid();
                                                  }))
        {
            return false;
        }
        return true;
    }
};

#endif /* BASE_PLUGIN_HPP */
<|endoftext|>


<commit_before>#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    cout << "Hello World!" << endl;
    return 0;
}
<commit_msg>Implement some stuff<commit_after>#include <iostream>

using namespace std;

struct Order
{
    double GetOrder, SendOrder, TransferAmount;
};

int sort (int *arr[], int size)
{
    if (size <= 0)
        cerr << "Invalid size" << endl;

    int *newarr = new int[size]; int temp;

    /* Сортировка массива пузырьком */
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                temp = newarr[j];
                arr[j] = arr[j + 1];
                newarr[j + 1] = temp;
            }
        }
    }

    return *newarr;
}

void GetCheckValue ()
{

}

int main (int argc, char *argv[])
{
    return 0;
}
<|endoftext|>


<commit_before>#include <kernel/task.H>
#include <kernel/scheduler.H>
#include <kernel/taskmgr.H>
#include <kernel/cpu.H>
#include <kernel/cpumgr.H>
#include <kernel/console.H>
#include <kernel/timemgr.H>

void Scheduler::addTask(task_t* t)
{
    if (t->cpu->idle_task != t)
    {
	iv_taskList.insert(t);
    }
}

void Scheduler::returnRunnable()
{
    this->addTask(TaskManager::getCurrentTask());
}

void Scheduler::setNextRunnable()
{
    task_t* t = iv_taskList.remove();

    if (NULL == t)
    {
	t = CpuManager::getCurrentCPU()->idle_task;
	// Set short decrementer.
	register uint64_t decrementer = TimeManager::getTimeSliceCount();
	asm volatile("mtdec %0" :: "r"(decrementer));
    }

    TaskManager::setCurrentTask(t);
}
<commit_msg>Ensure decrementer is initialized for normal task execution.<commit_after>#include <kernel/task.H>
#include <kernel/scheduler.H>
#include <kernel/taskmgr.H>
#include <kernel/cpu.H>
#include <kernel/cpumgr.H>
#include <kernel/console.H>
#include <kernel/timemgr.H>

void Scheduler::addTask(task_t* t)
{
    if (t->cpu->idle_task != t)
    {
	iv_taskList.insert(t);
    }
}

void Scheduler::returnRunnable()
{
    this->addTask(TaskManager::getCurrentTask());
}

void Scheduler::setNextRunnable()
{
    task_t* t = iv_taskList.remove();

    if (NULL == t)
    {
	t = CpuManager::getCurrentCPU()->idle_task;
	// TODO: Set short decrementer.
	register uint64_t decrementer = TimeManager::getTimeSliceCount();
	asm volatile("mtdec %0" :: "r"(decrementer));
    }
    else // Set normal timeslice to decrementer.
    {
	register uint64_t decrementer = TimeManager::getTimeSliceCount();
	asm volatile("mtdec %0" :: "r"(decrementer));
    }

    TaskManager::setCurrentTask(t);
}
<|endoftext|>


<commit_before>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "unit_tests.hpp"
#include "mfem.hpp"

namespace mfem
{

#ifdef MFEM_USE_MPI

namespace internal
{

std::vector<HYPRE_BigInt> GenerateColumnPartitioning(const int world_size,
                                                     const int rank, const int size_per_rank)
{
   std::vector<HYPRE_BigInt> col;
   if (HYPRE_AssumedPartitionCheck())
   {
      int offset = rank*size_per_rank;
      col = {offset, offset + size_per_rank};
   }
   else
   {
      col.resize(world_size+1);
      for (int i=0; i<=world_size; ++i)
      {
         col[i] = i*size_per_rank;
      }
   }
   return col;
}

} // namespace internal

TEST_CASE("HypreParVector I/O", "[Parallel], [HypreParVector]")
{
   // Create a test vector (two entries per rank) with entries increasing
   // sequentially. Write the vector to a file, read it into another vector, and
   // make sure we get the same answer.

   int world_size, rank;
   MPI_Comm_size(MPI_COMM_WORLD, &world_size);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   int size_per_rank = 2;

   HYPRE_BigInt glob_size = world_size*size_per_rank;
   std::vector<HYPRE_BigInt> col = internal::GenerateColumnPartitioning(world_size,
                                                                        rank, size_per_rank);

   // Initialize vector and write to files
   HypreParVector v1(MPI_COMM_WORLD, glob_size, col.data());
   for (int i=0; i<size_per_rank; ++i)
   {
      v1(i) = rank*size_per_rank + i;
   }
   v1.Print("vec");

   // Check that we read the same vector from disk
   HypreParVector v2;
   v2.Read(MPI_COMM_WORLD, "vec");
   v2 -= v1;
   REQUIRE(InnerProduct(v2, v2) == MFEM_Approx(0.0));

   // Clean up
   std::string prefix = "vec.";
   std::string suffix = std::to_string(rank);
   remove((prefix + suffix).c_str());
   remove((prefix + "INFO." + suffix).c_str());
}

TEST_CASE("HypreParVector Move Constructor", "[Parallel], [HypreParVector]")
{
   int world_size, rank;
   MPI_Comm_size(MPI_COMM_WORLD, &world_size);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   int size_per_rank = 2;

   HYPRE_BigInt glob_size = world_size*size_per_rank;
   std::vector<HYPRE_BigInt> col = internal::GenerateColumnPartitioning(world_size,
                                                                        rank, size_per_rank);

   // Initialize vector
   HypreParVector v1(MPI_COMM_WORLD, glob_size, col.data());
   for (int i=0; i<size_per_rank; ++i)
   {
      v1(i) = rank*size_per_rank + i;
   }

   // Make a copy so we can compare it later
   HypreParVector v1_copy(v1);

   // Also save off the data pointer
   double* v1_data = v1.GetData();

   // Now move from the original and compare
   HypreParVector v1_move(std::move(v1));

   REQUIRE(v1.GetOwnership() == 0);
   REQUIRE(v1_move.GetOwnership() == 1);
   REQUIRE(v1_move.Size() == v1_copy.Size());
   REQUIRE(v1_move.GlobalSize() == v1_copy.GlobalSize());

   REQUIRE(v1_move.GetData() == v1_data);

   // The full HypreParVectors should also be the same
   v1_copy -= v1_move;
   REQUIRE(InnerProduct(v1_copy, v1_copy) == MFEM_Approx(0.0));
}

TEST_CASE("HypreParVector Move Assignment", "[Parallel], [HypreParVector]")
{
   int world_size, rank;
   MPI_Comm_size(MPI_COMM_WORLD, &world_size);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   int size_per_rank = 2;

   HYPRE_BigInt glob_size = world_size*size_per_rank;
   std::vector<HYPRE_BigInt> col = internal::GenerateColumnPartitioning(world_size,
                                                                        rank, size_per_rank);

   // Initialize vector
   HypreParVector v1(MPI_COMM_WORLD, glob_size, col.data());
   for (int i=0; i<size_per_rank; ++i)
   {
      v1(i) = rank*size_per_rank + i;
   }

   // Make a copy so we can compare it later
   HypreParVector v1_copy(v1);

   // Also save off the data pointer
   double* v1_data = v1.GetData();

   // Now move from the original and compare
   HypreParVector v1_move;
   v1_move = std::move(v1);

   REQUIRE(v1.GetOwnership() == 0);
   REQUIRE(v1_move.GetOwnership() == 1);
   REQUIRE(v1_move.Size() == v1_copy.Size());
   REQUIRE(v1_move.GlobalSize() == v1_copy.GlobalSize());

   REQUIRE(v1_move.GetData() == v1_data);

   // The full HypreParVectors should also be the same
   v1_copy -= v1_move;
   REQUIRE(InnerProduct(v1_copy, v1_copy) == MFEM_Approx(0.0));
}

#endif // MFEM_USE_MPI

} // namespace mfem
<commit_msg>tests: make sure that moved-from hpvec is empty<commit_after>// Copyright (c) 2010-2021, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "unit_tests.hpp"
#include "mfem.hpp"

namespace mfem
{

#ifdef MFEM_USE_MPI

namespace internal
{

std::vector<HYPRE_BigInt> GenerateColumnPartitioning(const int world_size,
                                                     const int rank, const int size_per_rank)
{
   std::vector<HYPRE_BigInt> col;
   if (HYPRE_AssumedPartitionCheck())
   {
      int offset = rank*size_per_rank;
      col = {offset, offset + size_per_rank};
   }
   else
   {
      col.resize(world_size+1);
      for (int i=0; i<=world_size; ++i)
      {
         col[i] = i*size_per_rank;
      }
   }
   return col;
}

} // namespace internal

TEST_CASE("HypreParVector I/O", "[Parallel], [HypreParVector]")
{
   // Create a test vector (two entries per rank) with entries increasing
   // sequentially. Write the vector to a file, read it into another vector, and
   // make sure we get the same answer.

   int world_size, rank;
   MPI_Comm_size(MPI_COMM_WORLD, &world_size);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   int size_per_rank = 2;

   HYPRE_BigInt glob_size = world_size*size_per_rank;
   std::vector<HYPRE_BigInt> col = internal::GenerateColumnPartitioning(world_size,
                                                                        rank, size_per_rank);

   // Initialize vector and write to files
   HypreParVector v1(MPI_COMM_WORLD, glob_size, col.data());
   for (int i=0; i<size_per_rank; ++i)
   {
      v1(i) = rank*size_per_rank + i;
   }
   v1.Print("vec");

   // Check that we read the same vector from disk
   HypreParVector v2;
   v2.Read(MPI_COMM_WORLD, "vec");
   v2 -= v1;
   REQUIRE(InnerProduct(v2, v2) == MFEM_Approx(0.0));

   // Clean up
   std::string prefix = "vec.";
   std::string suffix = std::to_string(rank);
   remove((prefix + suffix).c_str());
   remove((prefix + "INFO." + suffix).c_str());
}

TEST_CASE("HypreParVector Move Constructor", "[Parallel], [HypreParVector]")
{
   int world_size, rank;
   MPI_Comm_size(MPI_COMM_WORLD, &world_size);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   int size_per_rank = 2;

   HYPRE_BigInt glob_size = world_size*size_per_rank;
   std::vector<HYPRE_BigInt> col = internal::GenerateColumnPartitioning(world_size,
                                                                        rank, size_per_rank);

   // Initialize vector
   HypreParVector v1(MPI_COMM_WORLD, glob_size, col.data());
   for (int i=0; i<size_per_rank; ++i)
   {
      v1(i) = rank*size_per_rank + i;
   }

   // Make a copy so we can compare it later
   HypreParVector v1_copy(v1);

   // Also save off the data pointer
   double* v1_data = v1.GetData();

   // Now move from the original and compare
   HypreParVector v1_move(std::move(v1));

   REQUIRE(v1.GetOwnership() == 0);
   REQUIRE(v1_move.GetOwnership() == 1);
   REQUIRE(v1_move.Size() == v1_copy.Size());
   REQUIRE(v1_move.GlobalSize() == v1_copy.GlobalSize());
   REQUIRE(v1.Size() == 0);
   REQUIRE(v1.GetData() == nullptr);

   REQUIRE(v1_move.GetData() == v1_data);

   // The full HypreParVectors should also be the same
   v1_copy -= v1_move;
   REQUIRE(InnerProduct(v1_copy, v1_copy) == MFEM_Approx(0.0));
}

TEST_CASE("HypreParVector Move Assignment", "[Parallel], [HypreParVector]")
{
   int world_size, rank;
   MPI_Comm_size(MPI_COMM_WORLD, &world_size);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   int size_per_rank = 2;

   HYPRE_BigInt glob_size = world_size*size_per_rank;
   std::vector<HYPRE_BigInt> col = internal::GenerateColumnPartitioning(world_size,
                                                                        rank, size_per_rank);

   // Initialize vector
   HypreParVector v1(MPI_COMM_WORLD, glob_size, col.data());
   for (int i=0; i<size_per_rank; ++i)
   {
      v1(i) = rank*size_per_rank + i;
   }

   // Make a copy so we can compare it later
   HypreParVector v1_copy(v1);

   // Also save off the data pointer
   double* v1_data = v1.GetData();

   // Now move from the original and compare
   HypreParVector v1_move;
   v1_move = std::move(v1);

   REQUIRE(v1.GetOwnership() == 0);
   REQUIRE(v1_move.GetOwnership() == 1);
   REQUIRE(v1_move.Size() == v1_copy.Size());
   REQUIRE(v1_move.GlobalSize() == v1_copy.GlobalSize());
   REQUIRE(v1.Size() == 0);
   REQUIRE(v1.GetData() == nullptr);

   REQUIRE(v1_move.GetData() == v1_data);

   // The full HypreParVectors should also be the same
   v1_copy -= v1_move;
   REQUIRE(InnerProduct(v1_copy, v1_copy) == MFEM_Approx(0.0));
}

#endif // MFEM_USE_MPI

} // namespace mfem
<|endoftext|>


<commit_before><commit_msg>Add a histogram to measure task execution time for the render thread.<commit_after><|endoftext|>


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

#include "chrome/test/ui/ui_layout_test.h"

#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/test/test_file_util.h"
#include "base/test/test_timeouts.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/automation/tab_proxy.h"
#include "net/base/escape.h"
#include "net/base/net_util.h"

#if defined(OS_WIN)
static const char kPlatformName[] = "chromium-win";
#elif defined(OS_MACOSX)
static const char kPlatformName[] = "chromium-mac";
#elif defined(OS_LINUX)
static const char kPlatformName[] = "chromium-linux";
#else
#error No known OS defined
#endif

static const char kTestCompleteCookie[] = "status";

UILayoutTest::UILayoutTest()
    : initialized_for_layout_test_(false),
      test_count_(0) {
}

UILayoutTest::~UILayoutTest() {
  if (!temp_test_dir_.empty()) {
    // The deletion might fail because HTTP server process might not been
    // completely shut down yet and is still holding certain handle to it.
    // To work around this problem, we try to repeat the deletion several
    // times.
    EXPECT_TRUE(file_util::DieFileDie(temp_test_dir_, true));
  }
}

void UILayoutTest::InitializeForLayoutTest(const FilePath& test_parent_dir,
                                           const FilePath& test_case_dir,
                                           int port) {
  FilePath src_dir;
  PathService::Get(base::DIR_SOURCE_ROOT, &src_dir);

  src_dir = src_dir.AppendASCII("chrome");
  src_dir = src_dir.AppendASCII("test");
  src_dir = src_dir.AppendASCII("data");
  src_dir = src_dir.AppendASCII("layout_tests");
  src_dir = src_dir.AppendASCII("LayoutTests");

  // Gets the file path to WebKit ui layout tests, that is,
  //   chrome/test/data/ui_tests/LayoutTests/...
  // Note that we have to use our own copy of WebKit layout tests because our
  // build machines do not have WebKit layout tests added.
  layout_test_dir_ = src_dir.Append(test_parent_dir);
  layout_test_dir_ = layout_test_dir_.Append(test_case_dir);
  ASSERT_TRUE(file_util::DirectoryExists(layout_test_dir_));

  // Gets the file path to rebased expected result directory for the current
  // platform.
  //   chrome/test/data/layout_tests/LayoutTests/platform/chromium_***/...
  rebase_result_dir_ = src_dir.AppendASCII("platform");
  rebase_result_dir_ = rebase_result_dir_.AppendASCII(kPlatformName);
  rebase_result_dir_ = rebase_result_dir_.Append(test_parent_dir);
  rebase_result_dir_ = rebase_result_dir_.Append(test_case_dir);

  // Generic chromium expected results. Not OS-specific. For example,
  // v8-specific differences go here.
  // chrome/test/data/layout_tests/LayoutTests/platform/chromium/...
  rebase_result_chromium_dir_ = src_dir.AppendASCII("platform")
                                       .AppendASCII("chromium")
                                       .Append(test_parent_dir)
                                       .Append(test_case_dir);

  // Gets the file path to rebased expected result directory under the
  // win32 platform. This is used by other non-win32 platform to use the same
  // rebased expected results.
#if !defined(OS_WIN)
  rebase_result_win_dir_ = src_dir.AppendASCII("platform")
                                  .AppendASCII("chromium-win")
                                  .Append(test_parent_dir)
                                  .Append(test_case_dir);
#endif

  // Creates the temporary directory.
  ASSERT_TRUE(file_util::CreateNewTempDirectory(
      FILE_PATH_LITERAL("chrome_ui_layout_tests_"), &temp_test_dir_));

  // Creates the new layout test subdirectory under the temp directory.
  // Note that we have to mimic the same layout test directory structure,
  // like .../LayoutTests/fast/workers/.... Otherwise those layout tests
  // dealing with location property, like worker-location.html, could fail.
  new_layout_test_dir_ = temp_test_dir_;
  new_layout_test_dir_ = new_layout_test_dir_.AppendASCII("LayoutTests");
  new_layout_test_dir_ = new_layout_test_dir_.Append(test_parent_dir);
  if (port == kHttpPort) {
    new_http_root_dir_ = new_layout_test_dir_;
    test_case_dir_ = test_case_dir;
  }
  new_layout_test_dir_ = new_layout_test_dir_.Append(test_case_dir);
  ASSERT_TRUE(file_util::CreateDirectory(new_layout_test_dir_));

  // Copy the resource subdirectory if it exists.
  FilePath layout_test_resource_path(layout_test_dir_);
  layout_test_resource_path =
      layout_test_resource_path.AppendASCII("resources");
  FilePath new_layout_test_resource_path(new_layout_test_dir_);
  new_layout_test_resource_path =
      new_layout_test_resource_path.AppendASCII("resources");
  file_util::CopyDirectory(layout_test_resource_path,
                           new_layout_test_resource_path, true);

  // Copies the parent resource subdirectory. This is needed in order to run
  // http layout tests.
  if (port == kHttpPort) {
    FilePath parent_resource_path(layout_test_dir_.DirName());
    parent_resource_path = parent_resource_path.AppendASCII("resources");
    FilePath new_parent_resource_path(new_layout_test_dir_.DirName());
    new_parent_resource_path =
        new_parent_resource_path.AppendASCII("resources");
    ASSERT_TRUE(file_util::CopyDirectory(
        parent_resource_path, new_parent_resource_path, true));
  }

  // Reads the layout test controller simulation script.
  FilePath path;
  PathService::Get(chrome::DIR_TEST_DATA, &path);
  path = path.AppendASCII("layout_tests");
  path = path.AppendASCII("layout_test_controller.html");
  ASSERT_TRUE(file_util::ReadFileToString(path, &layout_test_controller_));
}

void UILayoutTest::AddResourceForLayoutTest(const FilePath& parent_dir,
                                            const FilePath& resource_name) {
  FilePath root_dir;
  PathService::Get(base::DIR_SOURCE_ROOT, &root_dir);

  FilePath source = root_dir.AppendASCII("chrome");
  source = source.AppendASCII("test");
  source = source.AppendASCII("data");
  source = source.AppendASCII("layout_tests");
  source = source.AppendASCII("LayoutTests");
  source = source.Append(parent_dir);
  source = source.Append(resource_name);

  ASSERT_TRUE(file_util::PathExists(source));

  FilePath dest_parent_dir = temp_test_dir_.
      AppendASCII("LayoutTests").Append(parent_dir);
  ASSERT_TRUE(file_util::CreateDirectory(dest_parent_dir));
  FilePath dest = dest_parent_dir.Append(resource_name);

  if (file_util::DirectoryExists(source)) {
    ASSERT_TRUE(file_util::CopyDirectory(source, dest, true));
  } else {
    ASSERT_TRUE(file_util::CopyFile(source, dest));
  }
}

static size_t FindInsertPosition(const std::string& html) {
  size_t tag_start = html.find("<html");
  if (tag_start == std::string::npos)
    return 0;
  size_t tag_end = html.find(">", tag_start);
  if (tag_end == std::string::npos)
    return 0;
  return tag_end + 1;
}

void UILayoutTest::RunLayoutTest(const std::string& test_case_file_name,
                                 int port) {
  base::Time start = base::Time::Now();
  SCOPED_TRACE(test_case_file_name.c_str());

  ASSERT_TRUE(!layout_test_controller_.empty());

  // Creates a new cookie name. We will have to use a new cookie because
  // this function could be called multiple times.
  std::string status_cookie(kTestCompleteCookie);
  status_cookie += base::IntToString(test_count_);
  test_count_++;

  // Reads the layout test HTML file.
  FilePath test_file_path(layout_test_dir_);
  test_file_path = test_file_path.AppendASCII(test_case_file_name);
  std::string test_html;
  ASSERT_TRUE(file_util::ReadFileToString(test_file_path, &test_html));

  // Injects the layout test controller into the test HTML.
  size_t insertion_position = FindInsertPosition(test_html);
  test_html.insert(insertion_position, layout_test_controller_);
  ReplaceFirstSubstringAfterOffset(
      &test_html, insertion_position, "%COOKIE%", status_cookie.c_str());

  // Creates the new layout test HTML file.
  FilePath new_test_file_path(new_layout_test_dir_);
  new_test_file_path = new_test_file_path.AppendASCII(test_case_file_name);
  ASSERT_TRUE(file_util::WriteFile(new_test_file_path,
                                   &test_html.at(0),
                                   static_cast<int>(test_html.size())));
  // We expect the test case dir to be ASCII.  It might be empty, so we
  // can't test whether MaybeAsASCII succeeded, but the tests will fail
  // loudly in that case anyway.
  std::string url_path = test_case_dir_.MaybeAsASCII();

  scoped_ptr<GURL> new_test_url;
  if (port != kNoHttpPort)
    new_test_url.reset(new GURL(
        StringPrintf("http://127.0.0.1:%d/", port) +
        url_path + "/" + test_case_file_name));
  else
    new_test_url.reset(new GURL(net::FilePathToFileURL(new_test_file_path)));

  // Runs the new layout test.
  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());
  ASSERT_TRUE(tab->NavigateToURL(*new_test_url.get()));
  std::string escaped_value =
      WaitUntilCookieNonEmpty(tab.get(), *new_test_url.get(),
          status_cookie.c_str(), TestTimeouts::action_max_timeout_ms());

  // Unescapes and normalizes the actual result.
  std::string value = net::UnescapeURLComponent(escaped_value,
      UnescapeRule::NORMAL | UnescapeRule::SPACES |
          UnescapeRule::URL_SPECIAL_CHARS | UnescapeRule::CONTROL_CHARS);
  value += "\n";
  ReplaceSubstringsAfterOffset(&value, 0, "\r", "");

  // Reads the expected result. First try to read from rebase directory.
  // If failed, read from original directory.
  std::string expected_result_value;
  if (!ReadExpectedResult(rebase_result_dir_,
                          test_case_file_name,
                          &expected_result_value) &&
      !ReadExpectedResult(rebase_result_chromium_dir_,
                          test_case_file_name,
                          &expected_result_value)) {
    if (rebase_result_win_dir_.empty() ||
        !ReadExpectedResult(rebase_result_win_dir_,
                            test_case_file_name,
                            &expected_result_value))
      ReadExpectedResult(layout_test_dir_,
                         test_case_file_name,
                         &expected_result_value);
  }
  ASSERT_TRUE(!expected_result_value.empty());

  // Normalizes the expected result.
  ReplaceSubstringsAfterOffset(&expected_result_value, 0, "\r", "");

  // Compares the results.
  EXPECT_STREQ(expected_result_value.c_str(), value.c_str());

  VLOG(1) << "Test " << test_case_file_name
          << " took " << (base::Time::Now() - start).InMilliseconds() << "ms";
}

bool UILayoutTest::ReadExpectedResult(const FilePath& result_dir_path,
                                      const std::string test_case_file_name,
                                      std::string* expected_result_value) {
  FilePath expected_result_path(result_dir_path);
  expected_result_path = expected_result_path.AppendASCII(test_case_file_name);
  expected_result_path = expected_result_path.InsertBeforeExtension(
      FILE_PATH_LITERAL("-expected"));
  expected_result_path =
      expected_result_path.ReplaceExtension(FILE_PATH_LITERAL("txt"));
  return file_util::ReadFileToString(expected_result_path,
                                     expected_result_value);
}
<commit_msg>Make ui_layout_test probe in third_party/WebKit/ prior to chrome/test/data_layout_tests<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/ui/ui_layout_test.h"

#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/test/test_file_util.h"
#include "base/test/test_timeouts.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/automation/tab_proxy.h"
#include "net/base/escape.h"
#include "net/base/net_util.h"

#if defined(OS_WIN)
static const char kPlatformName[] = "chromium-win";
#elif defined(OS_MACOSX)
static const char kPlatformName[] = "chromium-mac";
#elif defined(OS_LINUX)
static const char kPlatformName[] = "chromium-linux";
#else
#error No known OS defined
#endif

static const char kTestCompleteCookie[] = "status";

UILayoutTest::UILayoutTest()
    : initialized_for_layout_test_(false),
      test_count_(0) {
}

UILayoutTest::~UILayoutTest() {
  if (!temp_test_dir_.empty()) {
    // The deletion might fail because HTTP server process might not been
    // completely shut down yet and is still holding certain handle to it.
    // To work around this problem, we try to repeat the deletion several
    // times.
    EXPECT_TRUE(file_util::DieFileDie(temp_test_dir_, true));
  }
}

// Gets layout tests root. For the current git workflow, this is
//    third_party/WebKit/LayoutTests
// On svn workflow (including build machines) and older git workflow, this is
//    chrome/test/data/layout_tests/LayoutTests
// This function probes for the first and then fallbacks to the second.
static FilePath GetLayoutTestRoot() {
  FilePath src_root;
  PathService::Get(base::DIR_SOURCE_ROOT, &src_root);

  FilePath webkit_layout_tests = src_root;
  webkit_layout_tests = webkit_layout_tests.AppendASCII("third_party");
  webkit_layout_tests = webkit_layout_tests.AppendASCII("WebKit");
  webkit_layout_tests = webkit_layout_tests.AppendASCII("LayoutTests");
  if (file_util::DirectoryExists(webkit_layout_tests))
    return webkit_layout_tests;

  FilePath chrome_layout_tests = src_root;
  chrome_layout_tests = chrome_layout_tests.AppendASCII("chrome");
  chrome_layout_tests = chrome_layout_tests.AppendASCII("test");
  chrome_layout_tests = chrome_layout_tests.AppendASCII("data");
  chrome_layout_tests = chrome_layout_tests.AppendASCII("layout_tests");
  chrome_layout_tests = chrome_layout_tests.AppendASCII("LayoutTests");
  return chrome_layout_tests;
}

void UILayoutTest::InitializeForLayoutTest(const FilePath& test_parent_dir,
                                           const FilePath& test_case_dir,
                                           int port) {
  FilePath src_dir = GetLayoutTestRoot();
  layout_test_dir_ = src_dir.Append(test_parent_dir);
  layout_test_dir_ = layout_test_dir_.Append(test_case_dir);
  ASSERT_TRUE(file_util::DirectoryExists(layout_test_dir_));

  // Gets the file path to rebased expected result directory for the current
  // platform.
  //   $LayoutTestRoot/platform/chromium_***/...
  rebase_result_dir_ = src_dir.AppendASCII("platform");
  rebase_result_dir_ = rebase_result_dir_.AppendASCII(kPlatformName);
  rebase_result_dir_ = rebase_result_dir_.Append(test_parent_dir);
  rebase_result_dir_ = rebase_result_dir_.Append(test_case_dir);

  // Generic chromium expected results. Not OS-specific. For example,
  // v8-specific differences go here.
  // chrome/test/data/layout_tests/LayoutTests/platform/chromium/...
  rebase_result_chromium_dir_ = src_dir.AppendASCII("platform")
                                       .AppendASCII("chromium")
                                       .Append(test_parent_dir)
                                       .Append(test_case_dir);

  // Gets the file path to rebased expected result directory under the
  // win32 platform. This is used by other non-win32 platform to use the same
  // rebased expected results.
#if !defined(OS_WIN)
  rebase_result_win_dir_ = src_dir.AppendASCII("platform")
                                  .AppendASCII("chromium-win")
                                  .Append(test_parent_dir)
                                  .Append(test_case_dir);
#endif

  // Creates the temporary directory.
  ASSERT_TRUE(file_util::CreateNewTempDirectory(
      FILE_PATH_LITERAL("chrome_ui_layout_tests_"), &temp_test_dir_));

  // Creates the new layout test subdirectory under the temp directory.
  // Note that we have to mimic the same layout test directory structure,
  // like .../LayoutTests/fast/workers/.... Otherwise those layout tests
  // dealing with location property, like worker-location.html, could fail.
  new_layout_test_dir_ = temp_test_dir_;
  new_layout_test_dir_ = new_layout_test_dir_.AppendASCII("LayoutTests");
  new_layout_test_dir_ = new_layout_test_dir_.Append(test_parent_dir);
  if (port == kHttpPort) {
    new_http_root_dir_ = new_layout_test_dir_;
    test_case_dir_ = test_case_dir;
  }
  new_layout_test_dir_ = new_layout_test_dir_.Append(test_case_dir);
  ASSERT_TRUE(file_util::CreateDirectory(new_layout_test_dir_));

  // Copy the resource subdirectory if it exists.
  FilePath layout_test_resource_path(layout_test_dir_);
  layout_test_resource_path =
      layout_test_resource_path.AppendASCII("resources");
  FilePath new_layout_test_resource_path(new_layout_test_dir_);
  new_layout_test_resource_path =
      new_layout_test_resource_path.AppendASCII("resources");
  file_util::CopyDirectory(layout_test_resource_path,
                           new_layout_test_resource_path, true);

  // Copies the parent resource subdirectory. This is needed in order to run
  // http layout tests.
  if (port == kHttpPort) {
    FilePath parent_resource_path(layout_test_dir_.DirName());
    parent_resource_path = parent_resource_path.AppendASCII("resources");
    FilePath new_parent_resource_path(new_layout_test_dir_.DirName());
    new_parent_resource_path =
        new_parent_resource_path.AppendASCII("resources");
    ASSERT_TRUE(file_util::CopyDirectory(
        parent_resource_path, new_parent_resource_path, true));
  }

  // Reads the layout test controller simulation script.
  FilePath path;
  PathService::Get(chrome::DIR_TEST_DATA, &path);
  path = path.AppendASCII("layout_tests");
  path = path.AppendASCII("layout_test_controller.html");
  ASSERT_TRUE(file_util::ReadFileToString(path, &layout_test_controller_));
}

void UILayoutTest::AddResourceForLayoutTest(const FilePath& parent_dir,
                                            const FilePath& resource_name) {
  FilePath source = GetLayoutTestRoot();
  source = source.Append(parent_dir);
  source = source.Append(resource_name);

  ASSERT_TRUE(file_util::PathExists(source));

  FilePath dest_parent_dir = temp_test_dir_.
      AppendASCII("LayoutTests").Append(parent_dir);
  ASSERT_TRUE(file_util::CreateDirectory(dest_parent_dir));
  FilePath dest = dest_parent_dir.Append(resource_name);

  if (file_util::DirectoryExists(source)) {
    ASSERT_TRUE(file_util::CopyDirectory(source, dest, true));
  } else {
    ASSERT_TRUE(file_util::CopyFile(source, dest));
  }
}

static size_t FindInsertPosition(const std::string& html) {
  size_t tag_start = html.find("<html");
  if (tag_start == std::string::npos)
    return 0;
  size_t tag_end = html.find(">", tag_start);
  if (tag_end == std::string::npos)
    return 0;
  return tag_end + 1;
}

void UILayoutTest::RunLayoutTest(const std::string& test_case_file_name,
                                 int port) {
  base::Time start = base::Time::Now();
  SCOPED_TRACE(test_case_file_name.c_str());

  ASSERT_TRUE(!layout_test_controller_.empty());

  // Creates a new cookie name. We will have to use a new cookie because
  // this function could be called multiple times.
  std::string status_cookie(kTestCompleteCookie);
  status_cookie += base::IntToString(test_count_);
  test_count_++;

  // Reads the layout test HTML file.
  FilePath test_file_path(layout_test_dir_);
  test_file_path = test_file_path.AppendASCII(test_case_file_name);
  std::string test_html;
  ASSERT_TRUE(file_util::ReadFileToString(test_file_path, &test_html));

  // Injects the layout test controller into the test HTML.
  size_t insertion_position = FindInsertPosition(test_html);
  test_html.insert(insertion_position, layout_test_controller_);
  ReplaceFirstSubstringAfterOffset(
      &test_html, insertion_position, "%COOKIE%", status_cookie.c_str());

  // Creates the new layout test HTML file.
  FilePath new_test_file_path(new_layout_test_dir_);
  new_test_file_path = new_test_file_path.AppendASCII(test_case_file_name);
  ASSERT_TRUE(file_util::WriteFile(new_test_file_path,
                                   &test_html.at(0),
                                   static_cast<int>(test_html.size())));
  // We expect the test case dir to be ASCII.  It might be empty, so we
  // can't test whether MaybeAsASCII succeeded, but the tests will fail
  // loudly in that case anyway.
  std::string url_path = test_case_dir_.MaybeAsASCII();

  scoped_ptr<GURL> new_test_url;
  if (port != kNoHttpPort)
    new_test_url.reset(new GURL(
        StringPrintf("http://127.0.0.1:%d/", port) +
        url_path + "/" + test_case_file_name));
  else
    new_test_url.reset(new GURL(net::FilePathToFileURL(new_test_file_path)));

  // Runs the new layout test.
  scoped_refptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab.get());
  ASSERT_TRUE(tab->NavigateToURL(*new_test_url.get()));
  std::string escaped_value =
      WaitUntilCookieNonEmpty(tab.get(), *new_test_url.get(),
          status_cookie.c_str(), TestTimeouts::action_max_timeout_ms());

  // Unescapes and normalizes the actual result.
  std::string value = net::UnescapeURLComponent(escaped_value,
      UnescapeRule::NORMAL | UnescapeRule::SPACES |
          UnescapeRule::URL_SPECIAL_CHARS | UnescapeRule::CONTROL_CHARS);
  value += "\n";
  ReplaceSubstringsAfterOffset(&value, 0, "\r", "");

  // Reads the expected result. First try to read from rebase directory.
  // If failed, read from original directory.
  std::string expected_result_value;
  if (!ReadExpectedResult(rebase_result_dir_,
                          test_case_file_name,
                          &expected_result_value) &&
      !ReadExpectedResult(rebase_result_chromium_dir_,
                          test_case_file_name,
                          &expected_result_value)) {
    if (rebase_result_win_dir_.empty() ||
        !ReadExpectedResult(rebase_result_win_dir_,
                            test_case_file_name,
                            &expected_result_value))
      ReadExpectedResult(layout_test_dir_,
                         test_case_file_name,
                         &expected_result_value);
  }
  ASSERT_TRUE(!expected_result_value.empty());

  // Normalizes the expected result.
  ReplaceSubstringsAfterOffset(&expected_result_value, 0, "\r", "");

  // Compares the results.
  EXPECT_STREQ(expected_result_value.c_str(), value.c_str());

  VLOG(1) << "Test " << test_case_file_name
          << " took " << (base::Time::Now() - start).InMilliseconds() << "ms";
}

bool UILayoutTest::ReadExpectedResult(const FilePath& result_dir_path,
                                      const std::string test_case_file_name,
                                      std::string* expected_result_value) {
  FilePath expected_result_path(result_dir_path);
  expected_result_path = expected_result_path.AppendASCII(test_case_file_name);
  expected_result_path = expected_result_path.InsertBeforeExtension(
      FILE_PATH_LITERAL("-expected"));
  expected_result_path =
      expected_result_path.ReplaceExtension(FILE_PATH_LITERAL("txt"));
  return file_util::ReadFileToString(expected_result_path,
                                     expected_result_value);
}
<|endoftext|>


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

#include "base/string_util.h"
#include "chrome/common/automation_constants.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome_frame/np_proxy_service.h"
#include "chrome_frame/np_browser_functions.h"

#include "net/proxy/proxy_config.h"

#include "third_party/xulrunner-sdk/win/include/xpcom/nsXPCOM.h"
#include "third_party/xulrunner-sdk/win/include/xpcom/nsIObserverService.h"
#include "third_party/xulrunner-sdk/win/include/xpcom/nsISupportsUtils.h"
#include "third_party/xulrunner-sdk/win/include/xpcom/nsStringAPI.h"

ASSOCIATE_IID(NS_IOBSERVERSERVICE_IID_STR, nsIObserverService);
ASSOCIATE_IID(NS_IPREFBRANCH_IID_STR, nsIPrefBranch);

// Firefox preference names.
const char* kProxyObserverRoot = "network.";
const char* kProxyObserverBranch = "proxy.";
const char* kProxyType = "proxy.type";
const char* kProxyAutoconfigUrl = "proxy.autoconfig_url";
const char* kProxyBypassList = "proxy.no_proxies_on";

const int kInvalidIntPref = -1;

// These are the proxy schemes that Chrome knows about at the moment.
// SOCKS is a notable ommission here, this will need to be updated when
// Chrome supports SOCKS proxies.
const NpProxyService::ProxyNames NpProxyService::kProxyInfo[] = {
    {"http", "proxy.http", "proxy.http_port"},
    {"https", "proxy.ssl", "proxy.ssl_port"},
    {"ftp", "proxy.ftp", "proxy.ftp_port"} };

NpProxyService::NpProxyService(void)
    : type_(PROXY_CONFIG_LAST), auto_detect_(false), no_proxy_(false),
      system_config_(false), automation_client_(NULL) {
}

NpProxyService::~NpProxyService(void) {
}

bool NpProxyService::Initialize(NPP instance,
    ChromeFrameAutomationClient* automation_client) {
  DCHECK(automation_client);
  automation_client_ = automation_client;

  // Get the pref service
  bool result = false;
  ScopedNsPtr<nsISupports> service_manager_base;
  npapi::GetValue(instance, NPNVserviceManager, service_manager_base.Receive());
  if (service_manager_base != NULL) {
    service_manager_.QueryFrom(service_manager_base);
    if (service_manager_.get() == NULL) {
      DLOG(ERROR) << "Failed to create ServiceManager. This only works in FF.";
    } else {
      service_manager_->GetServiceByContractID(
          NS_PREFSERVICE_CONTRACTID, NS_GET_IID(nsIPrefService),
          reinterpret_cast<void**>(pref_service_.Receive()));
      if (!pref_service_) {
        DLOG(ERROR) << "Failed to create PreferencesService";
      } else {
        result = InitializePrefBranch(pref_service_);
      }
    }
  }
  return result;
}

bool NpProxyService::InitializePrefBranch(nsIPrefService* pref_service) {
  DCHECK(pref_service);
  // Note that we cannot persist a reference to the pref branch because we
  // also act as an observer of changes to the branch. As per
  // nsIPrefBranch2.h, this would result in a circular reference between us
  // and the pref branch, which can impede cleanup. There are workarounds,
  // but let's try just not caching the branch reference for now.
  bool result = false;
  ScopedNsPtr<nsIPrefBranch> pref_branch;

  pref_service->ReadUserPrefs(nsnull);
  pref_service->GetBranch(kProxyObserverRoot, pref_branch.Receive());

  if (!pref_branch) {
    DLOG(ERROR) << "Failed to get nsIPrefBranch";
  } else {
    if (!ReadProxySettings(pref_branch.get())) {
      DLOG(ERROR) << "Could not read proxy settings.";
    } else {
      observer_pref_branch_.QueryFrom(pref_branch);
      if (!observer_pref_branch_) {
        DLOG(ERROR) << "Failed to get observer nsIPrefBranch2";
      } else {
        nsresult res = observer_pref_branch_->AddObserver(kProxyObserverBranch,
                                                          this, PR_FALSE);
        result = NS_SUCCEEDED(res);
      }
    }
  }
  return result;
}

bool NpProxyService::UnInitialize() {
  // Fail early if this was never created - we may not be running on FF.
  if (!pref_service_)
    return false;

  // Unhook ourselves as an observer.
  nsresult res = NS_ERROR_FAILURE;
  if (observer_pref_branch_)
    res = observer_pref_branch_->RemoveObserver(kProxyObserverBranch, this);

  return NS_SUCCEEDED(res);
}

NS_IMETHODIMP NpProxyService::Observe(nsISupports* subject, const char* topic,
                                     const PRUnichar* data) {
  if (!subject || !topic) {
    NOTREACHED();
    return NS_ERROR_UNEXPECTED;
  }

  std::string topic_str(topic);
  nsresult res = NS_OK;
  if (topic_str == NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) {
    // Looks like our proxy settings changed. We need to reload!
    // I have observed some extremely strange behaviour here. Specifically,
    // we are supposed to be able to QI |subject| and get from it an
    // nsIPrefBranch from which we can query new values. This has erratic
    // behaviour, specifically subject starts returning null on all member
    // queries. So I am using the cached nsIPrefBranch2 (that we used to add
    // the observer) to do the querying.
    if (NS_SUCCEEDED(res)) {
      if (!ReadProxySettings(observer_pref_branch_)) {
        res = NS_ERROR_UNEXPECTED;
      } else {
        std::string proxy_settings;
        if (GetProxyValueJSONString(&proxy_settings))
          automation_client_->SetProxySettings(proxy_settings);
      }
    }
  } else {
    NOTREACHED();
  }

  return res;
}

std::string NpProxyService::GetStringPref(nsIPrefBranch* pref_branch,
                                         const char* pref_name) {
  nsCString pref_string;
  std::string result;
  nsresult rv = pref_branch->GetCharPref(pref_name, getter_Copies(pref_string));
  if (SUCCEEDED(rv) && pref_string.get()) {
    result = pref_string.get();
  }
  return result;
}

int NpProxyService::GetIntPref(nsIPrefBranch* pref_branch,
                              const char* pref_name) {
  PRInt32 pref_int;
  int result = kInvalidIntPref;
  nsresult rv = pref_branch->GetIntPref(pref_name, &pref_int);
  if (SUCCEEDED(rv)) {
    result = pref_int;
  }
  return result;
}

bool NpProxyService::GetBoolPref(nsIPrefBranch* pref_branch,
                                const char* pref_name) {
  PRBool pref_bool;
  bool result = false;
  nsresult rv = pref_branch->GetBoolPref(pref_name, &pref_bool);
  if (SUCCEEDED(rv)) {
    result = pref_bool == PR_TRUE;
  }
  return result;
}

void NpProxyService::Reset() {
  type_ = PROXY_CONFIG_LAST;
  auto_detect_ = false;
  no_proxy_ = false;
  system_config_ = false;
  manual_proxies_.clear();
  pac_url_.clear();
  proxy_bypass_list_.clear();
}

bool NpProxyService::ReadProxySettings(nsIPrefBranch* pref_branch) {
  DCHECK(pref_branch);

  // Clear our current settings.
  Reset();
  type_ = GetIntPref(pref_branch, kProxyType);
  if (type_ == kInvalidIntPref) {
    NOTREACHED();
    return false;
  }

  switch (type_) {
    case PROXY_CONFIG_DIRECT:
    case PROXY_CONFIG_DIRECT4X:
      no_proxy_ = true;
      break;
    case PROXY_CONFIG_SYSTEM:
      // _SYSTEM is documented as "Use system settings if available, otherwise
      // DIRECT". It isn't clear under what circumstances system settings would
      // be unavailable, but I'll special-case this nonetheless and have
      // GetProxyValueJSONString() return empty if we get this proxy type.
      DLOG(WARNING) << "Received PROXY_CONFIG_SYSTEM proxy type.";
      system_config_ = true;
      break;
    case PROXY_CONFIG_WPAD:
      auto_detect_ = true;
      break;
    case PROXY_CONFIG_PAC:
      pac_url_ = GetStringPref(pref_branch, kProxyAutoconfigUrl);
      break;
    case PROXY_CONFIG_MANUAL:
      // Read in the values for each of the known schemes.
      for (int i = 0; i < arraysize(kProxyInfo); i++) {
        ManualProxyEntry entry;
        entry.url = GetStringPref(pref_branch, kProxyInfo[i].pref_name);
        entry.port = GetIntPref(pref_branch, kProxyInfo[i].port_pref_name);
        if (!entry.url.empty() && entry.port != kInvalidIntPref) {
          entry.scheme = kProxyInfo[i].chrome_scheme;
          manual_proxies_.push_back(entry);
        }
      }

      // Also pick up the list of URLs we bypass proxies for.
      proxy_bypass_list_ = GetStringPref(pref_branch, kProxyBypassList);
      break;
    default:
      NOTREACHED();
      return false;
  }
  return true;
}

DictionaryValue* NpProxyService::BuildProxyValueSet() {
  scoped_ptr<DictionaryValue> proxy_settings_value(new DictionaryValue);

  if (auto_detect_) {
    proxy_settings_value->SetBoolean(automation::kJSONProxyAutoconfig,
                                     auto_detect_);
  }

  if (no_proxy_) {
    proxy_settings_value->SetBoolean(automation::kJSONProxyNoProxy, no_proxy_);
  }

  if (!pac_url_.empty()) {
    proxy_settings_value->SetString(automation::kJSONProxyPacUrl, pac_url_);
  }

  if (!proxy_bypass_list_.empty()) {
    proxy_settings_value->SetString(automation::kJSONProxyBypassList,
                                    proxy_bypass_list_);
  }

  // Fill in the manual proxy settings. Build a string representation that
  // corresponds to the format of the input parameter to
  // ProxyConfig::ProxyRules::ParseFromString.
  std::string manual_proxy_settings;
  ManualProxyList::const_iterator iter(manual_proxies_.begin());
  for (; iter != manual_proxies_.end(); iter++) {
    DCHECK(!iter->scheme.empty());
    DCHECK(!iter->url.empty());
    DCHECK(iter->port != kInvalidIntPref);
    manual_proxy_settings += iter->scheme;
    manual_proxy_settings += "=";
    manual_proxy_settings += iter->url;
    manual_proxy_settings += ":";
    manual_proxy_settings += IntToString(iter->port);
    manual_proxy_settings += ";";
  }

  if (!manual_proxy_settings.empty()) {
    proxy_settings_value->SetString(automation::kJSONProxyServer,
                                    manual_proxy_settings);
  }

  return proxy_settings_value.release();
}

bool NpProxyService::GetProxyValueJSONString(std::string* output) {
  DCHECK(output);
  output->empty();

  // If we detected a PROXY_CONFIG_SYSTEM config type or failed to obtain the
  // pref service then return false here to make Chrome continue using its
  // default proxy settings.
  if (system_config_ || !pref_service_)
    return false;

  scoped_ptr<DictionaryValue> proxy_settings_value(BuildProxyValueSet());

  JSONStringValueSerializer serializer(output);
  return serializer.Serialize(*static_cast<Value*>(proxy_settings_value.get()));
}
<commit_msg>Applying "Solving a bug in Chrome Frame that Firefox doesn't set preferences correctly during startup" for hansl@.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/string_util.h"
#include "chrome/common/automation_constants.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome_frame/np_proxy_service.h"
#include "chrome_frame/np_browser_functions.h"

#include "net/proxy/proxy_config.h"

#include "third_party/xulrunner-sdk/win/include/xpcom/nsXPCOM.h"
#include "third_party/xulrunner-sdk/win/include/xpcom/nsIObserverService.h"
#include "third_party/xulrunner-sdk/win/include/xpcom/nsISupportsUtils.h"
#include "third_party/xulrunner-sdk/win/include/xpcom/nsStringAPI.h"

ASSOCIATE_IID(NS_IOBSERVERSERVICE_IID_STR, nsIObserverService);
ASSOCIATE_IID(NS_IPREFBRANCH_IID_STR, nsIPrefBranch);

// Firefox preference names.
const char* kProxyObserverRoot = "network.";
const char* kProxyObserverBranch = "proxy.";
const char* kProxyType = "proxy.type";
const char* kProxyAutoconfigUrl = "proxy.autoconfig_url";
const char* kProxyBypassList = "proxy.no_proxies_on";

const int kInvalidIntPref = -1;

// These are the proxy schemes that Chrome knows about at the moment.
// SOCKS is a notable ommission here, this will need to be updated when
// Chrome supports SOCKS proxies.
const NpProxyService::ProxyNames NpProxyService::kProxyInfo[] = {
    {"http", "proxy.http", "proxy.http_port"},
    {"https", "proxy.ssl", "proxy.ssl_port"},
    {"ftp", "proxy.ftp", "proxy.ftp_port"} };

NpProxyService::NpProxyService(void)
    : type_(PROXY_CONFIG_LAST), auto_detect_(false), no_proxy_(false),
      system_config_(false), automation_client_(NULL) {
}

NpProxyService::~NpProxyService(void) {
}

bool NpProxyService::Initialize(NPP instance,
    ChromeFrameAutomationClient* automation_client) {
  DCHECK(automation_client);
  automation_client_ = automation_client;

  // Get the pref service
  bool result = false;
  ScopedNsPtr<nsISupports> service_manager_base;
  npapi::GetValue(instance, NPNVserviceManager, service_manager_base.Receive());
  if (service_manager_base != NULL) {
    service_manager_.QueryFrom(service_manager_base);
    if (service_manager_.get() == NULL) {
      DLOG(ERROR) << "Failed to create ServiceManager. This only works in FF.";
    } else {
      service_manager_->GetServiceByContractID(
          NS_PREFSERVICE_CONTRACTID, NS_GET_IID(nsIPrefService),
          reinterpret_cast<void**>(pref_service_.Receive()));
      if (!pref_service_) {
        DLOG(ERROR) << "Failed to create PreferencesService";
      } else {
        result = InitializePrefBranch(pref_service_);
      }
    }
  }
  return result;
}

bool NpProxyService::InitializePrefBranch(nsIPrefService* pref_service) {
  DCHECK(pref_service);
  // Note that we cannot persist a reference to the pref branch because we
  // also act as an observer of changes to the branch. As per
  // nsIPrefBranch2.h, this would result in a circular reference between us
  // and the pref branch, which can impede cleanup. There are workarounds,
  // but let's try just not caching the branch reference for now.
  bool result = false;
  ScopedNsPtr<nsIPrefBranch> pref_branch;

  pref_service->GetBranch(kProxyObserverRoot, pref_branch.Receive());

  if (!pref_branch) {
    DLOG(ERROR) << "Failed to get nsIPrefBranch";
  } else {
    if (!ReadProxySettings(pref_branch.get())) {
      DLOG(ERROR) << "Could not read proxy settings.";
    } else {
      observer_pref_branch_.QueryFrom(pref_branch);
      if (!observer_pref_branch_) {
        DLOG(ERROR) << "Failed to get observer nsIPrefBranch2";
      } else {
        nsresult res = observer_pref_branch_->AddObserver(kProxyObserverBranch,
                                                          this, PR_FALSE);
        result = NS_SUCCEEDED(res);
      }
    }
  }
  return result;
}

bool NpProxyService::UnInitialize() {
  // Fail early if this was never created - we may not be running on FF.
  if (!pref_service_)
    return false;

  // Unhook ourselves as an observer.
  nsresult res = NS_ERROR_FAILURE;
  if (observer_pref_branch_)
    res = observer_pref_branch_->RemoveObserver(kProxyObserverBranch, this);

  return NS_SUCCEEDED(res);
}

NS_IMETHODIMP NpProxyService::Observe(nsISupports* subject, const char* topic,
                                     const PRUnichar* data) {
  if (!subject || !topic) {
    NOTREACHED();
    return NS_ERROR_UNEXPECTED;
  }

  std::string topic_str(topic);
  nsresult res = NS_OK;
  if (topic_str == NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) {
    // Looks like our proxy settings changed. We need to reload!
    // I have observed some extremely strange behaviour here. Specifically,
    // we are supposed to be able to QI |subject| and get from it an
    // nsIPrefBranch from which we can query new values. This has erratic
    // behaviour, specifically subject starts returning null on all member
    // queries. So I am using the cached nsIPrefBranch2 (that we used to add
    // the observer) to do the querying.
    if (NS_SUCCEEDED(res)) {
      if (!ReadProxySettings(observer_pref_branch_)) {
        res = NS_ERROR_UNEXPECTED;
      } else {
        std::string proxy_settings;
        if (GetProxyValueJSONString(&proxy_settings))
          automation_client_->SetProxySettings(proxy_settings);
      }
    }
  } else {
    NOTREACHED();
  }

  return res;
}

std::string NpProxyService::GetStringPref(nsIPrefBranch* pref_branch,
                                         const char* pref_name) {
  nsCString pref_string;
  std::string result;
  nsresult rv = pref_branch->GetCharPref(pref_name, getter_Copies(pref_string));
  if (SUCCEEDED(rv) && pref_string.get()) {
    result = pref_string.get();
  }
  return result;
}

int NpProxyService::GetIntPref(nsIPrefBranch* pref_branch,
                              const char* pref_name) {
  PRInt32 pref_int;
  int result = kInvalidIntPref;
  nsresult rv = pref_branch->GetIntPref(pref_name, &pref_int);
  if (SUCCEEDED(rv)) {
    result = pref_int;
  }
  return result;
}

bool NpProxyService::GetBoolPref(nsIPrefBranch* pref_branch,
                                const char* pref_name) {
  PRBool pref_bool;
  bool result = false;
  nsresult rv = pref_branch->GetBoolPref(pref_name, &pref_bool);
  if (SUCCEEDED(rv)) {
    result = pref_bool == PR_TRUE;
  }
  return result;
}

void NpProxyService::Reset() {
  type_ = PROXY_CONFIG_LAST;
  auto_detect_ = false;
  no_proxy_ = false;
  system_config_ = false;
  manual_proxies_.clear();
  pac_url_.clear();
  proxy_bypass_list_.clear();
}

bool NpProxyService::ReadProxySettings(nsIPrefBranch* pref_branch) {
  DCHECK(pref_branch);

  // Clear our current settings.
  Reset();
  type_ = GetIntPref(pref_branch, kProxyType);
  if (type_ == kInvalidIntPref) {
    NOTREACHED();
    return false;
  }

  switch (type_) {
    case PROXY_CONFIG_DIRECT:
    case PROXY_CONFIG_DIRECT4X:
      no_proxy_ = true;
      break;
    case PROXY_CONFIG_SYSTEM:
      // _SYSTEM is documented as "Use system settings if available, otherwise
      // DIRECT". It isn't clear under what circumstances system settings would
      // be unavailable, but I'll special-case this nonetheless and have
      // GetProxyValueJSONString() return empty if we get this proxy type.
      DLOG(WARNING) << "Received PROXY_CONFIG_SYSTEM proxy type.";
      system_config_ = true;
      break;
    case PROXY_CONFIG_WPAD:
      auto_detect_ = true;
      break;
    case PROXY_CONFIG_PAC:
      pac_url_ = GetStringPref(pref_branch, kProxyAutoconfigUrl);
      break;
    case PROXY_CONFIG_MANUAL:
      // Read in the values for each of the known schemes.
      for (int i = 0; i < arraysize(kProxyInfo); i++) {
        ManualProxyEntry entry;
        entry.url = GetStringPref(pref_branch, kProxyInfo[i].pref_name);
        entry.port = GetIntPref(pref_branch, kProxyInfo[i].port_pref_name);
        if (!entry.url.empty() && entry.port != kInvalidIntPref) {
          entry.scheme = kProxyInfo[i].chrome_scheme;
          manual_proxies_.push_back(entry);
        }
      }

      // Also pick up the list of URLs we bypass proxies for.
      proxy_bypass_list_ = GetStringPref(pref_branch, kProxyBypassList);
      break;
    default:
      NOTREACHED();
      return false;
  }
  return true;
}

DictionaryValue* NpProxyService::BuildProxyValueSet() {
  scoped_ptr<DictionaryValue> proxy_settings_value(new DictionaryValue);

  if (auto_detect_) {
    proxy_settings_value->SetBoolean(automation::kJSONProxyAutoconfig,
                                     auto_detect_);
  }

  if (no_proxy_) {
    proxy_settings_value->SetBoolean(automation::kJSONProxyNoProxy, no_proxy_);
  }

  if (!pac_url_.empty()) {
    proxy_settings_value->SetString(automation::kJSONProxyPacUrl, pac_url_);
  }

  if (!proxy_bypass_list_.empty()) {
    proxy_settings_value->SetString(automation::kJSONProxyBypassList,
                                    proxy_bypass_list_);
  }

  // Fill in the manual proxy settings. Build a string representation that
  // corresponds to the format of the input parameter to
  // ProxyConfig::ProxyRules::ParseFromString.
  std::string manual_proxy_settings;
  ManualProxyList::const_iterator iter(manual_proxies_.begin());
  for (; iter != manual_proxies_.end(); iter++) {
    DCHECK(!iter->scheme.empty());
    DCHECK(!iter->url.empty());
    DCHECK(iter->port != kInvalidIntPref);
    manual_proxy_settings += iter->scheme;
    manual_proxy_settings += "=";
    manual_proxy_settings += iter->url;
    manual_proxy_settings += ":";
    manual_proxy_settings += IntToString(iter->port);
    manual_proxy_settings += ";";
  }

  if (!manual_proxy_settings.empty()) {
    proxy_settings_value->SetString(automation::kJSONProxyServer,
                                    manual_proxy_settings);
  }

  return proxy_settings_value.release();
}

bool NpProxyService::GetProxyValueJSONString(std::string* output) {
  DCHECK(output);
  output->empty();

  // If we detected a PROXY_CONFIG_SYSTEM config type or failed to obtain the
  // pref service then return false here to make Chrome continue using its
  // default proxy settings.
  if (system_config_ || !pref_service_)
    return false;

  scoped_ptr<DictionaryValue> proxy_settings_value(BuildProxyValueSet());

  JSONStringValueSerializer serializer(output);
  return serializer.Serialize(*static_cast<Value*>(proxy_settings_value.get()));
}
<|endoftext|>


<commit_before>/* Copyright (c) 2006, NIF File Format Library and Tools
All rights reserved.  Please see niflib.h for licence. */

#include "NiTriStripsData.h"
using namespace Niflib;

//Definition of TYPE constant
const Type NiTriStripsData::TYPE("NiTriStripsData", &NI_TRI_STRIPS_DATA_PARENT::TypeConst() );

NiTriStripsData::NiTriStripsData() NI_TRI_STRIPS_DATA_CONSTRUCT {}

NiTriStripsData::~NiTriStripsData() {}

void NiTriStripsData::Read( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
	NI_TRI_STRIPS_DATA_READ
}

void NiTriStripsData::Write( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const {
	NI_TRI_STRIPS_DATA_WRITE
}

string NiTriStripsData::asString( bool verbose ) const {
	NI_TRI_STRIPS_DATA_STRING
}

void NiTriStripsData::FixLinks( const vector<NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
	NI_TRI_STRIPS_DATA_FIXLINKS
}

list<NiObjectRef> NiTriStripsData::GetRefs() const {
	NI_TRI_STRIPS_DATA_GETREFS
}

const Type & NiTriStripsData::GetType() const {
	return TYPE;
};

ushort NiTriStripsData::GetStripCount() const {
	return ushort(points.size());
}

void NiTriStripsData::SetStripCount(int n) {
	points.resize( n );

	//Recalculate Triangle Count
	numTriangles = CalcTriangleCount();
}

//Getters
vector<ushort> NiTriStripsData::GetStrip( int index ) const {
	return points[index];
}

vector<Triangle> NiTriStripsData::GetTriangles() const {

	//Create a vector to hold the triangles
	vector<Triangle> triangles( numTriangles );
	int n = 0; // Current triangle

	//Cycle through all strips
	vector< vector<ushort> >::const_iterator it;
	for (it = points.begin(); it != points.end(); ++it ) {
		//The first three values in the strip are the first triangle
		triangles[n].Set( (*it)[0], (*it)[1], (*it)[2] );

		//Move to the next triangle
		++n;

		//The remaining triangles use the previous two indices as their first two indices.
		for( uint i = 3; i < it->size(); ++i ) {
			//Odd numbered triangles need to be reversed to keep the vertices in counter-clockwise order
			if ( i % 2 == 0 ) {
				//cout << (*it)[i - 2] << ", " << (*it)[i - 1] << ", " << (*it)[i] << endl;
				triangles[n].Set( (*it)[i - 2], (*it)[i - 1], (*it)[i] );
			} else {
				//cout << (*it)[i] << ", " << (*it)[i - 1] << ", " << (*it)[i - 2] << endl;
				triangles[n].Set( (*it)[i], (*it)[i - 1], (*it)[i - 2] );
			}

			//Move to the next triangle
			++n;
		}
	}

	return triangles;
}

//Setter
void NiTriStripsData::SetStrip( int index, const vector<ushort> & in ) {
	points[index] = in;

	//Recalculate Triangle Count
	numTriangles = CalcTriangleCount();
}

ushort NiTriStripsData::CalcTriangleCount() const {

	//Calculate number of triangles
	//Sum of length of each strip - 2
	ushort numTriangles = 0;
	for ( uint i = 0; i < points.size(); ++i ) {
		numTriangles += ushort(points[i].size() - 2);
	}

	return numTriangles;
}

<commit_msg>NiTriStripsData::GetTriangles no longer returns triangles that have matching vertices and, thus, no surface area.<commit_after>/* Copyright (c) 2006, NIF File Format Library and Tools
All rights reserved.  Please see niflib.h for licence. */

#include "NiTriStripsData.h"
using namespace Niflib;

//Definition of TYPE constant
const Type NiTriStripsData::TYPE("NiTriStripsData", &NI_TRI_STRIPS_DATA_PARENT::TypeConst() );

NiTriStripsData::NiTriStripsData() NI_TRI_STRIPS_DATA_CONSTRUCT {}

NiTriStripsData::~NiTriStripsData() {}

void NiTriStripsData::Read( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
	NI_TRI_STRIPS_DATA_READ
}

void NiTriStripsData::Write( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version, unsigned int user_version ) const {
	NI_TRI_STRIPS_DATA_WRITE
}

string NiTriStripsData::asString( bool verbose ) const {
	NI_TRI_STRIPS_DATA_STRING
}

void NiTriStripsData::FixLinks( const vector<NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
	NI_TRI_STRIPS_DATA_FIXLINKS
}

list<NiObjectRef> NiTriStripsData::GetRefs() const {
	NI_TRI_STRIPS_DATA_GETREFS
}

const Type & NiTriStripsData::GetType() const {
	return TYPE;
};

ushort NiTriStripsData::GetStripCount() const {
	return ushort(points.size());
}

void NiTriStripsData::SetStripCount(int n) {
	points.resize( n );

	//Recalculate Triangle Count
	numTriangles = CalcTriangleCount();
}

//Getters
vector<ushort> NiTriStripsData::GetStrip( int index ) const {
	return points[index];
}

vector<Triangle> NiTriStripsData::GetTriangles() const {

	//Create a vector to hold the triangles
	vector<Triangle> triangles;
	int n = 0; // Current triangle

	//Cycle through all strips
	vector< vector<ushort> >::const_iterator it;
	Triangle t;
	for (it = points.begin(); it != points.end(); ++it ) {
		//The first three values in the strip are the first triangle
		t.Set( (*it)[0], (*it)[1], (*it)[2] );

		//Only add triangles to the list if none of the vertices match
		if ( t[0] != t[1] && t[0] != t[2] && t[1] != t[2] ) {
			triangles.push_back(t);
		}

		//Move to the next triangle
		++n;

		//The remaining triangles use the previous two indices as their first two indices.
		for( uint i = 3; i < it->size(); ++i ) {
			//Odd numbered triangles need to be reversed to keep the vertices in counter-clockwise order
			if ( i % 2 == 0 ) {
				//cout << (*it)[i - 2] << ", " << (*it)[i - 1] << ", " << (*it)[i] << endl;
				t.Set( (*it)[i - 2], (*it)[i - 1], (*it)[i] );
			} else {
				//cout << (*it)[i] << ", " << (*it)[i - 1] << ", " << (*it)[i - 2] << endl;
				t.Set( (*it)[i], (*it)[i - 1], (*it)[i - 2] );
			}

			//Only add triangles to the list if none of the vertices match
			if ( t[0] != t[1] && t[0] != t[2] && t[1] != t[2] ) {
				triangles.push_back(t);
			}

			//Move to the next triangle
			++n;
		}
	}

	return triangles;
}

//Setter
void NiTriStripsData::SetStrip( int index, const vector<ushort> & in ) {
	points[index] = in;

	//Recalculate Triangle Count
	numTriangles = CalcTriangleCount();
}

ushort NiTriStripsData::CalcTriangleCount() const {

	//Calculate number of triangles
	//Sum of length of each strip - 2
	ushort numTriangles = 0;
	for ( uint i = 0; i < points.size(); ++i ) {
		numTriangles += ushort(points[i].size() - 2);
	}

	return numTriangles;
}

<|endoftext|>


<commit_before>
#include <iostream>
#include <cstdlib>
#include <signal.h>

using std::cout;
using std::endl;

void my_handler(int signo) {
  cout << "NOPE!!" << endl;
} // my_handler

int main() {
  cout << NULL << endl;
  signal(SIGINT, (void (*)(int)) 42);
  // signal(SIGINT, my_handler);
  // sighandler_t old_handler = signal(SIGINT, SIG_IGN);
  //  signal(SIGINT, old_handler);
  // signal(SIGINT, SIG_DFL);
  while (true);
  return EXIT_SUCCESS;
} // main

<commit_msg>updated signal example<commit_after>
#include <iostream>
#include <cstdlib>
#include <signal.h>

using std::cout;
using std::endl;

void my_handler(int signo) {
  cout << "NOPE!!" << endl;
} // my_handler

int main() {
  //signal(SIGINT, (void (*)(int)) 42);
  signal(SIGINT, my_handler);
  // sighandler_t old_handler = signal(SIGINT, SIG_IGN);
  //  signal(SIGINT, old_handler);
  // signal(SIGINT, SIG_DFL);
  while (true);
  return EXIT_SUCCESS;
} // main

<|endoftext|>


<commit_before>// $Id$
//
// Copyright (C) 2003-2006 Rational Discovery LLC
//
//  @@ All Rights Reserved @@
//
#include "Dict.h"

#include <boost/lexical_cast.hpp>
#include <boost/shared_array.hpp>
#include <boost/tuple/tuple.hpp>
#include <vector>
#include <list>

namespace RDKit{
  Dict::Dict() {
    _data.clear();
  };
  Dict::Dict(const Dict &other) {
    _data = other._data;
  };
  Dict &Dict::operator=(const Dict &other) {
    _data = other._data;
    return *this;
  };

  bool Dict::hasVal(const char *what) const {
    std::string key(what);
    return hasVal(key);
  };
  bool Dict::hasVal(const std::string &what) const {
    return _data.count(what)>0;
  };

  STR_VECT Dict::keys() const {
    STR_VECT res;
    DataType::const_iterator item;
    for (item = _data.begin(); item != _data.end(); item++) {
      res.push_back(item->first);
    }
    return res;
  }

  //
  //  We're going to try and be somewhat crafty about this getVal stuff to make these
  //  containers a little bit more generic.  The normal behavior here is that the
  //  value being queried must be directly castable to type T.  We'll robustify a
  //  little bit by trying that and, if the cast fails, attempting a couple of
  //  other casts, which will then be lexically cast to type T.
  //
  void Dict::getVal(const std::string &what, std::string &res) const {
    if(! this->hasVal(what) ) throw KeyErrorException(what);
    const boost::any &val = _data.find(what)->second;
    try{
      res = boost::any_cast<std::string>(val);
    } catch (const boost::bad_any_cast &) {
      if(val.type()==typeid(int)){
	res = boost::lexical_cast<std::string>(boost::any_cast<int>(val));
      } else if(val.type()==typeid(long)){
	res = boost::lexical_cast<std::string>(boost::any_cast<long>(val));
      } else if(val.type()==typeid(float)){
	res = boost::lexical_cast<std::string>(boost::any_cast<float>(val));
      } else if(val.type()==typeid(double)){
	res = boost::lexical_cast<std::string>(boost::any_cast<double>(val));
      } else if(val.type()==typeid(const char *)){
	res = std::string(boost::any_cast<const char *>(val));
      } else {
	throw;
      }
    }
  };

  void Dict::clearVal(const std::string &what) {
    if(! this->hasVal(what) ) throw KeyErrorException(what);
    _data.erase(what);
  };

  void Dict::reset() {
    _data.clear();
  };

  template <typename T>
  T Dict::fromany(const boost::any &arg) const {
    return boost::any_cast<T>(arg);
  };

  template <typename T>
  boost::any Dict::toany(T arg) const {
    return boost::any(arg);
  };

#define ANY_FORCE(T) {tD.fromany< T >(boost::any(1));tD.toany< T >( T() );}

  void force_types(){
    Dict tD;
    bool fooBool = tD.fromany<bool>(boost::any(1));
    tD.toany<bool>(false);

    int fooInt = tD.fromany<int>(boost::any(1));
    fooInt += 1;
    tD.toany<int>(1);

    unsigned int fooUnsigned = tD.fromany<unsigned int>(boost::any(1));
    fooUnsigned += 1;
    tD.toany<unsigned int>(1);

    double fooDouble = tD.fromany<double>(boost::any(1));
    tD.toany<double>(1.0);

    std::string fooString = tD.fromany<std::string>(boost::any(std::string("1")));
    tD.toany<std::string>(std::string("1"));

    ANY_FORCE(std::vector<int>);
    ANY_FORCE(std::vector<double>);
    ANY_FORCE(std::vector<std::string>);

    ANY_FORCE(std::vector< std::vector<int> >);
    ANY_FORCE(std::vector< std::vector<double> >);

    ANY_FORCE(boost::shared_array<double>);
    ANY_FORCE(boost::shared_array<int>);

    ANY_FORCE(std::list<int>);

    // FIX: it's UGLY that we have to include things like this:
    //ANY_FORCE( boost::tuples::tuple<double,double,double> );
    tD.fromany< boost::tuples::tuple<double,double,double> >(boost::any(1));
    tD.toany< boost::tuples::tuple<double,double,double> >(boost::tuples::tuple<double,double,double>());

  }

}
<commit_msg>support a couple more types<commit_after>// $Id$
//
// Copyright (C) 2003-2006 Rational Discovery LLC
//
//  @@ All Rights Reserved @@
//
#include "Dict.h"

#include <boost/lexical_cast.hpp>
#include <boost/shared_array.hpp>
#include <boost/tuple/tuple.hpp>
#include <vector>
#include <list>

namespace RDKit{
  Dict::Dict() {
    _data.clear();
  };
  Dict::Dict(const Dict &other) {
    _data = other._data;
  };
  Dict &Dict::operator=(const Dict &other) {
    _data = other._data;
    return *this;
  };

  bool Dict::hasVal(const char *what) const {
    std::string key(what);
    return hasVal(key);
  };
  bool Dict::hasVal(const std::string &what) const {
    return _data.count(what)>0;
  };

  STR_VECT Dict::keys() const {
    STR_VECT res;
    DataType::const_iterator item;
    for (item = _data.begin(); item != _data.end(); item++) {
      res.push_back(item->first);
    }
    return res;
  }

  //
  //  We're going to try and be somewhat crafty about this getVal stuff to make these
  //  containers a little bit more generic.  The normal behavior here is that the
  //  value being queried must be directly castable to type T.  We'll robustify a
  //  little bit by trying that and, if the cast fails, attempting a couple of
  //  other casts, which will then be lexically cast to type T.
  //
  void Dict::getVal(const std::string &what, std::string &res) const {
    if(! this->hasVal(what) ) throw KeyErrorException(what);
    const boost::any &val = _data.find(what)->second;
    try{
      res = boost::any_cast<std::string>(val);
    } catch (const boost::bad_any_cast &) {
      if(val.type()==typeid(int)){
	res = boost::lexical_cast<std::string>(boost::any_cast<int>(val));
      } else if(val.type()==typeid(long)){
	res = boost::lexical_cast<std::string>(boost::any_cast<long>(val));
      } else if(val.type()==typeid(float)){
	res = boost::lexical_cast<std::string>(boost::any_cast<float>(val));
      } else if(val.type()==typeid(double)){
	res = boost::lexical_cast<std::string>(boost::any_cast<double>(val));
      } else if(val.type()==typeid(const char *)){
	res = std::string(boost::any_cast<const char *>(val));
      } else {
	throw;
      }
    }
  };

  void Dict::clearVal(const std::string &what) {
    if(! this->hasVal(what) ) throw KeyErrorException(what);
    _data.erase(what);
  };

  void Dict::reset() {
    _data.clear();
  };

  template <typename T>
  T Dict::fromany(const boost::any &arg) const {
    return boost::any_cast<T>(arg);
  };

  template <typename T>
  boost::any Dict::toany(T arg) const {
    return boost::any(arg);
  };

#define ANY_FORCE(T) {tD.fromany< T >(boost::any(1));tD.toany< T >( T() );}

  void force_types(){
    Dict tD;
    bool fooBool = tD.fromany<bool>(boost::any(1));
    tD.toany<bool>(false);

    int fooInt = tD.fromany<int>(boost::any(1));
    fooInt += 1;
    tD.toany<int>(1);

    unsigned int fooUnsigned = tD.fromany<unsigned int>(boost::any(1));
    fooUnsigned += 1;
    tD.toany<unsigned int>(1);

    double fooDouble = tD.fromany<double>(boost::any(1));
    tD.toany<double>(1.0);

    std::string fooString = tD.fromany<std::string>(boost::any(std::string("1")));
    tD.toany<std::string>(std::string("1"));

    ANY_FORCE(std::vector<int>);
    ANY_FORCE(std::vector<unsigned int>);
    ANY_FORCE(std::vector<unsigned long long>);
    ANY_FORCE(std::vector<double>);
    ANY_FORCE(std::vector<std::string>);

    ANY_FORCE(std::vector< std::vector<int> >);
    ANY_FORCE(std::vector< std::vector<double> >);

    ANY_FORCE(boost::shared_array<double>);
    ANY_FORCE(boost::shared_array<int>);

    ANY_FORCE(std::list<int>);

    // FIX: it's UGLY that we have to include things like this:
    //ANY_FORCE( boost::tuples::tuple<double,double,double> );
    tD.fromany< boost::tuples::tuple<double,double,double> >(boost::any(1));
    tD.toany< boost::tuples::tuple<double,double,double> >(boost::tuples::tuple<double,double,double>());

  }

}
<|endoftext|>