<commit_before>#include <sys/prctl.h>
#include <sys/wait.h>

#include <boost/lexical_cast.hpp>

#include "typename.h"
#include "Logger.h"
#include "demangle.h"
#include "exceptions.h"

logger::LogChannel tracelog("tracelog", "[trace] ");

stack_trace_::stack_trace_() {

	std::string programName = get_program_name();
	std::string pid         = get_pid();

	_stack_trace.push_back(std::string("\t[trace] back trace for ") + programName + " (" + pid + "):");

	// create a pipe to read gdb's output
	int pipefds[2];
	int res = pipe(pipefds);
	if (res < 0)
		return;

	// create a pipe to be used as a barrier
	int barrierfds[2];
	res = pipe(barrierfds);
	if (res < 0)
		return;

	// fork
	int childPid = fork();

	// child:
	if (!childPid) {

		LOG_ALL(tracelog) << "[child] waiting for parent process to allow attaching" << std::endl;

		// close writing end of barrier pipe
		close(barrierfds[1]);

		// wait until parent closes barrier pipe
		char buf[1];
		while (read(barrierfds[0], buf, sizeof(buf)) > 0)
			LOG_ALL(tracelog) << "[child] " << buf[0] << std::endl;

		LOG_ALL(tracelog) << "[child] parent process closed barrier pipe, preparing gdb invocation" << std::endl;

		// close barrier pipe
		close(barrierfds[0]);

		// close reading end of output pipe
		close(pipefds[0]);

		// redirect stdout and stderr to output pipe
		dup2(pipefds[1], 1);
		dup2(pipefds[1], 2);

		// close writing end of pipe (_we_ don't need it any longer)
		close(pipefds[1]);

		// start gdb
		execlp("gdb", "gdb", "--batch", "-n", "-ex", "bt full", programName.c_str(), pid.c_str(), NULL);

	// parent:
	} else {

		LOG_ALL(tracelog) << "[parent] allowing child to attach" << std::endl;

		// allow our child process to attach
		prctl(PR_SET_PTRACER, childPid, 0, 0, 0);

		LOG_ALL(tracelog) << "[parent] closing barrier pipe" << std::endl;

		// close barrier pipe to let child proceed
		close(barrierfds[0]);
		close(barrierfds[1]);

		LOG_ALL(tracelog) << "[parent] barrier pipe closed" << std::endl;

		// close the write end of pipe
		close(pipefds[1]);

		// capture child's output
		std::string output;

		// read the whole output of gdb
		char   buf[1];
		size_t n;
		while ((n = read(pipefds[0], buf, sizeof(buf))))
			output += std::string(buf, n);

		LOG_ALL(tracelog) << "[parent] end of pipe; I read: " << std::endl << output << std::endl;

		// split it at newline characters
		std::stringstream oss(output);
		std::string       line;

		// ignore every line until '#0 ...'
		while (std::getline(oss, line) && (line.size() < 2 || (line[0] != '#' && line[1] != '0')));

		// copy remaining lines to stack trace
		do {

			if (line.size() > 0 && line[0] != '\n')
				_stack_trace.push_back(std::string("\t[trace] ") + line);

		} while (std::getline(oss, line));

		// wait for the child to finish
		waitpid(childPid, NULL, 0);
	}

	return;
}

const std::vector<std::string>&
stack_trace_::get_stack_trace() const {

	return _stack_trace;
}

const std::string&
stack_trace_::get_program_name() {

	if (_program_name == "")
		initialise_program_name();

	return _program_name;
}

std::string
stack_trace_::get_pid() {

	return boost::lexical_cast<std::string>(getpid());
}

void
stack_trace_::initialise_program_name() {

	char link[1024];
	char name[1024];

	snprintf(link, sizeof link, "/proc/%d/exe", getpid());

	int size = readlink(link, name, sizeof link);
	if (size == -1) {

		_program_name = "[program name not found]";
		return;
	}

	for (int i = 0; i < size; i++)
		_program_name += name[i];
}

void handleException(boost::exception& e, std::ostream& out) {

	out << std::endl;
	out << "caught exception" << std::endl << std::endl;

	if (boost::get_error_info<stack_trace>(e)) {

		out << "###############" << std::endl;
		out << "# STACK TRACE #" << std::endl;
		out << "###############" << std::endl;
		out << std::endl << std::endl;
		out << *boost::get_error_info<stack_trace>(e);
		out << std::endl << std::endl;
	}

	out << "#####################" << std::endl;
	out << "# EXCEPTION SUMMARY #" << std::endl;
	out << "#####################" << std::endl;
	out << std::endl << std::endl;

	out << "exception type:" << std::endl << std::endl << "\t" << typeName(e) << std::endl << std::endl;

	if (boost::get_error_info<boost::throw_function>(e)) {

		out << "throw location:" << std::endl << std::endl;
		out << "\t" << *boost::get_error_info<boost::throw_function>(e) << std::endl;

		if (boost::get_error_info<boost::throw_file>(e)) {

			out << "\tin " << *boost::get_error_info<boost::throw_file>(e);
			if (boost::get_error_info<boost::throw_line>(e))
				out << "(" << *boost::get_error_info<boost::throw_line>(e) << ")";
		}

		out << std::endl;
	}

	if (boost::get_error_info<error_message>(e)) {

		out << std::endl << "error message:" << std::endl << std::endl;;
		out << "\t" << *boost::get_error_info<error_message>(e);
		out << std::endl;
	}
}
<commit_msg>fixed formatting of exception output<commit_after>#include <sys/prctl.h>
#include <sys/wait.h>

#include <boost/lexical_cast.hpp>

#include "typename.h"
#include "Logger.h"
#include "demangle.h"
#include "exceptions.h"

logger::LogChannel tracelog("tracelog", "[trace] ");

stack_trace_::stack_trace_() {

	std::string programName = get_program_name();
	std::string pid         = get_pid();

	_stack_trace.push_back(std::string("\t[trace] back trace for ") + programName + " (" + pid + "):");

	// create a pipe to read gdb's output
	int pipefds[2];
	int res = pipe(pipefds);
	if (res < 0)
		return;

	// create a pipe to be used as a barrier
	int barrierfds[2];
	res = pipe(barrierfds);
	if (res < 0)
		return;

	// fork
	int childPid = fork();

	// child:
	if (!childPid) {

		LOG_ALL(tracelog) << "[child] waiting for parent process to allow attaching" << std::endl;

		// close writing end of barrier pipe
		close(barrierfds[1]);

		// wait until parent closes barrier pipe
		char buf[1];
		while (read(barrierfds[0], buf, sizeof(buf)) > 0)
			LOG_ALL(tracelog) << "[child] " << buf[0] << std::endl;

		LOG_ALL(tracelog) << "[child] parent process closed barrier pipe, preparing gdb invocation" << std::endl;

		// close barrier pipe
		close(barrierfds[0]);

		// close reading end of output pipe
		close(pipefds[0]);

		// redirect stdout and stderr to output pipe
		dup2(pipefds[1], 1);
		dup2(pipefds[1], 2);

		// close writing end of pipe (_we_ don't need it any longer)
		close(pipefds[1]);

		// start gdb
		execlp("gdb", "gdb", "--batch", "-n", "-ex", "bt full", programName.c_str(), pid.c_str(), NULL);

	// parent:
	} else {

		LOG_ALL(tracelog) << "[parent] allowing child to attach" << std::endl;

		// allow our child process to attach
		prctl(PR_SET_PTRACER, childPid, 0, 0, 0);

		LOG_ALL(tracelog) << "[parent] closing barrier pipe" << std::endl;

		// close barrier pipe to let child proceed
		close(barrierfds[0]);
		close(barrierfds[1]);

		LOG_ALL(tracelog) << "[parent] barrier pipe closed" << std::endl;

		// close the write end of pipe
		close(pipefds[1]);

		// capture child's output
		std::string output;

		// read the whole output of gdb
		char   buf[1];
		size_t n;
		while ((n = read(pipefds[0], buf, sizeof(buf))))
			output += std::string(buf, n);

		LOG_ALL(tracelog) << "[parent] end of pipe; I read: " << std::endl << output << std::endl;

		// split it at newline characters
		std::stringstream oss(output);
		std::string       line;

		// ignore every line until '#0 ...'
		while (std::getline(oss, line) && (line.size() < 2 || (line[0] != '#' && line[1] != '0')));

		// copy remaining lines to stack trace
		do {

			if (line.size() > 0 && line[0] != '\n')
				_stack_trace.push_back(std::string("\t[trace] ") + line);

		} while (std::getline(oss, line));

		// wait for the child to finish
		waitpid(childPid, NULL, 0);
	}

	return;
}

const std::vector<std::string>&
stack_trace_::get_stack_trace() const {

	return _stack_trace;
}

const std::string&
stack_trace_::get_program_name() {

	if (_program_name == "")
		initialise_program_name();

	return _program_name;
}

std::string
stack_trace_::get_pid() {

	return boost::lexical_cast<std::string>(getpid());
}

void
stack_trace_::initialise_program_name() {

	char link[1024];
	char name[1024];

	snprintf(link, sizeof link, "/proc/%d/exe", getpid());

	int size = readlink(link, name, sizeof link);
	if (size == -1) {

		_program_name = "[program name not found]";
		return;
	}

	for (int i = 0; i < size; i++)
		_program_name += name[i];
}

void handleException(boost::exception& e, std::ostream& out) {

	out << std::endl;
	out << "caught exception" << std::endl << std::endl;

	if (boost::get_error_info<stack_trace>(e)) {

		out << "###############" << std::endl;
		out << "# STACK TRACE #" << std::endl;
		out << "###############" << std::endl;
		out << std::endl << std::endl;
		out << *boost::get_error_info<stack_trace>(e);
		out << std::endl << std::endl;
	}

	out << "#####################" << std::endl;
	out << "# EXCEPTION SUMMARY #" << std::endl;
	out << "#####################" << std::endl;
	out << std::endl << std::endl;

	out << "exception type:" << std::endl << std::endl << "\t" << typeName(e) << std::endl << std::endl;

	if (boost::get_error_info<boost::throw_function>(e)) {

		out << "throw location:" << std::endl << std::endl;
		out << "\t" << *boost::get_error_info<boost::throw_function>(e) << std::endl;

		if (boost::get_error_info<boost::throw_file>(e)) {

			out << "\tin " << *boost::get_error_info<boost::throw_file>(e);
			if (boost::get_error_info<boost::throw_line>(e))
				out << "(" << *boost::get_error_info<boost::throw_line>(e) << ")";
		}

		out << std::endl;
	}

	if (boost::get_error_info<error_message>(e)) {

		out << std::endl << "error message:" << std::endl << std::endl;;
		out << "\t" << *boost::get_error_info<error_message>(e);
		out << std::endl << std::endl;
	}
}
<|endoftext|>


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

#include "SurgSim/Math/MlcpConstraintType.h"
#include "SurgSim/Physics/Constraint.h"
#include "SurgSim/Physics/ConstraintData.h"
#include "SurgSim/Physics/Localization.h"

