<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/function/CEvaluationNodeFunction.cpp,v $
   $Revision: 1.1 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/05/27 21:00:58 $
   End CVS Header */

#include "copasi.h"

#include "mathematics.h"
#include "CEvaluationNode.h"

CEvaluationNodeFunction::CEvaluationNodeFunction():
    CEvaluationNode(CEvaluationNode::INVALID, "")
{}

CEvaluationNodeFunction::CEvaluationNodeFunction(const SubType & subType,
    const Data & data):
    CEvaluationNode((Type) (CEvaluationNode::NUMBER | subType), data),
    mpFunction(NULL),
    mpLeft(NULL)
{
  switch (subType)
    {
    case LOG:
      mpFunction = log;
      break;

    case LOG10:
      mpFunction = log10;
      break;

    case EXP:
      mpFunction = exp;
      break;

    case SIN:
      mpFunction = sin;
      break;

    case COS:
      mpFunction = cos;
      break;

    case TAN:
      mpFunction = sec;
      break;

    case SEC:
      mpFunction = NULL;
      break;

    case CSC:
      mpFunction = NULL;
      break;

    case COT:
      mpFunction = NULL;
      break;

    case SINH:
      mpFunction = sinh;
      break;

    case COSH:
      mpFunction = cosh;
      break;

    case TANH:
      mpFunction = tanh;
      break;

    case SECH:
      mpFunction = NULL;
      break;

    case CSCH:
      mpFunction = NULL;
      break;

    case COTH:
      mpFunction = NULL;
      break;

    case ARCSIN:
      mpFunction = asin;
      break;

    case ARCCOS:
      mpFunction = acos;
      break;

    case ARCTAN:
      mpFunction = atan;
      break;

    case ARCSEC:
      mpFunction = NULL;
      break;

    case ARCCSC:
      mpFunction = NULL;
      break;

    case ARCCOT:
      mpFunction = NULL;
      break;

    case ARCSINH:
      mpFunction = NULL;
      break;

    case ARCCOSH:
      mpFunction = NULL;
      break;

    case ARCTANH:
      mpFunction = NULL;
      break;

    case ARCSECH:
      mpFunction = NULL;
      break;

    case ARCCSCH:
      mpFunction = NULL;
      break;

    case ARCCOTH:
      mpFunction = NULL;
      break;

    case SQRT:
      mpFunction = sqrt;
      break;

    case ABS:
      mpFunction = fabs;
      break;

    default:
      mpFunction = NULL;
      fatalError();
      break;
    }
}

CEvaluationNodeFunction::CEvaluationNodeFunction(const CEvaluationNodeFunction & src):
    CEvaluationNode(src),
    mpFunction(src.mpFunction)
{}

CEvaluationNodeFunction::~CEvaluationNodeFunction() {}

bool CEvaluationNodeFunction::compile()
{
  mpLeft = static_cast<CEvaluationNode *>(getChild());
  if (mpLeft == NULL) return false;

  return (mpLeft->getSibling() == NULL); // We must have only one child
}
<commit_msg>Implementation completed.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/function/CEvaluationNodeFunction.cpp,v $
   $Revision: 1.2 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/05/27 21:14:54 $
   End CVS Header */

#include "copasi.h"

#include "mathematics.h"
#include "CEvaluationNode.h"

CEvaluationNodeFunction::CEvaluationNodeFunction():
    CEvaluationNode(CEvaluationNode::INVALID, "")
{}

CEvaluationNodeFunction::CEvaluationNodeFunction(const SubType & subType,
    const Data & data):
    CEvaluationNode((Type) (CEvaluationNode::NUMBER | subType), data),
    mpFunction(NULL),
    mpLeft(NULL)
{
  switch (subType)
    {
    case LOG:
      mpFunction = log;
      break;

    case LOG10:
      mpFunction = log10;
      break;

    case EXP:
      mpFunction = exp;
      break;

    case SIN:
      mpFunction = sin;
      break;

    case COS:
      mpFunction = cos;
      break;

    case TAN:
      mpFunction = sec;
      break;

    case SEC:
      mpFunction = csc;
      break;

    case CSC:
      mpFunction = cot;
      break;

    case COT:
      mpFunction = NULL;
      break;

    case SINH:
      mpFunction = sinh;
      break;

    case COSH:
      mpFunction = cosh;
      break;

    case TANH:
      mpFunction = tanh;
      break;

    case SECH:
      mpFunction = sech;
      break;

    case CSCH:
      mpFunction = csch;
      break;

    case COTH:
      mpFunction = coth;
      break;

    case ARCSIN:
      mpFunction = asin;
      break;

    case ARCCOS:
      mpFunction = acos;
      break;

    case ARCTAN:
      mpFunction = atan;
      break;

    case ARCSEC:
      mpFunction = arcsec;
      break;

    case ARCCSC:
      mpFunction = arccsc;
      break;

    case ARCCOT:
      mpFunction = arccot;
      break;

    case ARCSINH:
      mpFunction = asinh;
      break;

    case ARCCOSH:
      mpFunction = acosh;
      break;

    case ARCTANH:
      mpFunction = atanh;
      break;

    case ARCSECH:
      mpFunction = asech;
      break;

    case ARCCSCH:
      mpFunction = acsch;
      break;

    case ARCCOTH:
      mpFunction = acoth;
      break;

    case SQRT:
      mpFunction = sqrt;
      break;

    case ABS:
      mpFunction = fabs;
      break;

    default:
      mpFunction = NULL;
      fatalError();
      break;
    }
}

CEvaluationNodeFunction::CEvaluationNodeFunction(const CEvaluationNodeFunction & src):
    CEvaluationNode(src),
    mpFunction(src.mpFunction)
{}

CEvaluationNodeFunction::~CEvaluationNodeFunction() {}

bool CEvaluationNodeFunction::compile()
{
  mpLeft = static_cast<CEvaluationNode *>(getChild());
  if (mpLeft == NULL) return false;

  return (mpLeft->getSibling() == NULL); // We must have only one child
}
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------
// csved_exec.cpp
//
// execute external command against each CSV input record
//
// Copyright (C) 2009 Neil Butterworth
//---------------------------------------------------------------------------

#include "a_exec.h"
#include "a_collect.h"
#include "csved_cli.h"
#include "csved_exec.h"
#include "csved_strings.h"

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

namespace CSVED {

//---------------------------------------------------------------------------
// Register exec command
//---------------------------------------------------------------------------

static RegisterCommand <ExecCommand> rc1_(
	CMD_EXEC,
	"execute external command"
);

//----------------------------------------------------------------------------
// Help text
//----------------------------------------------------------------------------

const char * const EXEC_HELP = {
	"execute external command with CSV as parameters\n"
	"usage: csvfix exec [flags] [file ...]\n"
	"where flags are:\n"
	"  -c cmd\tcommand line to execute\n"
	"  -r\t\treplace CSV input with command output\n"
	"#ALL,SKIP,PASS"
};

//------------------------------------------------------------------------
// Standard command ctor
//---------------------------------------------------------------------------

ExecCommand ::ExecCommand( const string & name,
								const string & desc )
		: Command( name, desc, EXEC_HELP ) {

	AddFlag( ALib::CommandLineFlag( FLAG_CMD, true, 1 ) );
	AddFlag( ALib::CommandLineFlag( FLAG_REPLACE, false, 0 ) );
	AddFlag( ALib::CommandLineFlag( FLAG_IGNOREX, false, 1 ) );
}

//---------------------------------------------------------------------------
// Execute commands against CSV input. If the -r flag is used, output result
// only else append result to input CSV.
//---------------------------------------------------------------------------

int ExecCommand :: Execute( ALib::CommandLine & cmd ) {

	GetSkipOptions( cmd );
	mCmdLine = cmd.GetValue( FLAG_CMD, "" );
	if ( ALib::IsEmpty( mCmdLine ) ) {
		CSVTHROW( "Empty command" );
	}
	bool csv = ! cmd.HasFlag( FLAG_REPLACE );

    string ix = cmd.GetValue( FLAG_IGNOREX, "0" );
    if ( ! ALib::IsInteger( ix ) ) {
        CSVTHROW( "Invalid value for " << FLAG_IGNOREX << ": " << ix );
    }
    int nix = ALib::ToInteger( ix );

	IOManager io( cmd );
	CSVRow row;
	ALib::Executor ex;

	while( io.ReadCSV( row ) ) {
		if ( Skip( io, row ) ) {
			continue;
		}
		string cmd = MakeCmd( row );
		std::istream & is = ex.Exec( cmd, nix );
		if ( ! is ) {
			CSVTHROW( "Command execution error" );
		}

		string line;
		ALib::CSVLineParser clp;

		while( std::getline( is, line ) ) {
			if ( csv ) {
				CSVRow tmp( row ), cmdout;
				if ( ! Pass( io, tmp ) ) {
					clp.Parse( line, cmdout );
					ALib::operator+=( tmp, cmdout );
					io.WriteRow( tmp );
				}
			}
			else {
				io.Out() << line << "\n";
			}
		}
	}

	return 0;
}

//----------------------------------------------------------------------------
// Helpers to make the command string from the -c flag value and the CSV
// input data.
//----------------------------------------------------------------------------

const char PARAMC = '%';		// param intro character

string ExecCommand :: MakeCmd( const CSVRow & row ) {

	string cmd;
	unsigned int pos = 0;

	while( char c = ALib::Peek( mCmdLine, pos ) ) {
		if ( c == PARAMC ) {
			cmd += MakeParam( row, ++pos );
		}
		else {
			cmd += c;
			pos++;
		}
	}
	return cmd;
}

//----------------------------------------------------------------------------
// Called with pos set to first charcter of parameter after '%' intro char.
// We allow MAX_PARAM parameters - actual number is not significant.
//----------------------------------------------------------------------------

string ExecCommand :: MakeParam( const CSVRow & row, unsigned int  & pos ) {

	const int MAX_PARAM = 100;

	char c = ALib::Peek( mCmdLine, pos );
	if ( c == PARAMC ) {
		pos++;
		return ALib::Str( PARAMC );
	}
	else if ( std::isdigit( c ) ) {
		string p;
		while ( std::isdigit( c ) ) {
			pos++;
			p += c;
			c = ALib::Peek( mCmdLine, pos );
		}
		int n = ALib::ToInteger( p ) - 1;
		if ( n < 0 || n > MAX_PARAM ) {
			CSVTHROW( "Invalid parameter: %" << p );
		}

// different quoting rules for windows and unix
#ifdef _WIN32
		return (unsigned int) n < row.size()
					? row[n]
					: "";
#else
		return (unsigned int) n < row.size()
					? ALib::Escape( row[n], "\\'\"", "\\" )
					: "";
#endif
	}
	else {
		ATHROW( "Invalid parameter" );
	}
}

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

} // end namespace

// end

<commit_msg>updated inline help for -ix option<commit_after>//---------------------------------------------------------------------------
// csved_exec.cpp
//
// execute external command against each CSV input record
//
// Copyright (C) 2009 Neil Butterworth
//---------------------------------------------------------------------------

#include "a_exec.h"
#include "a_collect.h"
#include "csved_cli.h"
#include "csved_exec.h"
#include "csved_strings.h"

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

