<commit_before>#include "cpid.h"
#include "init.h"
#include "rpcclient.h"
#include "rpcserver.h"
#include "rpcprotocol.h"
#include "keystore.h"
#include "beacon.h"

double GetTotalBalance();

std::string GetBurnAddress() { return fTestNet ? "mk1e432zWKH1MW57ragKywuXaWAtHy1AHZ" : "S67nL4vELWwdDVzjgtEP4MxryarTZ9a8GB";
                             }

bool CheckMessageSignature(std::string sAction,std::string messagetype, std::string sMsg, std::string sSig, std::string strMessagePublicKey)
{
    std::string strMasterPubKey = "";
    if (messagetype=="project" || messagetype=="projectmapping")
    {
        strMasterPubKey= msMasterProjectPublicKey;
    }
    else
    {
        strMasterPubKey = msMasterMessagePublicKey;
    }

    if (!strMessagePublicKey.empty()) strMasterPubKey = strMessagePublicKey;
    if (sAction=="D" && messagetype=="beacon") strMasterPubKey = msMasterProjectPublicKey;
    if (sAction=="D" && messagetype=="poll")   strMasterPubKey = msMasterProjectPublicKey;
    if (sAction=="D" && messagetype=="vote")   strMasterPubKey = msMasterProjectPublicKey;
    if (messagetype=="protocol")  strMasterPubKey = msMasterProjectPublicKey;

    std::string db64 = DecodeBase64(sSig);
    CKey key;
    if (!key.SetPubKey(ParseHex(strMasterPubKey))) return false;
    std::vector<unsigned char> vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end());
    std::vector<unsigned char> vchSig = std::vector<unsigned char>(db64.begin(), db64.end());
    if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) return false;
    return true;
}

bool VerifyCPIDSignature(std::string sCPID, std::string sBlockHash, std::string sSignature)
{
    std::string sBeaconPublicKey = GetBeaconPublicKey(sCPID, false);
    std::string sConcatMessage = sCPID + sBlockHash;
    bool bValid = CheckMessageSignature("R","cpid", sConcatMessage, sSignature, sBeaconPublicKey);
    if(!bValid)
        LogPrintf("VerifyCPIDSignature: invalid signature sSignature=%s, cached key=%s"
                  ,sSignature, sBeaconPublicKey);
    return bValid;
}

std::string SignMessage(const std::string& sMsg, CKey& key)
{
    std::vector<unsigned char> vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end());
    std::vector<unsigned char> vchSig;
    if (!key.Sign(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
    {
        return "Unable to sign message, check private key.";
    }
    const std::string sig(vchSig.begin(), vchSig.end());
    std::string SignedMessage = EncodeBase64(sig);
    return SignedMessage;
}

std::string SignMessage(std::string sMsg, std::string sPrivateKey)
{
    CKey key;
    std::vector<unsigned char> vchPrivKey = ParseHex(sPrivateKey);
    key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash
    return SignMessage(sMsg, key);
}

std::string SendMessage(bool bAdd, std::string sType, std::string sPrimaryKey, std::string sValue,
                       std::string sMasterKey, int64_t MinimumBalance, double dFees, std::string strPublicKey)
{
    std::string sAddress = GetBurnAddress();
    CBitcoinAddress address(sAddress);
    if (!address.IsValid())       throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Gridcoin address");
    int64_t nAmount = AmountFromValue(dFees);
    // Wallet comments
    CWalletTx wtx;
    if (pwalletMain->IsLocked())  throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
    std::string sMessageType      = "<MT>" + sType  + "</MT>";  //Project or Smart Contract
    std::string sMessageKey       = "<MK>" + sPrimaryKey   + "</MK>";
    std::string sMessageValue     = "<MV>" + sValue + "</MV>";
    std::string sMessagePublicKey = "<MPK>"+ strPublicKey + "</MPK>";
    std::string sMessageAction    = bAdd ? "<MA>A</MA>" : "<MA>D</MA>"; //Add or Delete
    //Sign Message
    std::string sSig = SignMessage(sType+sPrimaryKey+sValue,sMasterKey);
    std::string sMessageSignature = "<MS>" + sSig + "</MS>";
    wtx.hashBoinc = sMessageType+sMessageKey+sMessageValue+sMessageAction+sMessagePublicKey+sMessageSignature;
    std::string strError = pwalletMain->SendMoneyToDestinationWithMinimumBalance(address.Get(), nAmount, MinimumBalance, wtx);
    if (!strError.empty())        throw JSONRPCError(RPC_WALLET_ERROR, strError);
    return wtx.GetHash().GetHex().c_str();
}

std::string SendContract(std::string sType, std::string sName, std::string sContract)
{
    std::string sPass = (sType=="project" || sType=="projectmapping" || sType=="smart_contract") ? GetArgument("masterprojectkey", msMasterMessagePrivateKey) : msMasterMessagePrivateKey;
    std::string result = SendMessage(true,sType,sName,sContract,sPass,AmountFromValue(1),.00001,"");
    return result;
}

bool SignBlockWithCPID(const std::string& sCPID, const std::string& sBlockHash, std::string& sSignature, std::string& sError, bool bAdvertising=false)
{
    // Check if there is a beacon for this user
    // If not then return false as GetStoresBeaconPrivateKey grabs from the config
    if (!HasActiveBeacon(sCPID) && !bAdvertising)
    {
        sError = "No active beacon";
        return false;
    }
    // Returns the Signature of the CPID+BlockHash message.
    CKey keyBeacon;
    if(!GetStoredBeaconPrivateKey(sCPID, keyBeacon))
    {
        sError = "No beacon key";
        return false;
    }
    std::string sMessage = sCPID + sBlockHash;
    sSignature = SignMessage(sMessage,keyBeacon);
    // If we failed to sign then return false
    if (sSignature == "Unable to sign message, check private key.")
    {
        sError = sSignature;
        sSignature = "";
        return false;
    }
    return true;
}

int64_t AmountFromDouble(double dAmount)
{
    if (dAmount <= 0.0 || dAmount > MAX_MONEY)        throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
    int64_t nAmount = roundint64(dAmount * COIN);
    if (!MoneyRange(nAmount))         throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
    return nAmount;
}

std::string executeRain(std::string sRecipients)
{
    CWalletTx wtx;
    wtx.mapValue["comment"] = "Rain";
    set<CBitcoinAddress> setAddress;
    vector<pair<CScript, int64_t> > vecSend;
    std::string sRainCommand = ExtractXML(sRecipients,"<RAIN>","</RAIN>");
    std::string sRainMessage = MakeSafeMessage(ExtractXML(sRecipients,"<RAINMESSAGE>","</RAINMESSAGE>"));
    std::string sRain = "<NARR>Project Rain: " + sRainMessage + "</NARR>";

    if (!sRainCommand.empty())
        sRecipients = sRainCommand;

    wtx.hashBoinc = sRain;
    int64_t totalAmount = 0;
    double dTotalToSend = 0;
    std::vector<std::string> vRecipients = split(sRecipients.c_str(),"<ROW>");
    LogPrintf("Creating Rain transaction with %" PRId64 " recipients. ", vRecipients.size());

    for (unsigned int i = 0; i < vRecipients.size(); i++)
    {
        std::string sRow = vRecipients[i];
        std::vector<std::string> vReward = split(sRow.c_str(),"<COL>");

        if (vReward.size() > 1)
        {
            std::string sAddress = vReward[0];
            std::string sAmount = vReward[1];

            if (sAddress.length() > 10 && sAmount.length() > 0)
            {
                double dAmount = RoundFromString(sAmount,4);
                if (dAmount > 0)
                {
                    CBitcoinAddress address(sAddress);
                    if (!address.IsValid())
                        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Gridcoin address: ")+sAddress);

                    if (setAddress.count(address))
                        throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+sAddress);

                    setAddress.insert(address);
                    dTotalToSend += dAmount;
                    int64_t nAmount = AmountFromDouble(dAmount);
                    CScript scriptPubKey;
                    scriptPubKey.SetDestination(address.Get());
                    totalAmount += nAmount;
                    vecSend.push_back(make_pair(scriptPubKey, nAmount));
                }
            }
        }
    }

    EnsureWalletIsUnlocked();
    // Check funds
    double dBalance = GetTotalBalance();

    if (dTotalToSend > dBalance)
        throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
    // Send
    CReserveKey keyChange(pwalletMain);
    int64_t nFeeRequired = 0;
    bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
    LogPrintf("Transaction Created.");

    if (!fCreated)
    {
        if (totalAmount + nFeeRequired > pwalletMain->GetBalance())
            throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
        throw JSONRPCError(RPC_WALLET_ERROR, "Transaction creation failed");
    }

    LogPrintf("Committing.");
    // Rain the recipients
    if (!pwalletMain->CommitTransaction(wtx, keyChange))
    {
        LogPrintf("Commit failed.");

        throw JSONRPCError(RPC_WALLET_ERROR, "Transaction commit failed");
    }
    std::string sNarr = "Rain successful:  Sent " + wtx.GetHash().GetHex() + ".";
    LogPrintf("Success %s",sNarr.c_str());
    return sNarr;
}
<commit_msg>Require addkey action scraper to use master key - Part II<commit_after>#include "cpid.h"
#include "init.h"
#include "rpcclient.h"
#include "rpcserver.h"
#include "rpcprotocol.h"
#include "keystore.h"
#include "beacon.h"

double GetTotalBalance();

std::string GetBurnAddress() { return fTestNet ? "mk1e432zWKH1MW57ragKywuXaWAtHy1AHZ" : "S67nL4vELWwdDVzjgtEP4MxryarTZ9a8GB";
                             }

bool CheckMessageSignature(std::string sAction,std::string messagetype, std::string sMsg, std::string sSig, std::string strMessagePublicKey)
{
    std::string strMasterPubKey = "";
    if (messagetype=="project" || messagetype=="projectmapping")
    {
        strMasterPubKey= msMasterProjectPublicKey;
    }
    else
    {
        strMasterPubKey = msMasterMessagePublicKey;
    }

    if (!strMessagePublicKey.empty()) strMasterPubKey = strMessagePublicKey;
    if (sAction=="D" && messagetype=="beacon") strMasterPubKey = msMasterProjectPublicKey;
    if (sAction=="D" && messagetype=="poll")   strMasterPubKey = msMasterProjectPublicKey;
    if (sAction=="D" && messagetype=="vote")   strMasterPubKey = msMasterProjectPublicKey;
    if (messagetype == "protocol" || messagetype == "scraper")  strMasterPubKey = msMasterProjectPublicKey;

    std::string db64 = DecodeBase64(sSig);
    CKey key;
    if (!key.SetPubKey(ParseHex(strMasterPubKey))) return false;
    std::vector<unsigned char> vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end());
    std::vector<unsigned char> vchSig = std::vector<unsigned char>(db64.begin(), db64.end());
    if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) return false;
    return true;
}

bool VerifyCPIDSignature(std::string sCPID, std::string sBlockHash, std::string sSignature)
{
    std::string sBeaconPublicKey = GetBeaconPublicKey(sCPID, false);
    std::string sConcatMessage = sCPID + sBlockHash;
    bool bValid = CheckMessageSignature("R","cpid", sConcatMessage, sSignature, sBeaconPublicKey);
    if(!bValid)
        LogPrintf("VerifyCPIDSignature: invalid signature sSignature=%s, cached key=%s"
                  ,sSignature, sBeaconPublicKey);
    return bValid;
}