#include "SurgSim/Framework/Assert.h"

namespace SurgSim
{

namespace Physics
{

Constraint::Constraint(ConstraintType constraintType,
	std::shared_ptr<ConstraintData> data,
	std::shared_ptr<Representation> representation0,
	const SurgSim::DataStructures::Location& location0,
	std::shared_ptr<Representation> representation1,
	const SurgSim::DataStructures::Location& location1)
{
	m_mlcpMap[INVALID_CONSTRAINT] = Math::MLCP_INVALID_CONSTRAINT;
	m_mlcpMap[FIXED_3DPOINT] = Math::MLCP_BILATERAL_3D_CONSTRAINT;
	m_mlcpMap[FIXED_3DROTATION_VECTOR] = Math::MLCP_BILATERAL_3D_CONSTRAINT;
	m_mlcpMap[FRICTIONAL_3DCONTACT] = Math::MLCP_UNILATERAL_3D_FRICTIONAL_CONSTRAINT;
	m_mlcpMap[FRICTIONLESS_3DCONTACT] = Math::MLCP_UNILATERAL_3D_FRICTIONLESS_CONSTRAINT;
	setInformation(constraintType, data, representation0, location0, representation1, location1);
}

Constraint::~Constraint()
{
}

const std::pair<std::shared_ptr<ConstraintImplementation>, std::shared_ptr<ConstraintImplementation>>&
	Constraint::getImplementations() const
{
	return m_implementations;
}

const std::pair<std::shared_ptr<Localization>, std::shared_ptr<Localization>>& Constraint::getLocalizations() const
{
	return m_localizations;
}

std::shared_ptr<ConstraintData> Constraint::getData() const
{
	return m_data;
}

size_t Constraint::getNumDof() const
{
	return m_numDof;
}

void Constraint::build(double dt,
	MlcpPhysicsProblem* mlcp,
	size_t indexOfRepresentation0,
	size_t indexOfRepresentation1,
	size_t indexOfConstraint)
{
	doBuild(dt, *m_data.get(), mlcp, indexOfRepresentation0, indexOfRepresentation1, indexOfConstraint);

	m_implementations.first->build(
		dt,
		*m_data.get(),
		m_localizations.first,
		mlcp,
		indexOfRepresentation0,
		indexOfConstraint,
		CONSTRAINT_POSITIVE_SIDE);

	m_implementations.second->build(
		dt,
		*m_data.get(),
		m_localizations.second,
		mlcp,
		indexOfRepresentation1,
		indexOfConstraint,
		CONSTRAINT_NEGATIVE_SIDE);

	mlcp->constraintTypes.push_back(m_mlcpMap[m_constraintType]);
}

bool Constraint::isActive()
{
	return m_localizations.first->getRepresentation()->isActive() &&
		   m_localizations.second->getRepresentation()->isActive();
}

void Constraint::doBuild(double dt,
	const ConstraintData& data,
	MlcpPhysicsProblem* mlcp,
	size_t indexOfRepresentation0,
	size_t indexOfRepresentation1,
	size_t indexOfConstraint)
{
}

void Constraint::setInformation(SurgSim::Physics::ConstraintType constraintType,
	std::shared_ptr<ConstraintData> data,
	std::shared_ptr<Representation> representation0,
	const SurgSim::DataStructures::Location& location0,
	std::shared_ptr<Representation> representation1,
	const SurgSim::DataStructures::Location& location1)
{
	m_constraintType = constraintType;
	SURGSIM_ASSERT(data != nullptr) << "ConstraintData can't be nullptr";
	SURGSIM_ASSERT(representation0 != nullptr) << "First representation can't be nullptr";
	SURGSIM_ASSERT(representation1 != nullptr) << "Second representation can't be nullptr";

	auto localization0 = representation0->createLocalization(location0);
	SURGSIM_ASSERT(localization0 != nullptr) << "Could not create localization for " << representation0->getName();

	auto localization1 = representation1->createLocalization(location1);
	SURGSIM_ASSERT(localization1 != nullptr) << "Could not create localization for " << representation1->getName();

	auto implementation0 = representation0->getConstraintImplementation(m_constraintType);
	SURGSIM_ASSERT(implementation0 != nullptr) << "Could not get implementation for " << representation0->getName();

	auto implementation1 = representation1->getConstraintImplementation(m_constraintType);
	SURGSIM_ASSERT(implementation1 != nullptr) << "Could not get implementation for " << representation1->getName();

	SURGSIM_ASSERT(implementation0->getNumDof() == implementation1->getNumDof())
		<< "The number of DOFs does not match between the two implementations";

	m_data = data;
	m_implementations = std::make_pair(implementation0, implementation1);
	m_localizations = std::make_pair(localization0, localization1);
	m_numDof = implementation0->getNumDof();
}

}; // namespace Physics

}; // namespace SurgSim
<commit_msg>Fix segfault from INVALID_CONSTRAINT used as array index<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "SurgSim/Math/MlcpConstraintType.h"
#include "SurgSim/Physics/Constraint.h"
#include "SurgSim/Physics/ConstraintData.h"
#include "SurgSim/Physics/Localization.h"

#include "SurgSim/Framework/Assert.h"

namespace SurgSim
{

namespace Physics
{

Constraint::Constraint(ConstraintType constraintType,
	std::shared_ptr<ConstraintData> data,
	std::shared_ptr<Representation> representation0,
	const SurgSim::DataStructures::Location& location0,
	std::shared_ptr<Representation> representation1,
	const SurgSim::DataStructures::Location& location1)
{
	m_mlcpMap[FIXED_3DPOINT] = Math::MLCP_BILATERAL_3D_CONSTRAINT;
	m_mlcpMap[FIXED_3DROTATION_VECTOR] = Math::MLCP_BILATERAL_3D_CONSTRAINT;
	m_mlcpMap[FRICTIONAL_3DCONTACT] = Math::MLCP_UNILATERAL_3D_FRICTIONAL_CONSTRAINT;
	m_mlcpMap[FRICTIONLESS_3DCONTACT] = Math::MLCP_UNILATERAL_3D_FRICTIONLESS_CONSTRAINT;
	setInformation(constraintType, data, representation0, location0, representation1, location1);
}

Constraint::~Constraint()
{
}

const std::pair<std::shared_ptr<ConstraintImplementation>, std::shared_ptr<ConstraintImplementation>>&
	Constraint::getImplementations() const
{
	return m_implementations;
}

const std::pair<std::shared_ptr<Localization>, std::shared_ptr<Localization>>& Constraint::getLocalizations() const
{
	return m_localizations;
}

std::shared_ptr<ConstraintData> Constraint::getData() const
{
	return m_data;
}

size_t Constraint::getNumDof() const
{
	return m_numDof;
}

void Constraint::build(double dt,
	MlcpPhysicsProblem* mlcp,
	size_t indexOfRepresentation0,
	size_t indexOfRepresentation1,
	size_t indexOfConstraint)
{
	doBuild(dt, *m_data.get(), mlcp, indexOfRepresentation0, indexOfRepresentation1, indexOfConstraint);

	m_implementations.first->build(
		dt,
		*m_data.get(),
		m_localizations.first,
		mlcp,
		indexOfRepresentation0,
		indexOfConstraint,
		CONSTRAINT_POSITIVE_SIDE);

	m_implementations.second->build(
		dt,
		*m_data.get(),
		m_localizations.second,
		mlcp,
		indexOfRepresentation1,
		indexOfConstraint,
		CONSTRAINT_NEGATIVE_SIDE);

	mlcp->constraintTypes.push_back(
				(m_constraintType != INVALID_CONSTRAINT) ? m_mlcpMap[m_constraintType] : Math::MLCP_INVALID_CONSTRAINT);
}

bool Constraint::isActive()
{
	return m_localizations.first->getRepresentation()->isActive() &&
		   m_localizations.second->getRepresentation()->isActive();
}

void Constraint::doBuild(double dt,
	const ConstraintData& data,
	MlcpPhysicsProblem* mlcp,
	size_t indexOfRepresentation0,
	size_t indexOfRepresentation1,
	size_t indexOfConstraint)
{
}

void Constraint::setInformation(SurgSim::Physics::ConstraintType constraintType,
	std::shared_ptr<ConstraintData> data,
	std::shared_ptr<Representation> representation0,
	const SurgSim::DataStructures::Location& location0,
	std::shared_ptr<Representation> representation1,
	const SurgSim::DataStructures::Location& location1)
{
	m_constraintType = constraintType;
	SURGSIM_ASSERT(data != nullptr) << "ConstraintData can't be nullptr";
	SURGSIM_ASSERT(representation0 != nullptr) << "First representation can't be nullptr";
	SURGSIM_ASSERT(representation1 != nullptr) << "Second representation can't be nullptr";

	auto localization0 = representation0->createLocalization(location0);
	SURGSIM_ASSERT(localization0 != nullptr) << "Could not create localization for " << representation0->getName();

	auto localization1 = representation1->createLocalization(location1);
	SURGSIM_ASSERT(localization1 != nullptr) << "Could not create localization for " << representation1->getName();

	auto implementation0 = representation0->getConstraintImplementation(m_constraintType);
	SURGSIM_ASSERT(implementation0 != nullptr) << "Could not get implementation for " << representation0->getName();

	auto implementation1 = representation1->getConstraintImplementation(m_constraintType);
	SURGSIM_ASSERT(implementation1 != nullptr) << "Could not get implementation for " << representation1->getName();

	SURGSIM_ASSERT(implementation0->getNumDof() == implementation1->getNumDof())
		<< "The number of DOFs does not match between the two implementations";

	m_data = data;
	m_implementations = std::make_pair(implementation0, implementation1);
	m_localizations = std::make_pair(localization0, localization1);
	m_numDof = implementation0->getNumDof();
}

}; // namespace Physics

}; // namespace SurgSim
<|endoftext|>