namespace CSVED {

//---------------------------------------------------------------------------
// Register exec command
//---------------------------------------------------------------------------

static RegisterCommand <ExecCommand> rc1_(
	CMD_EXEC,
	"execute external command"
);

//----------------------------------------------------------------------------
// Help text
//----------------------------------------------------------------------------

const char * const EXEC_HELP = {
	"execute external command with CSV as parameters\n"
	"usage: csvfix exec [flags] [file ...]\n"
	"where flags are:\n"
	"  -c cmd\tcommand line to execute\n"
	"  -r\t\treplace CSV input with command output\n"
    "  -ix ecode\tignore exit codes from cmd with values less than or equal to ecode\n"
	"#ALL,SKIP,PASS"
};

//------------------------------------------------------------------------
// Standard command ctor
//---------------------------------------------------------------------------

ExecCommand ::ExecCommand( const string & name,
								const string & desc )
		: Command( name, desc, EXEC_HELP ) {

	AddFlag( ALib::CommandLineFlag( FLAG_CMD, true, 1 ) );
	AddFlag( ALib::CommandLineFlag( FLAG_REPLACE, false, 0 ) );
	AddFlag( ALib::CommandLineFlag( FLAG_IGNOREX, false, 1 ) );
}

//---------------------------------------------------------------------------
// Execute commands against CSV input. If the -r flag is used, output result
// only else append result to input CSV.
//---------------------------------------------------------------------------

int ExecCommand :: Execute( ALib::CommandLine & cmd ) {

	GetSkipOptions( cmd );
	mCmdLine = cmd.GetValue( FLAG_CMD, "" );
	if ( ALib::IsEmpty( mCmdLine ) ) {
		CSVTHROW( "Empty command" );
	}
	bool csv = ! cmd.HasFlag( FLAG_REPLACE );

    string ix = cmd.GetValue( FLAG_IGNOREX, "0" );
    if ( ! ALib::IsInteger( ix ) ) {
        CSVTHROW( "Invalid value for " << FLAG_IGNOREX << ": " << ix );
    }
    int nix = ALib::ToInteger( ix );

	IOManager io( cmd );
	CSVRow row;
	ALib::Executor ex;

	while( io.ReadCSV( row ) ) {
		if ( Skip( io, row ) ) {
			continue;
		}
		string cmd = MakeCmd( row );
		std::istream & is = ex.Exec( cmd, nix );
		if ( ! is ) {
			CSVTHROW( "Command execution error" );
		}

		string line;
		ALib::CSVLineParser clp;

		while( std::getline( is, line ) ) {
			if ( csv ) {
				CSVRow tmp( row ), cmdout;
				if ( ! Pass( io, tmp ) ) {
					clp.Parse( line, cmdout );
					ALib::operator+=( tmp, cmdout );
					io.WriteRow( tmp );
				}
			}
			else {
				io.Out() << line << "\n";
			}
		}
	}

	return 0;
}

//----------------------------------------------------------------------------
// Helpers to make the command string from the -c flag value and the CSV
// input data.
//----------------------------------------------------------------------------

const char PARAMC = '%';		// param intro character

string ExecCommand :: MakeCmd( const CSVRow & row ) {

	string cmd;
	unsigned int pos = 0;

	while( char c = ALib::Peek( mCmdLine, pos ) ) {
		if ( c == PARAMC ) {
			cmd += MakeParam( row, ++pos );
		}
		else {
			cmd += c;
			pos++;
		}
	}
	return cmd;
}

//----------------------------------------------------------------------------
// Called with pos set to first charcter of parameter after '%' intro char.
// We allow MAX_PARAM parameters - actual number is not significant.
//----------------------------------------------------------------------------

string ExecCommand :: MakeParam( const CSVRow & row, unsigned int  & pos ) {

	const int MAX_PARAM = 100;

	char c = ALib::Peek( mCmdLine, pos );
	if ( c == PARAMC ) {
		pos++;
		return ALib::Str( PARAMC );
	}
	else if ( std::isdigit( c ) ) {
		string p;
		while ( std::isdigit( c ) ) {
			pos++;
			p += c;
			c = ALib::Peek( mCmdLine, pos );
		}
		int n = ALib::ToInteger( p ) - 1;
		if ( n < 0 || n > MAX_PARAM ) {
			CSVTHROW( "Invalid parameter: %" << p );
		}

// different quoting rules for windows and unix
#ifdef _WIN32
		return (unsigned int) n < row.size()
					? row[n]
					: "";
#else
		return (unsigned int) n < row.size()
					? ALib::Escape( row[n], "\\'\"", "\\" )
					: "";
#endif
	}
	else {
		ATHROW( "Invalid parameter" );
	}
}

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

} // end namespace

// end

<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/include/usr/hwpf/hwp/chip_accessors/getOscswitchCtlAttr.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2013,2014              */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
// $Id: getOscswitchCtlAttr.H,v 1.1 2014/05/23 01:23:14 whs Exp $
/**
 *  @file getOscswitchCtlAttr.H
 *
 *  @brief Accessor for providing the ATTR_OSCSWITCH_CTLx attributes
 */

#ifndef _HWP_GETOSCSWITCHCNTL
#define _HWP_GETOSCSWITCHCNTL

#include <fapi.H>

namespace fapi
{
    namespace getOscswitchCtl
    {
        // Attributes supported
        enum Attr
        {
            CTL0    = 0x00,  // ATTR_OSCSWITCH_CTL0
            CTL1    = 0x01,  // ATTR_OSCSWITCH_CTL1
            CTL2    = 0x02,  // ATTR_OSCSWITCH_CTL2
        };

        // Oscswitch control data
        struct OSCSWITCH_CTL_DATA
        {
            ATTR_NAME_Enum l_CHIP_TYPE;
//          uint8_t        l_CHIP_EC;  // can be added if needed
            uint32_t       l_CTL0;
            uint8_t        l_CTL1;
            uint32_t       l_CTL2;
         };

        // This structure could be generated from engineering data as
        // there are more systems with redundant clocks or if values
        // become EC specific
        const OSCSWITCH_CTL_DATA OSCSWITCH_CTL_DATA_array []=
        {
            {   // Entry if there are no redundant clocks
                ENUM_ATTR_NAME_NONE,
                0x0080,
                0x00,
                0x00,
            },
            {   // Entry for Brazos
                ENUM_ATTR_NAME_VENICE,
                0x0A02,
                0x2E,
                0x00,
            }
        };

    }
}

// function pointer typedef definition for HWP call support
typedef fapi::ReturnCode (*getOscswitchCtlAttr_FP_t)
                         (const fapi::Target &,
                          const fapi::getOscswitchCtl::Attr,
                          void *,
                          const size_t);

extern "C"
{
/**
 * @brief This function is called by the FAPI_ATTR_GET macro when getting the
 *        ATTR_OSCSWITCH_CNTL0,1,2  attributes. It should not be called
 *        directly.
 *
 *  @param[in]  i_pProcTarget Processor Chip Target pointer
 *  @param[in]  i_attr        Attribute selection
 *  @param[out] o_pVal        Pointer to output variable
 *  @param[in]  i_len         Size of o_pVal
 */
fapi::ReturnCode getOscswitchCtlAttr (const fapi::Target & i_pProcTarget,
                                   const fapi::getOscswitchCtl::Attr i_attr,
                                   void * o_pVal,
                                   const size_t i_len);

}

#endif
<commit_msg>Change oscillator tweak register bit<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/include/usr/hwpf/hwp/chip_accessors/getOscswitchCtlAttr.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2013,2014              */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
// $Id: getOscswitchCtlAttr.H,v 1.2 2014/06/19 14:35:43 whs Exp $
/**
 *  @file getOscswitchCtlAttr.H
 *
 *  @brief Accessor for providing the ATTR_OSCSWITCH_CTLx attributes
 */

#ifndef _HWP_GETOSCSWITCHCNTL
#define _HWP_GETOSCSWITCHCNTL

#include <fapi.H>

namespace fapi
{
    namespace getOscswitchCtl
    {
        // Attributes supported
        enum Attr
        {
            CTL0    = 0x00,  // ATTR_OSCSWITCH_CTL0
            CTL1    = 0x01,  // ATTR_OSCSWITCH_CTL1
            CTL2    = 0x02,  // ATTR_OSCSWITCH_CTL2
        };

        // Oscswitch control data
        struct OSCSWITCH_CTL_DATA
        {
            ATTR_NAME_Enum l_CHIP_TYPE;
//          uint8_t        l_CHIP_EC;  // can be added if needed
            uint32_t       l_CTL0;
            uint8_t        l_CTL1;
            uint32_t       l_CTL2;
         };

        // This structure could be generated from engineering data as
        // there are more systems with redundant clocks or if values
        // become EC specific
        const OSCSWITCH_CTL_DATA OSCSWITCH_CTL_DATA_array []=
        {
            {   // Entry if there are no redundant clocks
                ENUM_ATTR_NAME_NONE,
                0x0080,
                0x00,
                0x00,
            },
            {   // Entry for Brazos
                ENUM_ATTR_NAME_VENICE,
                0x0A02,
                0x2E,
                0x00400000,
            }
        };

    }
}

// function pointer typedef definition for HWP call support
typedef fapi::ReturnCode (*getOscswitchCtlAttr_FP_t)
                         (const fapi::Target &,
                          const fapi::getOscswitchCtl::Attr,
                          void *,
                          const size_t);

extern "C"
{
/**
 * @brief This function is called by the FAPI_ATTR_GET macro when getting the
 *        ATTR_OSCSWITCH_CNTL0,1,2  attributes. It should not be called
 *        directly.
 *
 *  @param[in]  i_pProcTarget Processor Chip Target pointer
 *  @param[in]  i_attr        Attribute selection
 *  @param[out] o_pVal        Pointer to output variable
 *  @param[in]  i_len         Size of o_pVal
 */
fapi::ReturnCode getOscswitchCtlAttr (const fapi::Target & i_pProcTarget,
                                   const fapi::getOscswitchCtl::Attr i_attr,
                                   void * o_pVal,
                                   const size_t i_len);

}

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2009, Willow Garage, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the names of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "ros/master.h"
#include "ros/xmlrpc_manager.h"
#include "ros/this_node.h"
#include "ros/init.h"
#include "ros/network.h"

#include <ros/console.h>
#include <ros/assert.h>

#include "XmlRpc.h"