std::string SignMessage(const std::string& sMsg, CKey& key)
{
    std::vector<unsigned char> vchMsg = std::vector<unsigned char>(sMsg.begin(), sMsg.end());
    std::vector<unsigned char> vchSig;
    if (!key.Sign(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
    {
        return "Unable to sign message, check private key.";
    }
    const std::string sig(vchSig.begin(), vchSig.end());
    std::string SignedMessage = EncodeBase64(sig);
    return SignedMessage;
}

std::string SignMessage(std::string sMsg, std::string sPrivateKey)
{
    CKey key;
    std::vector<unsigned char> vchPrivKey = ParseHex(sPrivateKey);
    key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash
    return SignMessage(sMsg, key);
}

std::string SendMessage(bool bAdd, std::string sType, std::string sPrimaryKey, std::string sValue,
                       std::string sMasterKey, int64_t MinimumBalance, double dFees, std::string strPublicKey)
{
    std::string sAddress = GetBurnAddress();
    CBitcoinAddress address(sAddress);
    if (!address.IsValid())       throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Gridcoin address");
    int64_t nAmount = AmountFromValue(dFees);
    // Wallet comments
    CWalletTx wtx;
    if (pwalletMain->IsLocked())  throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
    std::string sMessageType      = "<MT>" + sType  + "</MT>";  //Project or Smart Contract
    std::string sMessageKey       = "<MK>" + sPrimaryKey   + "</MK>";
    std::string sMessageValue     = "<MV>" + sValue + "</MV>";
    std::string sMessagePublicKey = "<MPK>"+ strPublicKey + "</MPK>";
    std::string sMessageAction    = bAdd ? "<MA>A</MA>" : "<MA>D</MA>"; //Add or Delete
    //Sign Message
    std::string sSig = SignMessage(sType+sPrimaryKey+sValue,sMasterKey);
    std::string sMessageSignature = "<MS>" + sSig + "</MS>";
    wtx.hashBoinc = sMessageType+sMessageKey+sMessageValue+sMessageAction+sMessagePublicKey+sMessageSignature;
    std::string strError = pwalletMain->SendMoneyToDestinationWithMinimumBalance(address.Get(), nAmount, MinimumBalance, wtx);
    if (!strError.empty())        throw JSONRPCError(RPC_WALLET_ERROR, strError);
    return wtx.GetHash().GetHex().c_str();
}

std::string SendContract(std::string sType, std::string sName, std::string sContract)
{
    std::string sPass = (sType=="project" || sType=="projectmapping" || sType=="smart_contract") ? GetArgument("masterprojectkey", msMasterMessagePrivateKey) : msMasterMessagePrivateKey;
    std::string result = SendMessage(true,sType,sName,sContract,sPass,AmountFromValue(1),.00001,"");
    return result;
}

bool SignBlockWithCPID(const std::string& sCPID, const std::string& sBlockHash, std::string& sSignature, std::string& sError, bool bAdvertising=false)
{
    // Check if there is a beacon for this user
    // If not then return false as GetStoresBeaconPrivateKey grabs from the config
    if (!HasActiveBeacon(sCPID) && !bAdvertising)
    {
        sError = "No active beacon";
        return false;
    }
    // Returns the Signature of the CPID+BlockHash message.
    CKey keyBeacon;
    if(!GetStoredBeaconPrivateKey(sCPID, keyBeacon))
    {
        sError = "No beacon key";
        return false;
    }
    std::string sMessage = sCPID + sBlockHash;
    sSignature = SignMessage(sMessage,keyBeacon);
    // If we failed to sign then return false
    if (sSignature == "Unable to sign message, check private key.")
    {
        sError = sSignature;
        sSignature = "";
        return false;
    }
    return true;
}

int64_t AmountFromDouble(double dAmount)
{
    if (dAmount <= 0.0 || dAmount > MAX_MONEY)        throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
    int64_t nAmount = roundint64(dAmount * COIN);
    if (!MoneyRange(nAmount))         throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
    return nAmount;
}

std::string executeRain(std::string sRecipients)
{
    CWalletTx wtx;
    wtx.mapValue["comment"] = "Rain";
    set<CBitcoinAddress> setAddress;
    vector<pair<CScript, int64_t> > vecSend;
    std::string sRainCommand = ExtractXML(sRecipients,"<RAIN>","</RAIN>");
    std::string sRainMessage = MakeSafeMessage(ExtractXML(sRecipients,"<RAINMESSAGE>","</RAINMESSAGE>"));
    std::string sRain = "<NARR>Project Rain: " + sRainMessage + "</NARR>";

    if (!sRainCommand.empty())
        sRecipients = sRainCommand;

    wtx.hashBoinc = sRain;
    int64_t totalAmount = 0;
    double dTotalToSend = 0;
    std::vector<std::string> vRecipients = split(sRecipients.c_str(),"<ROW>");
    LogPrintf("Creating Rain transaction with %" PRId64 " recipients. ", vRecipients.size());

    for (unsigned int i = 0; i < vRecipients.size(); i++)
    {
        std::string sRow = vRecipients[i];
        std::vector<std::string> vReward = split(sRow.c_str(),"<COL>");

        if (vReward.size() > 1)
        {
            std::string sAddress = vReward[0];
            std::string sAmount = vReward[1];

            if (sAddress.length() > 10 && sAmount.length() > 0)
            {
                double dAmount = RoundFromString(sAmount,4);
                if (dAmount > 0)
                {
                    CBitcoinAddress address(sAddress);
                    if (!address.IsValid())
                        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Gridcoin address: ")+sAddress);

                    if (setAddress.count(address))
                        throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+sAddress);

                    setAddress.insert(address);
                    dTotalToSend += dAmount;
                    int64_t nAmount = AmountFromDouble(dAmount);
                    CScript scriptPubKey;
                    scriptPubKey.SetDestination(address.Get());
                    totalAmount += nAmount;
                    vecSend.push_back(make_pair(scriptPubKey, nAmount));
                }
            }
        }
    }

    EnsureWalletIsUnlocked();
    // Check funds
    double dBalance = GetTotalBalance();

    if (dTotalToSend > dBalance)
        throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
    // Send
    CReserveKey keyChange(pwalletMain);
    int64_t nFeeRequired = 0;
    bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
    LogPrintf("Transaction Created.");

    if (!fCreated)
    {
        if (totalAmount + nFeeRequired > pwalletMain->GetBalance())
            throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
        throw JSONRPCError(RPC_WALLET_ERROR, "Transaction creation failed");
    }

    LogPrintf("Committing.");
    // Rain the recipients
    if (!pwalletMain->CommitTransaction(wtx, keyChange))
    {
        LogPrintf("Commit failed.");

        throw JSONRPCError(RPC_WALLET_ERROR, "Transaction commit failed");
    }
    std::string sNarr = "Rain successful:  Sent " + wtx.GetHash().GetHex() + ".";
    LogPrintf("Success %s",sNarr.c_str());
    return sNarr;
}
<|endoftext|>


<commit_before>
/*!
	\file

	\author Igor Mironchik (igor.mironchik at gmail dot com).

	Copyright (c) 2013-2017 Igor Mironchik

	Permission is hereby granted, free of charge, to any person
	obtaining a copy of this software and associated documentation
	files (the "Software"), to deal in the Software without
	restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the
	Software is furnished to do so, subject to the following
	conditions:

	The above copyright notice and this permission notice shall be
	included in all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
	OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef ARGS__VALUE_UTILS_HPP__INCLUDED
#define ARGS__VALUE_UTILS_HPP__INCLUDED

// Args include.
#include "utils.hpp"
#include "exceptions.hpp"
#include "types.hpp"

// C++ include.
#include <algorithm>

namespace Args {

//
// eatValues
//

//! Eat values in context.
template< typename Container, typename Cmd, typename Ctx >
bool eatValues( Ctx & context, Container & container,
	const String & errorDescription, Cmd * cmdLine )
{
	if( !context.atEnd() )
	{
		auto begin = context.begin();

		auto last = std::find_if( context.begin(), context.end(),
			[ & ] ( const String & v ) -> bool
			{
				if( details::isArgument( v ) || details::isFlag( v ) )
					return true;
				else
					return( cmdLine->findArgument( v ) != nullptr );
			}
		);

		if( last != begin )
		{
			begin = context.next();

			while( begin != last )
			{
				container.push_back( *begin );

				begin = context.next();
			}

			if( last != context.end() )
				context.putBack();

			return true;
		}
	}

	throw BaseException( errorDescription );
}

//
// eatOneValue
//

//! Eat one value.
template< typename Cmd, typename Ctx >
String eatOneValue( Ctx & context,
	const String & errorDescription, Cmd * cmdLine )
{
	if( !context.atEnd() )
	{
		auto val = context.next();

		if( !details::isArgument( *val ) && !details::isFlag( *val ) )
		{
			if( !cmdLine->findArgument( *val ) )
				return *val;
		}

		context.putBack();
	}

	throw BaseException( errorDescription );
}

} /* namespace Args */

#endif // ARGS__VALUE_UTILS_HPP__INCLUDED
<commit_msg>Allow to eat values started with "-", but don't allow to eat correct arguments' names.<commit_after>
/*!
	\file

	\author Igor Mironchik (igor.mironchik at gmail dot com).

	Copyright (c) 2013-2017 Igor Mironchik

	Permission is hereby granted, free of charge, to any person
	obtaining a copy of this software and associated documentation
	files (the "Software"), to deal in the Software without
	restriction, including without limitation the rights to use,
	copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the
	Software is furnished to do so, subject to the following
	conditions:

	The above copyright notice and this permission notice shall be
	included in all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
	EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
	OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
	NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
	HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
	WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
	OTHER DEALINGS IN THE SOFTWARE.
*/

#ifndef ARGS__VALUE_UTILS_HPP__INCLUDED
#define ARGS__VALUE_UTILS_HPP__INCLUDED

// Args include.
#include "utils.hpp"
#include "exceptions.hpp"
#include "types.hpp"

// C++ include.
#include <algorithm>

namespace Args {

//
// eatValues
//

//! Eat values in context.
template< typename Container, typename Cmd, typename Ctx >
bool eatValues( Ctx & context, Container & container,
	const String & errorDescription, Cmd * cmdLine )
{
	if( !context.atEnd() )
	{
		auto begin = context.begin();

		auto last = std::find_if( context.begin(), context.end(),
			[ & ] ( const String & v ) -> bool
			{
				return( cmdLine->findArgument( v ) != nullptr );
			}
		);

		if( last != begin )
		{
			begin = context.next();

			while( begin != last )
			{
				container.push_back( *begin );

				begin = context.next();
			}

			if( last != context.end() )
				context.putBack();

			return true;
		}
	}

	throw BaseException( errorDescription );
}

//
// eatOneValue
//

//! Eat one value.
template< typename Cmd, typename Ctx >
String eatOneValue( Ctx & context,
	const String & errorDescription, Cmd * cmdLine )
{
	if( !context.atEnd() )
	{
		auto val = context.next();

		if( !cmdLine->findArgument( *val ) )
			return *val;

		context.putBack();
	}

	throw BaseException( errorDescription );
}

} /* namespace Args */

#endif // ARGS__VALUE_UTILS_HPP__INCLUDED
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: cat %s | %cling
// RUN: cat %s | %cling 2>&1 | FileCheck %s
// Test handling and recovery from calling an unresolved symbol.

.rawInput
int foo(); // extern C++
void bar() { foo(); }
.rawInput
extern "C" int functionWithoutDefinition();

int i = 42;
i = functionWithoutDefinition();
// CHECK: ExecutionContext: use of undefined symbol 'functionWithoutDefinition'!
// CHECK: ExecutionContext::executeFunction: symbol 'functionWithoutDefinition' unresolved while linking function
i = foo();
// CHECK: ExecutionContext: use of undefined symbol '{{.*}}foo{{.*}}'!
// CHECK: ExecutionContext::executeFunction: symbol '{{.*}}foo{{.*}}' unresolved while linking function

extern "C" int printf(const char* fmt, ...);
printf("got i=%d\n", i); // CHECK: got i=42
int a = 12// CHECK: (int) 12

foo()
// CHECK: ExecutionContext::executeFunction: symbol '{{.*}}foo{{.*}}' unresolved
functionWithoutDefinition();
// CHECK: ExecutionContext::executeFunction: symbol 'functionWithoutDefinition' unresolved while linking function

bar();
// CHECK: ExecutionContext: use of undefined symbol '{{.*}}foo{{.*}}'!
// CHECK: ExecutionContext::executeFunction: symbol '{{.*}}foo{{.*}}' unresolved while linking function
bar();
// CHECK: ExecutionContext: calling unresolved symbol, see previous error message!

i = 13 //CHECK: (int) 13
.q
<commit_msg>Follow the change ExecutionContext -> IncrementalExecutor.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: cat %s | %cling
// RUN: cat %s | %cling 2>&1 | FileCheck %s
// Test handling and recovery from calling an unresolved symbol.

.rawInput
int foo(); // extern C++
void bar() { foo(); }
.rawInput
extern "C" int functionWithoutDefinition();

int i = 42;
i = functionWithoutDefinition();
// CHECK: IncrementalExecutor: use of undefined symbol 'functionWithoutDefinition'!
// CHECK: IncrementalExecutor::executeFunction: symbol 'functionWithoutDefinition' unresolved while linking function
i = foo();
// CHECK: IncrementalExecutor: use of undefined symbol '{{.*}}foo{{.*}}'!
// CHECK: IncrementalExecutor::executeFunction: symbol '{{.*}}foo{{.*}}' unresolved while linking function

extern "C" int printf(const char* fmt, ...);
printf("got i=%d\n", i); // CHECK: got i=42
int a = 12// CHECK: (int) 12

foo()
// CHECK: IncrementalExecutor::executeFunction: symbol '{{.*}}foo{{.*}}' unresolved
functionWithoutDefinition();
// CHECK: IncrementalExecutor::executeFunction: symbol 'functionWithoutDefinition' unresolved while linking function

bar();
// CHECK: IncrementalExecutor: use of undefined symbol '{{.*}}foo{{.*}}'!
// CHECK: IncrementalExecutor::executeFunction: symbol '{{.*}}foo{{.*}}' unresolved while linking function
bar();
// CHECK: IncrementalExecutor: calling unresolved symbol, see previous error message!

i = 13 //CHECK: (int) 13
.q
<|endoftext|>


<commit_before>#include <iostream>
#include <cstdlib>
#include <locale>
#include "commandline_options.hpp"

namespace kp19pp{
    commandline_options_type::commandline_options_type() :
        ifile_path_(), ofile_path_(), language_(language_cpp), indent_(indent_space4)
    {}

    namespace{
        std::string str_to_upper(const char *str){
            std::locale l;
            std::string ret;
            for(std::size_t i = 0; str[i]; ++i){
                ret += std::toupper(str[i], l);
            }
            return ret;
        }
    }

    bool commandline_options_type::get(int argc, const char **argv){
        int state = 0;
        for(int index = 1; index < argc; ++index){
            if(argv[index][0] == '-'){
                std::string str = str_to_upper(argv[index]);
                if(
                    str == "-C++" ||
                    str == "-CPP"
                ){
                    language_ = language_cpp;
                    continue;
                }
                if(
                    str == "-C#" ||
                    str == "-CS" ||
                    str == "-CSHARP"
                ){
                    language_ = language_csharp;
                    continue;
                }
                if(str == "-D"){
                    language_ = language_d;
                    continue;
                }
                if(str == "-JAVA"){
                    language_ = language_java;
                }
                if(
                    str == "-JS" ||
                    str == "-JAVASCRIPT"
                ){
                    language_ = language_javascript;
                    continue;
                }
                if(str == "-INDENT=SPACE"){
                    indent_ = indent_space;
                    continue;
                }
                if(str == "-INDENT=SPACE4"){
                    indent_ = indent_space4;
                    continue;
                }
                if(str == "-INDENT=SPACE8"){
                    indent_ = indent_space8;
                    continue;
                }
                if(str == "-INDENT=TAB"){
                    indent_ = indent_tab;
                    continue;
                }
                std::cerr << "unknown options" << argv[index] << "\n";
                return false;
            }
            switch(state){
            case 0: ifile_path_ = argv[index]; ++state; break;
            case 1: ofile_path_ = argv[index]; ++state; break;
            default:
                std::cerr << "too many arguments\n";
                return false;
            }
        }
        if(state < 2){
            std::cout << "kp19pp usage: kp19pp [ -c++ | -cs | -d | -java | -javascript | -indent=space | -indent=tab ] ifile_name ofile_name\n";
            return false;
        }
        return true;
    }

    const std::string &commandline_options_type::ifile_path() const{
        return ifile_path_;
    }

    std::string commandline_options_type::ifile_name() const{
        std::string ret;
        for(std::size_t i = 0, length = ifile_path_.length(); i < length; ++i){
            char c = ifile_path_[length - i - 1];
            if(c == '/' || c == '\\'){ break; }
            ret += c;
        }
        return ret;
    }

    const std::string &commandline_options_type::ofile_path() const{
        return ofile_path_;
    }

    commandline_options_type::language_enum commandline_options_type::language() const{
        return language_;
    }

    commandline_options_type::indent_enum commandline_options_type::indent() const{
        return indent_;
    }
}
<commit_msg>2012/04/09<commit_after>#include <iostream>
#include <algorithm>
#include <locale>
#include <cstdlib>
#include "commandline_options.hpp"

namespace kp19pp{
    commandline_options_type::commandline_options_type() :
        ifile_path_(), ofile_path_(), language_(language_cpp), indent_(indent_space4)
    {}

    namespace{
        std::string str_to_upper(const char *str){
            std::locale l;
            std::string ret;
            for(std::size_t i = 0; str[i]; ++i){
                ret += std::toupper(str[i], l);
            }
            return ret;
        }
    }

    bool commandline_options_type::get(int argc, const char **argv){
        int state = 0;
        for(int index = 1; index < argc; ++index){
            if(argv[index][0] == '-'){
                std::string str = str_to_upper(argv[index]);
                if(
                    str == "-C++" ||
                    str == "-CPP"
                ){
                    language_ = language_cpp;
                    continue;
                }
                if(
                    str == "-C#" ||
                    str == "-CS" ||
                    str == "-CSHARP"
                ){
                    language_ = language_csharp;
                    continue;
                }
                if(str == "-D"){
                    language_ = language_d;
                    continue;
                }
                if(str == "-JAVA"){
                    language_ = language_java;
                }
                if(
                    str == "-JS" ||
                    str == "-JAVASCRIPT"
                ){
                    language_ = language_javascript;
                    continue;
                }
                if(str == "-INDENT=SPACE"){
                    indent_ = indent_space;
                    continue;
                }
                if(str == "-INDENT=SPACE4"){
                    indent_ = indent_space4;
                    continue;
                }
                if(str == "-INDENT=SPACE8"){
                    indent_ = indent_space8;
                    continue;
                }
                if(str == "-INDENT=TAB"){
                    indent_ = indent_tab;
                    continue;
                }
                std::cerr << "unknown options" << argv[index] << "\n";
                return false;
            }
            switch(state){
            case 0: ifile_path_ = argv[index]; ++state; break;
            case 1: ofile_path_ = argv[index]; ++state; break;
            default:
                std::cerr << "too many arguments\n";
                return false;
            }
        }
        if(state < 2){
            std::cout << "kp19pp usage: kp19pp [ -c++ | -cs | -d | -java | -javascript | -indent=space | -indent=tab ] ifile_name ofile_name\n";
            return false;
        }
        return true;
    }

    const std::string &commandline_options_type::ifile_path() const{
        return ifile_path_;
    }

    std::string commandline_options_type::ifile_name() const{
        std::string ret;
        for(std::size_t i = 0, length = ifile_path_.length(); i < length; ++i){
            char c = ifile_path_[length - i - 1];
            if(c == '/' || c == '\\'){ break; }
            ret += c;
        }
        std::reverse(ret.begin(), ret.end());
        return ret;
    }

    const std::string &commandline_options_type::ofile_path() const{
        return ofile_path_;
    }

    commandline_options_type::language_enum commandline_options_type::language() const{
        return language_;
    }

    commandline_options_type::indent_enum commandline_options_type::indent() const{
        return indent_;
    }
}
<|endoftext|>


<commit_before>#include <iostream>

#include "CodeGen_Posix.h"
#include "CodeGen_Internal.h"
#include "LLVM_Headers.h"
#include "IR.h"
#include "IROperator.h"
#include "Debug.h"
#include "IRPrinter.h"
#include "Simplify.h"

namespace Halide {
namespace Internal {

using std::vector;
using std::string;
using std::map;
using std::pair;
using std::make_pair;

using namespace llvm;

CodeGen_Posix::CodeGen_Posix(Target t) :
  CodeGen_LLVM(t) {
}

Value *CodeGen_Posix::codegen_allocation_size(const std::string &name, Type type, const std::vector<Expr> &extents) {
    // Compute size from list of extents checking for 32-bit signed overflow.
    // Math is done using 64-bit intergers as overflow checked 32-bit mutliply
    // does not work with NaCl at the moment.

    Expr no_overflow = const_true(1);
    Expr total_size = Expr((int64_t)(type.lanes() * type.bytes()));
    Expr max_size = cast<int64_t>(0x7fffffff);
    for (size_t i = 0; i < extents.size(); i++) {
        total_size *= extents[i];
        no_overflow = no_overflow && (total_size <= max_size);
    }

    // For constant-sized allocations this check should simplify away.
    no_overflow = simplify(no_overflow);
    if (!is_one(no_overflow)) {
        create_assertion(codegen(no_overflow),
                         Call::make(Int(32), "halide_error_buffer_allocation_too_large",
                                    {name, total_size, max_size}, Call::Extern));
    }

    total_size = simplify(cast<int32_t>(total_size));
    return codegen(total_size);
}

CodeGen_Posix::Allocation CodeGen_Posix::create_allocation(const std::string &name, Type type,
                                                           const std::vector<Expr> &extents, Expr condition,
                                                           Expr new_expr, std::string free_function) {
    Value *llvm_size = NULL;
    int64_t stack_bytes = 0;
    int32_t constant_bytes = 0;
    if (constant_allocation_size(extents, name, constant_bytes)) {
        constant_bytes *= type.bytes();
        stack_bytes = constant_bytes;

        if (stack_bytes > ((int64_t(1) << 31) - 1)) {
            user_error << "Total size for allocation " << name << " is constant but exceeds 2^31 - 1.";
        } else if (stack_bytes > 1024 * 16) {
            stack_bytes = 0;
            llvm_size = codegen(Expr(constant_bytes));
        }
    } else {
        llvm_size = codegen_allocation_size(name, type, extents);
    }

    // Only allocate memory if the condition is true, otherwise 0.
    if (llvm_size != NULL) {
        // We potentially load one scalar value past the end of the
        // buffer, so pad the allocation with an extra instance of the
        // scalar type. If the allocation is on the stack, we can just
        // read one past the top of the stack, so we only need this
        // for heap allocations.
        llvm_size = builder->CreateAdd(llvm_size,
                                       ConstantInt::get(llvm_size->getType(), type.bytes()));

        Value *llvm_condition = codegen(condition);
        llvm_size = builder->CreateSelect(llvm_condition,
                                          llvm_size,
                                          ConstantInt::get(llvm_size->getType(), 0));
    }

    Allocation allocation;
    allocation.constant_bytes = constant_bytes;
    allocation.stack_bytes = new_expr.defined() ? 0 : stack_bytes;
    allocation.type = type;
    allocation.ptr = NULL;
    allocation.destructor = NULL;
    allocation.destructor_function = NULL;

    if (!new_expr.defined() && stack_bytes != 0) {
        // Try to find a free stack allocation we can use.
        vector<Allocation>::iterator free = free_stack_allocs.end();
        for (free = free_stack_allocs.begin(); free != free_stack_allocs.end(); ++free) {
            AllocaInst *alloca_inst = dyn_cast<AllocaInst>(free->ptr);
            llvm::Function *allocated_in = alloca_inst ? alloca_inst->getParent()->getParent() : NULL;
            llvm::Function *current_func = builder->GetInsertBlock()->getParent();

            if (allocated_in == current_func &&
                free->type == type &&
                free->stack_bytes >= stack_bytes) {
                break;
            }
        }
        if (free != free_stack_allocs.end()) {
            debug(4) << "Reusing freed stack allocation of " << free->stack_bytes
                     << " bytes for allocation " << name
                     << " of " << stack_bytes << " bytes.\n";
            // Use a free alloc we found.
            allocation.ptr = free->ptr;
            allocation.stack_bytes = free->stack_bytes;

            // This allocation isn't free anymore.
            free_stack_allocs.erase(free);
        } else {
            debug(4) << "Allocating " << stack_bytes << " bytes on the stack for " << name << "\n";
            // We used to do the alloca locally and save and restore the
            // stack pointer, but this makes llvm generate streams of
            // spill/reloads.
            int64_t stack_size = (stack_bytes + type.bytes() - 1) / type.bytes();
            allocation.ptr = create_alloca_at_entry(llvm_type_of(type), stack_size, false, name);
            allocation.stack_bytes = stack_bytes;
        }
    } else {
        if (new_expr.defined()) {
            allocation.ptr = codegen(new_expr);
        } else {
            // call malloc
            llvm::Function *malloc_fn = module->getFunction("halide_malloc");
            internal_assert(malloc_fn) << "Could not find halide_malloc in module\n";
            malloc_fn->setDoesNotAlias(0);

            llvm::Function::arg_iterator arg_iter = malloc_fn->arg_begin();
            ++arg_iter;  // skip the user context *
            llvm_size = builder->CreateIntCast(llvm_size, arg_iter->getType(), false);

            debug(4) << "Creating call to halide_malloc for allocation " << name
                     << " of size " << type.bytes();
            for (Expr e : extents) {
                debug(4) << " x " << e;
            }
            debug(4) << "\n";
            Value *args[2] = { get_user_context(), llvm_size };

            CallInst *call = builder->CreateCall(malloc_fn, args);
            allocation.ptr = call;
        }

        // Assert that the allocation worked.
        Value *check = builder->CreateIsNotNull(allocation.ptr);
        if (!new_expr.defined()) { // Zero sized allocation if allowed for custom new...
            Value *zero_size = builder->CreateIsNull(llvm_size);
            check = builder->CreateOr(check, zero_size);
        }

        create_assertion(check, Call::make(Int(32), "halide_error_out_of_memory",
                                           std::vector<Expr>(), Call::Extern));

        // Register a destructor for this allocation.
        if (free_function.empty()) {
            free_function = "halide_free";
        }
        llvm::Function *free_fn = module->getFunction(free_function);
        internal_assert(free_fn) << "Could not find " << free_function << " in module.\n";
        allocation.destructor = register_destructor(free_fn, allocation.ptr, OnError);
        allocation.destructor_function = free_fn;
    }

    // Push the allocation base pointer onto the symbol table
    debug(3) << "Pushing allocation called " << name << ".host onto the symbol table\n";

    allocations.push(name, allocation);

    return allocation;
}

void CodeGen_Posix::visit(const Allocate *alloc) {
    if (sym_exists(alloc->name + ".host")) {
        user_error << "Can't have two different buffers with the same name: "
                   << alloc->name << "\n";
    }

    Allocation allocation = create_allocation(alloc->name, alloc->type,
                                              alloc->extents, alloc->condition,
                                              alloc->new_expr, alloc->free_function);
    sym_push(alloc->name + ".host", allocation.ptr);

    codegen(alloc->body);

    // Should have been freed
    internal_assert(!sym_exists(alloc->name + ".host"));
    internal_assert(!allocations.contains(alloc->name));
}

void CodeGen_Posix::visit(const Free *stmt) {
    Allocation alloc = allocations.get(stmt->name);

    if (alloc.stack_bytes) {
        // Remember this allocation so it can be re-used by a later allocation.
        free_stack_allocs.push_back(alloc);
    } else {
        internal_assert(alloc.destructor);
        trigger_destructor(alloc.destructor_function, alloc.destructor);
    }

    allocations.pop(stmt->name);
    sym_pop(stmt->name + ".host");
}

}}
<commit_msg>Fix stack-stomping on 32-bit platforms<commit_after>#include <iostream>

#include "CodeGen_Posix.h"
#include "CodeGen_Internal.h"
#include "LLVM_Headers.h"
#include "IR.h"
#include "IROperator.h"
#include "Debug.h"
#include "IRPrinter.h"
#include "Simplify.h"

namespace Halide {
namespace Internal {

using std::vector;
using std::string;
using std::map;
using std::pair;
using std::make_pair;

using namespace llvm;

CodeGen_Posix::CodeGen_Posix(Target t) :
  CodeGen_LLVM(t) {
}

Value *CodeGen_Posix::codegen_allocation_size(const std::string &name, Type type, const std::vector<Expr> &extents) {
    // Compute size from list of extents checking for 32-bit signed overflow.
    // Math is done using 64-bit intergers as overflow checked 32-bit mutliply
    // does not work with NaCl at the moment.

    Expr no_overflow = const_true(1);
    Expr total_size = Expr((int64_t)(type.lanes() * type.bytes()));
    Expr max_size = cast<int64_t>(0x7fffffff);
    for (size_t i = 0; i < extents.size(); i++) {
        total_size *= extents[i];
        no_overflow = no_overflow && (total_size <= max_size);
    }

    // For constant-sized allocations this check should simplify away.
    no_overflow = simplify(no_overflow);
    if (!is_one(no_overflow)) {
        create_assertion(codegen(no_overflow),
                         Call::make(Int(32), "halide_error_buffer_allocation_too_large",
                                    {name, total_size, max_size}, Call::Extern));
    }

    total_size = simplify(cast<int32_t>(total_size));
    return codegen(total_size);
}

CodeGen_Posix::Allocation CodeGen_Posix::create_allocation(const std::string &name, Type type,
                                                           const std::vector<Expr> &extents, Expr condition,
                                                           Expr new_expr, std::string free_function) {
    Value *llvm_size = NULL;
    int64_t stack_bytes = 0;
    int32_t constant_bytes = 0;
    if (constant_allocation_size(extents, name, constant_bytes)) {
        constant_bytes *= type.bytes();
        stack_bytes = constant_bytes;

        if (stack_bytes > ((int64_t(1) << 31) - 1)) {
            user_error << "Total size for allocation " << name << " is constant but exceeds 2^31 - 1.";
        } else if (stack_bytes > 1024 * 16) {
            stack_bytes = 0;
            llvm_size = codegen(Expr(constant_bytes));
        }
    } else {
        llvm_size = codegen_allocation_size(name, type, extents);
    }

    // Only allocate memory if the condition is true, otherwise 0.
    if (llvm_size != NULL) {
        // We potentially load one scalar value past the end of the
        // buffer, so pad the allocation with an extra instance of the
        // scalar type. If the allocation is on the stack, we can just
        // read one past the top of the stack, so we only need this
        // for heap allocations.
        llvm_size = builder->CreateAdd(llvm_size,
                                       ConstantInt::get(llvm_size->getType(), type.bytes()));

        Value *llvm_condition = codegen(condition);
        llvm_size = builder->CreateSelect(llvm_condition,
                                          llvm_size,
                                          ConstantInt::get(llvm_size->getType(), 0));
    }

    Allocation allocation;
    allocation.constant_bytes = constant_bytes;
    allocation.stack_bytes = new_expr.defined() ? 0 : stack_bytes;
    allocation.type = type;
    allocation.ptr = NULL;
    allocation.destructor = NULL;
    allocation.destructor_function = NULL;

    if (!new_expr.defined() && stack_bytes != 0) {
        // Try to find a free stack allocation we can use.
        vector<Allocation>::iterator free = free_stack_allocs.end();
        for (free = free_stack_allocs.begin(); free != free_stack_allocs.end(); ++free) {
            AllocaInst *alloca_inst = dyn_cast<AllocaInst>(free->ptr);
            llvm::Function *allocated_in = alloca_inst ? alloca_inst->getParent()->getParent() : NULL;
            llvm::Function *current_func = builder->GetInsertBlock()->getParent();

            if (allocated_in == current_func &&
                free->type == type &&
                free->stack_bytes >= stack_bytes) {
                break;
            }
        }
        if (free != free_stack_allocs.end()) {
            debug(4) << "Reusing freed stack allocation of " << free->stack_bytes
                     << " bytes for allocation " << name
                     << " of " << stack_bytes << " bytes.\n";
            // Use a free alloc we found.
            allocation.ptr = free->ptr;
            allocation.stack_bytes = free->stack_bytes;

            // This allocation isn't free anymore.
            free_stack_allocs.erase(free);
        } else {
            debug(4) << "Allocating " << stack_bytes << " bytes on the stack for " << name << "\n";
            // We used to do the alloca locally and save and restore the
            // stack pointer, but this makes llvm generate streams of
            // spill/reloads.
            int64_t stack_size = (stack_bytes + type.bytes() - 1) / type.bytes();
            // Handles are stored as uint64s
            llvm::Type *t = llvm_type_of(type.is_handle() ? UInt(64, type.lanes()) : type);
            allocation.ptr = create_alloca_at_entry(t, stack_size, false, name);
            allocation.stack_bytes = stack_bytes;
        }
    } else {
        if (new_expr.defined()) {
            allocation.ptr = codegen(new_expr);
        } else {
            // call malloc
            llvm::Function *malloc_fn = module->getFunction("halide_malloc");
            internal_assert(malloc_fn) << "Could not find halide_malloc in module\n";
            malloc_fn->setDoesNotAlias(0);

            llvm::Function::arg_iterator arg_iter = malloc_fn->arg_begin();
            ++arg_iter;  // skip the user context *
            llvm_size = builder->CreateIntCast(llvm_size, arg_iter->getType(), false);

            debug(4) << "Creating call to halide_malloc for allocation " << name
                     << " of size " << type.bytes();
            for (Expr e : extents) {
                debug(4) << " x " << e;
            }
            debug(4) << "\n";
            Value *args[2] = { get_user_context(), llvm_size };

            CallInst *call = builder->CreateCall(malloc_fn, args);
            allocation.ptr = call;
        }

        // Assert that the allocation worked.
        Value *check = builder->CreateIsNotNull(allocation.ptr);
        if (!new_expr.defined()) { // Zero sized allocation if allowed for custom new...
            Value *zero_size = builder->CreateIsNull(llvm_size);
            check = builder->CreateOr(check, zero_size);
        }

        create_assertion(check, Call::make(Int(32), "halide_error_out_of_memory",
                                           std::vector<Expr>(), Call::Extern));

        // Register a destructor for this allocation.
        if (free_function.empty()) {
            free_function = "halide_free";
        }
        llvm::Function *free_fn = module->getFunction(free_function);
        internal_assert(free_fn) << "Could not find " << free_function << " in module.\n";
        allocation.destructor = register_destructor(free_fn, allocation.ptr, OnError);
        allocation.destructor_function = free_fn;
    }

    // Push the allocation base pointer onto the symbol table
    debug(3) << "Pushing allocation called " << name << ".host onto the symbol table\n";

    allocations.push(name, allocation);

    return allocation;
}

void CodeGen_Posix::visit(const Allocate *alloc) {
    if (sym_exists(alloc->name + ".host")) {
        user_error << "Can't have two different buffers with the same name: "
                   << alloc->name << "\n";
    }

    Allocation allocation = create_allocation(alloc->name, alloc->type,
                                              alloc->extents, alloc->condition,
                                              alloc->new_expr, alloc->free_function);
    sym_push(alloc->name + ".host", allocation.ptr);

    codegen(alloc->body);

    // Should have been freed
    internal_assert(!sym_exists(alloc->name + ".host"));
    internal_assert(!allocations.contains(alloc->name));
}

void CodeGen_Posix::visit(const Free *stmt) {
    Allocation alloc = allocations.get(stmt->name);

    if (alloc.stack_bytes) {
        // Remember this allocation so it can be re-used by a later allocation.
        free_stack_allocs.push_back(alloc);
    } else {
        internal_assert(alloc.destructor);
        trigger_destructor(alloc.destructor_function, alloc.destructor);
    }

    allocations.pop(stmt->name);
    sym_pop(stmt->name + ".host");
}

}}
<|endoftext|>


<commit_before>/// \file ROOT/TDisplayItem.h
/// \ingroup Base ROOT7
/// \author Sergey Linev
/// \date 2017-05-31
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_TPadDisplayItem
#define ROOT7_TPadDisplayItem

#include <ROOT/TDisplayItem.hxx>

#include <ROOT/TFrame.hxx>

#include <ROOT/TPad.hxx>

namespace ROOT {
namespace Experimental {

// list of snapshot for primitives in pad

using TDisplayItemsVector = std::vector<std::unique_ptr<TDisplayItem>>;

/// Display item for the pad
/// Includes different graphical properties of the pad itself plus
/// list of created items for all primitives

class TPadDisplayItem : public TDisplayItem {
protected:
   const TFrame *fFrame{nullptr};   ///< temporary pointer on frame object
   const TPadDrawingOpts *fDrawOpts{nullptr}; ///< temporary pointer on pad drawing options
   const TPadExtent *fSize{nullptr};  ///< temporary pointer on pad size attributes
   TDisplayItemsVector fPrimitives; ///< display items for all primitives in the pad
public:
   TPadDisplayItem() = default;
   virtual ~TPadDisplayItem() {}
   void SetFrame(const TFrame *f) { fFrame = f; }
   void SetDrawOpts(const TPadDrawingOpts *opts) { fDrawOpts = opts; }
   void SetSize(const TPadExtent *sz) { fSize = sz; }
   TDisplayItemsVector &GetPrimitives() { return fPrimitives; }
   void Add(std::unique_ptr<TDisplayItem> &&item) { fPrimitives.push_back(std::move(item)); }
   void Clear()
   {
      fPrimitives.clear();
      fFrame = nullptr;
      fDrawOpts = nullptr;
      fSize = nullptr;
   }
};

} // Experimental
} // ROOT

#endif
<commit_msg>Make using directive a class member.<commit_after>/// \file ROOT/TDisplayItem.h
/// \ingroup Base ROOT7
/// \author Sergey Linev
/// \date 2017-05-31
/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
/// is welcome!

/*************************************************************************
 * Copyright (C) 1995-2017, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_TPadDisplayItem
#define ROOT7_TPadDisplayItem

#include <ROOT/TDisplayItem.hxx>

#include <ROOT/TFrame.hxx>

#include <ROOT/TPad.hxx>

namespace ROOT {
namespace Experimental {

/// Display item for the pad
/// Includes different graphical properties of the pad itself plus
/// list of created items for all primitives

class TPadDisplayItem : public TDisplayItem {
public:
   // list of snapshot for primitives in pad
   using PadPrimitives_t = std::vector<std::unique_ptr<TDisplayItem>>;

protected:
   const TFrame *fFrame{nullptr};   ///< temporary pointer on frame object
   const TPadDrawingOpts *fDrawOpts{nullptr}; ///< temporary pointer on pad drawing options
   const TPadExtent *fSize{nullptr};  ///< temporary pointer on pad size attributes
   PadPrimitives_t fPrimitives; ///< display items for all primitives in the pad
public:
   TPadDisplayItem() = default;
   virtual ~TPadDisplayItem() {}
   void SetFrame(const TFrame *f) { fFrame = f; }
   void SetDrawOpts(const TPadDrawingOpts *opts) { fDrawOpts = opts; }
   void SetSize(const TPadExtent *sz) { fSize = sz; }
   PadPrimitives_t &GetPrimitives() { return fPrimitives; }
   void Add(std::unique_ptr<TDisplayItem> &&item) { fPrimitives.push_back(std::move(item)); }
   void Clear()
   {
      fPrimitives.clear();
      fFrame = nullptr;
      fDrawOpts = nullptr;
      fSize = nullptr;
   }
};

} // Experimental
} // ROOT

#endif
<|endoftext|>


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

#include "xwalk/runtime/browser/xwalk_browser_main_parts.h"

#include <stdlib.h>

#include <set>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "cc/base/switches.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/result_codes.h"
#include "extensions/browser/extension_system.h"
#include "net/base/filename_util.h"
#include "ui/gl/gl_switches.h"
#include "xwalk/application/browser/application.h"
#include "xwalk/application/browser/application_system.h"
#include "xwalk/extensions/browser/xwalk_extension_service.h"
#include "xwalk/extensions/common/xwalk_extension_switches.h"
#include "xwalk/runtime/browser/runtime.h"
#include "xwalk/runtime/browser/runtime_context.h"
#include "xwalk/runtime/browser/xwalk_runner.h"
#include "xwalk/runtime/common/xwalk_runtime_features.h"
#include "xwalk/runtime/common/xwalk_switches.h"

#if !defined(DISABLE_NACL)
#include "components/nacl/browser/nacl_browser.h"
#include "components/nacl/browser/nacl_process_host.h"
#include "xwalk/runtime/browser/nacl_host/nacl_browser_delegate_impl.h"
#endif

#if defined(USE_AURA) && defined(USE_X11)
#include "ui/base/ime/input_method_initializer.h"
#include "ui/events/x/touch_factory_x11.h"
#endif

namespace {

// FIXME: Compare with method in startup_browser_creator.cc.
GURL GetURLFromCommandLine(const CommandLine& command_line) {
  const CommandLine::StringVector& args = command_line.GetArgs();

  if (args.empty())
    return GURL();

  GURL url(args[0]);
  if (url.is_valid() && url.has_scheme())
    return url;

  base::FilePath path(args[0]);
  if (!path.IsAbsolute())
    path = MakeAbsoluteFilePath(path);

  return net::FilePathToFileURL(path);
}

}  // namespace

namespace xswitches {
// Redefine settings not exposed by content module.
const char kEnableOverlayScrollbars[] = "enable-overlay-scrollbars";
}

namespace xwalk {

XWalkBrowserMainParts::XWalkBrowserMainParts(
    const content::MainFunctionParams& parameters)
    : xwalk_runner_(XWalkRunner::GetInstance()),
      startup_url_(url::kAboutBlankURL),
      parameters_(parameters),
      run_default_message_loop_(true) {
#if defined(OS_LINUX)
  // FIXME: We disable the setuid sandbox on Linux because we don't ship
  // the setuid binary. It is important to remember that the seccomp-bpf
  // sandbox is still fully operational if supported by the kernel. See
  // issue #496.
  //
  // switches::kDisableSetuidSandbox is not being used here because it
  // doesn't have the CONTENT_EXPORT macro despite the fact it is exposed by
  // content_switches.h.
  CommandLine::ForCurrentProcess()->AppendSwitch("disable-setuid-sandbox");
#endif
}

XWalkBrowserMainParts::~XWalkBrowserMainParts() {
}

void XWalkBrowserMainParts::PreMainMessageLoopStart() {
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  command_line->AppendSwitch(switches::kEnableViewport);
  command_line->AppendSwitch(switches::kEnableViewportMeta);

  command_line->AppendSwitch(xswitches::kEnableOverlayScrollbars);

  // Enable multithreaded GPU compositing of web content.
  // This also enables pinch on Tizen.
  command_line->AppendSwitch(switches::kEnableThreadedCompositing);

  // FIXME: Add comment why this is needed on Android and Tizen.
  command_line->AppendSwitch(switches::kAllowFileAccessFromFiles);

  // Enable SIMD.JS API by default.
  /*
  std::string js_flags("--simd_object");
  if (command_line->HasSwitch(switches::kJavaScriptFlags)) {
    js_flags += " ";
    js_flags +=
        command_line->GetSwitchValueASCII(switches::kJavaScriptFlags);
  }
  command_line->AppendSwitchASCII(switches::kJavaScriptFlags, js_flags);
  */

  startup_url_ = GetURLFromCommandLine(*command_line);
}