<commit_before>/*
    Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "kabcmodel.h"

#include <kabc/addressee.h>
#include <kabc/contactgroup.h>
#include <kicon.h>
#include <klocale.h>
#include <akonadi/item.h>
#include <akonadi/itemfetchjob.h>
#include <akonadi/itemfetchscope.h>

using namespace Akonadi;

class KABCModel::Private
{
  public:
};

KABCModel::KABCModel( QObject *parent )
  : Akonadi::ItemModel( parent ),
    d( new Private() )
{
  fetchScope().fetchFullPayload();
}

KABCModel::~KABCModel()
{
  delete d;
}

int KABCModel::columnCount( const QModelIndex& ) const
{
  return 4;
}

QVariant KABCModel::data( const QModelIndex &index, int role ) const
{
  // pass through the queries for ItemModel
  if ( role == ItemModel::IdRole || role == ItemModel::MimeTypeRole )
    return ItemModel::data( index, role );

  if ( !index.isValid() )
    return QVariant();

  if ( index.row() >= rowCount() )
    return QVariant();

  const Item item = itemForIndex( index );

  if ( item.mimeType() == QLatin1String( "text/directory" ) ) {
    if ( !item.hasPayload<KABC::Addressee>() )
      return QVariant();

    const KABC::Addressee addr = item.payload<KABC::Addressee>();

    if ( role == Qt::DecorationRole ) {
      if ( index.column() == 0 ) {
        const KABC::Picture picture = addr.photo();
        if ( picture.isIntern() ) {
          return picture.data().scaled( QSize( 16, 16 ) );
        } else {
          return KIcon( QLatin1String( "x-office-contact" ) );
        }
      }
      return QVariant();
    } else if ( role == Qt::DisplayRole ) {
      switch ( index.column() ) {
        case 0:
          if ( !addr.formattedName().isEmpty() )
            return addr.formattedName();
          else
            return addr.assembledName();
        case 1:
          return addr.givenName();
          break;
        case 2:
          return addr.familyName();
          break;
        case 3:
          return addr.preferredEmail();
          break;
        default:
          break;
      }
    }
  } else if ( item.mimeType() == KABC::ContactGroup::mimeType() ) {
    if ( role == Qt::DecorationRole ) {
      if ( index.column() == 0 )
        return KIcon( QLatin1String( "x-mail-distribution-list" ) );
      else
        return QVariant();
    } else if ( role == Qt::DisplayRole ) {
      switch ( index.column() ) {
        case 0:
          {
            const KABC::ContactGroup group = item.payload<KABC::ContactGroup>();
            return group.name();
          }
          break;
        default:
          break;
      }
    }
  }

  return QVariant();
}

QVariant KABCModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
  if ( role != Qt::DisplayRole )
    return QVariant();

  if ( orientation != Qt::Horizontal )
    return QVariant();

  switch ( section ) {
    case 0:
      return i18nc( "@title:column, name of a person", "Name" );
      break;
    case 1:
      return KABC::Addressee::givenNameLabel();
      break;
    case 2:
      return KABC::Addressee::familyNameLabel();
      break;
    case 3:
      return KABC::Addressee::emailLabel();
      break;
    default:
      break;
  }

  return QVariant();
}
<commit_msg>Check for payload before accessing it. Same check as for the addressee case.<commit_after>/*
    Copyright (c) 2007 Tobias Koenig <tokoe@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "kabcmodel.h"

#include <kabc/addressee.h>
#include <kabc/contactgroup.h>
#include <kicon.h>
#include <klocale.h>
#include <akonadi/item.h>
#include <akonadi/itemfetchjob.h>
#include <akonadi/itemfetchscope.h>

using namespace Akonadi;

class KABCModel::Private
{
  public:
};

KABCModel::KABCModel( QObject *parent )
  : Akonadi::ItemModel( parent ),
    d( new Private() )
{
  fetchScope().fetchFullPayload();
}

KABCModel::~KABCModel()
{
  delete d;
}

int KABCModel::columnCount( const QModelIndex& ) const
{
  return 4;
}

QVariant KABCModel::data( const QModelIndex &index, int role ) const
{
  // pass through the queries for ItemModel
  if ( role == ItemModel::IdRole || role == ItemModel::MimeTypeRole )
    return ItemModel::data( index, role );

  if ( !index.isValid() )
    return QVariant();

  if ( index.row() >= rowCount() )
    return QVariant();

  const Item item = itemForIndex( index );

  if ( item.mimeType() == QLatin1String( "text/directory" ) ) {
    if ( !item.hasPayload<KABC::Addressee>() )
      return QVariant();

    const KABC::Addressee addr = item.payload<KABC::Addressee>();

    if ( role == Qt::DecorationRole ) {
      if ( index.column() == 0 ) {
        const KABC::Picture picture = addr.photo();
        if ( picture.isIntern() ) {
          return picture.data().scaled( QSize( 16, 16 ) );
        } else {
          return KIcon( QLatin1String( "x-office-contact" ) );
        }
      }
      return QVariant();
    } else if ( role == Qt::DisplayRole ) {
      switch ( index.column() ) {
        case 0:
          if ( !addr.formattedName().isEmpty() )
            return addr.formattedName();
          else
            return addr.assembledName();
        case 1:
          return addr.givenName();
          break;
        case 2:
          return addr.familyName();
          break;
        case 3:
          return addr.preferredEmail();
          break;
        default:
          break;
      }
    }
  } else if ( item.mimeType() == KABC::ContactGroup::mimeType() ) {
    if ( !item.hasPayload<KABC::ContactGroup>() )
      return QVariant();

    if ( role == Qt::DecorationRole ) {
      if ( index.column() == 0 )
        return KIcon( QLatin1String( "x-mail-distribution-list" ) );
      else
        return QVariant();
    } else if ( role == Qt::DisplayRole ) {
      switch ( index.column() ) {
        case 0:
          {
            const KABC::ContactGroup group = item.payload<KABC::ContactGroup>();
            return group.name();
          }
          break;
        default:
          break;
      }
    }
  }

  return QVariant();
}

QVariant KABCModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
  if ( role != Qt::DisplayRole )
    return QVariant();

  if ( orientation != Qt::Horizontal )
    return QVariant();

  switch ( section ) {
    case 0:
      return i18nc( "@title:column, name of a person", "Name" );
      break;
    case 1:
      return KABC::Addressee::givenNameLabel();
      break;
    case 2:
      return KABC::Addressee::familyNameLabel();
      break;
    case 3:
      return KABC::Addressee::emailLabel();
      break;
    default:
      break;
  }

  return QVariant();
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2018-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

#include "MethodReference.h"

#include "Resolver.h"
#include "Walkers.h"

namespace method_reference {

IRInstruction* make_load_const(uint16_t dest, size_t val) {
  auto load = new IRInstruction(OPCODE_CONST);
  load->set_dest(dest);
  load->set_literal(static_cast<int32_t>(val));
  return load;
}

IRInstruction* make_invoke(DexMethod* callee,
                           IROpcode opcode,
                           std::vector<uint16_t> args) {
  always_assert(callee->is_def() && is_public(callee));
  auto invoke = (new IRInstruction(opcode))->set_method(callee);
  invoke->set_arg_word_count(args.size());
  for (size_t i = 0; i < args.size(); i++) {
    invoke->set_src(i, args.at(i));
  }
  return invoke;
}

void patch_callsite(const CallSiteSpec& spec,
                    const boost::optional<uint32_t>& additional_arg) {
  const auto caller = spec.caller;
  const auto call_insn = spec.call_insn;
  const auto callee = spec.new_callee;
  TRACE(REFU, 9, " patching call site at %s\n", SHOW(call_insn));
  always_assert_log(is_public(callee),
                    "Updating a call site with a non-public new callee %s\n",
                    SHOW(callee));
  auto code = caller->get_code();
  auto additional_arg_reg = code->allocate_temp();
  auto load_additional_arg =
      make_load_const(additional_arg_reg, additional_arg.get_value_or(0));

  // Assuming the following move-result is there and good.
  std::vector<uint16_t> args;
  for (size_t i = 0; i < call_insn->srcs_size(); i++) {
    args.push_back(call_insn->src(i));
  }
  if (additional_arg != boost::none) {
    args.push_back(additional_arg_reg);
  }
  auto invoke = make_invoke(callee, call_insn->opcode(), args);
  if (additional_arg != boost::none) {
    code->insert_after(
        call_insn, std::vector<IRInstruction*>{load_additional_arg, invoke});
  } else {
    code->insert_after(call_insn, std::vector<IRInstruction*>{invoke});
  }

  // remove original call.
  code->remove_opcode(call_insn);
  TRACE(REFU, 9, " patched call site in %s\n%s\n", SHOW(caller), SHOW(code));
}

void update_call_refs_simple(
    const Scope& scope,
    const std::unordered_map<DexMethod*, DexMethod*>& old_to_new_callee) {
  auto patcher = [&](DexMethod* meth, IRCode& code) {
    for (auto& mie : InstructionIterable(code)) {
      auto insn = mie.insn;
      if (!insn->has_method()) {
        continue;
      }
      const auto method =
          resolve_method(insn->get_method(), opcode_to_search(insn));
      if (method == nullptr || old_to_new_callee.count(method) == 0) {
        continue;
      }
      auto new_callee = old_to_new_callee.at(method);
      // At this point, a non static private should not exist.
      always_assert_log(!is_private(new_callee) || is_static(new_callee),
                        "%s\n",
                        vshow(new_callee).c_str());
      TRACE(REFU, 9, " Updated call %s to %s\n", SHOW(insn), SHOW(new_callee));
      insn->set_method(new_callee);
      if (new_callee->is_virtual()) {
        always_assert_log(is_invoke_virtual(insn->opcode()),
                          "invalid callsite %s\n",
                          SHOW(insn));
      } else if (is_static(new_callee)) {
        always_assert_log(is_invoke_static(insn->opcode()),
                          "invalid callsite %s\n",
                          SHOW(insn));
      }
    }
  };
  walk::parallel::code(scope, patcher);
}

CallSites collect_call_refs(const Scope& scope,
                            const MethodOrderedSet& callees) {
  auto patcher = [&](std::nullptr_t, DexMethod* meth) {
    CallSites call_sites;
    auto code = meth->get_code();
    if (!code) {
      return call_sites;
    }

    for (auto& mie : InstructionIterable(meth->get_code())) {
      auto insn = mie.insn;
      if (!insn->has_method()) {
        continue;
      }

      const auto method =
          resolve_method(insn->get_method(),
                         opcode_to_search(const_cast<IRInstruction*>(insn)));
      if (method == nullptr || callees.count(method) == 0) {
        continue;
      }

      call_sites.emplace_back(meth, insn);
      TRACE(REFU, 9, "  Found call %s from %s\n", SHOW(insn), SHOW(meth));
    }

    return call_sites;
  };

  CallSites call_sites =
      walk::parallel::reduce_methods<std::nullptr_t, CallSites>(
          scope,
          patcher,
          [](CallSites left, CallSites right) {
            left.insert(left.end(), right.begin(), right.end());
            return left;
          },
          [](int) { return nullptr; });
  return call_sites;
}

} // namespace method_reference
<commit_msg>Update all protected (and package protected) methods to public when patching<commit_after>/**
 * Copyright (c) 2018-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

#include "MethodReference.h"

#include "Resolver.h"
#include "Walkers.h"

namespace method_reference {

IRInstruction* make_load_const(uint16_t dest, size_t val) {
  auto load = new IRInstruction(OPCODE_CONST);
  load->set_dest(dest);
  load->set_literal(static_cast<int32_t>(val));
  return load;
}

IRInstruction* make_invoke(DexMethod* callee,
                           IROpcode opcode,
                           std::vector<uint16_t> args) {
  always_assert(callee->is_def() && is_public(callee));
  auto invoke = (new IRInstruction(opcode))->set_method(callee);
  invoke->set_arg_word_count(args.size());
  for (size_t i = 0; i < args.size(); i++) {
    invoke->set_src(i, args.at(i));
  }
  return invoke;
}

void patch_callsite(const CallSiteSpec& spec,
                    const boost::optional<uint32_t>& additional_arg) {
  const auto caller = spec.caller;
  const auto call_insn = spec.call_insn;
  const auto callee = spec.new_callee;
  TRACE(REFU, 9, " patching call site at %s\n", SHOW(call_insn));

  // Update package protected or protected methods to public.
  if (is_static(callee) || is_any_init(callee) || !is_private(callee)) {
    set_public(callee);
  }
  always_assert_log(
      is_public(callee) || callee->get_class() == caller->get_class(),
      "Updating a call site of %s when not accessible from %s\n",
      SHOW(callee), SHOW(caller));

  auto code = caller->get_code();
  auto additional_arg_reg = code->allocate_temp();
  auto load_additional_arg =
      make_load_const(additional_arg_reg, additional_arg.get_value_or(0));

  // Assuming the following move-result is there and good.
  std::vector<uint16_t> args;
  for (size_t i = 0; i < call_insn->srcs_size(); i++) {
    args.push_back(call_insn->src(i));
  }
  if (additional_arg != boost::none) {
    args.push_back(additional_arg_reg);
  }
  auto invoke = make_invoke(callee, call_insn->opcode(), args);
  if (additional_arg != boost::none) {
    code->insert_after(
        call_insn, std::vector<IRInstruction*>{load_additional_arg, invoke});
  } else {
    code->insert_after(call_insn, std::vector<IRInstruction*>{invoke});
  }

  // remove original call.
  code->remove_opcode(call_insn);
  TRACE(REFU, 9, " patched call site in %s\n%s\n", SHOW(caller), SHOW(code));
}

void update_call_refs_simple(
    const Scope& scope,
    const std::unordered_map<DexMethod*, DexMethod*>& old_to_new_callee) {
  auto patcher = [&](DexMethod* meth, IRCode& code) {
    for (auto& mie : InstructionIterable(code)) {
      auto insn = mie.insn;
      if (!insn->has_method()) {
        continue;
      }
      const auto method =
          resolve_method(insn->get_method(), opcode_to_search(insn));
      if (method == nullptr || old_to_new_callee.count(method) == 0) {
        continue;
      }
      auto new_callee = old_to_new_callee.at(method);
      // At this point, a non static private should not exist.
      always_assert_log(!is_private(new_callee) || is_static(new_callee),
                        "%s\n",
                        vshow(new_callee).c_str());
      TRACE(REFU, 9, " Updated call %s to %s\n", SHOW(insn), SHOW(new_callee));
      insn->set_method(new_callee);
      if (new_callee->is_virtual()) {
        always_assert_log(is_invoke_virtual(insn->opcode()),
                          "invalid callsite %s\n",
                          SHOW(insn));
      } else if (is_static(new_callee)) {
        always_assert_log(is_invoke_static(insn->opcode()),
                          "invalid callsite %s\n",
                          SHOW(insn));
      }
    }
  };
  walk::parallel::code(scope, patcher);
}

CallSites collect_call_refs(const Scope& scope,
                            const MethodOrderedSet& callees) {
  auto patcher = [&](std::nullptr_t, DexMethod* meth) {
    CallSites call_sites;
    auto code = meth->get_code();
    if (!code) {
      return call_sites;
    }

    for (auto& mie : InstructionIterable(meth->get_code())) {
      auto insn = mie.insn;
      if (!insn->has_method()) {
        continue;
      }

      const auto method =
          resolve_method(insn->get_method(),
                         opcode_to_search(const_cast<IRInstruction*>(insn)));
      if (method == nullptr || callees.count(method) == 0) {
        continue;
      }

      call_sites.emplace_back(meth, insn);
      TRACE(REFU, 9, "  Found call %s from %s\n", SHOW(insn), SHOW(meth));
    }

    return call_sites;
  };

  CallSites call_sites =
      walk::parallel::reduce_methods<std::nullptr_t, CallSites>(
          scope,
          patcher,
          [](CallSites left, CallSites right) {
            left.insert(left.end(), right.begin(), right.end());
            return left;
          },
          [](int) { return nullptr; });
  return call_sites;
}

} // namespace method_reference
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 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/browser/login_prompt.h"

#include "base/command_line.h"
#include "base/lock.h"
#include "base/message_loop.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/password_manager/password_manager.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/tab_contents/constrained_window.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/browser/views/login_view.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/l10n_util.h"
#include "chrome/common/notification_service.h"
#include "chrome/views/dialog_delegate.h"
#include "grit/generated_resources.h"
#include "net/base/auth.h"
#include "net/url_request/url_request.h"

using namespace std;
using views::LoginView;

class LoginHandlerImpl;

// Helper to remove the ref from an URLRequest to the LoginHandler.
// Should only be called from the IO thread, since it accesses an URLRequest.
static void ResetLoginHandlerForRequest(URLRequest* request) {
  ResourceDispatcherHost::ExtraRequestInfo* info =
      ResourceDispatcherHost::ExtraInfoForRequest(request);
  if (!info)
    return;

  info->login_handler = NULL;
}

// Get the signon_realm under which this auth info should be stored.
//
// The format of the signon_realm for proxy auth is:
//     proxy-host/auth-realm
// The format of the signon_realm for server auth is:
//     url-scheme://url-host[:url-port]/auth-realm
//
// Be careful when changing this function, since you could make existing
// saved logins un-retrievable.

std::string GetSignonRealm(const GURL& url,
                           const net::AuthChallengeInfo& auth_info) {
  std::string signon_realm;
  if (auth_info.is_proxy) {
    signon_realm = WideToASCII(auth_info.host);
    signon_realm.append("/");
  } else {
    // Take scheme, host, and port from the url.
    signon_realm = url.GetOrigin().spec();
    // This ends with a "/".
  }
  signon_realm.append(WideToUTF8(auth_info.realm));
  return signon_realm;
}

// ----------------------------------------------------------------------------
// LoginHandlerImpl

// This class simply forwards the authentication from the LoginView (on
// the UI thread) to the URLRequest (on the I/O thread).
// This class uses ref counting to ensure that it lives until all InvokeLaters
// have been called.
class LoginHandlerImpl : public LoginHandler,
                         public base::RefCountedThreadSafe<LoginHandlerImpl>,
                         public views::DialogDelegate {
 public:
  LoginHandlerImpl(URLRequest* request, MessageLoop* ui_loop)
      : dialog_(NULL),
        handled_auth_(false),
        request_(request),
        request_loop_(MessageLoop::current()),
        ui_loop_(ui_loop),
        password_manager_(NULL) {
    DCHECK(request_) << "LoginHandler constructed with NULL request";

    AddRef();  // matched by ReleaseLater.
    if (!tab_util::GetTabContentsID(request_, &render_process_host_id_,
                                    &tab_contents_id_)) {
      NOTREACHED();
    }
  }

  ~LoginHandlerImpl() {
  }

  // Initialize the UI part of the LoginHandler.
  // Scary thread safety note: This can potentially be called *after* SetAuth
  // or CancelAuth (say, if the request was cancelled before the UI thread got
  // control).  However, that's OK since any UI interaction in those functions
  // will occur via an InvokeLater on the UI thread, which is guaranteed
  // to happen after this is called (since this was InvokeLater'd first).
  void InitWithDialog(ConstrainedWindow* dlg) {
    DCHECK(MessageLoop::current() == ui_loop_);
    dialog_ = dlg;
    SendNotifications();
  }

  // Returns the WebContents that needs authentication.
  WebContents* GetWebContentsForLogin() {
    DCHECK(MessageLoop::current() == ui_loop_);

    return tab_util::GetWebContentsByID(render_process_host_id_,
                                        tab_contents_id_);
  }

  void set_login_view(LoginView* login_view) {
    login_view_ = login_view;
  }

  void set_password_form(const PasswordForm& form) {
    password_form_ = form;
  }

  void set_password_manager(PasswordManager* password_manager) {
    password_manager_ = password_manager;
  }

  // views::DialogDelegate methods:
  virtual std::wstring GetDialogButtonLabel(DialogButton button) const {
    if (button == DIALOGBUTTON_OK)
      return l10n_util::GetString(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL);
    return DialogDelegate::GetDialogButtonLabel(button);
  }
  virtual std::wstring GetWindowTitle() const {
    return l10n_util::GetString(IDS_LOGIN_DIALOG_TITLE);
  }
  virtual void WindowClosing() {
    DCHECK(MessageLoop::current() == ui_loop_);

    // Reference is no longer valid.
    dialog_ = NULL;

    if (!WasAuthHandled(true)) {
      request_loop_->PostTask(FROM_HERE, NewRunnableMethod(
          this, &LoginHandlerImpl::CancelAuthDeferred));
      SendNotifications();
    }
  }
  virtual void DeleteDelegate() {
    // Delete this object once all InvokeLaters have been called.
    request_loop_->ReleaseSoon(FROM_HERE, this);
  }
  virtual bool Cancel() {
    DCHECK(MessageLoop::current() == ui_loop_);
    DCHECK(dialog_) << "LoginHandler invoked without being attached";
    CancelAuth();
    return true;
  }
  virtual bool Accept() {
    DCHECK(MessageLoop::current() == ui_loop_);
    DCHECK(dialog_) << "LoginHandler invoked without being attached";
    SetAuth(login_view_->GetUsername(), login_view_->GetPassword());
    return true;
  }
  virtual views::View* GetContentsView() {
    return login_view_;
  }

  // LoginHandler:
  virtual void SetAuth(const std::wstring& username,
                       const std::wstring& password) {
    if (WasAuthHandled(true))
      return;

    // Tell the password manager the credentials were submitted / accepted.
    if (password_manager_) {
      password_form_.username_value = username;
      password_form_.password_value = password;
      password_manager_->ProvisionallySavePassword(password_form_);
    }

    ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &LoginHandlerImpl::CloseContentsDeferred));
    ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &LoginHandlerImpl::SendNotifications));
    request_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &LoginHandlerImpl::SetAuthDeferred, username, password));
  }

  virtual void CancelAuth() {
    if (WasAuthHandled(true))
      return;

    ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &LoginHandlerImpl::CloseContentsDeferred));
    ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &LoginHandlerImpl::SendNotifications));
    request_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &LoginHandlerImpl::CancelAuthDeferred));
  }

  virtual void OnRequestCancelled() {
    DCHECK(MessageLoop::current() == request_loop_) <<
        "Why is OnRequestCancelled called from the UI thread?";

    // Reference is no longer valid.
    request_ = NULL;

    // Give up on auth if the request was cancelled.
    CancelAuth();
  }

 private:

  // Calls SetAuth from the request_loop.
  void SetAuthDeferred(const std::wstring& username,
                       const std::wstring& password) {
    DCHECK(MessageLoop::current() == request_loop_);

    if (request_) {
      request_->SetAuth(username, password);
      ResetLoginHandlerForRequest(request_);
    }
  }

  // Calls CancelAuth from the request_loop.
  void CancelAuthDeferred() {
    DCHECK(MessageLoop::current() == request_loop_);

    if (request_) {
      request_->CancelAuth();
      // Verify that CancelAuth does destroy the request via our delegate.
      DCHECK(request_ != NULL);
      ResetLoginHandlerForRequest(request_);
    }
  }

  // Closes the view_contents from the UI loop.
  void CloseContentsDeferred() {
    DCHECK(MessageLoop::current() == ui_loop_);

    // The hosting ConstrainedWindow may have been freed.
    if (dialog_)
      dialog_->CloseConstrainedWindow();
  }

  // Returns whether authentication had been handled (SetAuth or CancelAuth).
  // If |set_handled| is true, it will mark authentication as handled.
  bool WasAuthHandled(bool set_handled) {
    AutoLock lock(handled_auth_lock_);
    bool was_handled = handled_auth_;
    if (set_handled)
      handled_auth_ = true;
    return was_handled;
  }

  // Notify observers that authentication is needed or received.  The automation
  // proxy uses this for testing.
  void SendNotifications() {
    DCHECK(MessageLoop::current() == ui_loop_);

    NotificationService* service = NotificationService::current();
    WebContents* requesting_contents = GetWebContentsForLogin();
    if (!requesting_contents)
      return;

    NavigationController* controller = requesting_contents->controller();

    if (!WasAuthHandled(false)) {
      LoginNotificationDetails details(this);
      service->Notify(NotificationType::AUTH_NEEDED,
                      Source<NavigationController>(controller),
                      Details<LoginNotificationDetails>(&details));
    } else {
      service->Notify(NotificationType::AUTH_SUPPLIED,
                      Source<NavigationController>(controller),
                      NotificationService::NoDetails());
    }
  }

  // True if we've handled auth (SetAuth or CancelAuth has been called).
  bool handled_auth_;
  Lock handled_auth_lock_;

  // The ConstrainedWindow that is hosting our LoginView.
  // This should only be accessed on the ui_loop_.
  ConstrainedWindow* dialog_;

  // The MessageLoop of the thread that the ChromeViewContents lives in.
  MessageLoop* ui_loop_;

  // The request that wants login data.
  // This should only be accessed on the request_loop_.
  URLRequest* request_;

  // The MessageLoop of the thread that the URLRequest lives in.
  MessageLoop* request_loop_;

  // The LoginView that contains the user's login information
  LoginView* login_view_;

  // The PasswordForm sent to the PasswordManager. This is so we can refer to it
  // when later notifying the password manager if the credentials were accepted
  // or rejected.
  // This should only be accessed on the ui_loop_.
  PasswordForm password_form_;

  // Points to the password manager owned by the TabContents requesting auth.
  // Can be null if the TabContents is not a WebContents.
  // This should only be accessed on the ui_loop_.
  PasswordManager* password_manager_;

  // Cached from the URLRequest, in case it goes NULL on us.
  int render_process_host_id_;
  int tab_contents_id_;

  DISALLOW_EVIL_CONSTRUCTORS(LoginHandlerImpl);
};

// ----------------------------------------------------------------------------
// LoginDialogTask

// This task is run on the UI thread and creates a constrained window with
// a LoginView to prompt the user.  The response will be sent to LoginHandler,
// which then routes it to the URLRequest on the I/O thread.
class LoginDialogTask : public Task {
 public:
  LoginDialogTask(net::AuthChallengeInfo* auth_info, LoginHandlerImpl* handler)
      : auth_info_(auth_info), handler_(handler) {
  }
  virtual ~LoginDialogTask() {
  }

  void Run() {
    WebContents* parent_contents = handler_->GetWebContentsForLogin();
    if (!parent_contents) {
      // The request was probably cancelled.
      return;
    }

    wstring explanation = auth_info_->realm.empty() ?
        l10n_util::GetStringF(IDS_LOGIN_DIALOG_DESCRIPTION_NO_REALM,
                              auth_info_->host) :
        l10n_util::GetStringF(IDS_LOGIN_DIALOG_DESCRIPTION,
                              auth_info_->host,
                              auth_info_->realm);
    LoginView* view = new LoginView(explanation);
    // Tell the password manager to look for saved passwords. There is only
    // a password manager when dealing with a WebContents type.
    if (parent_contents->type() == TAB_CONTENTS_WEB) {
      PasswordManager* password_manager =
          parent_contents->AsWebContents()->GetPasswordManager();
      // Set the model for the login view. The model (password manager) is owned
      // by the view's parent TabContents, so natural destruction order means we
      // don't have to worry about calling SetModel(NULL), because the view will
      // be deleted before the password manager.
      view->SetModel(password_manager);
      std::vector<PasswordForm> v;
      MakeInputForPasswordManager(parent_contents->GetURL(), &v);
      password_manager->PasswordFormsSeen(v);
      handler_->set_password_manager(password_manager);
    }

    handler_->set_login_view(view);
    ConstrainedWindow* dialog =
        parent_contents->CreateConstrainedDialog(handler_, view);
    handler_->InitWithDialog(dialog);
  }

 private:
  // Helper to create a PasswordForm and stuff it into a vector as input
  // for PasswordManager::PasswordFormsSeen, the hook into PasswordManager.
  void MakeInputForPasswordManager(
      const GURL& origin_url,
      std::vector<PasswordForm>* password_manager_input) {
    PasswordForm dialog_form;
    if (LowerCaseEqualsASCII(auth_info_->scheme, "basic")) {
      dialog_form.scheme = PasswordForm::SCHEME_BASIC;
    } else if (LowerCaseEqualsASCII(auth_info_->scheme, "digest")) {
      dialog_form.scheme = PasswordForm::SCHEME_DIGEST;
    } else {
      dialog_form.scheme = PasswordForm::SCHEME_OTHER;
    }
    dialog_form.origin = origin_url;
    dialog_form.signon_realm = GetSignonRealm(dialog_form.origin, *auth_info_);
    password_manager_input->push_back(dialog_form);
    // Set the password form for the handler (by copy).
    handler_->set_password_form(dialog_form);
  }

  // Info about who/where/what is asking for authentication.
  scoped_refptr<net::AuthChallengeInfo> auth_info_;

  // Where to send the authentication when obtained.
  // This is owned by the ResourceDispatcherHost that invoked us.
  LoginHandlerImpl* handler_;

  DISALLOW_EVIL_CONSTRUCTORS(LoginDialogTask);
};

// ----------------------------------------------------------------------------
// Public API

LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info,
                                URLRequest* request,
                                MessageLoop* ui_loop) {
  LoginHandlerImpl* handler = new LoginHandlerImpl(request, ui_loop);
  ui_loop->PostTask(FROM_HERE, new LoginDialogTask(auth_info, handler));
  return handler;
}
<commit_msg>bustage fix - moved file<commit_after>// Copyright (c) 2006-2008 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/browser/login_prompt.h"

#include "base/command_line.h"
#include "base/lock.h"
#include "base/message_loop.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/password_manager/password_manager.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/tab_contents/constrained_window.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/browser/views/login_view.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/l10n_util.h"
#include "chrome/common/notification_service.h"
#include "chrome/views/window/dialog_delegate.h"
#include "grit/generated_resources.h"
#include "net/base/auth.h"
#include "net/url_request/url_request.h"

using namespace std;
using views::LoginView;

class LoginHandlerImpl;

// Helper to remove the ref from an URLRequest to the LoginHandler.
// Should only be called from the IO thread, since it accesses an URLRequest.
static void ResetLoginHandlerForRequest(URLRequest* request) {
  ResourceDispatcherHost::ExtraRequestInfo* info =
      ResourceDispatcherHost::ExtraInfoForRequest(request);
  if (!info)
    return;

  info->login_handler = NULL;
}

// Get the signon_realm under which this auth info should be stored.
//
// The format of the signon_realm for proxy auth is:
//     proxy-host/auth-realm
// The format of the signon_realm for server auth is:
//     url-scheme://url-host[:url-port]/auth-realm
//
// Be careful when changing this function, since you could make existing
// saved logins un-retrievable.

std::string GetSignonRealm(const GURL& url,
                           const net::AuthChallengeInfo& auth_info) {
  std::string signon_realm;
  if (auth_info.is_proxy) {
    signon_realm = WideToASCII(auth_info.host);
    signon_realm.append("/");
  } else {
    // Take scheme, host, and port from the url.
    signon_realm = url.GetOrigin().spec();
    // This ends with a "/".
  }
  signon_realm.append(WideToUTF8(auth_info.realm));
  return signon_realm;
}

// ----------------------------------------------------------------------------
// LoginHandlerImpl

// This class simply forwards the authentication from the LoginView (on
// the UI thread) to the URLRequest (on the I/O thread).
// This class uses ref counting to ensure that it lives until all InvokeLaters
// have been called.
class LoginHandlerImpl : public LoginHandler,
                         public base::RefCountedThreadSafe<LoginHandlerImpl>,
                         public views::DialogDelegate {
 public:
  LoginHandlerImpl(URLRequest* request, MessageLoop* ui_loop)
      : dialog_(NULL),
        handled_auth_(false),
        request_(request),
        request_loop_(MessageLoop::current()),
        ui_loop_(ui_loop),
        password_manager_(NULL) {
    DCHECK(request_) << "LoginHandler constructed with NULL request";

    AddRef();  // matched by ReleaseLater.
    if (!tab_util::GetTabContentsID(request_, &render_process_host_id_,
                                    &tab_contents_id_)) {
      NOTREACHED();
    }
  }

  ~LoginHandlerImpl() {
  }

  // Initialize the UI part of the LoginHandler.
  // Scary thread safety note: This can potentially be called *after* SetAuth
  // or CancelAuth (say, if the request was cancelled before the UI thread got
  // control).  However, that's OK since any UI interaction in those functions
  // will occur via an InvokeLater on the UI thread, which is guaranteed
  // to happen after this is called (since this was InvokeLater'd first).
  void InitWithDialog(ConstrainedWindow* dlg) {
    DCHECK(MessageLoop::current() == ui_loop_);
    dialog_ = dlg;
    SendNotifications();
  }

  // Returns the WebContents that needs authentication.
  WebContents* GetWebContentsForLogin() {
    DCHECK(MessageLoop::current() == ui_loop_);

    return tab_util::GetWebContentsByID(render_process_host_id_,
                                        tab_contents_id_);
  }

  void set_login_view(LoginView* login_view) {
    login_view_ = login_view;
  }

  void set_password_form(const PasswordForm& form) {
    password_form_ = form;
  }

  void set_password_manager(PasswordManager* password_manager) {
    password_manager_ = password_manager;
  }

  // views::DialogDelegate methods:
  virtual std::wstring GetDialogButtonLabel(DialogButton button) const {
    if (button == DIALOGBUTTON_OK)
      return l10n_util::GetString(IDS_LOGIN_DIALOG_OK_BUTTON_LABEL);
    return DialogDelegate::GetDialogButtonLabel(button);
  }
  virtual std::wstring GetWindowTitle() const {
    return l10n_util::GetString(IDS_LOGIN_DIALOG_TITLE);
  }
  virtual void WindowClosing() {
    DCHECK(MessageLoop::current() == ui_loop_);

    // Reference is no longer valid.
    dialog_ = NULL;

    if (!WasAuthHandled(true)) {
      request_loop_->PostTask(FROM_HERE, NewRunnableMethod(
          this, &LoginHandlerImpl::CancelAuthDeferred));
      SendNotifications();
    }
  }
  virtual void DeleteDelegate() {
    // Delete this object once all InvokeLaters have been called.
    request_loop_->ReleaseSoon(FROM_HERE, this);
  }
  virtual bool Cancel() {
    DCHECK(MessageLoop::current() == ui_loop_);
    DCHECK(dialog_) << "LoginHandler invoked without being attached";
    CancelAuth();
    return true;
  }
  virtual bool Accept() {
    DCHECK(MessageLoop::current() == ui_loop_);
    DCHECK(dialog_) << "LoginHandler invoked without being attached";
    SetAuth(login_view_->GetUsername(), login_view_->GetPassword());
    return true;
  }
  virtual views::View* GetContentsView() {
    return login_view_;
  }

  // LoginHandler:
  virtual void SetAuth(const std::wstring& username,
                       const std::wstring& password) {
    if (WasAuthHandled(true))
      return;

    // Tell the password manager the credentials were submitted / accepted.
    if (password_manager_) {
      password_form_.username_value = username;
      password_form_.password_value = password;
      password_manager_->ProvisionallySavePassword(password_form_);
    }

    ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &LoginHandlerImpl::CloseContentsDeferred));
    ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &LoginHandlerImpl::SendNotifications));
    request_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &LoginHandlerImpl::SetAuthDeferred, username, password));
  }

  virtual void CancelAuth() {
    if (WasAuthHandled(true))
      return;

    ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &LoginHandlerImpl::CloseContentsDeferred));
    ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &LoginHandlerImpl::SendNotifications));
    request_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        this, &LoginHandlerImpl::CancelAuthDeferred));
  }

  virtual void OnRequestCancelled() {
    DCHECK(MessageLoop::current() == request_loop_) <<
        "Why is OnRequestCancelled called from the UI thread?";

    // Reference is no longer valid.
    request_ = NULL;

    // Give up on auth if the request was cancelled.
    CancelAuth();
  }

 private:

  // Calls SetAuth from the request_loop.
  void SetAuthDeferred(const std::wstring& username,
                       const std::wstring& password) {
    DCHECK(MessageLoop::current() == request_loop_);

    if (request_) {
      request_->SetAuth(username, password);
      ResetLoginHandlerForRequest(request_);
    }
  }

  // Calls CancelAuth from the request_loop.
  void CancelAuthDeferred() {
    DCHECK(MessageLoop::current() == request_loop_);

    if (request_) {
      request_->CancelAuth();
      // Verify that CancelAuth does destroy the request via our delegate.
      DCHECK(request_ != NULL);
      ResetLoginHandlerForRequest(request_);
    }
  }

  // Closes the view_contents from the UI loop.
  void CloseContentsDeferred() {
    DCHECK(MessageLoop::current() == ui_loop_);

    // The hosting ConstrainedWindow may have been freed.
    if (dialog_)
      dialog_->CloseConstrainedWindow();
  }

  // Returns whether authentication had been handled (SetAuth or CancelAuth).
  // If |set_handled| is true, it will mark authentication as handled.
  bool WasAuthHandled(bool set_handled) {
    AutoLock lock(handled_auth_lock_);
    bool was_handled = handled_auth_;
    if (set_handled)
      handled_auth_ = true;
    return was_handled;
  }

  // Notify observers that authentication is needed or received.  The automation
  // proxy uses this for testing.
  void SendNotifications() {
    DCHECK(MessageLoop::current() == ui_loop_);

    NotificationService* service = NotificationService::current();
    WebContents* requesting_contents = GetWebContentsForLogin();
    if (!requesting_contents)
      return;

    NavigationController* controller = requesting_contents->controller();

    if (!WasAuthHandled(false)) {
      LoginNotificationDetails details(this);
      service->Notify(NotificationType::AUTH_NEEDED,
                      Source<NavigationController>(controller),
                      Details<LoginNotificationDetails>(&details));
    } else {
      service->Notify(NotificationType::AUTH_SUPPLIED,
                      Source<NavigationController>(controller),
                      NotificationService::NoDetails());
    }
  }

  // True if we've handled auth (SetAuth or CancelAuth has been called).
  bool handled_auth_;
  Lock handled_auth_lock_;

  // The ConstrainedWindow that is hosting our LoginView.
  // This should only be accessed on the ui_loop_.
  ConstrainedWindow* dialog_;

  // The MessageLoop of the thread that the ChromeViewContents lives in.
  MessageLoop* ui_loop_;

  // The request that wants login data.
  // This should only be accessed on the request_loop_.
  URLRequest* request_;

  // The MessageLoop of the thread that the URLRequest lives in.
  MessageLoop* request_loop_;

  // The LoginView that contains the user's login information
  LoginView* login_view_;

  // The PasswordForm sent to the PasswordManager. This is so we can refer to it
  // when later notifying the password manager if the credentials were accepted
  // or rejected.
  // This should only be accessed on the ui_loop_.
  PasswordForm password_form_;

  // Points to the password manager owned by the TabContents requesting auth.
  // Can be null if the TabContents is not a WebContents.
  // This should only be accessed on the ui_loop_.
  PasswordManager* password_manager_;

  // Cached from the URLRequest, in case it goes NULL on us.
  int render_process_host_id_;
  int tab_contents_id_;

  DISALLOW_EVIL_CONSTRUCTORS(LoginHandlerImpl);
};

// ----------------------------------------------------------------------------
// LoginDialogTask

// This task is run on the UI thread and creates a constrained window with
// a LoginView to prompt the user.  The response will be sent to LoginHandler,
// which then routes it to the URLRequest on the I/O thread.
class LoginDialogTask : public Task {
 public:
  LoginDialogTask(net::AuthChallengeInfo* auth_info, LoginHandlerImpl* handler)
      : auth_info_(auth_info), handler_(handler) {
  }
  virtual ~LoginDialogTask() {
  }

  void Run() {
    WebContents* parent_contents = handler_->GetWebContentsForLogin();
    if (!parent_contents) {
      // The request was probably cancelled.
      return;
    }

    wstring explanation = auth_info_->realm.empty() ?
        l10n_util::GetStringF(IDS_LOGIN_DIALOG_DESCRIPTION_NO_REALM,
                              auth_info_->host) :
        l10n_util::GetStringF(IDS_LOGIN_DIALOG_DESCRIPTION,
                              auth_info_->host,
                              auth_info_->realm);
    LoginView* view = new LoginView(explanation);
    // Tell the password manager to look for saved passwords. There is only
    // a password manager when dealing with a WebContents type.
    if (parent_contents->type() == TAB_CONTENTS_WEB) {
      PasswordManager* password_manager =
          parent_contents->AsWebContents()->GetPasswordManager();
      // Set the model for the login view. The model (password manager) is owned
      // by the view's parent TabContents, so natural destruction order means we
      // don't have to worry about calling SetModel(NULL), because the view will
      // be deleted before the password manager.
      view->SetModel(password_manager);
      std::vector<PasswordForm> v;
      MakeInputForPasswordManager(parent_contents->GetURL(), &v);
      password_manager->PasswordFormsSeen(v);
      handler_->set_password_manager(password_manager);
    }

    handler_->set_login_view(view);
    ConstrainedWindow* dialog =
        parent_contents->CreateConstrainedDialog(handler_, view);
    handler_->InitWithDialog(dialog);
  }

 private:
  // Helper to create a PasswordForm and stuff it into a vector as input
  // for PasswordManager::PasswordFormsSeen, the hook into PasswordManager.
  void MakeInputForPasswordManager(
      const GURL& origin_url,
      std::vector<PasswordForm>* password_manager_input) {
    PasswordForm dialog_form;
    if (LowerCaseEqualsASCII(auth_info_->scheme, "basic")) {
      dialog_form.scheme = PasswordForm::SCHEME_BASIC;
    } else if (LowerCaseEqualsASCII(auth_info_->scheme, "digest")) {
      dialog_form.scheme = PasswordForm::SCHEME_DIGEST;
    } else {
      dialog_form.scheme = PasswordForm::SCHEME_OTHER;
    }
    dialog_form.origin = origin_url;
    dialog_form.signon_realm = GetSignonRealm(dialog_form.origin, *auth_info_);
    password_manager_input->push_back(dialog_form);
    // Set the password form for the handler (by copy).
    handler_->set_password_form(dialog_form);
  }

  // Info about who/where/what is asking for authentication.
  scoped_refptr<net::AuthChallengeInfo> auth_info_;

  // Where to send the authentication when obtained.
  // This is owned by the ResourceDispatcherHost that invoked us.
  LoginHandlerImpl* handler_;

  DISALLOW_EVIL_CONSTRUCTORS(LoginDialogTask);
};

// ----------------------------------------------------------------------------
// Public API

LoginHandler* CreateLoginPrompt(net::AuthChallengeInfo* auth_info,
                                URLRequest* request,
                                MessageLoop* ui_loop) {
  LoginHandlerImpl* handler = new LoginHandlerImpl(request, ui_loop);
  ui_loop->PostTask(FROM_HERE, new LoginDialogTask(auth_info, handler));
  return handler;
}
<|endoftext|>


<commit_before>#include "pprint/c_pprint.hpp"

#include <ostream>
#include <string>
#include <vector>
#include <stdexcept>

namespace bfc {
namespace pprint {

c_pprint::c_pprint(void) = default;

/* Halp I feel so dirty halp. */
c_pprint::config::config(void) :
  prelude{
    "#include <stdio.h>",
    "static unsigned char mem[30000];",
    "static unsigned char *bfc_hp = mem + 10000;",
    "#define bfc_add(off, val) (bfc_hp[(off)] += (val))",
    "#define bfc_sub(off, val) (bfc_hp[(off)] -= (val))",
    "#define bfc_mov(off) (bfc_hp += (off))",
    "#define bfc_mul(off, val) \
      do { \
        bfc_hp[(off)] += *bfc_hp * (val); \
        *bfc_hp = 0; \
      } while(0)",
    "#define bfc_getc(off) \
      do { \
        int _bfc_ch = getchar(); \
        if (_bfc_ch != EOF) \
          bfc_hp[(off)] = _bfc_ch; \
      } while (0)",
    "#define bfc_putc(off) putchar(bfc_hp[(off)])",
    "int main(void) {"
  },
  postlude {
    "  return 0;",
    "}"
  },
  label_prefix{"bfc_l"},
  hp_iden{"bfc_hp"},
  getc_iden{"bfc_getc"},
  putc_iden{"bfc_putc"},
  add_iden{"bfc_add"},
  sub_iden{"bfc_sub"},
  mul_iden{"bfc_mul"},
  mov_iden{"bfc_mov"}
  /*set_iden{"bfc_set"}*/
{}