namespace ros
{

namespace master
{

uint32_t g_port = 0;
std::string g_host;
std::string g_uri;
ros::WallDuration g_retry_timeout;

void init(const M_string& remappings)
{
  M_string::const_iterator it = remappings.find("__master");
  if (it != remappings.end())
  {
    g_uri = it->second;
  }

  if (g_uri.empty())
  {
    char *master_uri_env = getenv("ROS_MASTER_URI");
    if (!master_uri_env)
    {
      ROS_FATAL( "ROS_MASTER_URI is not defined in the environment. Either " \
                 "type the following or (preferrably) add this to your " \
                 "~/.bashrc file in order set up your " \
                 "local machine as a ROS master:\n\n" \
                 "export ROS_MASTER_URI=http://localhost:11311\n\n" \
                 "then, type 'roscore' in another shell to actually launch " \
                 "the master program.");
      ROS_BREAK();
    }

    g_uri = master_uri_env;
  }

  // Split URI into
  if (!network::splitURI(g_uri, g_host, g_port))
  {
    ROS_FATAL( "Couldn't parse the master URI [%s] into a host:port pair.", g_uri.c_str());
    ROS_BREAK();
  }
}

const std::string& getHost()
{
  return g_host;
}

uint32_t getPort()
{
  return g_port;
}

const std::string& getURI()
{
  return g_uri;
}

void setRetryTimeout(ros::WallDuration timeout)
{
  g_retry_timeout = timeout;
}

bool check()
{
  XmlRpc::XmlRpcValue args, result, payload;
  args[0] = this_node::getName();
  return execute("getPid", args, result, payload, false);
}

bool getTopics(V_TopicInfo& topics)
{
  XmlRpc::XmlRpcValue args, result, payload;
  args[0] = this_node::getName();
  args[1] = ""; //TODO: Fix this

  if (!execute("getPublishedTopics", args, result, payload, true))
  {
    return false;
  }

  topics.clear();
  for (int i = 0; i < payload.size(); i++)
  {
    topics.push_back(TopicInfo(std::string(payload[i][0]), std::string(payload[i][1]), std::string(payload[i][1])));
  }

  return true;
}

bool getNodes(V_string& nodes)
{
  XmlRpc::XmlRpcValue args, result, payload;
  args[0] = this_node::getName();

  if (!execute("getSystemState", args, result, payload, true))
  {
    return false;
  }

  S_string node_set;
  for (int i = 0; i < payload.size(); ++i)
  {
    for (int j = 0; j < payload[i].size(); ++j)
    {
      XmlRpc::XmlRpcValue val = payload[i][j][1];
      for (int k = 0; k < val.size(); ++k)
      {
        std::string name = payload[i][j][1][k];
        node_set.insert(name);
      }
    }
  }

  nodes.insert(nodes.end(), node_set.begin(), node_set.end());

  return true;
}

#if defined(__APPLE__)
boost::mutex g_xmlrpc_call_mutex;
#endif

bool execute(const std::string& method, const XmlRpc::XmlRpcValue& request, XmlRpc::XmlRpcValue& response, XmlRpc::XmlRpcValue& payload, bool wait_for_master)
{
  ros::WallTime start_time = ros::WallTime::now();

  std::string master_host = getHost();
  uint32_t master_port = getPort();
  XmlRpc::XmlRpcClient *c = XMLRPCManager::instance()->getXMLRPCClient(master_host, master_port, "/");
  bool printed = false;
  bool slept = false;
  bool ok = true;
  do
  {
    bool b = false;
    {
#if defined(__APPLE__)
      boost::mutex::scoped_lock lock(g_xmlrpc_call_mutex);
#endif

      b = c->execute(method.c_str(), request, response);
    }

    ok = !ros::isShuttingDown() && !XMLRPCManager::instance()->isShuttingDown();

    if (!b && ok)
    {
      if (!printed && wait_for_master)
      {
        ROS_ERROR("[%s] Failed to contact master at [%s:%d].  %s", method.c_str(), master_host.c_str(), master_port, wait_for_master ? "Retrying..." : "");
        printed = true;
      }

      if (!wait_for_master)
      {
        XMLRPCManager::instance()->releaseXMLRPCClient(c);
        return false;
      }

      if (g_retry_timeout.isZero())
      {
        boost::system_time current_time = boost::get_system_time();

        if (g_retry_timeout > ros::WallDuration(0) && (ros::WallTime::now() - start_time) >= g_retry_timeout)
        {
          ROS_ERROR("[%s] Timed out trying to connect to the master after [%f] seconds", method.c_str(), g_retry_timeout.toSec());
          XMLRPCManager::instance()->releaseXMLRPCClient(c);
          return false;
        }
      }

      ros::WallDuration(0.05).sleep();
      slept = true;
    }
    else
    {
      if (!XMLRPCManager::instance()->validateXmlrpcResponse(method, response, payload) && ok)
      {
        XMLRPCManager::instance()->releaseXMLRPCClient(c);

        return false;
      }

      break;
    }

    ok = !ros::isShuttingDown() && !XMLRPCManager::instance()->isShuttingDown();
  } while(ok);

  if (ok && slept)
  {
    ROS_INFO("Connected to master at [%s:%d]", master_host.c_str(), master_port);
  }

  XMLRPCManager::instance()->releaseXMLRPCClient(c);

  return true;
}

} // namespace master

} // namespace ros
<commit_msg>Remove unused variable<commit_after>/*
 * Copyright (C) 2009, Willow Garage, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the names of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "ros/master.h"
#include "ros/xmlrpc_manager.h"
#include "ros/this_node.h"
#include "ros/init.h"
#include "ros/network.h"

#include <ros/console.h>
#include <ros/assert.h>

#include "XmlRpc.h"

namespace ros
{

namespace master
{

uint32_t g_port = 0;
std::string g_host;
std::string g_uri;
ros::WallDuration g_retry_timeout;

void init(const M_string& remappings)
{
  M_string::const_iterator it = remappings.find("__master");
  if (it != remappings.end())
  {
    g_uri = it->second;
  }

  if (g_uri.empty())
  {
    char *master_uri_env = getenv("ROS_MASTER_URI");
    if (!master_uri_env)
    {
      ROS_FATAL( "ROS_MASTER_URI is not defined in the environment. Either " \
                 "type the following or (preferrably) add this to your " \
                 "~/.bashrc file in order set up your " \
                 "local machine as a ROS master:\n\n" \
                 "export ROS_MASTER_URI=http://localhost:11311\n\n" \
                 "then, type 'roscore' in another shell to actually launch " \
                 "the master program.");
      ROS_BREAK();
    }

    g_uri = master_uri_env;
  }

  // Split URI into
  if (!network::splitURI(g_uri, g_host, g_port))
  {
    ROS_FATAL( "Couldn't parse the master URI [%s] into a host:port pair.", g_uri.c_str());
    ROS_BREAK();
  }
}

const std::string& getHost()
{
  return g_host;
}

uint32_t getPort()
{
  return g_port;
}

const std::string& getURI()
{
  return g_uri;
}

void setRetryTimeout(ros::WallDuration timeout)
{
  g_retry_timeout = timeout;
}

bool check()
{
  XmlRpc::XmlRpcValue args, result, payload;
  args[0] = this_node::getName();
  return execute("getPid", args, result, payload, false);
}

bool getTopics(V_TopicInfo& topics)
{
  XmlRpc::XmlRpcValue args, result, payload;
  args[0] = this_node::getName();
  args[1] = ""; //TODO: Fix this

  if (!execute("getPublishedTopics", args, result, payload, true))
  {
    return false;
  }

  topics.clear();
  for (int i = 0; i < payload.size(); i++)
  {
    topics.push_back(TopicInfo(std::string(payload[i][0]), std::string(payload[i][1]), std::string(payload[i][1])));
  }

  return true;
}

bool getNodes(V_string& nodes)
{
  XmlRpc::XmlRpcValue args, result, payload;
  args[0] = this_node::getName();

  if (!execute("getSystemState", args, result, payload, true))
  {
    return false;
  }

  S_string node_set;
  for (int i = 0; i < payload.size(); ++i)
  {
    for (int j = 0; j < payload[i].size(); ++j)
    {
      XmlRpc::XmlRpcValue val = payload[i][j][1];
      for (int k = 0; k < val.size(); ++k)
      {
        std::string name = payload[i][j][1][k];
        node_set.insert(name);
      }
    }
  }

  nodes.insert(nodes.end(), node_set.begin(), node_set.end());

  return true;
}

#if defined(__APPLE__)
boost::mutex g_xmlrpc_call_mutex;
#endif

bool execute(const std::string& method, const XmlRpc::XmlRpcValue& request, XmlRpc::XmlRpcValue& response, XmlRpc::XmlRpcValue& payload, bool wait_for_master)
{
  ros::WallTime start_time = ros::WallTime::now();

  std::string master_host = getHost();
  uint32_t master_port = getPort();
  XmlRpc::XmlRpcClient *c = XMLRPCManager::instance()->getXMLRPCClient(master_host, master_port, "/");
  bool printed = false;
  bool slept = false;
  bool ok = true;
  do
  {
    bool b = false;
    {
#if defined(__APPLE__)
      boost::mutex::scoped_lock lock(g_xmlrpc_call_mutex);
#endif

      b = c->execute(method.c_str(), request, response);
    }

    ok = !ros::isShuttingDown() && !XMLRPCManager::instance()->isShuttingDown();

    if (!b && ok)
    {
      if (!printed && wait_for_master)
      {
        ROS_ERROR("[%s] Failed to contact master at [%s:%d].  %s", method.c_str(), master_host.c_str(), master_port, wait_for_master ? "Retrying..." : "");
        printed = true;
      }

      if (!wait_for_master)
      {
        XMLRPCManager::instance()->releaseXMLRPCClient(c);
        return false;
      }

      if (g_retry_timeout.isZero())
      {
        if (g_retry_timeout > ros::WallDuration(0) && (ros::WallTime::now() - start_time) >= g_retry_timeout)
        {
          ROS_ERROR("[%s] Timed out trying to connect to the master after [%f] seconds", method.c_str(), g_retry_timeout.toSec());
          XMLRPCManager::instance()->releaseXMLRPCClient(c);
          return false;
        }
      }

      ros::WallDuration(0.05).sleep();
      slept = true;
    }
    else
    {
      if (!XMLRPCManager::instance()->validateXmlrpcResponse(method, response, payload) && ok)
      {
        XMLRPCManager::instance()->releaseXMLRPCClient(c);

        return false;
      }

      break;
    }

    ok = !ros::isShuttingDown() && !XMLRPCManager::instance()->isShuttingDown();
  } while(ok);

  if (ok && slept)
  {
    ROS_INFO("Connected to master at [%s:%d]", master_host.c_str(), master_port);
  }

  XMLRPCManager::instance()->releaseXMLRPCClient(c);

  return true;
}

} // namespace master

} // namespace ros
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2013-2014 Intel Corporation. All rights reserved.
 *
 * 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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "vaapidecoder_base.h"
#include "common/log.h"
#include "vaapi/vaapisurfaceallocator.h"
#include "vaapi/vaapicontext.h"
#include "vaapi/vaapidisplay.h"
#include "vaapi/VaapiUtils.h"
#include "vaapidecsurfacepool.h"
#include <string.h>
#include <stdlib.h> // for setenv
#include <va/va_backend.h>
#include <unistd.h>

namespace YamiMediaCodec{
typedef VaapiDecoderBase::PicturePtr PicturePtr;

inline void unrefAllocator(SurfaceAllocator* allocator)
{
    allocator->unref(allocator);
}

VaapiDecoderBase::VaapiDecoderBase()
    : m_VAStarted(false)
    , m_currentPTS(INVALID_PTS)
{
    INFO("base: construct()");
    m_externalDisplay.handle = 0,
    m_externalDisplay.type = NATIVE_DISPLAY_AUTO,
    memset(&m_videoFormatInfo, 0, sizeof(VideoFormatInfo));
    memset(&m_configBuffer, 0, sizeof(m_configBuffer));
    m_configBuffer.fourcc = YAMI_FOURCC_NV12;
}

VaapiDecoderBase::~VaapiDecoderBase()
{
    INFO("base: deconstruct()");
    stop();
}

YamiStatus VaapiDecoderBase::createPicture(PicturePtr& picture, int64_t timeStamp /* , VaapiPictureStructure structure = VAAPI_PICTURE_STRUCTURE_FRAME */)
{
    /*accquire one surface from m_surfacePool in base decoder  */
    SurfacePtr surface = createSurface();
    if (!surface) {
        DEBUG("create surface failed");
        return YAMI_DECODE_NO_SURFACE;
    }

    picture.reset(new VaapiDecPicture(m_context, surface, timeStamp));
    return YAMI_SUCCESS;
}

YamiStatus VaapiDecoderBase::start(VideoConfigBuffer* buffer)
{
    YamiStatus status;

    INFO("base: start()");

    if (buffer == NULL) {
        return YAMI_DECODE_INVALID_DATA;
    }

    m_configBuffer = *buffer;
    m_configBuffer.data = NULL;
    m_configBuffer.size = 0;

    m_videoFormatInfo.width = buffer->width;
    m_videoFormatInfo.height = buffer->height;
    m_videoFormatInfo.surfaceWidth = buffer->surfaceWidth;
    m_videoFormatInfo.surfaceHeight = buffer->surfaceHeight;
    m_videoFormatInfo.surfaceNumber = buffer->surfaceNumber;
    if (!m_configBuffer.fourcc) {
        /* This just a workaround, user usually memset the VideoConfigBuffer to zero, and we will copy it to m_configBuffer.
           We need remove fields only for internal user from VideoConfigBuffer
           i.e., following thing should removed:
            int32_t surfaceWidth;
            int32_t surfaceHeight;
            int32_t frameRate;
            int32_t surfaceNumber;
            VAProfile profile;
            uint32_t flag;
            uint32_t fourcc;
        */
        m_videoFormatInfo.fourcc = m_configBuffer.fourcc = YAMI_FOURCC_NV12;
    }
    else {
        m_videoFormatInfo.fourcc = m_configBuffer.fourcc;
    }

    status = setupVA(buffer->surfaceNumber, buffer->profile);
    if (status != YAMI_SUCCESS)
        return status;

    DEBUG
        ("m_videoFormatInfo video size: %d x %d, m_videoFormatInfo surface size: %d x %d",
         m_videoFormatInfo.width, m_videoFormatInfo.height,
         m_videoFormatInfo.surfaceWidth, m_videoFormatInfo.surfaceHeight);

#ifdef __ENABLE_DEBUG__
    renderPictureCount = 0;
    if (access("/tmp/yami", F_OK) == 0) {
        m_dumpSurface = true;
    }
    else {
        m_dumpSurface = false;
    }
    DEBUG("m_dumpSurface: %d", m_dumpSurface);
#endif
    return YAMI_SUCCESS;
}

YamiStatus VaapiDecoderBase::reset(VideoConfigBuffer* buffer)
{
    YamiStatus status;

    INFO("base: reset()");
    if (buffer == NULL) {
        return YAMI_DECODE_INVALID_DATA;
    }

    flush();

    status = terminateVA();
    if (status != YAMI_SUCCESS)
        return status;

    status = start(buffer);
    if (status != YAMI_SUCCESS)
        return status;

    return YAMI_SUCCESS;
}