void XWalkBrowserMainParts::PostMainMessageLoopStart() {
}

void XWalkBrowserMainParts::PreEarlyInitialization() {
#if defined(USE_AURA) && defined(USE_X11)
    ui::InitializeInputMethodForTesting();
#endif
}

int XWalkBrowserMainParts::PreCreateThreads() {
  return content::RESULT_CODE_NORMAL_EXIT;
}

void XWalkBrowserMainParts::RegisterExternalExtensions() {
  CommandLine* cmd_line = CommandLine::ForCurrentProcess();

#if defined(OS_TIZEN)
  std::string value = cmd_line->GetSwitchValueASCII(
      switches::kXWalkExternalExtensionsPath);

#if defined(ARCH_CPU_64_BITS)
  const char tec_path[] = "/usr/lib64/tizen-extensions-crosswalk";
#else
  const char tec_path[] = "/usr/lib/tizen-extensions-crosswalk";
#endif

  if (value.empty())
    cmd_line->AppendSwitchASCII(switches::kXWalkExternalExtensionsPath,
        tec_path);
  else if (value != tec_path)
    VLOG(0) << "Loading Tizen extensions from " << value << " rather than " <<
        tec_path;

  cmd_line->AppendSwitch(
        switches::kXWalkAllowExternalExtensionsForRemoteSources);
#else
  if (!cmd_line->HasSwitch(switches::kXWalkExternalExtensionsPath))
    return;
#endif

  if (!cmd_line->HasSwitch(
          switches::kXWalkAllowExternalExtensionsForRemoteSources) &&
      (!startup_url_.is_empty() && !startup_url_.SchemeIsFile())) {
    VLOG(0) << "Unsupported scheme for external extensions: " <<
          startup_url_.scheme();
    return;
  }

  base::FilePath extensions_dir =
      cmd_line->GetSwitchValuePath(switches::kXWalkExternalExtensionsPath);
  if (!base::DirectoryExists(extensions_dir)) {
    LOG(WARNING) << "Ignoring non-existent extension directory: "
                 << extensions_dir.AsUTF8Unsafe();
    return;
  }

  extension_service_->RegisterExternalExtensionsForPath(extensions_dir);
}