namespace {

class pp_delegate : public ast::visitor {

  using label_id = unsigned long;

public:

  pp_delegate(std::ostream &out, const c_pprint::config &opts) :
    ast::visitor{}, next_label_id{0}, opts{opts}, sink{out}
  {}

  void emit(const ast::node &node)
  {
    node.accept(*this);
  }

  ast::visitor::status visit(const ast::program &prgm) override
  {
    pp_prelude();
    for (auto &node: prgm)
      node.accept(*this);
    pp_postlude();
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::loop &loop) override
  {
    auto begin_id = get_label();
    auto end_id = get_label();
    pp_label(begin_id);
    pp_bez(end_id);
    for (auto &node: loop)
      node.accept(*this);
    pp_bnz(begin_id);
    pp_label(end_id);
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::add &node) override
  {
    pp_add(node.offset(), node.value());
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::sub &node) override
  {
    pp_sub(node.offset(), node.value());
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::mul &node) override
  {
    pp_mul(node.offset(), node.value());
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::mov &node) override
  {
    pp_mov(node.offset());
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::read &node) override
  {
    pp_getc(node.offset());
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::write &node) override
  {
    pp_putc(node.offset());
    return ast::visitor::CONTINUE;
  }

private:

  label_id get_label(void) noexcept
  {
    auto id = next_label_id;
    next_label_id += 1;
    return id;
  }