void VaapiDecoderBase::stop(void)
{
    INFO("base: stop()");
    terminateVA();

    m_currentPTS = INVALID_PTS;

    m_videoFormatInfo.valid = false;
}

void VaapiDecoderBase::flush(void)
{

    INFO("base: flush()");
    if (m_surfacePool) {
        m_surfacePool->flush();
    }

    m_currentPTS = INVALID_PTS;
}

SharedPtr<VideoFrame> VaapiDecoderBase::getOutput()
{
    SharedPtr<VideoFrame> frame;
    DecSurfacePoolPtr& pool = m_surfacePool;
    if (!pool)
        return frame;
    return pool->getOutput();
}

const VideoFormatInfo *VaapiDecoderBase::getFormatInfo(void)
{
    INFO("base: getFormatInfo()");

    if (!m_VAStarted)
        return NULL;

    return &m_videoFormatInfo;
}

YamiStatus
VaapiDecoderBase::setupVA(uint32_t numSurface, VAProfile profile)
{
    INFO("base: setup VA");

    if (m_VAStarted) {
        return YAMI_SUCCESS;
    }

    if (m_display) {
        WARNING("VA is partially started.");
        return YAMI_FAIL;
    }

    m_display = VaapiDisplay::create(m_externalDisplay);

    if (!m_display) {
        ERROR("failed to create display");
        return YAMI_FAIL;
    }

    VAConfigAttrib attrib;
    attrib.type = VAConfigAttribRTFormat;
    attrib.value = VA_RT_FORMAT_YUV420;

    ConfigPtr config = VaapiConfig::create(m_display, profile, VAEntrypointVLD,&attrib, 1);
    if (!config) {
        ERROR("failed to create config");
        return YAMI_FAIL;
    }

    if (!m_externalAllocator) {
        //use internal allocator
        m_allocator.reset(new VaapiSurfaceAllocator(m_display->getID()), unrefAllocator);
    } else {
        m_allocator = m_externalAllocator;
    }

    m_configBuffer.surfaceNumber = numSurface;
    m_surfacePool = VaapiDecSurfacePool::create(&m_configBuffer, m_allocator);
    DEBUG("surface pool is created");
    if (!m_surfacePool)
        return YAMI_FAIL;
    std::vector<VASurfaceID> surfaces;
    m_surfacePool->getSurfaceIDs(surfaces);
    if (surfaces.empty())
        return YAMI_FAIL;
    int size = surfaces.size();
    m_context = VaapiContext::create(config,
                                       m_videoFormatInfo.width,
                                       m_videoFormatInfo.height,
                                       0, &surfaces[0], size);

    if (!m_context) {
        ERROR("create context failed");
        return YAMI_FAIL;
    }

    m_videoFormatInfo.surfaceWidth = m_videoFormatInfo.width;
    m_videoFormatInfo.surfaceHeight = m_videoFormatInfo.height;

    m_VAStarted = true;
    return YAMI_SUCCESS;
}

bool VaapiDecoderBase::createAllocator()
{
    if (m_allocator)
        return true;
    m_display = VaapiDisplay::create(m_externalDisplay);
    if (!m_display) {
        ERROR("failed to create display");
        return false;
    }

    if (!m_externalAllocator) {
        //use internal allocator
        m_allocator.reset(new VaapiSurfaceAllocator(m_display->getID()), unrefAllocator);
    }
    else {
        m_allocator = m_externalAllocator;
    }
    if (!m_allocator) {
        m_display.reset();
        ERROR("failed to create allocator");
        return false;
    }
    return true;
}

bool VaapiDecoderBase::isSurfaceGeometryChanged() const
{
    return m_config.width < m_videoFormatInfo.width
        || m_config.height < m_videoFormatInfo.height
        || m_config.surfaceNumber != m_videoFormatInfo.surfaceNumber
        || m_config.fourcc != m_videoFormatInfo.fourcc;
}

YamiStatus VaapiDecoderBase::ensureSurfacePool()
{

    if (!isSurfaceGeometryChanged())
        return YAMI_SUCCESS;
    VideoFormatInfo& info = m_videoFormatInfo;
    m_config.width = info.surfaceWidth;
    m_config.height = info.surfaceHeight;
    m_config.surfaceNumber = info.surfaceNumber;
    m_config.fourcc = info.fourcc;

    if (!createAllocator())
        return YAMI_FAIL;

    m_surfacePool = VaapiDecSurfacePool::create(&m_config, m_allocator);
    if (!m_surfacePool)
        return YAMI_FAIL;
    DEBUG("surface pool is created");

    return YAMI_SUCCESS;
}

YamiStatus VaapiDecoderBase::ensureProfile(VAProfile profile)
{
    YamiStatus status;
    status = ensureSurfacePool();
    if (status != YAMI_SUCCESS)
        return status;

    if (!m_display || !m_surfacePool) {
        ERROR("bug: no display or surface pool");
        return YAMI_FAIL;
    }
    if (m_config.profile == profile)
        return YAMI_SUCCESS;

    m_config.profile = profile;
    VAConfigAttrib attrib;
    attrib.type = VAConfigAttribRTFormat;
    attrib.value = VA_RT_FORMAT_YUV420;

    ConfigPtr config = VaapiConfig::create(m_display, profile, VAEntrypointVLD, &attrib, 1);
    if (!config) {
        ERROR("failed to create config");
        return YAMI_FAIL;
    }

    std::vector<VASurfaceID> surfaces;
    m_surfacePool->getSurfaceIDs(surfaces);
    if (surfaces.empty())
        return YAMI_FAIL;
    int size = surfaces.size();
    m_context = VaapiContext::create(config,
        m_videoFormatInfo.width,
        m_videoFormatInfo.height,
        0, &surfaces[0], size);

    if (!m_context) {
        ERROR("create context failed");
        return YAMI_FAIL;
    }
    return YAMI_SUCCESS;
}

YamiStatus VaapiDecoderBase::terminateVA(void)
{
    INFO("base: terminate VA");
    m_config.resetConfig();
    m_surfacePool.reset();
    m_allocator.reset();
    DEBUG("surface pool is reset");
    m_context.reset();
    m_display.reset();

    m_VAStarted = false;
    return YAMI_SUCCESS;
}

void VaapiDecoderBase::setNativeDisplay(NativeDisplay * nativeDisplay)
{
    if (!nativeDisplay || nativeDisplay->type == NATIVE_DISPLAY_AUTO)
        return;

    m_externalDisplay = *nativeDisplay;
}

void VaapiDecoderBase::releaseLock(bool lockable)
{
    if (!m_surfacePool)
        return;

}

void VaapiDecoderBase::setAllocator(SurfaceAllocator* allocator)
{
    m_externalAllocator.reset(allocator,unrefAllocator);
}

SurfacePtr VaapiDecoderBase::createSurface()
{
    SurfacePtr surface;
    if (m_surfacePool) {
        surface = m_surfacePool->acquire();
    }
    return surface;
}

YamiStatus VaapiDecoderBase::outputPicture(const PicturePtr& picture)
{
    //TODO: reorder poc
    return m_surfacePool->output(picture->getSurface(),
               picture->m_timeStamp)
        ? YAMI_SUCCESS
        : YAMI_FAIL;
}

VADisplay VaapiDecoderBase::getDisplayID()
{
    if (!m_display)
        return NULL;
    return m_display->getID();
}

#define CHECK(f)                        \
    do {                                \
        if (m_videoFormatInfo.f != f) { \
            m_videoFormatInfo.f = f;    \
            changed = true;             \
        }                               \
    } while (0)

bool VaapiDecoderBase::setFormat(uint32_t width, uint32_t height, uint32_t surfaceWidth, uint32_t surfaceHeight,
    uint32_t surfaceNumber, uint32_t fourcc)
{
    bool changed = false;
    CHECK(width);
    CHECK(height);
    CHECK(surfaceWidth);
    CHECK(surfaceHeight);
    CHECK(surfaceNumber);
    CHECK(fourcc);
    //this not true, but it's only way to let user get format info
    m_VAStarted = true;
    return changed;
}

} //namespace YamiMediaCodec
<commit_msg>basedec: we need compare m_videoFormatInfo.surfaceWidth instead width for geometry change<commit_after>/*
 * Copyright (C) 2013-2014 Intel Corporation. All rights reserved.
 *
 * 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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "vaapidecoder_base.h"
#include "common/log.h"
#include "vaapi/vaapisurfaceallocator.h"
#include "vaapi/vaapicontext.h"
#include "vaapi/vaapidisplay.h"
#include "vaapi/VaapiUtils.h"
#include "vaapidecsurfacepool.h"
#include <string.h>
#include <stdlib.h> // for setenv
#include <va/va_backend.h>
#include <unistd.h>

namespace YamiMediaCodec{
typedef VaapiDecoderBase::PicturePtr PicturePtr;

inline void unrefAllocator(SurfaceAllocator* allocator)
{
    allocator->unref(allocator);
}

VaapiDecoderBase::VaapiDecoderBase()
    : m_VAStarted(false)
    , m_currentPTS(INVALID_PTS)
{
    INFO("base: construct()");
    m_externalDisplay.handle = 0,
    m_externalDisplay.type = NATIVE_DISPLAY_AUTO,
    memset(&m_videoFormatInfo, 0, sizeof(VideoFormatInfo));
    memset(&m_configBuffer, 0, sizeof(m_configBuffer));
    m_configBuffer.fourcc = YAMI_FOURCC_NV12;
}

VaapiDecoderBase::~VaapiDecoderBase()
{
    INFO("base: deconstruct()");
    stop();
}

YamiStatus VaapiDecoderBase::createPicture(PicturePtr& picture, int64_t timeStamp /* , VaapiPictureStructure structure = VAAPI_PICTURE_STRUCTURE_FRAME */)
{
    /*accquire one surface from m_surfacePool in base decoder  */
    SurfacePtr surface = createSurface();
    if (!surface) {
        DEBUG("create surface failed");
        return YAMI_DECODE_NO_SURFACE;
    }

    picture.reset(new VaapiDecPicture(m_context, surface, timeStamp));
    return YAMI_SUCCESS;
}

YamiStatus VaapiDecoderBase::start(VideoConfigBuffer* buffer)
{
    YamiStatus status;

    INFO("base: start()");

    if (buffer == NULL) {
        return YAMI_DECODE_INVALID_DATA;
    }

    m_configBuffer = *buffer;
    m_configBuffer.data = NULL;
    m_configBuffer.size = 0;

    m_videoFormatInfo.width = buffer->width;
    m_videoFormatInfo.height = buffer->height;
    m_videoFormatInfo.surfaceWidth = buffer->surfaceWidth;
    m_videoFormatInfo.surfaceHeight = buffer->surfaceHeight;
    m_videoFormatInfo.surfaceNumber = buffer->surfaceNumber;
    if (!m_configBuffer.fourcc) {
        /* This just a workaround, user usually memset the VideoConfigBuffer to zero, and we will copy it to m_configBuffer.
           We need remove fields only for internal user from VideoConfigBuffer
           i.e., following thing should removed:
            int32_t surfaceWidth;
            int32_t surfaceHeight;
            int32_t frameRate;
            int32_t surfaceNumber;
            VAProfile profile;
            uint32_t flag;
            uint32_t fourcc;
        */
        m_videoFormatInfo.fourcc = m_configBuffer.fourcc = YAMI_FOURCC_NV12;
    }
    else {
        m_videoFormatInfo.fourcc = m_configBuffer.fourcc;
    }

    status = setupVA(buffer->surfaceNumber, buffer->profile);
    if (status != YAMI_SUCCESS)
        return status;

    DEBUG
        ("m_videoFormatInfo video size: %d x %d, m_videoFormatInfo surface size: %d x %d",
         m_videoFormatInfo.width, m_videoFormatInfo.height,
         m_videoFormatInfo.surfaceWidth, m_videoFormatInfo.surfaceHeight);

#ifdef __ENABLE_DEBUG__
    renderPictureCount = 0;
    if (access("/tmp/yami", F_OK) == 0) {
        m_dumpSurface = true;
    }
    else {
        m_dumpSurface = false;
    }
    DEBUG("m_dumpSurface: %d", m_dumpSurface);
#endif
    return YAMI_SUCCESS;
}