void XWalkBrowserMainParts::PreMainMessageLoopRun() {
  xwalk_runner_->PreMainMessageLoopRun();

  extension_service_ = xwalk_runner_->extension_service();

  if (extension_service_)
    RegisterExternalExtensions();

#if !defined(DISABLE_NACL)
  NaClBrowserDelegateImpl* delegate = new NaClBrowserDelegateImpl();
  nacl::NaClBrowser::SetDelegate(delegate);

  content::BrowserThread::PostTask(
      content::BrowserThread::IO,
      FROM_HERE,
      base::Bind(nacl::NaClProcessHost::EarlyStartup));
#endif

  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kRemoteDebuggingPort)) {
    std::string port_str =
        command_line->GetSwitchValueASCII(switches::kRemoteDebuggingPort);
    int port;
    base::StringToInt(port_str, &port);
    xwalk_runner_->EnableRemoteDebugging(port);
  }

  NativeAppWindow::Initialize();

  if (command_line->HasSwitch(switches::kListFeaturesFlags)) {
    XWalkRuntimeFeatures::GetInstance()->DumpFeaturesFlags();
    run_default_message_loop_ = false;
    return;
  }

#if !defined(SHARED_PROCESS_MODE)
  application::ApplicationSystem* app_system = xwalk_runner_->app_system();
  app_system->LaunchFromCommandLine(*command_line, startup_url_,
                                    run_default_message_loop_);
  // If the |ui_task| is specified in main function parameter, it indicates
  // that we will run this UI task instead of running the the default main
  // message loop. See |content::BrowserTestBase::SetUp| for |ui_task| usage
  // case.
  if (parameters_.ui_task) {
    parameters_.ui_task->Run();
    delete parameters_.ui_task;
    run_default_message_loop_ = false;
  }