  void pp_indent(void) const
  {
    sink << ' ' << ' ';
  }

  void pp_indent(unsigned long nlevels) const
  {
    while (nlevels--)
      pp_indent();
  }

  template <class InputIt>
  void pp_iter(InputIt begin, InputIt end) const
  {
    for (; begin != end; ++begin)
      sink << *begin << std::endl;
  }

  void pp_label_name(unsigned long id)
  {
    sink << opts.label_prefix << id;
  }

  void pp_label(unsigned long id)
  {
    pp_label_name(id);
    sink << ':' << std::endl;
  }

  void pp_jump(unsigned long id)
  {
    pp_indent();
    sink << "goto ";
    pp_label_name(id);
    sink << ';' << std::endl;
  }

  void pp_bez(label_id id)
  {
    pp_branch(id, true);
  }

  void pp_bnz(label_id id)
  {
    pp_branch(id, false);
  }

  void pp_branch(label_id id, bool invert)
  {
    pp_indent();
    sink << "if (";
    if (invert)
      sink << '!';
    sink << "*" << opts.hp_iden;
    sink << ')' << std::endl;
    pp_indent(2);
    pp_jump(id);
  }

  void pp_fn(const char *fn)
  {
    pp_indent();
    sink << fn << "();" << std::endl;
  }