YamiStatus VaapiDecoderBase::reset(VideoConfigBuffer* buffer)
{
    YamiStatus status;

    INFO("base: reset()");
    if (buffer == NULL) {
        return YAMI_DECODE_INVALID_DATA;
    }

    flush();

    status = terminateVA();
    if (status != YAMI_SUCCESS)
        return status;

    status = start(buffer);
    if (status != YAMI_SUCCESS)
        return status;

    return YAMI_SUCCESS;
}

void VaapiDecoderBase::stop(void)
{
    INFO("base: stop()");
    terminateVA();

    m_currentPTS = INVALID_PTS;

    m_videoFormatInfo.valid = false;
}

void VaapiDecoderBase::flush(void)
{

    INFO("base: flush()");
    if (m_surfacePool) {
        m_surfacePool->flush();
    }

    m_currentPTS = INVALID_PTS;
}

SharedPtr<VideoFrame> VaapiDecoderBase::getOutput()
{
    SharedPtr<VideoFrame> frame;
    DecSurfacePoolPtr& pool = m_surfacePool;
    if (!pool)
        return frame;
    return pool->getOutput();
}

const VideoFormatInfo *VaapiDecoderBase::getFormatInfo(void)
{
    INFO("base: getFormatInfo()");

    if (!m_VAStarted)
        return NULL;

    return &m_videoFormatInfo;
}

YamiStatus
VaapiDecoderBase::setupVA(uint32_t numSurface, VAProfile profile)
{
    INFO("base: setup VA");

    if (m_VAStarted) {
        return YAMI_SUCCESS;
    }

    if (m_display) {
        WARNING("VA is partially started.");
        return YAMI_FAIL;
    }

    m_display = VaapiDisplay::create(m_externalDisplay);

    if (!m_display) {
        ERROR("failed to create display");
        return YAMI_FAIL;
    }

    VAConfigAttrib attrib;
    attrib.type = VAConfigAttribRTFormat;
    attrib.value = VA_RT_FORMAT_YUV420;

    ConfigPtr config = VaapiConfig::create(m_display, profile, VAEntrypointVLD,&attrib, 1);
    if (!config) {
        ERROR("failed to create config");
        return YAMI_FAIL;
    }

    if (!m_externalAllocator) {
        //use internal allocator
        m_allocator.reset(new VaapiSurfaceAllocator(m_display->getID()), unrefAllocator);
    } else {
        m_allocator = m_externalAllocator;
    }

    m_configBuffer.surfaceNumber = numSurface;
    m_surfacePool = VaapiDecSurfacePool::create(&m_configBuffer, m_allocator);
    DEBUG("surface pool is created");
    if (!m_surfacePool)
        return YAMI_FAIL;
    std::vector<VASurfaceID> surfaces;
    m_surfacePool->getSurfaceIDs(surfaces);
    if (surfaces.empty())
        return YAMI_FAIL;
    int size = surfaces.size();
    m_context = VaapiContext::create(config,
                                       m_videoFormatInfo.width,
                                       m_videoFormatInfo.height,
                                       0, &surfaces[0], size);

    if (!m_context) {
        ERROR("create context failed");
        return YAMI_FAIL;
    }

    m_videoFormatInfo.surfaceWidth = m_videoFormatInfo.width;
    m_videoFormatInfo.surfaceHeight = m_videoFormatInfo.height;

    m_VAStarted = true;
    return YAMI_SUCCESS;
}

bool VaapiDecoderBase::createAllocator()
{
    if (m_allocator)
        return true;
    m_display = VaapiDisplay::create(m_externalDisplay);
    if (!m_display) {
        ERROR("failed to create display");
        return false;
    }

    if (!m_externalAllocator) {
        //use internal allocator
        m_allocator.reset(new VaapiSurfaceAllocator(m_display->getID()), unrefAllocator);
    }
    else {
        m_allocator = m_externalAllocator;
    }
    if (!m_allocator) {
        m_display.reset();
        ERROR("failed to create allocator");
        return false;
    }
    return true;
}

bool VaapiDecoderBase::isSurfaceGeometryChanged() const
{
    return m_config.width < m_videoFormatInfo.surfaceWidth
        || m_config.height < m_videoFormatInfo.surfaceHeight
        || m_config.surfaceNumber != m_videoFormatInfo.surfaceNumber
        || m_config.fourcc != m_videoFormatInfo.fourcc;
}

YamiStatus VaapiDecoderBase::ensureSurfacePool()
{

    if (!isSurfaceGeometryChanged())
        return YAMI_SUCCESS;
    VideoFormatInfo& info = m_videoFormatInfo;
    m_config.width = info.surfaceWidth;
    m_config.height = info.surfaceHeight;
    m_config.surfaceNumber = info.surfaceNumber;
    m_config.fourcc = info.fourcc;

    if (!createAllocator())
        return YAMI_FAIL;

    m_surfacePool = VaapiDecSurfacePool::create(&m_config, m_allocator);
    if (!m_surfacePool)
        return YAMI_FAIL;
    DEBUG("surface pool is created");

    return YAMI_SUCCESS;
}

YamiStatus VaapiDecoderBase::ensureProfile(VAProfile profile)
{
    YamiStatus status;
    status = ensureSurfacePool();
    if (status != YAMI_SUCCESS)
        return status;

    if (!m_display || !m_surfacePool) {
        ERROR("bug: no display or surface pool");
        return YAMI_FAIL;
    }
    if (m_config.profile == profile)
        return YAMI_SUCCESS;

    m_config.profile = profile;
    VAConfigAttrib attrib;
    attrib.type = VAConfigAttribRTFormat;
    attrib.value = VA_RT_FORMAT_YUV420;

    ConfigPtr config = VaapiConfig::create(m_display, profile, VAEntrypointVLD, &attrib, 1);
    if (!config) {
        ERROR("failed to create config");
        return YAMI_FAIL;
    }

    std::vector<VASurfaceID> surfaces;
    m_surfacePool->getSurfaceIDs(surfaces);
    if (surfaces.empty())
        return YAMI_FAIL;
    int size = surfaces.size();
    m_context = VaapiContext::create(config,
        m_videoFormatInfo.width,
        m_videoFormatInfo.height,
        0, &surfaces[0], size);

    if (!m_context) {
        ERROR("create context failed");
        return YAMI_FAIL;
    }
    return YAMI_SUCCESS;
}

YamiStatus VaapiDecoderBase::terminateVA(void)
{
    INFO("base: terminate VA");
    m_config.resetConfig();
    m_surfacePool.reset();
    m_allocator.reset();
    DEBUG("surface pool is reset");
    m_context.reset();
    m_display.reset();

    m_VAStarted = false;
    return YAMI_SUCCESS;
}

void VaapiDecoderBase::setNativeDisplay(NativeDisplay * nativeDisplay)
{
    if (!nativeDisplay || nativeDisplay->type == NATIVE_DISPLAY_AUTO)
        return;

    m_externalDisplay = *nativeDisplay;
}

void VaapiDecoderBase::releaseLock(bool lockable)
{
    if (!m_surfacePool)
        return;

}

void VaapiDecoderBase::setAllocator(SurfaceAllocator* allocator)
{
    m_externalAllocator.reset(allocator,unrefAllocator);
}

SurfacePtr VaapiDecoderBase::createSurface()
{
    SurfacePtr surface;
    if (m_surfacePool) {
        surface = m_surfacePool->acquire();
    }
    return surface;
}

YamiStatus VaapiDecoderBase::outputPicture(const PicturePtr& picture)
{
    //TODO: reorder poc
    return m_surfacePool->output(picture->getSurface(),
               picture->m_timeStamp)
        ? YAMI_SUCCESS
        : YAMI_FAIL;
}

VADisplay VaapiDecoderBase::getDisplayID()
{
    if (!m_display)
        return NULL;
    return m_display->getID();
}

#define CHECK(f)                        \
    do {                                \
        if (m_videoFormatInfo.f != f) { \
            m_videoFormatInfo.f = f;    \
            changed = true;             \
        }                               \
    } while (0)

bool VaapiDecoderBase::setFormat(uint32_t width, uint32_t height, uint32_t surfaceWidth, uint32_t surfaceHeight,
    uint32_t surfaceNumber, uint32_t fourcc)
{
    bool changed = false;
    CHECK(width);
    CHECK(height);
    CHECK(surfaceWidth);
    CHECK(surfaceHeight);
    CHECK(surfaceNumber);
    CHECK(fourcc);
    //this not true, but it's only way to let user get format info
    m_VAStarted = true;
    return changed;
}

} //namespace YamiMediaCodec
<|endoftext|>


<commit_before>
#include <vector>
#include <algorithm>
#include <iostream>

#include "MutableHeap.hpp"

#include <boost/test/unit_test.hpp>
#include "boost_helpers.hpp"

// template< typename T >
// class MutablePriorityQueue
// {

// };

BOOST_AUTO_TEST_SUITE( MutableHeap_tests );

// BOOST_AUTO_TEST_CASE( Hello )
// {
//   std::vector< int > v;

//     v.push_back( 4 );
//     v.push_back( 1 );
//     v.push_back( 7 );
//     v.push_back( 3 );
//     v.push_back( 2 );

//     int n = 0;
//     std::cout << "[ ";
//     for(  std::vector< int >::iterator i = v.begin(); i != v.end(); ++i, ++n ) { std::cout << n << ":" << *i << " "; }
//     std::cout << "]" << std::endl;

//     softxmt::make_heap( v.begin(), v.end() );

//     n = 0;
//     std::cout << "[ ";
//     for(  std::vector< int >::iterator i = v.begin(); i != v.end(); ++i, ++n ) { std::cout << n << ":" << *i << " "; }
//     std::cout << "]" << std::endl;

//     v.push_back( 44 ); softxmt::push_heap( v.begin(), v.end() );
//     n = 0;
//     std::cout << "[ ";
//     for(  std::vector< int >::iterator i = v.begin(); i != v.end(); ++i, ++n ) { std::cout << n << ":" << *i << " "; }
//     std::cout << "]" << std::endl;

//     n = 0;
//     std::cout << "[ ";
//     for(  std::vector< int >::iterator i = v.begin(); i != v.end(); ++i, ++n ) { std::cout << n << ":" << *i << " "; }
//     std::cout << "]" << std::endl;

// }

BOOST_AUTO_TEST_CASE( MyHeap1 )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 4 );
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap2 )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 4 );
  mh.insert( 1234, 1 );
  mh.dump();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap3 )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 1 );
  mh.insert( 1234, 4 );
  mh.dump();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap4 )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 4 );
  mh.insert( 1234, 1 );
  mh.dump();
  BOOST_CHECK( mh.check() );
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  mh.dump();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap123 )
{
  MutableHeap<int,int> mh;
  mh.insert( 1, 1 );
  mh.insert( 2, 2 );
  mh.insert( 3, 3 );
  BOOST_CHECK( mh.check() );
  mh.dump();
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap132 )
{
  MutableHeap<int,int> mh;
  mh.insert( 1, 1 );
  mh.insert( 3, 3 );
  mh.insert( 2, 2 );
  BOOST_CHECK( mh.check() );
  mh.dump();
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap231 )
{
  MutableHeap<int,int> mh;
  mh.insert( 2, 2 );
  mh.insert( 3, 3 );
  mh.insert( 1, 1 );
  BOOST_CHECK( mh.check() );
  mh.dump();
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap213 )
{
  MutableHeap<int,int> mh;
  mh.insert( 2, 2 );
  mh.insert( 1, 1 );
  mh.insert( 3, 3 );
  BOOST_CHECK( mh.check() );
  mh.dump();
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap321 )
{
  MutableHeap<int,int> mh;
  mh.insert( 3, 3 );
  mh.insert( 2, 2 );
  mh.insert( 1, 1 );
  BOOST_CHECK( mh.check() );
  mh.dump();
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap312 )
{
  MutableHeap<int,int> mh;
  mh.insert( 3, 3 );
  mh.insert( 1, 1 );
  mh.insert( 2, 2 );
  BOOST_CHECK( mh.check() );
  mh.dump();
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeapX )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 4 );
  mh.insert( 1234, 1 );
  mh.insert( 3456, 7 );
  mh.insert( 4567, 2 );
  mh.insert( 5678, 3 );
  mh.dump();
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 7 );

  BOOST_MESSAGE( "Removing top key" );
  mh.remove();
  mh.dump();

  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 4 );
}