#endif
}

bool XWalkBrowserMainParts::MainMessageLoopRun(int* result_code) {
  return !run_default_message_loop_;
}

void XWalkBrowserMainParts::PostMainMessageLoopRun() {
  xwalk_runner_->PostMainMessageLoopRun();
}

void XWalkBrowserMainParts::CreateInternalExtensionsForUIThread(
    content::RenderProcessHost* host,
    extensions::XWalkExtensionVector* extensions) {
}

void XWalkBrowserMainParts::CreateInternalExtensionsForExtensionThread(
    content::RenderProcessHost* host,
    extensions::XWalkExtensionVector* extensions) {
}

}  // namespace xwalk
<commit_msg>Reenable --simd-object after M38 rebasing.<commit_after>// Copyright (c) 2013 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "xwalk/runtime/browser/xwalk_browser_main_parts.h"

#include <stdlib.h>

#include <set>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_number_conversions.h"
#include "cc/base/switches.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/result_codes.h"
#include "extensions/browser/extension_system.h"
#include "net/base/filename_util.h"
#include "ui/gl/gl_switches.h"
#include "xwalk/application/browser/application.h"
#include "xwalk/application/browser/application_system.h"
#include "xwalk/extensions/browser/xwalk_extension_service.h"
#include "xwalk/extensions/common/xwalk_extension_switches.h"
#include "xwalk/runtime/browser/runtime.h"
#include "xwalk/runtime/browser/runtime_context.h"
#include "xwalk/runtime/browser/xwalk_runner.h"
#include "xwalk/runtime/common/xwalk_runtime_features.h"
#include "xwalk/runtime/common/xwalk_switches.h"