  template <class Arg>
  void pp_fn(const char *fn, Arg &&arg)
  {
    pp_indent();
    sink << fn << '(' << arg << ");" << std::endl;
  }

  template <class Arg, class ...Args>
  void pp_fn(const char *fn, Arg &&arg, Args &&...args)
  {
    pp_indent();
    sink << fn << '(' << std::forward<Arg>(arg);
    pp_fn_recur(std::forward<Args>(args)...);
    sink << ");" << std::endl;
  }

  template <class Arg>
  void pp_fn_recur(Arg &&arg)
  {
    sink << ", " << std::forward<Arg>(arg);
  }

  template <class Arg, class ...Args>
  void pp_fn_recur(Arg &&arg, Args &&...args)
  {
    sink << ", " << std::forward<Arg>(arg);
    pp_fn_recur(std::forward<Args>(args)...);
  }

  void pp_prelude(void) const
  {
    auto &vec = opts.prelude;
    pp_iter(vec.begin(), vec.end());
  }

  void pp_postlude(void) const
  {
    auto &vec = opts.postlude;
    pp_iter(vec.begin(), vec.end());
  }

  void pp_add(ptrdiff_t offset, int value)
  {
    pp_indent();
    pp_fn(opts.add_iden.data(), offset, value);
  }

  void pp_sub(ptrdiff_t offset, int value)
  {
    pp_indent();
    pp_fn(opts.sub_iden.data(), offset, value);
  }