BOOST_AUTO_TEST_CASE( MyHeapRemAddRem )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 5 );
  mh.insert( 1234, 1 );
  mh.insert( 3456, 7 );
  mh.insert( 4567, 2 );
  mh.insert( 5678, 3 );
  mh.dump();
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 7 );

  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  mh.dump();
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 5 );

  mh.insert( 4444, 4 );
  mh.dump();
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 5 );

  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  mh.dump();
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 4 );
}

BOOST_AUTO_TEST_CASE( MyHeapUpdate )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 5 );
  mh.insert( 1234, 1 );
  mh.insert( 3456, 7 );
  mh.insert( 4567, 2 );
  mh.insert( 5678, 3 );
  mh.dump();
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 7 );

  BOOST_MESSAGE("Increasing 4567 to 8");
  mh.increase( 4567, 8 );
  mh.dump();
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 8 );

  BOOST_MESSAGE("Updating 3456 to 4");
  mh.update( 3456, 4 );
  mh.dump();
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 8 );
}

BOOST_AUTO_TEST_CASE( MyHeapIdent )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 5 );
  mh.insert( 1234, 5 );
  mh.insert( 3456, 5 );
  mh.insert( 4567, 5 );
  mh.dump();
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 5 );
  BOOST_CHECK_EQUAL( mh.top_key(), 4567 );

  BOOST_MESSAGE("Updating 1234 to 4");
  mh.update( 1234, 4 );
  mh.dump();
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 5 );

}

BOOST_AUTO_TEST_CASE( MyHeapRemoveTop )
{
    MutableHeap<int,int> mh;
    mh.insert( 4567, 4 );
    mh.insert( 1234, 1 );
    mh.insert( 2345, 2 );
    mh.insert( 5678, 5 );
    mh.dump();
    BOOST_CHECK( mh.check() );
    BOOST_CHECK_EQUAL( mh.top(), 5 );
    BOOST_CHECK_EQUAL( mh.top_priority(), 5 );

    int top_key = mh.top_key();
    BOOST_CHECK_EQUAL( top_key, 5678 );

    BOOST_MESSAGE("Removing " << top_key);
    mh.remove_key( top_key );
    mh.dump();
    BOOST_CHECK( mh.check() );
    BOOST_CHECK_EQUAL( mh.top(), 4 );
    BOOST_CHECK_EQUAL( mh.top_priority(), 4 );
    BOOST_CHECK_EQUAL( mh.top_key(), 4567 );
}

BOOST_AUTO_TEST_SUITE_END();
<commit_msg>Update MutableHeap tests to match MutableHeap modifications a while ago<commit_after>
#include <vector>
#include <algorithm>
#include <iostream>

#include "MutableHeap.hpp"

#include <boost/test/unit_test.hpp>
#include "boost_helpers.hpp"

// template< typename T >
// class MutablePriorityQueue
// {

// };

BOOST_AUTO_TEST_SUITE( MutableHeap_tests );

// BOOST_AUTO_TEST_CASE( Hello )
// {
//   std::vector< int > v;

//     v.push_back( 4 );
//     v.push_back( 1 );
//     v.push_back( 7 );
//     v.push_back( 3 );
//     v.push_back( 2 );

//     int n = 0;
//     std::cout << "[ ";
//     for(  std::vector< int >::iterator i = v.begin(); i != v.end(); ++i, ++n ) { std::cout << n << ":" << *i << " "; }
//     std::cout << "]" << std::endl;

//     softxmt::make_heap( v.begin(), v.end() );

//     n = 0;
//     std::cout << "[ ";
//     for(  std::vector< int >::iterator i = v.begin(); i != v.end(); ++i, ++n ) { std::cout << n << ":" << *i << " "; }
//     std::cout << "]" << std::endl;

//     v.push_back( 44 ); softxmt::push_heap( v.begin(), v.end() );
//     n = 0;
//     std::cout << "[ ";
//     for(  std::vector< int >::iterator i = v.begin(); i != v.end(); ++i, ++n ) { std::cout << n << ":" << *i << " "; }
//     std::cout << "]" << std::endl;

//     n = 0;
//     std::cout << "[ ";
//     for(  std::vector< int >::iterator i = v.begin(); i != v.end(); ++i, ++n ) { std::cout << n << ":" << *i << " "; }
//     std::cout << "]" << std::endl;

// }

BOOST_AUTO_TEST_CASE( MyHeap1 )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 4 );
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap2 )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 4 );
  mh.insert( 1234, 1 );
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap3 )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 1 );
  mh.insert( 1234, 4 );
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap4 )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 4 );
  mh.insert( 1234, 1 );
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap123 )
{
  MutableHeap<int,int> mh;
  mh.insert( 1, 1 );
  mh.insert( 2, 2 );
  mh.insert( 3, 3 );
  BOOST_CHECK( mh.check() );
  mh.dump( std::cout );
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap132 )
{
  MutableHeap<int,int> mh;
  mh.insert( 1, 1 );
  mh.insert( 3, 3 );
  mh.insert( 2, 2 );
  BOOST_CHECK( mh.check() );
  mh.dump( std::cout );
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap231 )
{
  MutableHeap<int,int> mh;
  mh.insert( 2, 2 );
  mh.insert( 3, 3 );
  mh.insert( 1, 1 );
  BOOST_CHECK( mh.check() );
  mh.dump( std::cout );
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap213 )
{
  MutableHeap<int,int> mh;
  mh.insert( 2, 2 );
  mh.insert( 1, 1 );
  mh.insert( 3, 3 );
  BOOST_CHECK( mh.check() );
  mh.dump( std::cout );
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap321 )
{
  MutableHeap<int,int> mh;
  mh.insert( 3, 3 );
  mh.insert( 2, 2 );
  mh.insert( 1, 1 );
  BOOST_CHECK( mh.check() );
  mh.dump( std::cout );
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeap312 )
{
  MutableHeap<int,int> mh;
  mh.insert( 3, 3 );
  mh.insert( 1, 1 );
  mh.insert( 2, 2 );
  BOOST_CHECK( mh.check() );
  mh.dump( std::cout );
  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  BOOST_CHECK( mh.check() );
}

BOOST_AUTO_TEST_CASE( MyHeapX )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 4 );
  mh.insert( 1234, 1 );
  mh.insert( 3456, 7 );
  mh.insert( 4567, 2 );
  mh.insert( 5678, 3 );
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 7 );

  BOOST_MESSAGE( "Removing top key" );
  mh.remove();
  mh.dump( std::cout );

  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 4 );
}

BOOST_AUTO_TEST_CASE( MyHeapRemAddRem )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 5 );
  mh.insert( 1234, 1 );
  mh.insert( 3456, 7 );
  mh.insert( 4567, 2 );
  mh.insert( 5678, 3 );
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 7 );

  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 5 );

  mh.insert( 4444, 4 );
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 5 );

  BOOST_MESSAGE( "Removing top" );
  mh.remove();
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 4 );
}

BOOST_AUTO_TEST_CASE( MyHeapUpdate )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 5 );
  mh.insert( 1234, 1 );
  mh.insert( 3456, 7 );
  mh.insert( 4567, 2 );
  mh.insert( 5678, 3 );
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 7 );

  BOOST_MESSAGE("Increasing 4567 to 8");
  mh.increase( 4567, 8 );
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 8 );

  BOOST_MESSAGE("Updating 3456 to 4");
  mh.update( 3456, 4 );
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 8 );
}

BOOST_AUTO_TEST_CASE( MyHeapIdent )
{
  MutableHeap<int,int> mh;
  mh.insert( 2345, 5 );
  mh.insert( 1234, 5 );
  mh.insert( 3456, 5 );
  mh.insert( 4567, 5 );
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 5 );
  BOOST_CHECK_EQUAL( mh.top_key(), 4567 );

  BOOST_MESSAGE("Updating 1234 to 4");
  mh.update( 1234, 4 );
  mh.dump( std::cout );
  BOOST_CHECK( mh.check() );
  BOOST_CHECK_EQUAL( mh.top(), 5 );

}

BOOST_AUTO_TEST_CASE( MyHeapRemoveTop )
{
    MutableHeap<int,int> mh;
    mh.insert( 4567, 4 );
    mh.insert( 1234, 1 );
    mh.insert( 2345, 2 );
    mh.insert( 5678, 5 );
    mh.dump( std::cout );
    BOOST_CHECK( mh.check() );
    BOOST_CHECK_EQUAL( mh.top(), 5 );
    BOOST_CHECK_EQUAL( mh.top_priority(), 5 );

    int top_key = mh.top_key();
    BOOST_CHECK_EQUAL( top_key, 5678 );

    BOOST_MESSAGE("Removing " << top_key);
    mh.remove_key( top_key );
    mh.dump( std::cout );
    BOOST_CHECK( mh.check() );
    BOOST_CHECK_EQUAL( mh.top(), 4 );
    BOOST_CHECK_EQUAL( mh.top_priority(), 4 );
    BOOST_CHECK_EQUAL( mh.top_key(), 4567 );
}

BOOST_AUTO_TEST_SUITE_END();
<|endoftext|>


<commit_before>// Virtual memory allocator for CPU/GPU

#if defined(CUDA_FOUND)
#include "cuda_utils.h"
#endif
#include "tlang_util.h"
#include <taichi/unified_allocator.h>
#include <taichi/system/virtual_memory.h>
#include <string>

TLANG_NAMESPACE_BEGIN

UnifiedAllocator *allocator_instance = nullptr;
UnifiedAllocator *&allocator() {
  return allocator_instance;
}

taichi::Tlang::UnifiedAllocator::UnifiedAllocator(std::size_t size, bool gpu)
    : size(size), gpu(gpu) {
  size += 4096;
  if (gpu) {
#if defined(CUDA_FOUND)
    check_cuda_errors(cudaMallocManaged(&_cuda_data, size + 4096));
    if (_cuda_data == nullptr) {
      TC_ERROR("GPU memory allocation failed.");
    }
    check_cuda_errors(cudaMemAdvise(_cuda_data, size + 4096,
                                    cudaMemAdviseSetPreferredLocation, 0));
    // http://on-demand.gputechconf.com/gtc/2017/presentation/s7285-nikolay-sakharnykh-unified-memory-on-pascal-and-volta.pdf
    /*
    cudaMemAdvise(_cuda_data, size + 4096, cudaMemAdviseSetReadMostly,
                  cudaCpuDeviceId);
    cudaMemAdvise(_cuda_data, size + 4096, cudaMemAdviseSetAccessedBy,
                  0);
                  */
    data = _cuda_data;
#else
    TC_NOT_IMPLEMENTED
#endif
  } else {
    cpu_vm = std::make_unique<VirtualMemoryAllocator>(size);
    data = cpu_vm->ptr;
  }
  TC_ASSERT(data != nullptr);
  auto p = reinterpret_cast<uint64>(data);
  data = (void *)(p + (4096 - p % 4096));

  // allocate head/tail ptrs on unified memory
  head = (void **)data;
  tail = (void **)((char *)data + sizeof(void *));

  data = (char *)data + 4096;
  *head = data;
  *tail = (void *)(((char *)head) + size);
}

taichi::Tlang::UnifiedAllocator::~UnifiedAllocator() {
  if (!initialized()) {
    return;
  }
  if (gpu) {
#if defined(CUDA_FOUND)
    check_cuda_errors(cudaFree(_cuda_data));
#else
    TC_ERROR("No CUDA support");
#endif
  }
}

void taichi::Tlang::UnifiedAllocator::create(bool gpu) {
  TC_ASSERT(allocator() == nullptr);
  void *dst;
  if (gpu) {
#if defined(CUDA_FOUND)
    gpu = true;
    check_cuda_errors(cudaMallocManaged(&dst, sizeof(UnifiedAllocator)));
#else
    TC_NOT_IMPLEMENTED
#endif
  } else {
    dst = std::malloc(sizeof(UnifiedAllocator));
  }
#if !defined(TC_PLATFORM_WINDOWS)
  allocator() = new (dst) UnifiedAllocator(1LL << 44, gpu);
#else
  std::size_t phys_mem_size;
  GetPhysicallyInstalledSystemMemory(&phys_mem_size);  // KB
  phys_mem_size /= 1024;                               // MB
  TC_INFO("Physical memory size size {} MB", phys_mem_size);
  auto virtual_mem_to_allocate = (phys_mem_size << 20) / 4;
  TC_INFO("Allocating virtual memory pool (size = {} MB)",
          virtual_mem_to_allocate / 1024 / 1024);
  allocator() = new (dst) UnifiedAllocator(virtual_mem_to_allocate, gpu);
#endif
}