#if !defined(DISABLE_NACL)
#include "components/nacl/browser/nacl_browser.h"
#include "components/nacl/browser/nacl_process_host.h"
#include "xwalk/runtime/browser/nacl_host/nacl_browser_delegate_impl.h"
#endif

#if defined(USE_AURA) && defined(USE_X11)
#include "ui/base/ime/input_method_initializer.h"
#include "ui/events/x/touch_factory_x11.h"
#endif

namespace {

// FIXME: Compare with method in startup_browser_creator.cc.
GURL GetURLFromCommandLine(const CommandLine& command_line) {
  const CommandLine::StringVector& args = command_line.GetArgs();

  if (args.empty())
    return GURL();

  GURL url(args[0]);
  if (url.is_valid() && url.has_scheme())
    return url;

  base::FilePath path(args[0]);
  if (!path.IsAbsolute())
    path = MakeAbsoluteFilePath(path);

  return net::FilePathToFileURL(path);
}

}  // namespace

namespace xswitches {
// Redefine settings not exposed by content module.
const char kEnableOverlayScrollbars[] = "enable-overlay-scrollbars";
}

namespace xwalk {

XWalkBrowserMainParts::XWalkBrowserMainParts(
    const content::MainFunctionParams& parameters)
    : xwalk_runner_(XWalkRunner::GetInstance()),
      startup_url_(url::kAboutBlankURL),
      parameters_(parameters),
      run_default_message_loop_(true) {
#if defined(OS_LINUX)
  // FIXME: We disable the setuid sandbox on Linux because we don't ship
  // the setuid binary. It is important to remember that the seccomp-bpf
  // sandbox is still fully operational if supported by the kernel. See
  // issue #496.
  //
  // switches::kDisableSetuidSandbox is not being used here because it
  // doesn't have the CONTENT_EXPORT macro despite the fact it is exposed by
  // content_switches.h.
  CommandLine::ForCurrentProcess()->AppendSwitch("disable-setuid-sandbox");
#endif
}

XWalkBrowserMainParts::~XWalkBrowserMainParts() {
}

void XWalkBrowserMainParts::PreMainMessageLoopStart() {
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  command_line->AppendSwitch(switches::kEnableViewport);
  command_line->AppendSwitch(switches::kEnableViewportMeta);

  command_line->AppendSwitch(xswitches::kEnableOverlayScrollbars);

  // Enable multithreaded GPU compositing of web content.
  // This also enables pinch on Tizen.
  command_line->AppendSwitch(switches::kEnableThreadedCompositing);

  // FIXME: Add comment why this is needed on Android and Tizen.
  command_line->AppendSwitch(switches::kAllowFileAccessFromFiles);

  // Enable SIMD.JS API by default.
  std::string js_flags("--simd_object");
  if (command_line->HasSwitch(switches::kJavaScriptFlags)) {
    js_flags += " ";
    js_flags +=
        command_line->GetSwitchValueASCII(switches::kJavaScriptFlags);
  }
  command_line->AppendSwitchASCII(switches::kJavaScriptFlags, js_flags);

  startup_url_ = GetURLFromCommandLine(*command_line);
}

void XWalkBrowserMainParts::PostMainMessageLoopStart() {
}

void XWalkBrowserMainParts::PreEarlyInitialization() {
#if defined(USE_AURA) && defined(USE_X11)
    ui::InitializeInputMethodForTesting();
#endif
}

int XWalkBrowserMainParts::PreCreateThreads() {
  return content::RESULT_CODE_NORMAL_EXIT;
}

void XWalkBrowserMainParts::RegisterExternalExtensions() {
  CommandLine* cmd_line = CommandLine::ForCurrentProcess();

#if defined(OS_TIZEN)
  std::string value = cmd_line->GetSwitchValueASCII(
      switches::kXWalkExternalExtensionsPath);

#if defined(ARCH_CPU_64_BITS)
  const char tec_path[] = "/usr/lib64/tizen-extensions-crosswalk";
#else
  const char tec_path[] = "/usr/lib/tizen-extensions-crosswalk";
#endif

  if (value.empty())
    cmd_line->AppendSwitchASCII(switches::kXWalkExternalExtensionsPath,
        tec_path);
  else if (value != tec_path)
    VLOG(0) << "Loading Tizen extensions from " << value << " rather than " <<
        tec_path;

  cmd_line->AppendSwitch(
        switches::kXWalkAllowExternalExtensionsForRemoteSources);
#else
  if (!cmd_line->HasSwitch(switches::kXWalkExternalExtensionsPath))
    return;
#endif

  if (!cmd_line->HasSwitch(
          switches::kXWalkAllowExternalExtensionsForRemoteSources) &&
      (!startup_url_.is_empty() && !startup_url_.SchemeIsFile())) {
    VLOG(0) << "Unsupported scheme for external extensions: " <<
          startup_url_.scheme();
    return;
  }

  base::FilePath extensions_dir =
      cmd_line->GetSwitchValuePath(switches::kXWalkExternalExtensionsPath);
  if (!base::DirectoryExists(extensions_dir)) {
    LOG(WARNING) << "Ignoring non-existent extension directory: "
                 << extensions_dir.AsUTF8Unsafe();
    return;
  }

  extension_service_->RegisterExternalExtensionsForPath(extensions_dir);
}

void XWalkBrowserMainParts::PreMainMessageLoopRun() {
  xwalk_runner_->PreMainMessageLoopRun();

  extension_service_ = xwalk_runner_->extension_service();

  if (extension_service_)
    RegisterExternalExtensions();

#if !defined(DISABLE_NACL)
  NaClBrowserDelegateImpl* delegate = new NaClBrowserDelegateImpl();
  nacl::NaClBrowser::SetDelegate(delegate);

  content::BrowserThread::PostTask(
      content::BrowserThread::IO,
      FROM_HERE,
      base::Bind(nacl::NaClProcessHost::EarlyStartup));
#endif

  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kRemoteDebuggingPort)) {
    std::string port_str =
        command_line->GetSwitchValueASCII(switches::kRemoteDebuggingPort);
    int port;
    base::StringToInt(port_str, &port);
    xwalk_runner_->EnableRemoteDebugging(port);
  }

  NativeAppWindow::Initialize();

  if (command_line->HasSwitch(switches::kListFeaturesFlags)) {
    XWalkRuntimeFeatures::GetInstance()->DumpFeaturesFlags();
    run_default_message_loop_ = false;
    return;
  }

#if !defined(SHARED_PROCESS_MODE)
  application::ApplicationSystem* app_system = xwalk_runner_->app_system();
  app_system->LaunchFromCommandLine(*command_line, startup_url_,
                                    run_default_message_loop_);
  // If the |ui_task| is specified in main function parameter, it indicates
  // that we will run this UI task instead of running the the default main
  // message loop. See |content::BrowserTestBase::SetUp| for |ui_task| usage
  // case.
  if (parameters_.ui_task) {
    parameters_.ui_task->Run();
    delete parameters_.ui_task;
    run_default_message_loop_ = false;
  }
#endif
}

bool XWalkBrowserMainParts::MainMessageLoopRun(int* result_code) {
  return !run_default_message_loop_;
}

void XWalkBrowserMainParts::PostMainMessageLoopRun() {
  xwalk_runner_->PostMainMessageLoopRun();
}

void XWalkBrowserMainParts::CreateInternalExtensionsForUIThread(
    content::RenderProcessHost* host,
    extensions::XWalkExtensionVector* extensions) {
}

void XWalkBrowserMainParts::CreateInternalExtensionsForExtensionThread(
    content::RenderProcessHost* host,
    extensions::XWalkExtensionVector* extensions) {
}

}  // namespace xwalk
<|endoftext|>


<commit_before>// RUN: %libomp-cxx-compile-and-run | %sort-threads | FileCheck %s
// REQUIRES: ompt

#include <iostream>
#include <thread>
#if !defined(__NetBSD__)
#include <alloca.h>
#else
#include <cstdlib>
#endif

#include "callback.h"
#include "omp.h"

int condition = 0;

void f() {
  // Call OpenMP API function to force initialization of OMPT.
  // (omp_get_thread_num() does not work because it just returns 0 if the
  // runtime isn't initialized yet...)
  omp_get_num_threads();

  // Call alloca() to force availability of frame pointer
  void *p = alloca(0);

  OMPT_SIGNAL(condition);
  // Wait for both initial threads to arrive that will eventually become the
  // master threads in the following parallel region.
  OMPT_WAIT(condition, 2);

#pragma omp parallel num_threads(2)
  {
    // Wait for all threads to arrive so that no worker thread can be reused...
    OMPT_SIGNAL(condition);
    OMPT_WAIT(condition, 6);
  }
}

int main() {
  std::thread t1(f);
  std::thread t2(f);
  t1.join();
  t2.join();
}

// Check if libomp supports the callbacks for this test.
// CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_task_create'
// CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_task_schedule'
// CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_parallel_begin'
// CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_parallel_end'
// CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_implicit_task'
// CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_thread_begin'

// CHECK: 0: NULL_POINTER=[[NULL:.*$]]

// first master thread
// CHECK: {{^}}[[MASTER_ID_1:[0-9]+]]: ompt_event_thread_begin:
// CHECK-SAME: thread_type=ompt_thread_initial=1, thread_id=[[MASTER_ID_1]]

// CHECK: {{^}}[[MASTER_ID_1]]: ompt_event_task_create: parent_task_id=0
// CHECK-SAME: parent_task_frame.exit=[[NULL]]
// CHECK-SAME: parent_task_frame.reenter=[[NULL]]
// CHECK-SAME: new_task_id=[[PARENT_TASK_ID_1:[0-9]+]]
// CHECK-SAME: codeptr_ra=[[NULL]], task_type=ompt_task_initial=1
// CHECK-SAME: has_dependences=no

// CHECK: {{^}}[[MASTER_ID_1]]: ompt_event_parallel_begin:
// CHECK-SAME: parent_task_id=[[PARENT_TASK_ID_1]]
// CHECK-SAME: parent_task_frame.exit=[[NULL]]
// CHECK-SAME: parent_task_frame.reenter={{0x[0-f]+}}
// CHECK-SAME: parallel_id=[[PARALLEL_ID_1:[0-9]+]], requested_team_size=2
// CHECK-SAME: codeptr_ra=0x{{[0-f]+}}, invoker={{.*}}

// CHECK: {{^}}[[MASTER_ID_1]]: ompt_event_parallel_end:
// CHECK-SAME: parallel_id=[[PARALLEL_ID_1]], task_id=[[PARENT_TASK_ID_1]]
// CHECK-SAME: invoker={{[0-9]+}}

// CHECK: {{^}}[[MASTER_ID_1]]: ompt_event_thread_end:
// CHECK-SAME: thread_id=[[MASTER_ID_1]]