  void pp_mul(ptrdiff_t offset, int value)
  {
    pp_indent();
    pp_fn(opts.mul_iden.data(), offset, value);
  }

  void pp_getc(ptrdiff_t offset)
  {
    pp_indent();
    pp_fn(opts.getc_iden.data(), offset);
  }

  void pp_putc(ptrdiff_t offset)
  {
    pp_indent();
    pp_fn(opts.putc_iden.data(), offset);
  }

  void pp_mov(ptrdiff_t offset)
  {
    pp_indent();
    pp_fn(opts.mov_iden.data(), offset);
  }

  label_id next_label_id;
  const c_pprint::config &opts;
  std::ostream &sink;

};
}

void
c_pprint::emit(std::ostream &out, const ast::node &node)
{
  auto pp = pp_delegate{out, opts};
  pp.emit(node);
}

}
}
<commit_msg>squelch order warning<commit_after>#include "pprint/c_pprint.hpp"

#include <ostream>
#include <string>
#include <vector>
#include <stdexcept>

namespace bfc {
namespace pprint {

c_pprint::c_pprint(void) = default;

/* Halp I feel so dirty halp. */
c_pprint::config::config(void) :
  prelude{
    "#include <stdio.h>",
    "static unsigned char mem[30000];",
    "static unsigned char *bfc_hp = mem + 10000;",
    "#define bfc_add(off, val) (bfc_hp[(off)] += (val))",
    "#define bfc_sub(off, val) (bfc_hp[(off)] -= (val))",
    "#define bfc_mov(off) (bfc_hp += (off))",
    "#define bfc_mul(off, val) \
      do { \
        bfc_hp[(off)] += *bfc_hp * (val); \
        *bfc_hp = 0; \
      } while(0)",
    "#define bfc_getc(off) \
      do { \
        int _bfc_ch = getchar(); \
        if (_bfc_ch != EOF) \
          bfc_hp[(off)] = _bfc_ch; \
      } while (0)",
    "#define bfc_putc(off) putchar(bfc_hp[(off)])",
    "int main(void) {"
  },
  postlude {
    "  return 0;",
    "}"
  },
  label_prefix{"bfc_l"},
  hp_iden{"bfc_hp"},
  mov_iden{"bfc_mov"},
  getc_iden{"bfc_getc"},
  putc_iden{"bfc_putc"},
  add_iden{"bfc_add"},
  sub_iden{"bfc_sub"},
  mul_iden{"bfc_mul"}
  /*set_iden{"bfc_set"}*/
{}

namespace {

class pp_delegate : public ast::visitor {

  using label_id = unsigned long;

public:

  pp_delegate(std::ostream &out, const c_pprint::config &opts) :
    ast::visitor{}, next_label_id{0}, opts{opts}, sink{out}
  {}

  void emit(const ast::node &node)
  {
    node.accept(*this);
  }

  ast::visitor::status visit(const ast::program &prgm) override
  {
    pp_prelude();
    for (auto &node: prgm)
      node.accept(*this);
    pp_postlude();
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::loop &loop) override
  {
    auto begin_id = get_label();
    auto end_id = get_label();
    pp_label(begin_id);
    pp_bez(end_id);
    for (auto &node: loop)
      node.accept(*this);
    pp_bnz(begin_id);
    pp_label(end_id);
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::add &node) override
  {
    pp_add(node.offset(), node.value());
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::sub &node) override
  {
    pp_sub(node.offset(), node.value());
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::mul &node) override
  {
    pp_mul(node.offset(), node.value());
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::mov &node) override
  {
    pp_mov(node.offset());
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::read &node) override
  {
    pp_getc(node.offset());
    return ast::visitor::CONTINUE;
  }

  ast::visitor::status visit(const ast::write &node) override
  {
    pp_putc(node.offset());
    return ast::visitor::CONTINUE;
  }

private:

  label_id get_label(void) noexcept
  {
    auto id = next_label_id;
    next_label_id += 1;
    return id;
  }

  void pp_indent(void) const
  {
    sink << ' ' << ' ';
  }

  void pp_indent(unsigned long nlevels) const
  {
    while (nlevels--)
      pp_indent();
  }

  template <class InputIt>
  void pp_iter(InputIt begin, InputIt end) const
  {
    for (; begin != end; ++begin)
      sink << *begin << std::endl;
  }

  void pp_label_name(unsigned long id)
  {
    sink << opts.label_prefix << id;
  }

  void pp_label(unsigned long id)
  {
    pp_label_name(id);
    sink << ':' << std::endl;
  }

  void pp_jump(unsigned long id)
  {
    pp_indent();
    sink << "goto ";
    pp_label_name(id);
    sink << ';' << std::endl;
  }

  void pp_bez(label_id id)
  {
    pp_branch(id, true);
  }

  void pp_bnz(label_id id)
  {
    pp_branch(id, false);
  }

  void pp_branch(label_id id, bool invert)
  {
    pp_indent();
    sink << "if (";
    if (invert)
      sink << '!';
    sink << "*" << opts.hp_iden;
    sink << ')' << std::endl;
    pp_indent(2);
    pp_jump(id);
  }

  void pp_fn(const char *fn)
  {
    pp_indent();
    sink << fn << "();" << std::endl;
  }

  template <class Arg>
  void pp_fn(const char *fn, Arg &&arg)
  {
    pp_indent();
    sink << fn << '(' << arg << ");" << std::endl;
  }

  template <class Arg, class ...Args>
  void pp_fn(const char *fn, Arg &&arg, Args &&...args)
  {
    pp_indent();
    sink << fn << '(' << std::forward<Arg>(arg);
    pp_fn_recur(std::forward<Args>(args)...);
    sink << ");" << std::endl;
  }

  template <class Arg>
  void pp_fn_recur(Arg &&arg)
  {
    sink << ", " << std::forward<Arg>(arg);
  }

  template <class Arg, class ...Args>
  void pp_fn_recur(Arg &&arg, Args &&...args)
  {
    sink << ", " << std::forward<Arg>(arg);
    pp_fn_recur(std::forward<Args>(args)...);
  }

  void pp_prelude(void) const
  {
    auto &vec = opts.prelude;
    pp_iter(vec.begin(), vec.end());
  }

  void pp_postlude(void) const
  {
    auto &vec = opts.postlude;
    pp_iter(vec.begin(), vec.end());
  }

  void pp_add(ptrdiff_t offset, int value)
  {
    pp_indent();
    pp_fn(opts.add_iden.data(), offset, value);
  }

  void pp_sub(ptrdiff_t offset, int value)
  {
    pp_indent();
    pp_fn(opts.sub_iden.data(), offset, value);
  }

  void pp_mul(ptrdiff_t offset, int value)
  {
    pp_indent();
    pp_fn(opts.mul_iden.data(), offset, value);
  }

  void pp_getc(ptrdiff_t offset)
  {
    pp_indent();
    pp_fn(opts.getc_iden.data(), offset);
  }