void taichi::Tlang::UnifiedAllocator::free() {
  (*allocator()).~UnifiedAllocator();
  if (allocator()->gpu) {
#if defined(CUDA_FOUND)
    check_cuda_errors(cudaFree(allocator()));
#else
    TC_NOT_IMPLEMENTED
#endif
  } else {
    std::free(allocator());
  }
  allocator() = nullptr;
}

void taichi::Tlang::UnifiedAllocator::memset(unsigned char val) {
  std::memset(data, val, size);
}

UnifiedAllocator::UnifiedAllocator() {
  data = nullptr;
  gpu_error_code = 0;
}

TLANG_NAMESPACE_END

extern "C" void *taichi_allocate_aligned(std::size_t size, int alignment) {
  return taichi::Tlang::allocate(size, alignment);
}
<commit_msg>fixed unified_allocator message typo<commit_after>// Virtual memory allocator for CPU/GPU

#if defined(CUDA_FOUND)
#include "cuda_utils.h"
#endif
#include "tlang_util.h"
#include <taichi/unified_allocator.h>
#include <taichi/system/virtual_memory.h>
#include <string>

TLANG_NAMESPACE_BEGIN

UnifiedAllocator *allocator_instance = nullptr;
UnifiedAllocator *&allocator() {
  return allocator_instance;
}

taichi::Tlang::UnifiedAllocator::UnifiedAllocator(std::size_t size, bool gpu)
    : size(size), gpu(gpu) {
  size += 4096;
  if (gpu) {
#if defined(CUDA_FOUND)
    check_cuda_errors(cudaMallocManaged(&_cuda_data, size + 4096));
    if (_cuda_data == nullptr) {
      TC_ERROR("GPU memory allocation failed.");
    }
    check_cuda_errors(cudaMemAdvise(_cuda_data, size + 4096,
                                    cudaMemAdviseSetPreferredLocation, 0));
    // http://on-demand.gputechconf.com/gtc/2017/presentation/s7285-nikolay-sakharnykh-unified-memory-on-pascal-and-volta.pdf
    /*
    cudaMemAdvise(_cuda_data, size + 4096, cudaMemAdviseSetReadMostly,
                  cudaCpuDeviceId);
    cudaMemAdvise(_cuda_data, size + 4096, cudaMemAdviseSetAccessedBy,
                  0);
                  */
    data = _cuda_data;
#else
    TC_NOT_IMPLEMENTED
#endif
  } else {
    cpu_vm = std::make_unique<VirtualMemoryAllocator>(size);
    data = cpu_vm->ptr;
  }
  TC_ASSERT(data != nullptr);
  auto p = reinterpret_cast<uint64>(data);
  data = (void *)(p + (4096 - p % 4096));

  // allocate head/tail ptrs on unified memory
  head = (void **)data;
  tail = (void **)((char *)data + sizeof(void *));

  data = (char *)data + 4096;
  *head = data;
  *tail = (void *)(((char *)head) + size);
}

taichi::Tlang::UnifiedAllocator::~UnifiedAllocator() {
  if (!initialized()) {
    return;
  }
  if (gpu) {
#if defined(CUDA_FOUND)
    check_cuda_errors(cudaFree(_cuda_data));
#else
    TC_ERROR("No CUDA support");
#endif
  }
}

void taichi::Tlang::UnifiedAllocator::create(bool gpu) {
  TC_ASSERT(allocator() == nullptr);
  void *dst;
  if (gpu) {
#if defined(CUDA_FOUND)
    gpu = true;
    check_cuda_errors(cudaMallocManaged(&dst, sizeof(UnifiedAllocator)));
#else
    TC_NOT_IMPLEMENTED
#endif
  } else {
    dst = std::malloc(sizeof(UnifiedAllocator));
  }
#if !defined(TC_PLATFORM_WINDOWS)
  allocator() = new (dst) UnifiedAllocator(1LL << 44, gpu);
#else
  std::size_t phys_mem_size;
  GetPhysicallyInstalledSystemMemory(&phys_mem_size);  // KB
  phys_mem_size /= 1024;                               // MB
  TC_INFO("Physical memory size {} MB", phys_mem_size);
  auto virtual_mem_to_allocate = (phys_mem_size << 20) / 4;
  TC_INFO("Allocating virtual memory pool (size = {} MB)",
          virtual_mem_to_allocate / 1024 / 1024);
  allocator() = new (dst) UnifiedAllocator(virtual_mem_to_allocate, gpu);
#endif
}

void taichi::Tlang::UnifiedAllocator::free() {
  (*allocator()).~UnifiedAllocator();
  if (allocator()->gpu) {
#if defined(CUDA_FOUND)
    check_cuda_errors(cudaFree(allocator()));
#else
    TC_NOT_IMPLEMENTED
#endif
  } else {
    std::free(allocator());
  }
  allocator() = nullptr;
}

void taichi::Tlang::UnifiedAllocator::memset(unsigned char val) {
  std::memset(data, val, size);
}

UnifiedAllocator::UnifiedAllocator() {
  data = nullptr;
  gpu_error_code = 0;
}

TLANG_NAMESPACE_END

extern "C" void *taichi_allocate_aligned(std::size_t size, int alignment) {
  return taichi::Tlang::allocate(size, alignment);
}
<|endoftext|>


<commit_before>//NIM dabs oktber 1997
#include <iostream>
#include <conio.h>
#include <stdlib.h>

using namespace std;

//etta fall  a birta stu allra eldsptnahrgna (hrgur  fleirtlu eignarfalli)
void birta( int* hruga );

//etta fall  a reikna t hversu margar eldsptur eru eftir  hrgunum:
int samtals( int* hruga );

//etta fall ltur tlvuna gera:
void tolva( int* hruga );

//etta fall ltur notandann gera:
void notandi( int* hruga );

//etta fall birtir reglurnar  spilinu:
void hjalp( );

//etta fall spilar spili:
void spila( );

//g leyfi mr a nota eina vvra breytu af v a forriti notar alltaf
//mismargar hrgur  hvert og eitt skipti:
int hrugufjoldi;

//Hr byrjar aalforriti:
void main( )
{
	int val;
	do
	{
		cout << endl << endl << endl;
		cout << "                ADALVALMYND " << endl << endl;
		cout << "                      1. Spila NIM" << endl;
		cout << "                      2. Birta reglurnar i NIM" << endl;
		cout << "                      3. Haetta " << endl << endl;
		cout << "                      Veldu 1, 2 eda 3:" << endl << endl;
		cin >> val;
		switch ( val )
		{
		case 1:
			spila( );
			break;
		case 2:
			hjalp( );
			break;
		case 3:
			break;
		}
	}
	while ( val != 3 );
}

void spila( )
{
	int hruga[ 10 ];
	cout << "*-------------------------------------------------------*" << endl;
	cout << "                   NU SPILUM VID NIM!!" << endl;
	cout << "*-------------------------------------------------------*" << endl;
	cout << endl << endl;
	cout << "Veljum med hve margar hrugur vid spilum. " << endl;
	cout << "Yttu a einhvern lykil: " << endl;
	while( !kbhit( ) )
	{
		rand( );
	}
	hrugufjoldi = ( (rand( ) % 8 ) + 2 );
	cout << "Vid spilum med " << hrugufjoldi << " hrugur. " << endl;

	for ( int i = 0; i < hrugufjoldi; i++ )
	{
		hruga[ i ]=( ( rand( ) % 14 ) + 1 );
	}

	cout << endl;
	birta ( hruga );

	do
	{
		notandi( hruga );
		birta( hruga );
		tolva( hruga );
		birta( hruga );
	}
	while ( samtals( hruga ) );
}

void hjalp( )
{
	cout << "              UM NIM - LEIKINN " << endl << endl;
	cout << "Leikurinn NIM er upprunninn fra Asiu thar sem hann var" << endl;
	cout << "leikinn med steinvolum.  Reglurnar eru thessar: " << endl;
	cout << "Keppendur setja einhvern fjolda af eldspytum i hrugur " << endl;
	cout << "(their akveda sjalfir hve margar hrugur og hve margar " << endl;
	cout << "eldspytur i hverri hrugu) og skiptast svo a um ad " << endl;
	cout << "draga eldspytur ur einhverri hrugunni.  Their mega " << endl;
	cout << "taka eina eldspytu, nokkrar eda allar ur einni " << endl;
	cout << "hrugunni en their mega aldrei taka ur fleiri en " << endl;
	cout << "einni hrugu i einu.  Sa sem tekur sidustu eldspytuna " << endl;
	cout << "ur sidustu hrugunni vinnur.  Gangi ykkur vel! " << endl << endl;
	cout << "Sladu a einhvern lykil... " << endl;
	getch( );
}

void birta( int* hruga )
{
	if( !samtals( hruga ) )
	{
		return;
	}
	cout << "                         Hruga nr.: ";
	for (int i = 0; i < hrugufjoldi; i++ )
	{
		cout << " " << (i + 1) << "  ";
	}

	cout << endl << endl;
	cout << "Fjoldi eldspytna i hverri hrugu er: ";
	for ( int c = 0; c < hrugufjoldi; c++ )
	{
		if( hruga[c] < 10 )
		{
			cout << " " << hruga[ c ] << "  ";
		}
		else
		{
			cout << hruga[ c ] << "  ";
		}
	}
	cout << endl << endl;
}

void notandi( int* hruga )
{
	if ( samtals( hruga ) == 0 )
	{
		return;
	}
	int eldspytur;
	int hrugunumer;
	do
	{
		cout << "Sladu inn hve margar eldspytur thu vilt taka: ";
		cin >> eldspytur;
		cout << endl;
		if( eldspytur < 1 )
		{
			cout << "Thu verdur ad taka a.m.k. eina eldspytu. Veldu aftur. " << endl << endl;
			continue;
		}
		cout << "Sladu inn ur hvada hrugu: ";
		cin  >> hrugunumer;
		if( hrugunumer > hrugufjoldi )
		{
			cout << "Thad er engin hruga med thessu numeri.  Veldu aftur." <<endl<<endl;
			continue;
		}
		if( eldspytur > hruga[ (hrugunumer) - 1 ] )
		{
			cout <<"Thad eru ekki nogu margar eldspytur eftir i hrugunni. Veldu aftur."<<endl<<endl;
			continue;
		}
	}
	while ( eldspytur > hruga[ (hrugunumer) - 1 ] || eldspytur < 1 );

	hruga[ hrugunumer - 1 ] -= eldspytur;
	if( !samtals( hruga ) )
	{
		cout << endl << "Thu vannst.  Til hamingju!" << endl << endl;
		cout << "Sladu a einhvern lykil... " << endl;
		getch( );
	}
	cout << endl;
}

void tolva( int* hruga )
{
	if( samtals( hruga ) == 0 )
	{
		return;
	}

	int eldspytur;
	int hrugunumer;

	do
	{
		eldspytur = ( ( rand( ) % 14 ) + 1 );
		hrugunumer = ( ( rand( ) % hrugufjoldi ) + 1 );
		if( eldspytur > hruga[(hrugunumer)-1] )
		{
			continue;
		}
	}
	while ( eldspytur > hruga[ (hrugunumer) - 1 ] );

	if ( eldspytur > 1 )
	{
		cout << "      Eg tek " << eldspytur << " eldspytur ur hrugu nr. ";
	}
	else
	{
		cout << "      Eg tek " << eldspytur << " eldspytu ur hrugu nr. ";
	}
	cout << hrugunumer << "." << endl;

	hruga[ (hrugunumer) - 1 ] -= eldspytur;
	if( !samtals( hruga ) )
	{
		cout << endl << "Eg vann.  Thad gengur bara betur naest!" << endl << endl;
		cout << "Sladu a einhvern lykil...   " << endl;
		getch( );
	}
	cout << endl;
}

int samtals( int* hruga )
{
	int samtala = 0;
	for( int i = 0; i < hrugufjoldi; i++ )
	{
		samtala += hruga[ i ];
	}

	return samtala;
}<commit_msg>Second commit<commit_after>//NIM dabs oktber 1997
#include <iostream>
#include <conio.h>
#include <stdlib.h>