// second master thread
// CHECK: {{^}}[[MASTER_ID_2:[0-9]+]]: ompt_event_thread_begin:
// CHECK-SAME: thread_type=ompt_thread_initial=1, thread_id=[[MASTER_ID_2]]

// CHECK: {{^}}[[MASTER_ID_2]]: ompt_event_task_create: parent_task_id=0
// CHECK-SAME: parent_task_frame.exit=[[NULL]]
// CHECK-SAME: parent_task_frame.reenter=[[NULL]]
// CHECK-SAME: new_task_id=[[PARENT_TASK_ID_2:[0-9]+]]
// CHECK-SAME: codeptr_ra=[[NULL]], task_type=ompt_task_initial=1
// CHECK-SAME: has_dependences=no

// CHECK: {{^}}[[MASTER_ID_2]]: ompt_event_parallel_begin:
// CHECK-SAME: parent_task_id=[[PARENT_TASK_ID_2]]
// CHECK-SAME: parent_task_frame.exit=[[NULL]]
// CHECK-SAME: parent_task_frame.reenter={{0x[0-f]+}}
// CHECK-SAME: parallel_id=[[PARALLEL_ID_2:[0-9]+]]
// CHECK-SAME: requested_team_size=2, codeptr_ra=0x{{[0-f]+}}
// CHECK-SAME: invoker={{.*}}

// CHECK: {{^}}[[MASTER_ID_2]]: ompt_event_parallel_end:
// CHECK-SAME: parallel_id=[[PARALLEL_ID_2]], task_id=[[PARENT_TASK_ID_2]]
// CHECK-SAME: invoker={{[0-9]+}}

// CHECK: {{^}}[[MASTER_ID_2]]: ompt_event_thread_end:
// CHECK-SAME: thread_id=[[MASTER_ID_2]]

// first worker thread
// CHECK: {{^}}[[THREAD_ID_1:[0-9]+]]: ompt_event_thread_begin:
// CHECK-SAME: thread_type=ompt_thread_worker=2, thread_id=[[THREAD_ID_1]]

// CHECK: {{^}}[[THREAD_ID_1]]: ompt_event_thread_end:
// CHECK-SAME: thread_id=[[THREAD_ID_1]]

// second worker thread
// CHECK: {{^}}[[THREAD_ID_2:[0-9]+]]: ompt_event_thread_begin:
// CHECK-SAME: thread_type=ompt_thread_worker=2, thread_id=[[THREAD_ID_2]]

// CHECK: {{^}}[[THREAD_ID_2]]: ompt_event_thread_end:
// CHECK-SAME: thread_id=[[THREAD_ID_2]]
<commit_msg>Fix interoperability test compilation on FreeBSD<commit_after>// RUN: %libomp-cxx-compile-and-run | %sort-threads | FileCheck %s
// REQUIRES: ompt

#include <iostream>
#include <thread>
#if !defined(__FreeBSD__) && !defined(__NetBSD__)
#include <alloca.h>
#else
#include <cstdlib>
#endif

#include "callback.h"
#include "omp.h"

int condition = 0;

void f() {
  // Call OpenMP API function to force initialization of OMPT.
  // (omp_get_thread_num() does not work because it just returns 0 if the
  // runtime isn't initialized yet...)
  omp_get_num_threads();

  // Call alloca() to force availability of frame pointer
  void *p = alloca(0);

  OMPT_SIGNAL(condition);
  // Wait for both initial threads to arrive that will eventually become the
  // master threads in the following parallel region.
  OMPT_WAIT(condition, 2);

#pragma omp parallel num_threads(2)
  {
    // Wait for all threads to arrive so that no worker thread can be reused...
    OMPT_SIGNAL(condition);
    OMPT_WAIT(condition, 6);
  }
}

int main() {
  std::thread t1(f);
  std::thread t2(f);
  t1.join();
  t2.join();
}

// Check if libomp supports the callbacks for this test.
// CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_task_create'
// CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_task_schedule'
// CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_parallel_begin'
// CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_parallel_end'
// CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_implicit_task'
// CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_thread_begin'

// CHECK: 0: NULL_POINTER=[[NULL:.*$]]

// first master thread
// CHECK: {{^}}[[MASTER_ID_1:[0-9]+]]: ompt_event_thread_begin:
// CHECK-SAME: thread_type=ompt_thread_initial=1, thread_id=[[MASTER_ID_1]]

// CHECK: {{^}}[[MASTER_ID_1]]: ompt_event_task_create: parent_task_id=0
// CHECK-SAME: parent_task_frame.exit=[[NULL]]
// CHECK-SAME: parent_task_frame.reenter=[[NULL]]
// CHECK-SAME: new_task_id=[[PARENT_TASK_ID_1:[0-9]+]]
// CHECK-SAME: codeptr_ra=[[NULL]], task_type=ompt_task_initial=1
// CHECK-SAME: has_dependences=no

// CHECK: {{^}}[[MASTER_ID_1]]: ompt_event_parallel_begin:
// CHECK-SAME: parent_task_id=[[PARENT_TASK_ID_1]]
// CHECK-SAME: parent_task_frame.exit=[[NULL]]
// CHECK-SAME: parent_task_frame.reenter={{0x[0-f]+}}
// CHECK-SAME: parallel_id=[[PARALLEL_ID_1:[0-9]+]], requested_team_size=2
// CHECK-SAME: codeptr_ra=0x{{[0-f]+}}, invoker={{.*}}

// CHECK: {{^}}[[MASTER_ID_1]]: ompt_event_parallel_end:
// CHECK-SAME: parallel_id=[[PARALLEL_ID_1]], task_id=[[PARENT_TASK_ID_1]]
// CHECK-SAME: invoker={{[0-9]+}}

// CHECK: {{^}}[[MASTER_ID_1]]: ompt_event_thread_end:
// CHECK-SAME: thread_id=[[MASTER_ID_1]]

// second master thread
// CHECK: {{^}}[[MASTER_ID_2:[0-9]+]]: ompt_event_thread_begin:
// CHECK-SAME: thread_type=ompt_thread_initial=1, thread_id=[[MASTER_ID_2]]

// CHECK: {{^}}[[MASTER_ID_2]]: ompt_event_task_create: parent_task_id=0
// CHECK-SAME: parent_task_frame.exit=[[NULL]]
// CHECK-SAME: parent_task_frame.reenter=[[NULL]]
// CHECK-SAME: new_task_id=[[PARENT_TASK_ID_2:[0-9]+]]
// CHECK-SAME: codeptr_ra=[[NULL]], task_type=ompt_task_initial=1
// CHECK-SAME: has_dependences=no

// CHECK: {{^}}[[MASTER_ID_2]]: ompt_event_parallel_begin:
// CHECK-SAME: parent_task_id=[[PARENT_TASK_ID_2]]
// CHECK-SAME: parent_task_frame.exit=[[NULL]]
// CHECK-SAME: parent_task_frame.reenter={{0x[0-f]+}}
// CHECK-SAME: parallel_id=[[PARALLEL_ID_2:[0-9]+]]
// CHECK-SAME: requested_team_size=2, codeptr_ra=0x{{[0-f]+}}
// CHECK-SAME: invoker={{.*}}

// CHECK: {{^}}[[MASTER_ID_2]]: ompt_event_parallel_end:
// CHECK-SAME: parallel_id=[[PARALLEL_ID_2]], task_id=[[PARENT_TASK_ID_2]]
// CHECK-SAME: invoker={{[0-9]+}}

// CHECK: {{^}}[[MASTER_ID_2]]: ompt_event_thread_end:
// CHECK-SAME: thread_id=[[MASTER_ID_2]]

// first worker thread
// CHECK: {{^}}[[THREAD_ID_1:[0-9]+]]: ompt_event_thread_begin:
// CHECK-SAME: thread_type=ompt_thread_worker=2, thread_id=[[THREAD_ID_1]]

// CHECK: {{^}}[[THREAD_ID_1]]: ompt_event_thread_end:
// CHECK-SAME: thread_id=[[THREAD_ID_1]]

// second worker thread
// CHECK: {{^}}[[THREAD_ID_2:[0-9]+]]: ompt_event_thread_begin:
// CHECK-SAME: thread_type=ompt_thread_worker=2, thread_id=[[THREAD_ID_2]]

// CHECK: {{^}}[[THREAD_ID_2]]: ompt_event_thread_end:
// CHECK-SAME: thread_id=[[THREAD_ID_2]]
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	固定サイズ文字列クラス @n
			Copyright 2017 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <algorithm>
#include <cstring>

namespace utils {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  固定サイズ文字列クラス
		@param[in]	SIZE	文字列サイズ
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <uint16_t SIZE>
	class fixed_string {
		char		text_[SIZE];
		uint16_t	pos_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクタ
		*/
		//-----------------------------------------------------------------//
		fixed_string() : pos_(0) { text_[0] = 0; }

		//-----------------------------------------------------------------//
		/*!
			@brief  最大サイズを返す
			@return 最大サイズ
		*/
		//-----------------------------------------------------------------//
		uint16_t max_size() const { return SIZE; }