  void pp_putc(ptrdiff_t offset)
  {
    pp_indent();
    pp_fn(opts.putc_iden.data(), offset);
  }

  void pp_mov(ptrdiff_t offset)
  {
    pp_indent();
    pp_fn(opts.mov_iden.data(), offset);
  }

  label_id next_label_id;
  const c_pprint::config &opts;
  std::ostream &sink;

};
}

void
c_pprint::emit(std::ostream &out, const ast::node &node)
{
  auto pp = pp_delegate{out, opts};
  pp.emit(node);
}

}
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 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/file_util.h"
#include "base/path_service.h"
#include "build/build_config.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"
#include "net/test/test_server.h"
#include "webkit/glue/plugins/plugin_switches.h"

namespace {

// Platform-specific filename relative to the chrome executable.
#if defined(OS_WIN)
const wchar_t library_name[] = L"ppapi_tests.dll";
#elif defined(OS_MACOSX)
const char library_name[] = "ppapi_tests.plugin";
#elif defined(OS_POSIX)
const char library_name[] = "libppapi_tests.so";
#endif

}  // namespace

class PPAPITest : public UITest {
 public:
  PPAPITest() {
    // Append the switch to register the pepper plugin.
    // library name = <out dir>/<test_name>.<library_extension>
    // MIME type = application/x-ppapi-<test_name>
    FilePath plugin_dir;
    PathService::Get(base::DIR_EXE, &plugin_dir);

    FilePath plugin_lib = plugin_dir.Append(library_name);
    EXPECT_TRUE(file_util::PathExists(plugin_lib));
    FilePath::StringType pepper_plugin = plugin_lib.value();
    pepper_plugin.append(FILE_PATH_LITERAL(";application/x-ppapi-tests"));
    launch_arguments_.AppendSwitchNative(switches::kRegisterPepperPlugins,
                                         pepper_plugin);

    // The test sends us the result via a cookie.
    launch_arguments_.AppendSwitch(switches::kEnableFileCookies);

    // Some stuff is hung off of the testing interface which is not enabled
    // by default.
    launch_arguments_.AppendSwitch(switches::kEnablePepperTesting);

    // Give unlimited quota for files to Pepper tests.
    // TODO(dumi): remove this switch once we have a quota management
    // system in place.
    launch_arguments_.AppendSwitch(switches::kUnlimitedQuotaForFiles);
  }

  void RunTest(const std::string& test_case) {
    FilePath test_path;
    PathService::Get(base::DIR_SOURCE_ROOT, &test_path);
    test_path = test_path.Append(FILE_PATH_LITERAL("ppapi"));
    test_path = test_path.Append(FILE_PATH_LITERAL("tests"));
    test_path = test_path.Append(FILE_PATH_LITERAL("test_case.html"));

    // Sanity check the file name.
    EXPECT_TRUE(file_util::PathExists(test_path));

    GURL::Replacements replacements;
    replacements.SetQuery(test_case.c_str(),
                          url_parse::Component(0, test_case.size()));
    GURL test_url = net::FilePathToFileURL(test_path);
    RunTestURL(test_url.ReplaceComponents(replacements));
  }

  void RunTestViaHTTP(const std::string& test_case) {
    net::TestServer test_server(
        net::TestServer::TYPE_HTTP,
        FilePath(FILE_PATH_LITERAL("ppapi/tests")));
    ASSERT_TRUE(test_server.Start());
    RunTestURL(test_server.GetURL("files/test_case.html?" + test_case));
  }

 private:
  void RunTestURL(const GURL& test_url) {
    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());
    ASSERT_TRUE(tab->NavigateToURL(test_url));
    std::string escaped_value =
        WaitUntilCookieNonEmpty(tab.get(), test_url,
            "COMPLETION_COOKIE", action_max_timeout_ms());
    EXPECT_STREQ("PASS", escaped_value.c_str());
  }
};

TEST_F(PPAPITest, FAILS_Instance) {
  RunTest("Instance");
}

TEST_F(PPAPITest, Graphics2D) {
  RunTest("Graphics2D");
}

// TODO(brettw) bug 51344: this is flaky on bots. Seems to timeout navigating.
// Possibly all the image allocations slow things down on a loaded bot too much.
TEST_F(PPAPITest, FLAKY_ImageData) {
  RunTest("ImageData");
}

TEST_F(PPAPITest, Buffer) {
  RunTest("Buffer");
}

// Flakey, http:L//crbug.com/57053
TEST_F(PPAPITest, FLAKY_URLLoader) {
  RunTestViaHTTP("URLLoader");
}

// Flaky, http://crbug.com/51012
TEST_F(PPAPITest, FLAKY_PaintAggregator) {
  RunTestViaHTTP("PaintAggregator");
}

// Flaky, http://crbug.com/48544.
TEST_F(PPAPITest, FLAKY_Scrollbar) {
  RunTest("Scrollbar");
}

TEST_F(PPAPITest, UrlUtil) {
  RunTest("UrlUtil");
}

TEST_F(PPAPITest, CharSet) {
  RunTest("CharSet");
}

TEST_F(PPAPITest, Var) {
  RunTest("Var");
}

// TODO(dumi): figure out why this test is flaky on Mac and Win XP (dbg).
#if defined(OS_MACOSX) || defined(OS_WIN)
#define DISABLED_ON_MAC_AND_WIN(test_name) DISABLED_##test_name
#else
#define DISABLED_ON_MAC_AND_WIN(test_name) test_name
#endif
TEST_F(PPAPITest, DISABLED_ON_MAC_AND_WIN(FileIO)) {
  RunTestViaHTTP("FileIO");
}

TEST_F(PPAPITest, FileRef) {
  RunTestViaHTTP("FileRef");
}

TEST_F(PPAPITest, DirectoryReader) {
  RunTestViaHTTP("DirectoryReader");
}
<commit_msg>Disable crashy PPAPITest.FileIO/FileRef.<commit_after>// Copyright (c) 2010 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/file_util.h"
#include "base/path_service.h"
#include "build/build_config.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/base/net_util.h"
#include "net/test/test_server.h"
#include "webkit/glue/plugins/plugin_switches.h"

namespace {

// Platform-specific filename relative to the chrome executable.
#if defined(OS_WIN)
const wchar_t library_name[] = L"ppapi_tests.dll";
#elif defined(OS_MACOSX)
const char library_name[] = "ppapi_tests.plugin";
#elif defined(OS_POSIX)
const char library_name[] = "libppapi_tests.so";
#endif

}  // namespace

class PPAPITest : public UITest {
 public:
  PPAPITest() {
    // Append the switch to register the pepper plugin.
    // library name = <out dir>/<test_name>.<library_extension>
    // MIME type = application/x-ppapi-<test_name>
    FilePath plugin_dir;
    PathService::Get(base::DIR_EXE, &plugin_dir);

    FilePath plugin_lib = plugin_dir.Append(library_name);
    EXPECT_TRUE(file_util::PathExists(plugin_lib));
    FilePath::StringType pepper_plugin = plugin_lib.value();
    pepper_plugin.append(FILE_PATH_LITERAL(";application/x-ppapi-tests"));
    launch_arguments_.AppendSwitchNative(switches::kRegisterPepperPlugins,
                                         pepper_plugin);

    // The test sends us the result via a cookie.
    launch_arguments_.AppendSwitch(switches::kEnableFileCookies);

    // Some stuff is hung off of the testing interface which is not enabled
    // by default.
    launch_arguments_.AppendSwitch(switches::kEnablePepperTesting);

    // Give unlimited quota for files to Pepper tests.
    // TODO(dumi): remove this switch once we have a quota management
    // system in place.
    launch_arguments_.AppendSwitch(switches::kUnlimitedQuotaForFiles);
  }

  void RunTest(const std::string& test_case) {
    FilePath test_path;
    PathService::Get(base::DIR_SOURCE_ROOT, &test_path);
    test_path = test_path.Append(FILE_PATH_LITERAL("ppapi"));
    test_path = test_path.Append(FILE_PATH_LITERAL("tests"));
    test_path = test_path.Append(FILE_PATH_LITERAL("test_case.html"));

    // Sanity check the file name.
    EXPECT_TRUE(file_util::PathExists(test_path));

    GURL::Replacements replacements;
    replacements.SetQuery(test_case.c_str(),
                          url_parse::Component(0, test_case.size()));
    GURL test_url = net::FilePathToFileURL(test_path);
    RunTestURL(test_url.ReplaceComponents(replacements));
  }

  void RunTestViaHTTP(const std::string& test_case) {
    net::TestServer test_server(
        net::TestServer::TYPE_HTTP,
        FilePath(FILE_PATH_LITERAL("ppapi/tests")));
    ASSERT_TRUE(test_server.Start());
    RunTestURL(test_server.GetURL("files/test_case.html?" + test_case));
  }

 private:
  void RunTestURL(const GURL& test_url) {
    scoped_refptr<TabProxy> tab(GetActiveTab());
    ASSERT_TRUE(tab.get());
    ASSERT_TRUE(tab->NavigateToURL(test_url));
    std::string escaped_value =
        WaitUntilCookieNonEmpty(tab.get(), test_url,
            "COMPLETION_COOKIE", action_max_timeout_ms());
    EXPECT_STREQ("PASS", escaped_value.c_str());
  }
};

TEST_F(PPAPITest, FAILS_Instance) {
  RunTest("Instance");
}

TEST_F(PPAPITest, Graphics2D) {
  RunTest("Graphics2D");
}

// TODO(brettw) bug 51344: this is flaky on bots. Seems to timeout navigating.
// Possibly all the image allocations slow things down on a loaded bot too much.
TEST_F(PPAPITest, FLAKY_ImageData) {
  RunTest("ImageData");
}

TEST_F(PPAPITest, Buffer) {
  RunTest("Buffer");
}

// Flakey, http:L//crbug.com/57053
TEST_F(PPAPITest, FLAKY_URLLoader) {
  RunTestViaHTTP("URLLoader");
}

// Flaky, http://crbug.com/51012
TEST_F(PPAPITest, FLAKY_PaintAggregator) {
  RunTestViaHTTP("PaintAggregator");
}

// Flaky, http://crbug.com/48544.
TEST_F(PPAPITest, FLAKY_Scrollbar) {
  RunTest("Scrollbar");
}

TEST_F(PPAPITest, UrlUtil) {
  RunTest("UrlUtil");
}

TEST_F(PPAPITest, CharSet) {
  RunTest("CharSet");
}

TEST_F(PPAPITest, Var) {
  RunTest("Var");
}

// TODO(dumi): figure out why this test is flaky / crashing.
TEST_F(PPAPITest, DISABLED_FileIO) {
  RunTestViaHTTP("FileIO");
}

// TODO(dumi): figure out why this test is flaky / crashing.
TEST_F(PPAPITest, DISABLED_FileRef) {
  RunTestViaHTTP("FileRef");
}

TEST_F(PPAPITest, DirectoryReader) {
  RunTestViaHTTP("DirectoryReader");
}
<|endoftext|>