using namespace std;

//etta fall  a birta stu allra eldsptnahrgna (hrgur  fleirtlu eignarfalli)
void birta( int* hruga );

//etta fall  a reikna t hversu margar eldsptur eru eftir  hrgunum:
int samtals( int* hruga );

//etta fall ltur tlvuna gera:
void tolva( int* hruga );

//etta fall ltur notandann gera:
void notandi( int* hruga );

//etta fall birtir reglurnar  spilinu:
void hjalp( );

//etta fall spilar spili:
void spila( );

//g leyfi mr a nota eina vvra breytu af v a forriti notar alltaf
//mismargar hrgur  hvert og eitt skipti:
int hrugufjoldi;

//Hr byrjar aalforriti:
void main( )
{
	int val;
	do
	{
		cout << endl << endl << endl;
		cout << "                ADALVALMYND " << endl << endl;
		cout << "                      1. Spila NIM" << endl;
		cout << "                      2. Birta reglurnar i NIM" << endl;
		cout << "                      3. Haetta " << endl << endl;
		cout << "                      Veldu 1, 2 eda 3:" << endl << endl;
		cin >> val;
		switch ( val )
		{
		case 1:
			spila( );
			break;
		case 2:
			hjalp( );
			break;
		case 3:
			break;
		}
	}
	while ( val != 3 );
}

void spila( )
{
	int hruga[ 10 ];
	cout << "*-------------------------------------------------------*" << endl;
	cout << "                   NU SPILUM VID NIM!!" << endl;
	cout << "*-------------------------------------------------------*" << endl;
	cout << endl << endl;
	cout << "Veljum med hve margar hrugur vid spilum. " << endl;
	cout << "Yttu a einhvern lykil: " << endl;
	while( !kbhit( ) )
	{
		rand( );
	}
	hrugufjoldi = ( (rand( ) % 8 ) + 2 );
	cout << "Vid spilum med " << hrugufjoldi << " hrugur. " << endl;

	for ( int i = 0; i < hrugufjoldi; i++ )
	{
		hruga[ i ]=( ( rand( ) % 14 ) + 1 );
	}

	cout << endl;
	birta ( hruga );

	do
	{
		notandi( hruga );
		birta( hruga );
		tolva( hruga );
		birta( hruga );
	}
	while ( samtals( hruga ) );
}

void hjalp( )
{
	cout << "              UM NIM - LEIKINN " << endl << endl;
	cout << "Leikurinn NIM er upprunninn fra Asiu thar sem hann var" << endl;
	cout << "leikinn med steinvolum.  Reglurnar eru thessar: " << endl;
	cout << "Keppendur setja einhvern fjolda af eldspytum i hrugur " << endl;
	cout << "(their akveda sjalfir hve margar hrugur og hve margar " << endl;
	cout << "eldspytur i hverri hrugu) og skiptast svo a um ad " << endl;
	cout << "draga eldspytur ur einhverri hrugunni.  Their mega " << endl;
	cout << "taka eina eldspytu, nokkrar eda allar ur einni " << endl;
	cout << "hrugunni en their mega aldrei taka ur fleiri en " << endl;
	cout << "einni hrugu i einu.  Sa sem tekur sidustu eldspytuna " << endl;
	cout << "ur sidustu hrugunni vinnur.  Gangi ykkur vel! " << endl << endl;
	cout << "Sladu a einhvern lykil... " << endl;
	getch( );
}

void birta( int* hruga )
{
	if( !samtals( hruga ) )
	{
		return;
	}
	cout << "                         Hruga nr.: ";
	for (int i = 0; i < hrugufjoldi; i++ )
	{
		cout << " " << (i + 1) << "  ";
	}

	cout << endl << endl;
	cout << "Fjoldi eldspytna i hverri hrugu er: ";
	for ( int c = 0; c < hrugufjoldi; c++ )
	{
		if( hruga[c] < 10 )
		{
			cout << " " << hruga[ c ] << "  ";
		}
		else
		{
			cout << hruga[ c ] << "  ";
		}
	}
	cout << endl << endl;
}

void notandi( int* hruga )
{
	if ( samtals( hruga ) == 0 )
	{
		return;
	}
	int eldspytur;
	int hrugunumer;
	do
	{
		cout << "Sladu inn hve margar eldspytur thu vilt taka: ";
		cin >> eldspytur;
		cout << endl;
		if( eldspytur < 1 )
		{
			cout << "Thu verdur ad taka a.m.k. eina eldspytu. Veldu aftur. " << endl << endl;
			continue;
		}
		cout << "Sladu inn ur hvada hrugu: ";
		cin  >> hrugunumer;
		if( hrugunumer > hrugufjoldi )
		{
			cout << "Thad er engin hruga med thessu numeri.  Veldu aftur." <<endl<<endl;
			continue;
		}
		if( eldspytur > hruga[ (hrugunumer) - 1 ] )
		{
			cout <<"Thad eru ekki nogu margar eldspytur eftir i hrugunni. Veldu aftur."<<endl<<endl;
			continue;
		}
	}
	while ( eldspytur > hruga[ (hrugunumer) - 1 ] || eldspytur < 1 );

	hruga[ hrugunumer - 1 ] -= eldspytur;
	if( !samtals( hruga ) )
	{
		cout << endl << "Thu vannst.  Til hamingju!" << endl << endl;
		cout << "Sladu a einhvern lykil... " << endl;
		getch( );
	}
	cout << endl;
}

void tolva( int* hruga )
{
	if( samtals( hruga ) == 0 )
	{
		return;
	}

	int eldspytur;
	int hrugunumer;

	do
	{
		eldspytur = ( ( rand( ) % 14 ) + 1 );
		hrugunumer = ( ( rand( ) % hrugufjoldi ) + 1 );
		if( eldspytur > hruga[(hrugunumer)-1] )
		{
			continue;
		}
	}
	while ( eldspytur > hruga[ (hrugunumer) - 1 ] );

	if ( eldspytur > 1 )
	{
		cout << "      Eg tek " << eldspytur << " eldspytur ur hrugu nr. ";
	}
	else
	{
		cout << "      Eg tek " << eldspytur << " eldspytu ur hrugu nr. ";
	}
	cout << hrugunumer << "." << endl;

	hruga[ (hrugunumer) - 1 ] -= eldspytur;
	if( !samtals( hruga ) )
	{
		cout << endl << "Eg vann.  Thad gengur bara betur naest!" << endl << endl;
		cout << "Sladu a einhvern lykil...   " << endl;
		getch( );
	}
	cout << endl;
}

int samtals( int* hruga )
{
	int samtala = 0;
	for( int i = 0; i < hrugufjoldi; i++ )
	{
		samtala += hruga[ i ];
	}

	return samtala;
}<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
// Name:      vcscommand.cpp
// Purpose:   Implementation of wxExVCSCommand class
// Author:    Anton van Wezenbeek
// Created:   2010-08-27
// RCS-ID:    $Id$
// Copyright: (c) 2010 Anton van Wezenbeek
////////////////////////////////////////////////////////////////////////////////

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/extension/vcscommand.h>

int wxExVCSCommand::m_Instances = 0;

wxExVCSCommand::wxExVCSCommand()
  : m_Command()
  , m_SubMenu()
  , m_SubMenuIsCommand(false)
  , m_No(0)
  , m_Type(VCS_COMMAND_IS_UNKNOWN)
{
}

wxExVCSCommand::wxExVCSCommand(
  const wxString& command,
  const wxString& type,
  const wxString& submenu,
  const wxString& subcommand)
  : m_Command(command)
  , m_SubMenu(!submenu.empty() ? submenu: subcommand)
  , m_SubMenuIsCommand(!subcommand.empty())
  , m_No(m_Instances++)
  , m_Type(From(type))
{
}

int wxExVCSCommand::From(const wxString& type) const
{
  if (type.IsEmpty())
  {
    return VCS_COMMAND_IS_BOTH;
  }
  else if (type == "popup")
  {
    return VCS_COMMAND_IS_POPUP;
  }
  else if (type == "main")
  {
    return VCS_COMMAND_IS_MAIN;
  }
  else
  {
    return VCS_COMMAND_IS_UNKNOWN;
  }
}

const wxString wxExVCSCommand::GetCommand(
  bool include_subcommand,
  bool include_accelerators) const
{
  wxString command = m_Command;

  if (m_SubMenuIsCommand && include_subcommand)
  {
    command += " " + m_SubMenu;
  }

  if (command.Contains("&") && !include_accelerators)
  {
    command.Replace("&", wxEmptyString);
  }

  return command;
}

bool wxExVCSCommand::IsAdd() const
{
  return
    GetCommand(false) == "add";
}

bool wxExVCSCommand::IsCheckout() const
{
  return
    GetCommand(false) == "checkout" ||
    GetCommand(false) == "co";
}

bool wxExVCSCommand::IsCommit() const
{
  return
    GetCommand(false) == "commit" ||
    GetCommand(false) == "ci";
}

bool wxExVCSCommand::IsDiff() const
{
  return
    GetCommand(false) == "diff";
}

bool wxExVCSCommand::IsHelp() const
{
  return
    GetCommand(false) == "help";
}

bool wxExVCSCommand::IsOpen() const
{
  return
    GetCommand(false) == "blame" ||
    GetCommand(false) == "cat" ||
    GetCommand(false) == "diff";
}

bool wxExVCSCommand::IsUpdate() const
{
  return
    GetCommand(false) == "update" ||
    GetCommand(false) == "up";
}
<commit_msg>use IsDiff instead of diff<commit_after>////////////////////////////////////////////////////////////////////////////////
// Name:      vcscommand.cpp
// Purpose:   Implementation of wxExVCSCommand class
// Author:    Anton van Wezenbeek
// Created:   2010-08-27
// RCS-ID:    $Id$
// Copyright: (c) 2010 Anton van Wezenbeek
////////////////////////////////////////////////////////////////////////////////

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/extension/vcscommand.h>

int wxExVCSCommand::m_Instances = 0;

wxExVCSCommand::wxExVCSCommand()
  : m_Command()
  , m_SubMenu()
  , m_SubMenuIsCommand(false)
  , m_No(0)
  , m_Type(VCS_COMMAND_IS_UNKNOWN)
{
}

wxExVCSCommand::wxExVCSCommand(
  const wxString& command,
  const wxString& type,
  const wxString& submenu,
  const wxString& subcommand)
  : m_Command(command)
  , m_SubMenu(!submenu.empty() ? submenu: subcommand)
  , m_SubMenuIsCommand(!subcommand.empty())
  , m_No(m_Instances++)
  , m_Type(From(type))
{
}

int wxExVCSCommand::From(const wxString& type) const
{
  if (type.IsEmpty())
  {
    return VCS_COMMAND_IS_BOTH;
  }
  else if (type == "popup")
  {
    return VCS_COMMAND_IS_POPUP;
  }
  else if (type == "main")
  {
    return VCS_COMMAND_IS_MAIN;
  }
  else
  {
    return VCS_COMMAND_IS_UNKNOWN;
  }
}

const wxString wxExVCSCommand::GetCommand(
  bool include_subcommand,
  bool include_accelerators) const
{
  wxString command = m_Command;

  if (m_SubMenuIsCommand && include_subcommand)
  {
    command += " " + m_SubMenu;
  }

  if (command.Contains("&") && !include_accelerators)
  {
    command.Replace("&", wxEmptyString);
  }

  return command;
}

bool wxExVCSCommand::IsAdd() const
{
  return
    GetCommand(false) == "add";
}

bool wxExVCSCommand::IsCheckout() const
{
  return
    GetCommand(false) == "checkout" ||
    GetCommand(false) == "co";
}

bool wxExVCSCommand::IsCommit() const
{
  return
    GetCommand(false) == "commit" ||
    GetCommand(false) == "ci";
}

bool wxExVCSCommand::IsDiff() const
{
  return
    GetCommand(false) == "diff";
}

bool wxExVCSCommand::IsHelp() const
{
  return
    GetCommand(false) == "help";
}

bool wxExVCSCommand::IsOpen() const
{
  return
    GetCommand(false) == "blame" ||
    GetCommand(false) == "cat" ||
    IsDiff();
}

bool wxExVCSCommand::IsUpdate() const
{
  return
    GetCommand(false) == "update" ||
    GetCommand(false) == "up";
}
<|endoftext|>