		//-----------------------------------------------------------------//
		/*!
			@brief  現在のサイズを返す
			@return 現在のサイズ
		*/
		//-----------------------------------------------------------------//
		uint16_t size() const { return pos_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  文字列をクリア
		*/
		//-----------------------------------------------------------------//
		void clear() noexcept {
			pos_ = 0;
			text_[pos_] = 0;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  文字列を返す
			@return 文字列
		*/
		//-----------------------------------------------------------------//
		const char* c_str() const noexcept { return text_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  交換
			@param[in]	src	ソース
			@return 自分
		*/
		//-----------------------------------------------------------------//
		void swap(fixed_string& src) {
			std::swap(src.text_, text_);
			std::swap(src.pos_, pos_);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  代入
			@param[in]	src	ソース
			@return 自分
		*/
		//-----------------------------------------------------------------//
		fixed_string& operator = (const fixed_string& src) {
			std::strcpy(text_, src.text_);
			pos_ = src.pos_;
			return *this;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  文字を加える
			@param[in]	ch	文字
			@return 自分
		*/
		//-----------------------------------------------------------------//
		fixed_string& operator += (char ch) {
			if(pos_ < (SIZE - 1)) {
				text_[pos_] = ch;
				++pos_;
				text_[pos_] = 0;
			}
			return *this;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  文字参照
			@param[in]	pos	配列位置
			@return 文字
		*/
		//-----------------------------------------------------------------//
		char& operator [] (uint32_t pos) {
			if(pos >= pos_) {
				static char tmp = 0;
				return tmp;
			}
			return text_[pos];
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  一致比較
			@param[in]	text	文字列
			@return 同じなら「true」
		*/
		//-----------------------------------------------------------------//
		bool operator == (const char* text) const {
			if(text == nullptr) {
				return pos_ == 0;
			}
			return std::strcmp(text_, text) == 0;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  一致比較
			@param[in]	th	比較対象
			@return 同じなら「true」
		*/
		//-----------------------------------------------------------------//
		bool operator == (const fixed_string& th) const {
			return std::strcmp(c_str(), th.c_str()) == 0;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  不一致比較
			@param[in]	th	比較対象
			@return 同じなら「true」
		*/
		//-----------------------------------------------------------------//
		bool operator != (const fixed_string& th) const {
			return std::strcmp(c_str(), th.c_str()) != 0;
		}
	};
}
<commit_msg>update new version (for tested code)<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	固定サイズ文字列クラス @n
			Copyright 2017 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <algorithm>
#include <cstring>

namespace utils {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  固定サイズ文字列クラス
		@param[in]	SIZE	文字列サイズ
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <uint32_t SIZE>
	class fixed_string {
		char		text_[SIZE];
		uint32_t	pos_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクタ
			@param[in]	str	初期設定文字列
		*/
		//-----------------------------------------------------------------//
		fixed_string(const char* str = nullptr) : pos_(0) {
			if(str != nullptr) {
				std::strcpy(text_, str);
				pos_ = std::strlen(text_);
			} else {
				text_[pos_] = 0;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  格納可能な最大サイズを返す（終端の数を除外）
			@return 格納可能な最大サイズ
		*/
		//-----------------------------------------------------------------//
		uint32_t capacity() const noexcept { return SIZE - 1; }

		//-----------------------------------------------------------------//
		/*!
			@brief  現在のサイズを返す
			@return 現在のサイズ
		*/
		//-----------------------------------------------------------------//
		uint32_t size() const noexcept { return pos_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  文字列をクリア（リセット）
		*/
		//-----------------------------------------------------------------//
		void clear() noexcept {
			pos_ = 0;
			text_[pos_] = 0;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  文字列を返す
			@return 文字列
		*/
		//-----------------------------------------------------------------//
		const char* c_str() const noexcept { return text_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  交換
			@param[in]	src	ソース
			@return 自分
		*/
		//-----------------------------------------------------------------//
		void swap(fixed_string& src) noexcept {
			std::swap(src.text_, text_);
			std::swap(src.pos_, pos_);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  代入
			@param[in]	src	ソース
			@return 自分
		*/
		//-----------------------------------------------------------------//
		fixed_string& operator = (const fixed_string& src) {
			std::strcpy(text_, src.c_str());
			pos_ = src.pos_;
			return *this;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  文字を追加
			@param[in]	ch	文字
			@return 自分
		*/
		//-----------------------------------------------------------------//
		fixed_string& operator += (char ch) {
			if(pos_ < (SIZE - 1)) {
				text_[pos_] = ch;
				++pos_;
				text_[pos_] = 0;
			}
			return *this;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  文字列を追加
			@param[in]	str	文字列
			@return 自分
		*/
		//-----------------------------------------------------------------//
		fixed_string& operator += (const char* str) {
			if(str == nullptr) {
				return *this;
			}

			uint32_t l = std::strlen(str);
			if((pos_ + l) < (SIZE - 1)) {
				std::strcpy(&text_[pos_], str);
				pos_ += l;
			} else {  // バッファが許す範囲でコピー
				l = SIZE - pos_ - 1;
				std::strncpy(&text_[pos_], str, l);
				pos_ = SIZE - 1;
			}
			text_[pos_] = 0;
			return *this;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  文字参照
			@param[in]	pos	配列位置
			@return 文字
		*/
		//-----------------------------------------------------------------//
		char& operator [] (uint32_t pos) noexcept {
			if(pos >= pos_) {
				static char tmp = 0;
				return tmp;
			}
			return text_[pos];
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  一致比較
			@param[in]	text	文字列
			@return 同じなら「true」
		*/
		//-----------------------------------------------------------------//
		bool cmp(const char* text) const noexcept {
			if(text == nullptr) {
				return pos_ == 0;
			}
			return std::strcmp(c_str(), text) == 0;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  一致比較（オペレーター）
			@param[in]	text	文字列
			@return 同じなら「true」
		*/
		//-----------------------------------------------------------------//
		bool operator == (const char* text) const { return cmp(text); }

		//-----------------------------------------------------------------//
		/*!
			@brief  不一致比較（オペレーター）
			@param[in]	text	文字列
			@return 同じなら「true」
		*/
		//-----------------------------------------------------------------//
		bool operator != (const char* text) const { return !cmp(text); }

		//-----------------------------------------------------------------//
		/*!
			@brief  クラス、一致比較（オペレーター）
			@param[in]	th	比較対象
			@return 同じなら「true」
		*/
		//-----------------------------------------------------------------//
		bool operator == (const fixed_string& th) const {
			return std::strcmp(c_str(), th.c_str()) == 0;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  クラス、不一致比較（オペレーター）
			@param[in]	th	比較対象
			@return 同じなら「true」
		*/
		//-----------------------------------------------------------------//
		bool operator != (const fixed_string& th) const {
			return std::strcmp(c_str(), th.c_str()) != 0;
		}
	};
}
<|endoftext|>


<commit_before>#include "signalcenter.h"
#include "dispatchentry.h"

// TEST: git subtree commit in upstream repo
// TEST 2: git subtree commit made in application repo
// TEST 3: git subtree commit made in application repo and pushed with git subtree push
// TEST 4: yet another git subtree commit made in application repo and pushed with git subtree push

/*!
    \class SignalCenter
    \inmodule QtxCore
    \brief The SignalCenter class provides a mechanism for dispatching
           notifications within an application.
 */

/*!
    Returns a pointer to the application's default SignalCenter instance.
*/
SignalCenter* SignalCenter::instance()
{
    static SignalCenter *center = 0;
    if (!center) {
        center = new SignalCenter();
    }
    return center;
}

/*!
    Constructs a SignalCenter object with the given \a parent.
*/
SignalCenter::SignalCenter(QObject *parent /* = 0 */)
    : QObject(parent),
      mPoster(0)
{
}

/*!
    Destroy the object.
*/
SignalCenter::~SignalCenter()
{
}

/*!
    TODO: \a signal \a receiver \a slot
*/
void SignalCenter::observe(const QString & signal, QObject *receiver, const char *slot)
{
    observe(0, signal, receiver, slot);
}

/*!
    TODO: \a sender \a signal \a receiver \a slot
*/
void SignalCenter::observe(const QObject *sender, const QString & signal,
                           QObject *receiver, const char *slot)
{
    DispatchEntry *entry = new DispatchEntry(sender, signal, receiver, slot);
    mDispatchTable.append(entry);

    QObject::connect(receiver, SIGNAL(destroyed(QObject *)), SLOT(onDestroyed(QObject *)));
}

/*!
    TODO: \a receiver
*/
void SignalCenter::unobserve(const QObject *receiver)
{
    unobserve(0, "", receiver);
}

/*!
    TODO: \a sender \a signal \a receiver
*/
void SignalCenter::unobserve(const QObject *sender, const QString & signal, const QObject *receiver)
{
    QMutableListIterator<DispatchEntry *> itr(mDispatchTable);
    while (itr.hasNext()) {
        DispatchEntry* entry = itr.next();
        if (entry->receiver() == receiver
            && (entry->sender() == sender || !sender)
            && (entry->signal() == signal || signal.isEmpty())) {
            itr.remove();
        }
    }
}

/*!
    TODO: \a sender \a signal \a val0 \a val1 \a val2 \a val3 \a val4 \a val5 \a val6 \a val7 \a val8 \a val9
*/
void SignalCenter::post(QObject *sender, const QString & signal,
                        QGenericArgument val0 /* = QGenericArgument( 0 ) */, QGenericArgument val1 /* = QGenericArgument() */, QGenericArgument val2 /* = QGenericArgument() */, QGenericArgument val3 /* = QGenericArgument() */, QGenericArgument val4 /* = QGenericArgument() */, QGenericArgument val5 /* = QGenericArgument() */, QGenericArgument val6 /* = QGenericArgument() */, QGenericArgument val7 /* = QGenericArgument() */, QGenericArgument val8 /* = QGenericArgument() */, QGenericArgument val9 /* = QGenericArgument() */)
{
    mPoster = sender;

    QList<DispatchEntry *> table(mDispatchTable);
    QMutableListIterator<DispatchEntry *> itr(table);
    while (itr.hasNext()) {
        DispatchEntry* entry = itr.next();
        if ((entry->sender() == sender || !entry->sender())
            && (entry->signal() == signal || entry->signal().isEmpty())) {

            QObject *receiver = entry->receiver();
            const char *slot = entry->slot();
            const QMetaObject* metaReceiver = receiver->metaObject();
            int idx = metaReceiver->indexOfSlot(slot);
            if (idx == -1) {
                continue;
            }
            QMetaMethod method = metaReceiver->method(idx);
            method.invoke(receiver, Qt::DirectConnection, val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
        }
    }

    mPoster = 0;
}

/*!
    TODO:
*/
QObject *SignalCenter::poster() const
{
    return mPoster;
}

void SignalCenter::onDestroyed(QObject * obj /* = 0 */)
{
    if (!obj) {
        return;
    }

    unobserve(obj);
}
<commit_msg>Remove comments made while testing git subtree.<commit_after>#include "signalcenter.h"
#include "dispatchentry.h"

/*!
    \class SignalCenter
    \inmodule QtxCore
    \brief The SignalCenter class provides a mechanism for dispatching
           notifications within an application.
 */

/*!
    Returns a pointer to the application's default SignalCenter instance.
*/
SignalCenter* SignalCenter::instance()
{
    static SignalCenter *center = 0;
    if (!center) {
        center = new SignalCenter();
    }
    return center;
}

/*!
    Constructs a SignalCenter object with the given \a parent.
*/
SignalCenter::SignalCenter(QObject *parent /* = 0 */)
    : QObject(parent),
      mPoster(0)
{
}

/*!
    Destroy the object.
*/
SignalCenter::~SignalCenter()
{
}

/*!
    TODO: \a signal \a receiver \a slot
*/
void SignalCenter::observe(const QString & signal, QObject *receiver, const char *slot)
{
    observe(0, signal, receiver, slot);
}

/*!
    TODO: \a sender \a signal \a receiver \a slot
*/
void SignalCenter::observe(const QObject *sender, const QString & signal,
                           QObject *receiver, const char *slot)
{
    DispatchEntry *entry = new DispatchEntry(sender, signal, receiver, slot);
    mDispatchTable.append(entry);

    QObject::connect(receiver, SIGNAL(destroyed(QObject *)), SLOT(onDestroyed(QObject *)));
}

/*!
    TODO: \a receiver
*/
void SignalCenter::unobserve(const QObject *receiver)
{
    unobserve(0, "", receiver);
}

/*!
    TODO: \a sender \a signal \a receiver
*/
void SignalCenter::unobserve(const QObject *sender, const QString & signal, const QObject *receiver)
{
    QMutableListIterator<DispatchEntry *> itr(mDispatchTable);
    while (itr.hasNext()) {
        DispatchEntry* entry = itr.next();
        if (entry->receiver() == receiver
            && (entry->sender() == sender || !sender)
            && (entry->signal() == signal || signal.isEmpty())) {
            itr.remove();
        }
    }
}

/*!
    TODO: \a sender \a signal \a val0 \a val1 \a val2 \a val3 \a val4 \a val5 \a val6 \a val7 \a val8 \a val9
*/
void SignalCenter::post(QObject *sender, const QString & signal,
                        QGenericArgument val0 /* = QGenericArgument( 0 ) */, QGenericArgument val1 /* = QGenericArgument() */, QGenericArgument val2 /* = QGenericArgument() */, QGenericArgument val3 /* = QGenericArgument() */, QGenericArgument val4 /* = QGenericArgument() */, QGenericArgument val5 /* = QGenericArgument() */, QGenericArgument val6 /* = QGenericArgument() */, QGenericArgument val7 /* = QGenericArgument() */, QGenericArgument val8 /* = QGenericArgument() */, QGenericArgument val9 /* = QGenericArgument() */)
{
    mPoster = sender;

    QList<DispatchEntry *> table(mDispatchTable);
    QMutableListIterator<DispatchEntry *> itr(table);
    while (itr.hasNext()) {
        DispatchEntry* entry = itr.next();
        if ((entry->sender() == sender || !entry->sender())
            && (entry->signal() == signal || entry->signal().isEmpty())) {

            QObject *receiver = entry->receiver();
            const char *slot = entry->slot();
            const QMetaObject* metaReceiver = receiver->metaObject();
            int idx = metaReceiver->indexOfSlot(slot);
            if (idx == -1) {
                continue;
            }
            QMetaMethod method = metaReceiver->method(idx);
            method.invoke(receiver, Qt::DirectConnection, val0, val1, val2, val3, val4, val5, val6, val7, val8, val9);
        }
    }

    mPoster = 0;
}

/*!
    TODO:
*/
QObject *SignalCenter::poster() const
{
    return mPoster;
}

void SignalCenter::onDestroyed(QObject * obj /* = 0 */)
{
    if (!obj) {
        return;
    }

    unobserve(obj);
}
<|endoftext|>