<commit_before>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad   */
/* Complutense de Madrid (dsa-research.org)                                   */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

#include <sqlite3.h>

#include "Template.h"
#include "template_syntax.h"

#include <iostream>
#include <sstream>
#include <cstring>

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

Template::~Template()
{
    multimap<string,Attribute *>::iterator  it;

    for ( it = attributes.begin(); it != attributes.end(); it++)
    {
        delete it->second;
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

pthread_mutex_t Template::mutex = PTHREAD_MUTEX_INITIALIZER;

extern "C"
{
    typedef struct yy_buffer_state * YY_BUFFER_STATE;

    extern FILE *template_in, *template_out;

    int template_parse(Template * tmpl, char ** errmsg);

    int template_lex_destroy();

    YY_BUFFER_STATE template__scan_string(const char * str);

    void template__delete_buffer(YY_BUFFER_STATE);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Template::parse(const char * filename, char **error_msg)
{
    int     rc;

    pthread_mutex_lock(&mutex);

    *error_msg = 0;

    template_in = fopen (filename, "r");

    if ( template_in == 0 )
    {
        goto error_open;
    }

    rc = template_parse(this,error_msg);

    fclose(template_in);

    template_lex_destroy();

    pthread_mutex_unlock(&mutex);

    return rc;

error_open:
    *error_msg = strdup("Error opening template file");

    pthread_mutex_unlock(&mutex);

    return -1;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Template::parse(const string &parse_str, char **error_msg)
{
    YY_BUFFER_STATE     str_buffer = 0;
    const char *        str;
    int                 rc;

    pthread_mutex_lock(&mutex);

    *error_msg = 0;

    str = parse_str.c_str();

    str_buffer = template__scan_string(str);

    if (str_buffer == 0)
    {
        goto error_yy;
    }

    rc = template_parse(this,error_msg);

    template__delete_buffer(str_buffer);

    template_lex_destroy();

    pthread_mutex_unlock(&mutex);

    return rc;

error_yy:

    *error_msg=strdup("Error setting scan buffer");

    pthread_mutex_unlock(&mutex);

    return -1;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Template::marshall(string &str, const char delim)
{
    multimap<string,Attribute *>::iterator  it;
    string *                                attr;

    for(it=attributes.begin(),str="";it!=attributes.end();it++)
    {
        attr = it->second->marshall();

        if ( attr == 0 )
        {
            continue;
        }

        str += it->first + "=" + *attr + delim;

        delete attr;
    }
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Template::set(Attribute * attr)
{
    if ( replace_mode == true )
    {
        multimap<string, Attribute *>::iterator         i;
        pair<multimap<string, Attribute *>::iterator,
        multimap<string, Attribute *>::iterator>        index;

        index = attributes.equal_range(attr->name());

        for ( i = index.first; i != index.second; i++)
        {
            delete i->second;
        }

        attributes.erase(attr->name());
    }

    attributes.insert(make_pair(attr->name(),attr));
};

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Template::remove(const string& name, vector<Attribute *>& values)
{
    multimap<string, Attribute *>::iterator         i;
    pair<multimap<string, Attribute *>::iterator,
    multimap<string, Attribute *>::iterator>        index;
    int                                             j;

    index = attributes.equal_range(name);

    for ( i = index.first,j=0 ; i != index.second ; i++,j++ )
    {
        values.push_back(i->second);
    }

    attributes.erase(index.first,index.second);

    return j;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Template::get(
    const string& name,
    vector<const Attribute*>& values) const
{
    multimap<string, Attribute *>::const_iterator       i;
    pair<multimap<string, Attribute *>::const_iterator,
    multimap<string, Attribute *>::const_iterator>      index;
    int                                                 j;

    index = attributes.equal_range(name);

    for ( i = index.first,j=0 ; i != index.second ; i++,j++ )
    {
        values.push_back(i->second);
    }

    return j;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Template::get(
    const string& name,
    vector<Attribute*>& values)
{
    multimap<string, Attribute *>::iterator       i;
    pair<multimap<string, Attribute *>::iterator,
    multimap<string, Attribute *>::iterator>      index;
    int                                           j;

    index = attributes.equal_range(name);

    for ( i = index.first,j=0 ; i != index.second ; i++,j++ )
    {
        values.push_back(i->second);
    }

    return j;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Template::get(
        string& name,
        string& value) const
{
    vector<const Attribute *>   attrs;
    const SingleAttribute *     sattr;
    int                         rc;

    transform (name.begin(),name.end(),name.begin(),(int(*)(int))toupper);

    rc = get(name,attrs);

    if  (rc == 0)
    {
        value = "";
        return;
    }

    sattr = dynamic_cast<const SingleAttribute *>(attrs[0]);

    if ( sattr != 0 )
    {
        value = sattr->value();
    }
    else
    {
        value="";
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Template::get(
        string& name,
        int&    value) const
{
    string sval;

    get(name, sval);

    if ( sval == "" )
    {
        value = 0;
        return;
    }

    istringstream iss(sval);

    iss >> value;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& Template::to_xml(string& xml) const
{
    multimap<string,Attribute *>::const_iterator  it;
    ostringstream                   		oss;
    string *                                s;

    oss << "<" << xml_root << ">";

    for ( it = attributes.begin(); it!=attributes.end(); it++)
    {
        s = it->second->to_xml();

        oss << *s;

        delete s;
    }

    oss << "</" << xml_root << ">";

    xml = oss.str();

	return xml;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& Template::to_str(string& str) const
{
	ostringstream os;
    multimap<string,Attribute *>::const_iterator  it;
    string *                                s;

    for ( it = attributes.begin(); it!=attributes.end(); it++)
    {
        s = it->second->marshall(",");

        os << endl << "\t" << it->first << separator << *s;

        delete s;
    }

	str = os.str();
    return str;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

ostream& operator << (ostream& os, const Template& t)
{
	string str;

	os << t.to_str(str);

    return os;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

<commit_msg>Compilation error gcc 4.4<commit_after>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad   */
/* Complutense de Madrid (dsa-research.org)                                   */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

#include <sqlite3.h>

#include "Template.h"
#include "template_syntax.h"

#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdio>

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

Template::~Template()
{
    multimap<string,Attribute *>::iterator  it;

    for ( it = attributes.begin(); it != attributes.end(); it++)
    {
        delete it->second;
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

pthread_mutex_t Template::mutex = PTHREAD_MUTEX_INITIALIZER;

extern "C"
{
    typedef struct yy_buffer_state * YY_BUFFER_STATE;

    extern FILE *template_in, *template_out;

    int template_parse(Template * tmpl, char ** errmsg);

    int template_lex_destroy();

    YY_BUFFER_STATE template__scan_string(const char * str);

    void template__delete_buffer(YY_BUFFER_STATE);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Template::parse(const char * filename, char **error_msg)
{
    int     rc;

    pthread_mutex_lock(&mutex);

    *error_msg = 0;

    template_in = fopen (filename, "r");

    if ( template_in == 0 )
    {
        goto error_open;
    }

    rc = template_parse(this,error_msg);

    fclose(template_in);

    template_lex_destroy();

    pthread_mutex_unlock(&mutex);

    return rc;

error_open:
    *error_msg = strdup("Error opening template file");

    pthread_mutex_unlock(&mutex);

    return -1;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Template::parse(const string &parse_str, char **error_msg)
{
    YY_BUFFER_STATE     str_buffer = 0;
    const char *        str;
    int                 rc;

    pthread_mutex_lock(&mutex);

    *error_msg = 0;

    str = parse_str.c_str();

    str_buffer = template__scan_string(str);

    if (str_buffer == 0)
    {
        goto error_yy;
    }

    rc = template_parse(this,error_msg);

    template__delete_buffer(str_buffer);

    template_lex_destroy();

    pthread_mutex_unlock(&mutex);

    return rc;

error_yy:

    *error_msg=strdup("Error setting scan buffer");

    pthread_mutex_unlock(&mutex);

    return -1;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Template::marshall(string &str, const char delim)
{
    multimap<string,Attribute *>::iterator  it;
    string *                                attr;

    for(it=attributes.begin(),str="";it!=attributes.end();it++)
    {
        attr = it->second->marshall();

        if ( attr == 0 )
        {
            continue;
        }

        str += it->first + "=" + *attr + delim;

        delete attr;
    }
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Template::set(Attribute * attr)
{
    if ( replace_mode == true )
    {
        multimap<string, Attribute *>::iterator         i;
        pair<multimap<string, Attribute *>::iterator,
        multimap<string, Attribute *>::iterator>        index;

        index = attributes.equal_range(attr->name());

        for ( i = index.first; i != index.second; i++)
        {
            delete i->second;
        }

        attributes.erase(attr->name());
    }

    attributes.insert(make_pair(attr->name(),attr));
};

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Template::remove(const string& name, vector<Attribute *>& values)
{
    multimap<string, Attribute *>::iterator         i;
    pair<multimap<string, Attribute *>::iterator,
    multimap<string, Attribute *>::iterator>        index;
    int                                             j;

    index = attributes.equal_range(name);

    for ( i = index.first,j=0 ; i != index.second ; i++,j++ )
    {
        values.push_back(i->second);
    }

    attributes.erase(index.first,index.second);

    return j;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Template::get(
    const string& name,
    vector<const Attribute*>& values) const
{
    multimap<string, Attribute *>::const_iterator       i;
    pair<multimap<string, Attribute *>::const_iterator,
    multimap<string, Attribute *>::const_iterator>      index;
    int                                                 j;

    index = attributes.equal_range(name);

    for ( i = index.first,j=0 ; i != index.second ; i++,j++ )
    {
        values.push_back(i->second);
    }

    return j;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int Template::get(
    const string& name,
    vector<Attribute*>& values)
{
    multimap<string, Attribute *>::iterator       i;
    pair<multimap<string, Attribute *>::iterator,
    multimap<string, Attribute *>::iterator>      index;
    int                                           j;

    index = attributes.equal_range(name);

    for ( i = index.first,j=0 ; i != index.second ; i++,j++ )
    {
        values.push_back(i->second);
    }

    return j;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Template::get(
        string& name,
        string& value) const
{
    vector<const Attribute *>   attrs;
    const SingleAttribute *     sattr;
    int                         rc;

    transform (name.begin(),name.end(),name.begin(),(int(*)(int))toupper);

    rc = get(name,attrs);

    if  (rc == 0)
    {
        value = "";
        return;
    }

    sattr = dynamic_cast<const SingleAttribute *>(attrs[0]);

    if ( sattr != 0 )
    {
        value = sattr->value();
    }
    else
    {
        value="";
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

void Template::get(
        string& name,
        int&    value) const
{
    string sval;

    get(name, sval);

    if ( sval == "" )
    {
        value = 0;
        return;
    }

    istringstream iss(sval);

    iss >> value;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& Template::to_xml(string& xml) const
{
    multimap<string,Attribute *>::const_iterator  it;
    ostringstream                   		oss;
    string *                                s;

    oss << "<" << xml_root << ">";

    for ( it = attributes.begin(); it!=attributes.end(); it++)
    {
        s = it->second->to_xml();

        oss << *s;

        delete s;
    }

    oss << "</" << xml_root << ">";

    xml = oss.str();

	return xml;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

string& Template::to_str(string& str) const
{
	ostringstream os;
    multimap<string,Attribute *>::const_iterator  it;
    string *                                s;

    for ( it = attributes.begin(); it!=attributes.end(); it++)
    {
        s = it->second->marshall(",");

        os << endl << "\t" << it->first << separator << *s;

        delete s;
    }

	str = os.str();
    return str;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

ostream& operator << (ostream& os, const Template& t)
{
	string str;

	os << t.to_str(str);

    return os;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

<|endoftext|>


<commit_before>// Copyright (c) 2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <chainparams.h>
#include <compressor.h>
#include <core_io.h>
#include <core_memusage.h>
#include <policy/policy.h>
#include <pubkey.h>
#include <script/descriptor.h>
#include <script/script.h>
#include <script/sign.h>
#include <script/signingprovider.h>
#include <script/standard.h>
#include <streams.h>
#include <test/fuzz/fuzz.h>
#include <util/memory.h>

void initialize()
{
    // Fuzzers using pubkey must hold an ECCVerifyHandle.
    static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
}

void test_one_input(const std::vector<uint8_t>& buffer)
{
    const CScript script(buffer.begin(), buffer.end());

    std::vector<unsigned char> compressed;
    (void)CompressScript(script, compressed);

    CTxDestination address;
    (void)ExtractDestination(script, address);

    txnouttype type_ret;
    std::vector<CTxDestination> addresses;
    int required_ret;
    (void)ExtractDestinations(script, type_ret, addresses, required_ret);

    (void)GetScriptForWitness(script);

    const FlatSigningProvider signing_provider;
    (void)InferDescriptor(script, signing_provider);

    (void)IsSegWitOutput(signing_provider, script);

    (void)IsSolvable(signing_provider, script);

    txnouttype which_type;
    (void)IsStandard(script, which_type);

    (void)RecursiveDynamicUsage(script);

    std::vector<std::vector<unsigned char>> solutions;
    (void)Solver(script, solutions);

    (void)script.HasValidOps();
    (void)script.IsPayToScriptHash();
    (void)script.IsPayToWitnessScriptHash();
    (void)script.IsPushOnly();
    (void)script.IsUnspendable();
    (void)script.GetSigOpCount(/* fAccurate= */ false);
}
<commit_msg>tests: Fuzz additional functions in the script fuzzing harness<commit_after>// Copyright (c) 2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <chainparams.h>
#include <compressor.h>
#include <core_io.h>
#include <core_memusage.h>
#include <policy/policy.h>
#include <pubkey.h>
#include <script/descriptor.h>
#include <script/script.h>
#include <script/sign.h>
#include <script/signingprovider.h>
#include <script/standard.h>
#include <streams.h>
#include <test/fuzz/fuzz.h>
#include <univalue.h>
#include <util/memory.h>

void initialize()
{
    // Fuzzers using pubkey must hold an ECCVerifyHandle.
    static const auto verify_handle = MakeUnique<ECCVerifyHandle>();

    SelectParams(CBaseChainParams::REGTEST);
}

void test_one_input(const std::vector<uint8_t>& buffer)
{
    const CScript script(buffer.begin(), buffer.end());

    std::vector<unsigned char> compressed;
    if (CompressScript(script, compressed)) {
        const unsigned int size = compressed[0];
        assert(size >= 0 && size <= 5);
        CScript decompressed_script;
        const bool ok = DecompressScript(decompressed_script, size, compressed);
        assert(ok);
    }

    for (unsigned int size = 0; size < 6; ++size) {
        std::vector<unsigned char> vch(GetSpecialScriptSize(size), 0x00);
        vch.insert(vch.end(), buffer.begin(), buffer.end());
        CScript decompressed_script;
        (void)DecompressScript(decompressed_script, size, vch);
    }

    CTxDestination address;
    (void)ExtractDestination(script, address);

    txnouttype type_ret;
    std::vector<CTxDestination> addresses;
    int required_ret;
    (void)ExtractDestinations(script, type_ret, addresses, required_ret);

    (void)GetScriptForWitness(script);

    const FlatSigningProvider signing_provider;
    (void)InferDescriptor(script, signing_provider);

    (void)IsSegWitOutput(signing_provider, script);

    (void)IsSolvable(signing_provider, script);

    txnouttype which_type;
    (void)IsStandard(script, which_type);

    (void)RecursiveDynamicUsage(script);

    std::vector<std::vector<unsigned char>> solutions;
    (void)Solver(script, solutions);

    (void)script.HasValidOps();
    (void)script.IsPayToScriptHash();
    (void)script.IsPayToWitnessScriptHash();
    (void)script.IsPushOnly();
    (void)script.IsUnspendable();
    (void)script.GetSigOpCount(/* fAccurate= */ false);

    (void)FormatScript(script);
    (void)ScriptToAsmStr(script, false);
    (void)ScriptToAsmStr(script, true);

    UniValue o1(UniValue::VOBJ);
    ScriptPubKeyToUniv(script, o1, true);
    UniValue o2(UniValue::VOBJ);
    ScriptPubKeyToUniv(script, o2, false);
    UniValue o3(UniValue::VOBJ);
    ScriptToUniv(script, o3, true);
    UniValue o4(UniValue::VOBJ);
    ScriptToUniv(script, o4, false);
}
<|endoftext|>


<commit_before>// memory_test.cpp
#include <counting_allocator.h>
#include "test.h"

TEST(CountingAllocatorConstructorsTest, DefaultConstructor)
{
  using namespace StevensDev;

  sgdm::CountingAllocator<int> *a;
  a = new sgdm::CountingAllocator<int>;

  ASSERT_TRUE(a != 0);
  ASSERT_TRUE(a->getAllocationCount() == 0);
  ASSERT_TRUE(a->getReleaseCount() == 0);
  ASSERT_TRUE(a->getOutstandingCount() == 0);
}

TEST(CountingAllocatorConstructorsTest, CopyConstructor)
{
  using namespace StevensDev;

  sgdm::CountingAllocator<int> *a;
  sgdm::CountingAllocator<int> *b;
  a = new sgdm::CountingAllocator<int>;
  b = a;

  ASSERT_TRUE(b == a);
}

TEST(CountingAllocatorTrackingTest, AllocationCounting)
{
    using namespace StevensDev;

    int *a, *b;

    sgdm::CountingAllocator<int> *alloc;
    alloc = new sgdm::CountingAllocator<int>;

    a = alloc->get( 4 );
    b = alloc->get( 4 );

    ASSERT_TRUE( alloc->getAllocationCount() == 2 );
    ASSERT_TRUE( sgdm::CountingAllocator<int>::getTotalAllocationCount() == 2 );

    alloc->release( a, 1 );

    ASSERT_TRUE( alloc->getReleaseCount() == 1 );
    ASSERT_TRUE( sgdm::CountingAllocator<int>::getTotalReleaseCount() == 1 );
    ASSERT_TRUE( alloc->getOutstandingCount() == 1 );
    ASSERT_TRUE(
        sgdm::CountingAllocator<int>::getTotalOutstandingCount() == 1 );
}
<commit_msg>Add more to the DynamicArrayMemory test<commit_after>// memory_test.cpp
#include <counting_allocator.h>
#include "test.h"

TEST(CountingAllocatorConstructorsTest, DefaultConstructor)
{
  using namespace StevensDev;

  sgdm::CountingAllocator<int> *a;
  a = new sgdm::CountingAllocator<int>;

  ASSERT_TRUE(a != 0);
  ASSERT_TRUE(a->getAllocationCount() == 0);
  ASSERT_TRUE(a->getReleaseCount() == 0);
  ASSERT_TRUE(a->getOutstandingCount() == 0);
}

TEST(CountingAllocatorConstructorsTest, CopyConstructor)
{
  using namespace StevensDev;

  sgdm::CountingAllocator<int> *a;
  sgdm::CountingAllocator<int> *b;
  a = new sgdm::CountingAllocator<int>;
  b = a;

  ASSERT_TRUE(b == a);
}

TEST(CountingAllocatorTrackingTest, AllocationCounting)
{
    using namespace StevensDev;

    int *a, *b;

    sgdm::CountingAllocator<int> *alloc;
    alloc = new sgdm::CountingAllocator<int>;

    a = alloc->get( 4 );
    b = alloc->get( 4 );

    ASSERT_TRUE( alloc->getAllocationCount() == 2 );
    ASSERT_TRUE( sgdm::CountingAllocator<int>::getTotalAllocationCount() == 2 );

    alloc->release( a, 1 );

    ASSERT_TRUE( alloc->getReleaseCount() == 1 );
    ASSERT_TRUE( sgdm::CountingAllocator<int>::getTotalReleaseCount() == 1 );
    ASSERT_TRUE( alloc->getOutstandingCount() == 1 );
    ASSERT_TRUE(
        sgdm::CountingAllocator<int>::getTotalOutstandingCount() == 1 );

    alloc->release( b, 1 );
    ASSERT_TRUE( alloc->getReleaseCount() == 2 );
    ASSERT_TRUE( sgdm::CountingAllocator<int>::getTotalReleaseCount() == 2 );
    ASSERT_TRUE( alloc->getOutstandingCount() == 0 );
    ASSERT_TRUE(
        sgdm::CountingAllocator<int>::getTotalOutstandingCount() == 0 );
}
<|endoftext|>


<commit_before>#if (defined(__clang__) || defined(__GNUC__)) && defined(__x86_64__)

#include "../test.h"
#include "taocppjson/include/tao/json.hh"

static void GenStat(Stat& stat, const tao::json::value& v){
   switch (v.type()) {
      case tao::json::type::ARRAY:
         for (auto& element : v.get_array()) {
            GenStat(stat, element);
         }
         stat.arrayCount++;
         stat.elementCount += v.get_array().size();
         break;

      case tao::json::type::OBJECT:
         for (auto& element : v.get_object()) {
            GenStat(stat, element.second);
            stat.stringLength += element.first.size();
         }
         stat.objectCount++;
         stat.memberCount += v.get_object().size();
         stat.stringCount += v.get_object().size();
         break;

      case tao::json::type::STRING:
         stat.stringCount++;
         stat.stringLength += v.get_string().size();
         break;

      case tao::json::type::SIGNED:
      case tao::json::type::UNSIGNED:
      case tao::json::type::DOUBLE:
         stat.numberCount++;
         break;

      case tao::json::type::BOOL:
         if (v.get_bool())
            stat.trueCount++;
         else
            stat.falseCount++;
         break;

      case tao::json::type::NULL_:
         stat.nullCount++;
         break;

      case tao::json::type::POINTER:
         // not applicable in this benchmark
         throw std::runtime_error( "code should be unreachable" );
   }
}

class TAOCPPJSONParseResult : public ParseResultBase {
public:
   tao::json::value root;
};

class TAOCPPJSONStringResult : public StringResultBase {
public:
   virtual const char* c_str() const { return s.c_str(); }

   std::string s;
};
class TAOCPPJSONTest : public TestBase {
public:
#if TEST_INFO
   virtual const char* GetName() const { return "taocpp/json (C++11)"; }
   virtual const char* GetFilename() const { return __FILE__; }
#endif

#if TEST_PARSE
   virtual ParseResultBase* Parse(const char* j, size_t length) const {
      (void)length;
      TAOCPPJSONParseResult* pr = new TAOCPPJSONParseResult;
      try {
         pr->root = tao::json::from_string(j);
      }
      catch (...) {
         delete pr;
         return 0;
      }
      return pr;
   }
#endif

#if TEST_STRINGIFY
   virtual StringResultBase* Stringify(const ParseResultBase* parseResult) const {
      const TAOCPPJSONParseResult* pr = static_cast<const TAOCPPJSONParseResult*>(parseResult);
      TAOCPPJSONStringResult* sr = new TAOCPPJSONStringResult;
      sr->s = to_string(pr->root);
      return sr;
   }
#endif

#if TEST_PRETTIFY
   virtual StringResultBase* Prettify(const ParseResultBase* parseResult) const {
      const TAOCPPJSONParseResult* pr = static_cast<const TAOCPPJSONParseResult*>(parseResult);
      TAOCPPJSONStringResult* sr = new TAOCPPJSONStringResult;
      sr->s = to_string(pr->root, 4);
      return sr;
   }
#endif

#if TEST_STATISTICS
   virtual bool Statistics(const ParseResultBase* parseResult, Stat* stat) const {
      const TAOCPPJSONParseResult* pr = static_cast<const TAOCPPJSONParseResult*>(parseResult);
      memset(stat, 0, sizeof(Stat));
      GenStat(*stat, pr->root);
      return true;
   }
#endif

#if TEST_CONFORMANCE
   virtual bool ParseDouble(const char* j, double* d) const {
      try {
         auto root = tao::json::from_string(j);
         *d = root[0].get_double();
         return true;
      }
      catch (...) {
      }
      return false;
   }

   virtual bool ParseString(const char* j, std::string& s) const {
      try {
         auto root = tao::json::from_string(j);
         s = root[0].get_string();
         return true;
      }
      catch (...) {
      }
      return false;
   }
#endif
};

REGISTER_TEST(TAOCPPJSONTest);

#endif
<commit_msg>Use `length` to avoid copy of input<commit_after>#if (defined(__clang__) || defined(__GNUC__)) && defined(__x86_64__)

#include "../test.h"
#include "taocppjson/include/tao/json.hh"

static void GenStat(Stat& stat, const tao::json::value& v){
   switch (v.type()) {
      case tao::json::type::ARRAY:
         for (auto& element : v.get_array()) {
            GenStat(stat, element);
         }
         stat.arrayCount++;
         stat.elementCount += v.get_array().size();
         break;

      case tao::json::type::OBJECT:
         for (auto& element : v.get_object()) {
            GenStat(stat, element.second);
            stat.stringLength += element.first.size();
         }
         stat.objectCount++;
         stat.memberCount += v.get_object().size();
         stat.stringCount += v.get_object().size();
         break;

      case tao::json::type::STRING:
         stat.stringCount++;
         stat.stringLength += v.get_string().size();
         break;

      case tao::json::type::SIGNED:
      case tao::json::type::UNSIGNED:
      case tao::json::type::DOUBLE:
         stat.numberCount++;
         break;

      case tao::json::type::BOOL:
         if (v.get_bool())
            stat.trueCount++;
         else
            stat.falseCount++;
         break;

      case tao::json::type::NULL_:
         stat.nullCount++;
         break;

      case tao::json::type::POINTER:
         // not applicable in this benchmark
         throw std::runtime_error( "code should be unreachable" );
   }
}

class TAOCPPJSONParseResult : public ParseResultBase {
public:
   tao::json::value root;
};

class TAOCPPJSONStringResult : public StringResultBase {
public:
   virtual const char* c_str() const { return s.c_str(); }

   std::string s;
};
class TAOCPPJSONTest : public TestBase {
public:
#if TEST_INFO
   virtual const char* GetName() const { return "taocpp/json (C++11)"; }
   virtual const char* GetFilename() const { return __FILE__; }
#endif

#if TEST_PARSE
   virtual ParseResultBase* Parse(const char* j, size_t length) const {
      TAOCPPJSONParseResult* pr = new TAOCPPJSONParseResult;
      try {
         pr->root = tao::json::from_string(j, length);
      }
      catch (...) {
         delete pr;
         return 0;
      }
      return pr;
   }
#endif

#if TEST_STRINGIFY
   virtual StringResultBase* Stringify(const ParseResultBase* parseResult) const {
      const TAOCPPJSONParseResult* pr = static_cast<const TAOCPPJSONParseResult*>(parseResult);
      TAOCPPJSONStringResult* sr = new TAOCPPJSONStringResult;
      sr->s = to_string(pr->root);
      return sr;
   }
#endif

#if TEST_PRETTIFY
   virtual StringResultBase* Prettify(const ParseResultBase* parseResult) const {
      const TAOCPPJSONParseResult* pr = static_cast<const TAOCPPJSONParseResult*>(parseResult);
      TAOCPPJSONStringResult* sr = new TAOCPPJSONStringResult;
      sr->s = to_string(pr->root, 4);
      return sr;
   }
#endif

#if TEST_STATISTICS
   virtual bool Statistics(const ParseResultBase* parseResult, Stat* stat) const {
      const TAOCPPJSONParseResult* pr = static_cast<const TAOCPPJSONParseResult*>(parseResult);
      memset(stat, 0, sizeof(Stat));
      GenStat(*stat, pr->root);
      return true;
   }
#endif

#if TEST_CONFORMANCE
   virtual bool ParseDouble(const char* j, double* d) const {
      try {
         auto root = tao::json::from_string(j);
         *d = root[0].get_double();
         return true;
      }
      catch (...) {
      }
      return false;
   }

   virtual bool ParseString(const char* j, std::string& s) const {
      try {
         auto root = tao::json::from_string(j);
         s = root[0].get_string();
         return true;
      }
      catch (...) {
      }
      return false;
   }
#endif
};

REGISTER_TEST(TAOCPPJSONTest);

#endif
<|endoftext|>


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

//
// A WebAssembly shell, loads a .wast file (WebAssembly in S-Expression format)
// and executes it. This provides similar functionality as the reference
// interpreter, like assert_* calls, so it can run the spec test suite.
//

#include <memory>

#include "pass.h"
#include "shell-interface.h"
#include "support/command-line.h"
#include "support/file.h"
#include "wasm-interpreter.h"
#include "wasm-printing.h"
#include "wasm-s-parser.h"
#include "wasm-validator.h"

using namespace cashew;
using namespace wasm;

//
// An invocation into a module
//

struct Invocation {
  ModuleInstance* instance;
  IString name;
  LiteralList arguments;

  Invocation(Element& invoke, ModuleInstance* instance, SExpressionWasmBuilder& builder) : instance(instance) {
    assert(invoke[0]->str() == INVOKE);
    name = invoke[1]->str();
    for (size_t j = 2; j < invoke.size(); j++) {
      Expression* argument = builder.parseExpression(*invoke[j]);
      arguments.push_back(argument->dynCast<Const>()->value);
    }
  }

  Literal invoke() {
    return instance->callExport(name, arguments);
  }
};

static void verify_result(Literal a, Literal b) {
  if (a == b) return;
  // accept equal nans if equal in all bits
  assert(a.type == b.type);
  if (a.type == f32) {
    assert(a.reinterpreti32() == b.reinterpreti32());
  } else if (a.type == f64) {
    assert(a.reinterpreti64() == b.reinterpreti64());
  } else {
    abort();
  }
}

static void run_asserts(size_t* i, bool* checked, Module* wasm,
                        Element* root,
                        std::unique_ptr<SExpressionWasmBuilder>* builder,
                        Name entry) {
  std::unique_ptr<ShellExternalInterface> interface;
  std::unique_ptr<ModuleInstance> instance;
  if (wasm) {
    interface = wasm::make_unique<ShellExternalInterface>(); // prefix make_unique to work around visual studio bugs
    instance = wasm::make_unique<ModuleInstance>(*wasm, interface.get());
    if (entry.is()) {
      Function* function = wasm->getFunction(entry);
      if (!function) {
        std::cerr << "Unknown entry " << entry << std::endl;
      } else {
        LiteralList arguments;
        for (WasmType param : function->params) {
          arguments.push_back(Literal(param));
        }
        try {
          instance->callExport(entry, arguments);
        } catch (ExitException&) {
        }
      }
    }
  }
  while (*i < root->size()) {
    Element& curr = *(*root)[*i];
    IString id = curr[0]->str();
    if (id == MODULE) break;
    *checked = true;
    Colors::red(std::cerr);
    std::cerr << *i << '/' << (root->size() - 1);
    Colors::green(std::cerr);
    std::cerr << " CHECKING: ";
    Colors::normal(std::cerr);
    std::cerr << curr;
    Colors::green(std::cerr);
    std::cerr << " [line: " << curr.line << "]\n";
    Colors::normal(std::cerr);
    if (id == ASSERT_INVALID) {
      // a module invalidity test
      Module wasm;
      bool invalid = false;
      std::unique_ptr<SExpressionWasmBuilder> builder;
      try {
        builder = std::unique_ptr<SExpressionWasmBuilder>(
          new SExpressionWasmBuilder(wasm, *curr[1])
        );
      } catch (const ParseException&) {
        invalid = true;
      }
      if (!invalid) {
        // maybe parsed ok, but otherwise incorrect
        invalid = !WasmValidator().validate(wasm);
      }
      assert(invalid);
    } else if (id == INVOKE) {
      assert(wasm);
      Invocation invocation(curr, instance.get(), *builder->get());
      invocation.invoke();
    } else {
      // an invoke test
      assert(wasm);
      bool trapped = false;
      WASM_UNUSED(trapped);
      Literal result;
      try {
        Invocation invocation(*curr[1], instance.get(), *builder->get());
        result = invocation.invoke();
      } catch (const TrapException&) {
        trapped = true;
      }
      if (id == ASSERT_RETURN) {
        assert(!trapped);
        if (curr.size() >= 3) {
          Literal expected = builder->get()
                                 ->parseExpression(*curr[2])
                                 ->dynCast<Const>()
                                 ->value;
          std::cerr << "seen " << result << ", expected " << expected << '\n';
          verify_result(expected, result);
        } else {
          Literal expected;
          std::cerr << "seen " << result << ", expected " << expected << '\n';
          verify_result(expected, result);
        }
      }
      if (id == ASSERT_TRAP) assert(trapped);
    }
    *i += 1;
  }
}

//
// main
//

int main(int argc, const char* argv[]) {
  Name entry;

  Options options("wasm-shell", "Execute .wast files");
  options
      .add(
          "--entry", "-e", "call the entry point after parsing the module",
          Options::Arguments::One,
          [&entry](Options*, const std::string& argument) { entry = argument; })
      .add_positional("INFILE", Options::Arguments::One,
                      [](Options* o, const std::string& argument) {
                        o->extra["infile"] = argument;
                      });
  options.parse(argc, argv);

  auto input(read_file<std::vector<char>>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release));

  bool checked = false;

  try {
    if (options.debug) std::cerr << "parsing text to s-expressions...\n";
    SExpressionParser parser(input.data());
    Element& root = *parser.root;

    // A .wast may have multiple modules, with some asserts after them
    size_t i = 0;
    while (i < root.size()) {
      Element& curr = *root[i];
      IString id = curr[0]->str();
      if (id == MODULE) {
        if (options.debug) std::cerr << "parsing s-expressions to wasm...\n";
        Module wasm;
        std::unique_ptr<SExpressionWasmBuilder> builder;
        builder = wasm::make_unique<SExpressionWasmBuilder>(wasm, *root[i]);
        i++;
        assert(WasmValidator().validate(wasm));
        run_asserts(&i, &checked, &wasm, &root, &builder, entry);
      } else {
        run_asserts(&i, &checked, nullptr, &root, nullptr, entry);
      }
    }
  } catch (ParseException& p) {
    p.dump(std::cerr);
    abort();
  }

  if (checked) {
    Colors::green(std::cerr);
    Colors::bold(std::cerr);
    std::cerr << "all checks passed.\n";
    Colors::normal(std::cerr);
  }
}
<commit_msg>better printing when assert_invalids fail<commit_after>/*
 * Copyright 2015 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// A WebAssembly shell, loads a .wast file (WebAssembly in S-Expression format)
// and executes it. This provides similar functionality as the reference
// interpreter, like assert_* calls, so it can run the spec test suite.
//

#include <memory>

#include "pass.h"
#include "shell-interface.h"
#include "support/command-line.h"
#include "support/file.h"
#include "wasm-interpreter.h"
#include "wasm-printing.h"
#include "wasm-s-parser.h"
#include "wasm-validator.h"

using namespace cashew;
using namespace wasm;

//
// An invocation into a module
//

struct Invocation {
  ModuleInstance* instance;
  IString name;
  LiteralList arguments;

  Invocation(Element& invoke, ModuleInstance* instance, SExpressionWasmBuilder& builder) : instance(instance) {
    assert(invoke[0]->str() == INVOKE);
    name = invoke[1]->str();
    for (size_t j = 2; j < invoke.size(); j++) {
      Expression* argument = builder.parseExpression(*invoke[j]);
      arguments.push_back(argument->dynCast<Const>()->value);
    }
  }

  Literal invoke() {
    return instance->callExport(name, arguments);
  }
};

static void verify_result(Literal a, Literal b) {
  if (a == b) return;
  // accept equal nans if equal in all bits
  assert(a.type == b.type);
  if (a.type == f32) {
    assert(a.reinterpreti32() == b.reinterpreti32());
  } else if (a.type == f64) {
    assert(a.reinterpreti64() == b.reinterpreti64());
  } else {
    abort();
  }
}

static void run_asserts(size_t* i, bool* checked, Module* wasm,
                        Element* root,
                        std::unique_ptr<SExpressionWasmBuilder>* builder,
                        Name entry) {
  std::unique_ptr<ShellExternalInterface> interface;
  std::unique_ptr<ModuleInstance> instance;
  if (wasm) {
    interface = wasm::make_unique<ShellExternalInterface>(); // prefix make_unique to work around visual studio bugs
    instance = wasm::make_unique<ModuleInstance>(*wasm, interface.get());
    if (entry.is()) {
      Function* function = wasm->getFunction(entry);
      if (!function) {
        std::cerr << "Unknown entry " << entry << std::endl;
      } else {
        LiteralList arguments;
        for (WasmType param : function->params) {
          arguments.push_back(Literal(param));
        }
        try {
          instance->callExport(entry, arguments);
        } catch (ExitException&) {
        }
      }
    }
  }
  while (*i < root->size()) {
    Element& curr = *(*root)[*i];
    IString id = curr[0]->str();
    if (id == MODULE) break;
    *checked = true;
    Colors::red(std::cerr);
    std::cerr << *i << '/' << (root->size() - 1);
    Colors::green(std::cerr);
    std::cerr << " CHECKING: ";
    Colors::normal(std::cerr);
    std::cerr << curr;
    Colors::green(std::cerr);
    std::cerr << " [line: " << curr.line << "]\n";
    Colors::normal(std::cerr);
    if (id == ASSERT_INVALID) {
      // a module invalidity test
      Module wasm;
      bool invalid = false;
      std::unique_ptr<SExpressionWasmBuilder> builder;
      try {
        builder = std::unique_ptr<SExpressionWasmBuilder>(
          new SExpressionWasmBuilder(wasm, *curr[1])
        );
      } catch (const ParseException&) {
        invalid = true;
      }
      if (!invalid) {
        // maybe parsed ok, but otherwise incorrect
        invalid = !WasmValidator().validate(wasm);
      }
      if (!invalid) {
        Colors::red(std::cerr);
        std::cerr << "[should have been invalid]\n";
        Colors::normal(std::cerr);
        std::cerr << &wasm << '\n';
        abort();
      }
    } else if (id == INVOKE) {
      assert(wasm);
      Invocation invocation(curr, instance.get(), *builder->get());
      invocation.invoke();
    } else {
      // an invoke test
      assert(wasm);
      bool trapped = false;
      WASM_UNUSED(trapped);
      Literal result;
      try {
        Invocation invocation(*curr[1], instance.get(), *builder->get());
        result = invocation.invoke();
      } catch (const TrapException&) {
        trapped = true;
      }
      if (id == ASSERT_RETURN) {
        assert(!trapped);
        if (curr.size() >= 3) {
          Literal expected = builder->get()
                                 ->parseExpression(*curr[2])
                                 ->dynCast<Const>()
                                 ->value;
          std::cerr << "seen " << result << ", expected " << expected << '\n';
          verify_result(expected, result);
        } else {
          Literal expected;
          std::cerr << "seen " << result << ", expected " << expected << '\n';
          verify_result(expected, result);
        }
      }
      if (id == ASSERT_TRAP) assert(trapped);
    }
    *i += 1;
  }
}

//
// main
//

int main(int argc, const char* argv[]) {
  Name entry;

  Options options("wasm-shell", "Execute .wast files");
  options
      .add(
          "--entry", "-e", "call the entry point after parsing the module",
          Options::Arguments::One,
          [&entry](Options*, const std::string& argument) { entry = argument; })
      .add_positional("INFILE", Options::Arguments::One,
                      [](Options* o, const std::string& argument) {
                        o->extra["infile"] = argument;
                      });
  options.parse(argc, argv);

  auto input(read_file<std::vector<char>>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release));

  bool checked = false;

  try {
    if (options.debug) std::cerr << "parsing text to s-expressions...\n";
    SExpressionParser parser(input.data());
    Element& root = *parser.root;

    // A .wast may have multiple modules, with some asserts after them
    size_t i = 0;
    while (i < root.size()) {
      Element& curr = *root[i];
      IString id = curr[0]->str();
      if (id == MODULE) {
        if (options.debug) std::cerr << "parsing s-expressions to wasm...\n";
        Module wasm;
        std::unique_ptr<SExpressionWasmBuilder> builder;
        builder = wasm::make_unique<SExpressionWasmBuilder>(wasm, *root[i]);
        i++;
        assert(WasmValidator().validate(wasm));
        run_asserts(&i, &checked, &wasm, &root, &builder, entry);
      } else {
        run_asserts(&i, &checked, nullptr, &root, nullptr, entry);
      }
    }
  } catch (ParseException& p) {
    p.dump(std::cerr);
    abort();
  }

  if (checked) {
    Colors::green(std::cerr);
    Colors::bold(std::cerr);
    std::cerr << "all checks passed.\n";
    Colors::normal(std::cerr);
  }
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkProbeFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2000 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

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

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

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

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

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

=========================================================================*/
#include "vtkProbeFilter.h"
#include "vtkObjectFactory.h"

//----------------------------------------------------------------------------
vtkProbeFilter* vtkProbeFilter::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkProbeFilter");
  if(ret)
    {
    return (vtkProbeFilter*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkProbeFilter;
}

//----------------------------------------------------------------------------
vtkProbeFilter::vtkProbeFilter()
{
  this->SpatialMatch = 0;
}

//----------------------------------------------------------------------------
vtkProbeFilter::~vtkProbeFilter()
{
}

//----------------------------------------------------------------------------
void vtkProbeFilter::SetSource(vtkDataSet *input)
{
  this->vtkProcessObject::SetNthInput(1, input);
}

//----------------------------------------------------------------------------
vtkDataSet *vtkProbeFilter::GetSource()
{
  if (this->NumberOfInputs < 2)
    {
    return NULL;
    }

  return (vtkDataSet *)(this->Inputs[1]);
}

//----------------------------------------------------------------------------
void vtkProbeFilter::Execute()
{
  int ptId;
  float *x, tol2;
  vtkCell *cell;
  vtkPointData *pd, *outPD;
  int numPts, subId;
  vtkDataSet *source = this->GetSource();
  vtkDataSet *input = this->GetInput();
  vtkDataSet *output= this->GetOutput();
  float pcoords[3], *weights;
  float fastweights[256];

  vtkDebugMacro(<<"Probing data");

  if (source == NULL)
    {
    vtkErrorMacro (<< "Source is NULL.");
    return;
    }

  pd = source->GetPointData();
  if (pd == NULL)
    {
    vtkErrorMacro(<< "PointData is NULL.");
    return;
    }

  // lets use a stack allocated array if possible for performance reasons
  int mcs = source->GetMaxCellSize();
  if (mcs<=256)
    {
    weights = fastweights;
    }
  else
    {
    weights = new float[mcs];
    }

  // First, copy the input to the output as a starting point
  output->CopyStructure( input );

  numPts = input->GetNumberOfPoints();
  //
  // Allocate storage for output PointData
  //
  outPD = output->GetPointData();
  outPD->InterpolateAllocate(pd);
  //
  // Use tolerance as a function of size of source data
  //
  tol2 = source->GetLength();
  tol2 = tol2*tol2 / 1000.0;
  //
  // Loop over all input points, interpolating source data
  //
  for (ptId=0; ptId < numPts; ptId++)
    {
    // Get the xyz coordinate of the point in the input dataset
    x = input->GetPoint(ptId);

    // Find the cell that contains xyz and get it
    cell = source->FindAndGetCell(x,NULL,-1,tol2,subId,pcoords,weights);
    if (cell)
      {
      // Interpolate the point data
      outPD->InterpolatePoint(pd,ptId,cell->PointIds,weights);
      }
    else
      {
      outPD->NullPoint(ptId);
      }
    }
  if (mcs>256)
    {
    delete [] weights;
    }
}

//----------------------------------------------------------------------------
void vtkProbeFilter::ExecuteInformation()
{
  if (this->GetInput() == NULL || this->GetSource() == NULL)
    {
    vtkErrorMacro("Missing input or source");
    return;
    }
  this->GetOutput()->SetMaximumNumberOfPieces(
                        this->GetInput()->GetMaximumNumberOfPieces());
}

//----------------------------------------------------------------------------
void vtkProbeFilter::ComputeInputUpdateExtents( vtkDataObject *output )
{
  vtkDataObject *input = this->GetInput();
  vtkDataObject *source = this->GetSource();
  int usePiece = 0;

  // What ever happend to CopyUpdateExtent in vtkDataObject?
  // Copying both piece and extent could be bad.  Setting the piece
  // of a structured data set will affect the extent.
  if (output->IsA("vtkUnstructuredPoints") || output->IsA("vtkPolyData"))
    {
    usePiece = 1;
    }

  if ( ! this->SpatialMatch)
    {
    source->SetUpdateExtent(0, 1, 0);
    }
  else
    {
    if (usePiece)
      {
      source->SetUpdateExtent(output->GetUpdatePiece(),
			      output->GetUpdateNumberOfPieces(),
			      output->GetUpdateGhostLevel());
      }
    else
      {
      source->SetUpdateExtent(output->GetUpdateExtent());
      }
    }

  if (usePiece)
    {
    input->SetUpdateExtent(output->GetUpdatePiece(),
			   output->GetUpdateNumberOfPieces(),
			   output->GetUpdateGhostLevel());
    }
  else
    {
    input->SetUpdateExtent(output->GetUpdateExtent());
    }
}

//----------------------------------------------------------------------------
void vtkProbeFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkDataSet *source = this->GetSource();

  vtkDataSetToDataSetFilter::PrintSelf(os,indent);
  os << indent << "Source: " << source << "\n";
  if (this->SpatialMatch)
    {
    os << indent << "SpatialMatchOn\n";
    }
  else
    {
    os << indent << "SpatialMatchOff\n";
    }
}
<commit_msg>Fixed bug: Probe was not executing because it was not setting the whole extent.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkProbeFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2000 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

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

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

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

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

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

=========================================================================*/
#include "vtkProbeFilter.h"
#include "vtkObjectFactory.h"

//----------------------------------------------------------------------------
vtkProbeFilter* vtkProbeFilter::New()
{
  // First try to create the object from the vtkObjectFactory
  vtkObject* ret = vtkObjectFactory::CreateInstance("vtkProbeFilter");
  if(ret)
    {
    return (vtkProbeFilter*)ret;
    }
  // If the factory was unable to create the object, then create it here.
  return new vtkProbeFilter;
}

//----------------------------------------------------------------------------
vtkProbeFilter::vtkProbeFilter()
{
  this->SpatialMatch = 0;
}

//----------------------------------------------------------------------------
vtkProbeFilter::~vtkProbeFilter()
{
}

//----------------------------------------------------------------------------
void vtkProbeFilter::SetSource(vtkDataSet *input)
{
  this->vtkProcessObject::SetNthInput(1, input);
}

//----------------------------------------------------------------------------
vtkDataSet *vtkProbeFilter::GetSource()
{
  if (this->NumberOfInputs < 2)
    {
    return NULL;
    }

  return (vtkDataSet *)(this->Inputs[1]);
}

//----------------------------------------------------------------------------
void vtkProbeFilter::Execute()
{
  int ptId;
  float *x, tol2;
  vtkCell *cell;
  vtkPointData *pd, *outPD;
  int numPts, subId;
  vtkDataSet *source = this->GetSource();
  vtkDataSet *input = this->GetInput();
  vtkDataSet *output= this->GetOutput();
  float pcoords[3], *weights;
  float fastweights[256];

  vtkDebugMacro(<<"Probing data");

  if (source == NULL)
    {
    vtkErrorMacro (<< "Source is NULL.");
    return;
    }

  pd = source->GetPointData();
  if (pd == NULL)
    {
    vtkErrorMacro(<< "PointData is NULL.");
    return;
    }

  // lets use a stack allocated array if possible for performance reasons
  int mcs = source->GetMaxCellSize();
  if (mcs<=256)
    {
    weights = fastweights;
    }
  else
    {
    weights = new float[mcs];
    }

  // First, copy the input to the output as a starting point
  output->CopyStructure( input );

  numPts = input->GetNumberOfPoints();
  //
  // Allocate storage for output PointData
  //
  outPD = output->GetPointData();
  outPD->InterpolateAllocate(pd);
  //
  // Use tolerance as a function of size of source data
  //
  tol2 = source->GetLength();
  tol2 = tol2*tol2 / 1000.0;
  //
  // Loop over all input points, interpolating source data
  //
  for (ptId=0; ptId < numPts; ptId++)
    {
    // Get the xyz coordinate of the point in the input dataset
    x = input->GetPoint(ptId);

    // Find the cell that contains xyz and get it
    cell = source->FindAndGetCell(x,NULL,-1,tol2,subId,pcoords,weights);
    if (cell)
      {
      // Interpolate the point data
      outPD->InterpolatePoint(pd,ptId,cell->PointIds,weights);
      }
    else
      {
      outPD->NullPoint(ptId);
      }
    }
  if (mcs>256)
    {
    delete [] weights;
    }
}

//----------------------------------------------------------------------------
void vtkProbeFilter::ExecuteInformation()
{
  // Copy whole extent ...
  this->vtkSource::ExecuteInformation();

  if (this->GetInput() == NULL || this->GetSource() == NULL)
    {
    vtkErrorMacro("Missing input or source");
    return;
    }
  this->GetOutput()->SetMaximumNumberOfPieces(
                        this->GetInput()->GetMaximumNumberOfPieces());
}

//----------------------------------------------------------------------------
void vtkProbeFilter::ComputeInputUpdateExtents( vtkDataObject *output )
{
  vtkDataObject *input = this->GetInput();
  vtkDataObject *source = this->GetSource();
  int usePiece = 0;

  // What ever happend to CopyUpdateExtent in vtkDataObject?
  // Copying both piece and extent could be bad.  Setting the piece
  // of a structured data set will affect the extent.
  if (output->IsA("vtkUnstructuredPoints") || output->IsA("vtkPolyData"))
    {
    usePiece = 1;
    }

  if ( ! this->SpatialMatch)
    {
    source->SetUpdateExtent(0, 1, 0);
    }
  else
    {
    if (usePiece)
      {
      source->SetUpdateExtent(output->GetUpdatePiece(),
			      output->GetUpdateNumberOfPieces(),
			      output->GetUpdateGhostLevel());
      }
    else
      {
      source->SetUpdateExtent(output->GetUpdateExtent());
      }
    }

  if (usePiece)
    {
    input->SetUpdateExtent(output->GetUpdatePiece(),
			   output->GetUpdateNumberOfPieces(),
			   output->GetUpdateGhostLevel());
    }
  else
    {
    input->SetUpdateExtent(output->GetUpdateExtent());
    }
}

//----------------------------------------------------------------------------
void vtkProbeFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkDataSet *source = this->GetSource();

  vtkDataSetToDataSetFilter::PrintSelf(os,indent);
  os << indent << "Source: " << source << "\n";
  if (this->SpatialMatch)
    {
    os << indent << "SpatialMatchOn\n";
    }
  else
    {
    os << indent << "SpatialMatchOff\n";
    }
}
<|endoftext|>


<commit_before>// @(#)root/gui:$Name:  $:$Id: TGButtonGroup.cxx,v 1.6 2001/04/11 17:25:41 brun Exp $
// Author: Valeriy Onuchin & Fons Rademakers   16/10/2000

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// The TGButtonGroup widget organizes TGButton widgets in a group.      //
//                                                                      //
// A button group widget makes it easier to deal with groups of buttons.//
// A button in a button group is associated with a unique identifer.    //
// The button group emits a Clicked() signal with this identifier when  //
// the button is clicked. Thus, a button group is an ideal solution     //
// when you have several similar buttons and want to connect all their  //
// Clicked() signals, for example, to one slot.                         //
//                                                                      //
// An exclusive button group switches off all toggle buttons except     //
// the one that was clicked. A button group is by default non-exclusive.//
// All radio buttons that are inserted, will be mutually exclusive even //
// if the button group is non-exclusive.                                //
//                                                                      //
//                                                                      //
// There are two ways of using a button group:                          //
//                                                                      //
//    The button group is a parent widget of a number of buttons,       //
//    i.e. the button group is the parent argument in the button        //
//    constructor. The buttons are assigned identifiers 1, 2, 3 etc.    //
///   in the order they are created or you can specify button id in     //
//    the button constructor. A TGButtonGroup can display a frame and   //
//    a title because it inherits from TGGroupFrame.                    //
//                                                                      //
// Example:                                                             //
//                                                                      //
//    // vertical frame without border and title                        //
//    TGVButtonGroup *bg = new TGVButtonGroup(main_frame);              //
//                                                                      //
//    // create text button with id=1                                   //
//    TGTextButton *button1 = new TGTextButton(bg,"some text");         //
//                                                                      //
//    // create another text button with id=2                           //
//    TGTextButton *button2 = new TGTextButton(bg,"another text");      //
//                                                                      //
//    // map all buttons                                                //
//    bg->Show();                                                       //
//                                                                      //
//                                                                      //
//  ButtonGroup Signals:                                                //
//                                                                      //
//    Pressed(Int_t id)  -->  is emitted when a button in the group is  //
//                            pressed down. The id argument is the      //
//                            button's identifier.                      //
//    Released(Int_t id) -->  is emitted when a button in the group is  //
//                            released. The id argument is the button's //
//                            identifier.                               //
//    Clicked(Int_t id)  -->  is emitted when a button in the group is  //
//                            clicked. The id argument is the button's  //
//                            identifier.                               //
//                                                                      //
//                                                                      //
// The TGHButtonGroup widget organizes TGButton widgets in a group      //
// with one horizontal row. TGHButtonGroup is a convenience class that  //
// offers a thin layer on top of TGButtonGroup. It inherits from        //
// TGButtonGroup.                                                       //
//                                                                      //
// The TGVButtonGroup widget organizes TGButton widgets in a group      //
// with one vertical column. TGVButtonGroup is a convenience class that //
// offers a thin layer on top of TGButtonGroup. It inherits from        //
// TGButtonGroup.                                                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TGButtonGroup.h"
#include "TGButton.h"
#include "TClass.h"
#include "TGLayout.h"

ClassImpQ(TGButtonGroup)
ClassImpQ(TGHButtonGroup)
ClassImpQ(TGVButtonGroup)

//______________________________________________________________________________
TGButtonGroup::TGButtonGroup(TGWindow *parent,
                             const TString &title,
                             UInt_t options,
                             GContext_t norm,
                             FontStruct_t font,
                             ULong_t back) :
   TGGroupFrame(parent, new TGString(title), options, norm, font, back)
{
   // Constructor. Layout 1 row or 1 column.

   Init();
   if (options & kVerticalFrame) {
      SetLayoutManager(new TGVerticalLayout(this));
   } else {
      SetLayoutManager(new TGHorizontalLayout(this));
   }

   fDrawBorder = !title.IsNull();
}

//______________________________________________________________________________
TGButtonGroup::TGButtonGroup(TGWindow *parent,
                             UInt_t r, UInt_t c,
                             Int_t s, Int_t h,
                             const TString &title,
                             GContext_t norm ,
                             FontStruct_t font ,
                             ULong_t back) :
   TGGroupFrame(parent, new TGString(title), 0, norm, font, back)
{
   // Constructor. Layout defined by TGMatrixLayout:
   //    r = number of rows
   //    c = number of columns
   //    s = interval between frames
   //    h = layout hints

   Init();
   fDrawBorder = !title.IsNull();
   SetLayoutManager(new TGMatrixLayout(this,r,c,s,h));
}

//______________________________________________________________________________
void TGButtonGroup::Init()
{
   // Default init.

   fMapOfButtons = new TMap();  // map of button/id pairs
   fExclGroup    = kFALSE;
   fRadioExcl    = kFALSE;
   fDrawBorder   = kTRUE;
}

//______________________________________________________________________________
TGButtonGroup::~TGButtonGroup()
{
   // Destructor, we do not delete the buttons.

   TIter next(fMapOfButtons);
   register TGButton *item = 0;

   while ((item = (TGButton*)next())) {
      item->SetGroup(0);
   }

   SafeDelete(fMapOfButtons);
}

//______________________________________________________________________________
void TGButtonGroup::SetBorderDrawn(Bool_t enable)
{
   // Makes border to be visible/invisible.

   if (enable != IsBorderDrawn()) {
      fDrawBorder = enable;
      ChangedBy("SetBorderDrawn");        // emit signal
   }
}

//______________________________________________________________________________
void TGButtonGroup::SetExclusive(Bool_t enable)
{
   // Sets the button group to be exclusive if enable is kTRUE,
   // or to be non-exclusive if enable is kFALSE.
   // An exclusive button group switches off all other toggle buttons when
   // one is switched on. This is ideal for groups of radio-buttons
   // A non-exclusive group allow many buttons to be switched on at the same
   // time. The default setting is kFALSE.

   if (enable != IsExclusive()) {
      fExclGroup = enable;
      ChangedBy("SetExclusive");  // emit signal
   }
}

//______________________________________________________________________________
void TGButtonGroup::SetRadioButtonExclusive(Bool_t enable)
{
   // If enable is kTRUE, this button group will treat radio buttons as
   // mutually exclusive, and other buttons according to IsExclusive().
   // This function is called automatically whenever a TGRadioButton
   // is inserted, so you should normally never have to call it.

   if (enable != IsRadioButtonExclusive()) {
      fRadioExcl = enable;
      ChangedBy("SetRadioButtonExclusive"); // emit signal
   }
}

//______________________________________________________________________________
void TGButtonGroup::SetButton(Int_t id, Bool_t down)
{
   // Sets the button with id to be on/down, and if this is an
   // exclusive group, all other button in the group to be off/up.

   TGButton *b = Find(id);
   if (b) b->SetDown(down);
}

//______________________________________________________________________________
Int_t TGButtonGroup::Insert(TGButton *button, Int_t id)
{
   // Inserts a button with the identifier id into the button group.
   // Returns the button identifier.
   //
   // It is not necessary to manually insert buttons that have this button
   // group as their parent widget. An exception is when you want custom
   // identifiers instead of the default 1, 2, 3 etc.
   //
   // The button is assigned the identifier id or an automatically
   // generated identifier.  It works as follows: If id > 0, this
   // identifier is assigned.  If id == -1 (default), the identifier is
   // equal to the number of buttons in the group+1.  If id is any other
   // negative integer, for instance -2, a unique identifier (negative
   // integer <= -2) is generated.
   //
   // Inserting several buttons with id = -1 assigns the identifiers 1,
   // 2, 3, etc.

   if (button->fGroup && button->fGroup != this)
      button->fGroup->Remove(button);

   if (button->fGroup == this) {
      if (id == -1)
         return GetId(button);    // the button is already in group
      else
         button->fGroup->Remove(button);  // want to set a new id
   }

   button->fGroup = this;

   static int seq_no = -2;
   int bid;

   if (id < -1)       bid = seq_no--;
   else if (id == -1) bid = GetCount()+1;
   else               bid = id;

   fMapOfButtons->Add(button, (TObject*)bid);
   AddFrame(button);

   SetRadioButtonExclusive(button->IsA()->InheritsFrom(TGRadioButton::Class()));

   Connect(button, "Pressed()" , "TGButtonGroup", this, "ReleaseButtons()");
   Connect(button, "Pressed()" , "TGButtonGroup", this, "ButtonPressed()");
   Connect(button, "Released()", "TGButtonGroup", this, "ButtonReleased()");
   Connect(button, "Clicked()" , "TGButtonGroup", this, "ButtonClicked()");

   return bid;
}

//______________________________________________________________________________
void TGButtonGroup::Remove(TGButton *button)
{
   // Removes a button from the button group.

   TGButton *item = (TGButton*) fMapOfButtons->Remove(button);
   if (item) {
      button->SetGroup(0);
      button->Disconnect(this);
   }

   RemoveFrame(button);
}

//______________________________________________________________________________
TGButton *TGButtonGroup::Find(Int_t id) const
{
   // Finds and returns a pointer to the button with the specified
   // identifier id. Returns null if the button was not found.

   TIter next(fMapOfButtons);
   register TGButton *item = 0;

   while ((item = (TGButton*)next())) {
      if ((Long_t)fMapOfButtons->GetValue(item) == id) break;   // found
   }

   return item;
}

//______________________________________________________________________________
Int_t TGButtonGroup::GetId(TGButton *button) const
{
   // Finds and returns the id of the button.
   // Returns -1 if the button is not a member of this group.

   TAssoc *a = (TAssoc*) fMapOfButtons->FindObject(button);
   if (a)
      return (Int_t)Long_t(a->Value());
   else
      return -1;
}

//______________________________________________________________________________
void TGButtonGroup::ButtonPressed()
{
   // This slot is activated when one of the buttons in the group emits the
   // Pressed() signal.

#if 0
   // Is here for historical purposes and example. Now this is not needed
   // anymore since TGButton has has its own GetSender() method returning
   // the TGButton proper.

   // This is needed since gTQSender points to TQObject part of TGButton
#ifdef R__RTTI
   TGButton *btn = dynamic_cast<TGButton*>((TQObject*)gTQSender);
#else
   TQObject *oq = (TQObject*)gTQSender;
   TGButton *btn = (TGButton*)oq->IsA()->DynamicCast(TQObject::Class(), oq, kFALSE);
#endif
   if (!btn) {
      Error("ButtonPressed", "gTQSender not a TGButton");
      return;
   }
#else
      TGButton *btn = (TGButton*)gTQSender;
#endif

   TAssoc *a = (TAssoc*) fMapOfButtons->FindObject(btn);
   if (a) {
      Int_t id = (Int_t)Long_t(a->Value());
      Pressed(id);
   }
}

//______________________________________________________________________________
void TGButtonGroup::ButtonReleased()
{
   // This slot is activated when one of the buttons in the group emits the
   // Released() signal.

   TGButton *btn = (TGButton*)gTQSender;

   TAssoc *a = (TAssoc*) fMapOfButtons->FindObject(btn);
   if (a) {
      Int_t id = (Int_t)Long_t(a->Value());
      Released(id);
   }
}

//______________________________________________________________________________
void TGButtonGroup::ButtonClicked()
{
   // This slot is activated when one of the buttons in the group emits the
   // Clicked() signal.

   TGButton *btn = (TGButton*)gTQSender;

   TAssoc *a = (TAssoc*) fMapOfButtons->FindObject(btn);
   if (a) {
      Int_t id = (Int_t)Long_t(a->Value());
      Clicked(id);
   }
}

//______________________________________________________________________________
void TGButtonGroup::ReleaseButtons()
{
   // This slot is activated when one of the buttons in the
   // exclusive group emits the Pressed() signal.

   if (!fExclGroup && !fRadioExcl) return;

   TGButton *btn = (TGButton*)gTQSender;

   if (!fExclGroup && !btn->IsA()->InheritsFrom(TGRadioButton::Class()))
      return;

   TIter next(fMapOfButtons);
   register TGButton *item = 0;

   while ((item = (TGButton*)next())) {    // loop over all buttons
      item->SetDown(btn==item);
   }
}

//______________________________________________________________________________
void TGButtonGroup::Show()
{
   // Show group of buttons.

   MapSubwindows();
   Layout();
   Resize(GetLayoutManager()->GetDefaultSize());
   MapRaised();
   fClient->NeedRedraw(this);
}

//______________________________________________________________________________
void TGButtonGroup::Hide()
{
   // Hide group of buttons.

   UnmapWindow();
}

//______________________________________________________________________________
void TGButtonGroup::SetTitle(TGString *title)
{
   // Set or change title.

   if (!title) {
      Error("SetTitle", "title cannot be 0, try \"\"");
      return;
   }

   if (strcmp(fText->GetString(), title->GetString())) {
      SetBorderDrawn(title->GetLength() ? kTRUE : kFALSE);
      TGGroupFrame::SetTitle(title);
      ChangedBy("SetTitle");
   }
}

//______________________________________________________________________________
void TGButtonGroup::SetTitle(const char *title)
{
   // Set or change title.

   if (!title) {
      Error("SetTitle", "title cannot be 0, try \"\"");
      return;
   }

   if (strcmp(fText->GetString(), title)) {
      SetBorderDrawn(title && strlen(title));
      TGGroupFrame::SetTitle(title);
      ChangedBy("SetTitle");
   }
}

//______________________________________________________________________________
void TGButtonGroup::SetLayoutHints(TGLayoutHints *l, TGButton *button)
{
   // Set layout hints.

   TGFrameElement *el;
   TIter next(fList);

   while ((el = (TGFrameElement *)next())) {
      if ((el->fFrame==(TGFrame*)button) || !button) {
         el->fLayout = l ? l : fgDefaultHints;
      }
   }
   Layout();
}

<commit_msg>added extra comment on how buttons are to be added to the button group (no need to call AddFrame() and the use of SetLayoutHints()).<commit_after>// @(#)root/gui:$Name:  $:$Id: TGButtonGroup.cxx,v 1.7 2001/04/12 08:13:19 rdm Exp $
// Author: Valeriy Onuchin & Fons Rademakers   16/10/2000

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// The TGButtonGroup widget organizes TGButton widgets in a group.      //
//                                                                      //
// A button group widget makes it easier to deal with groups of buttons.//
// A button in a button group is associated with a unique identifer.    //
// The button group emits a Clicked() signal with this identifier when  //
// the button is clicked. Thus, a button group is an ideal solution     //
// when you have several similar buttons and want to connect all their  //
// Clicked() signals, for example, to one slot.                         //
//                                                                      //
// An exclusive button group switches off all toggle buttons except     //
// the one that was clicked. A button group is by default non-exclusive.//
// All radio buttons that are inserted, will be mutually exclusive even //
// if the button group is non-exclusive.                                //
//                                                                      //
//                                                                      //
// There are two ways of using a button group:                          //
//                                                                      //
//    The button group is a parent widget of a number of buttons,       //
//    i.e. the button group is the parent argument in the button        //
//    constructor. The buttons are assigned identifiers 1, 2, 3 etc.    //
///   in the order they are created or you can specify button id in     //
//    the button constructor. A TGButtonGroup can display a frame and   //
//    a title because it inherits from TGGroupFrame.                    //
//                                                                      //
// Example:                                                             //
//                                                                      //
//    // vertical frame without border and title                        //
//    TGVButtonGroup *bg = new TGVButtonGroup(main_frame);              //
//                                                                      //
//    // create text button with id=1                                   //
//    TGTextButton *button1 = new TGTextButton(bg,"some text");         //
//                                                                      //
//    // create another text button with id=2                           //
//    TGTextButton *button2 = new TGTextButton(bg,"another text");      //
//                                                                      //
//    // map all buttons                                                //
//    bg->Show();                                                       //
//                                                                      //
// NOTE: there is no need to call AddFrame() since the buttons are      //
// automatically added with a default layout hint to their parent,      //
// i.e. the buttongroup. To override the default layout hints use the   //
// SetLayoutHints() method.                                             //
//                                                                      //
//  ButtonGroup Signals:                                                //
//                                                                      //
//    Pressed(Int_t id)  -->  is emitted when a button in the group is  //
//                            pressed down. The id argument is the      //
//                            button's identifier.                      //
//    Released(Int_t id) -->  is emitted when a button in the group is  //
//                            released. The id argument is the button's //
//                            identifier.                               //
//    Clicked(Int_t id)  -->  is emitted when a button in the group is  //
//                            clicked. The id argument is the button's  //
//                            identifier.                               //
//                                                                      //
//                                                                      //
// The TGHButtonGroup widget organizes TGButton widgets in a group      //
// with one horizontal row. TGHButtonGroup is a convenience class that  //
// offers a thin layer on top of TGButtonGroup. It inherits from        //
// TGButtonGroup.                                                       //
//                                                                      //
// The TGVButtonGroup widget organizes TGButton widgets in a group      //
// with one vertical column. TGVButtonGroup is a convenience class that //
// offers a thin layer on top of TGButtonGroup. It inherits from        //
// TGButtonGroup.                                                       //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TGButtonGroup.h"
#include "TGButton.h"
#include "TClass.h"
#include "TGLayout.h"

ClassImpQ(TGButtonGroup)
ClassImpQ(TGHButtonGroup)
ClassImpQ(TGVButtonGroup)

//______________________________________________________________________________
TGButtonGroup::TGButtonGroup(TGWindow *parent,
                             const TString &title,
                             UInt_t options,
                             GContext_t norm,
                             FontStruct_t font,
                             ULong_t back) :
   TGGroupFrame(parent, new TGString(title), options, norm, font, back)
{
   // Constructor. Layout 1 row or 1 column.

   Init();
   if (options & kVerticalFrame) {
      SetLayoutManager(new TGVerticalLayout(this));
   } else {
      SetLayoutManager(new TGHorizontalLayout(this));
   }

   fDrawBorder = !title.IsNull();
}

//______________________________________________________________________________
TGButtonGroup::TGButtonGroup(TGWindow *parent,
                             UInt_t r, UInt_t c,
                             Int_t s, Int_t h,
                             const TString &title,
                             GContext_t norm ,
                             FontStruct_t font ,
                             ULong_t back) :
   TGGroupFrame(parent, new TGString(title), 0, norm, font, back)
{
   // Constructor. Layout defined by TGMatrixLayout:
   //    r = number of rows
   //    c = number of columns
   //    s = interval between frames
   //    h = layout hints

   Init();
   fDrawBorder = !title.IsNull();
   SetLayoutManager(new TGMatrixLayout(this,r,c,s,h));
}

//______________________________________________________________________________
void TGButtonGroup::Init()
{
   // Default init.

   fMapOfButtons = new TMap();  // map of button/id pairs
   fExclGroup    = kFALSE;
   fRadioExcl    = kFALSE;
   fDrawBorder   = kTRUE;
}

//______________________________________________________________________________
TGButtonGroup::~TGButtonGroup()
{
   // Destructor, we do not delete the buttons.

   TIter next(fMapOfButtons);
   register TGButton *item = 0;

   while ((item = (TGButton*)next())) {
      item->SetGroup(0);
   }

   SafeDelete(fMapOfButtons);
}

//______________________________________________________________________________
void TGButtonGroup::SetBorderDrawn(Bool_t enable)
{
   // Makes border to be visible/invisible.

   if (enable != IsBorderDrawn()) {
      fDrawBorder = enable;
      ChangedBy("SetBorderDrawn");        // emit signal
   }
}

//______________________________________________________________________________
void TGButtonGroup::SetExclusive(Bool_t enable)
{
   // Sets the button group to be exclusive if enable is kTRUE,
   // or to be non-exclusive if enable is kFALSE.
   // An exclusive button group switches off all other toggle buttons when
   // one is switched on. This is ideal for groups of radio-buttons
   // A non-exclusive group allow many buttons to be switched on at the same
   // time. The default setting is kFALSE.

   if (enable != IsExclusive()) {
      fExclGroup = enable;
      ChangedBy("SetExclusive");  // emit signal
   }
}

//______________________________________________________________________________
void TGButtonGroup::SetRadioButtonExclusive(Bool_t enable)
{
   // If enable is kTRUE, this button group will treat radio buttons as
   // mutually exclusive, and other buttons according to IsExclusive().
   // This function is called automatically whenever a TGRadioButton
   // is inserted, so you should normally never have to call it.

   if (enable != IsRadioButtonExclusive()) {
      fRadioExcl = enable;
      ChangedBy("SetRadioButtonExclusive"); // emit signal
   }
}

//______________________________________________________________________________
void TGButtonGroup::SetButton(Int_t id, Bool_t down)
{
   // Sets the button with id to be on/down, and if this is an
   // exclusive group, all other button in the group to be off/up.

   TGButton *b = Find(id);
   if (b) b->SetDown(down);
}

//______________________________________________________________________________
Int_t TGButtonGroup::Insert(TGButton *button, Int_t id)
{
   // Inserts a button with the identifier id into the button group.
   // Returns the button identifier.
   //
   // It is not necessary to manually insert buttons that have this button
   // group as their parent widget. An exception is when you want custom
   // identifiers instead of the default 1, 2, 3 etc.
   //
   // The button is assigned the identifier id or an automatically
   // generated identifier.  It works as follows: If id > 0, this
   // identifier is assigned.  If id == -1 (default), the identifier is
   // equal to the number of buttons in the group+1.  If id is any other
   // negative integer, for instance -2, a unique identifier (negative
   // integer <= -2) is generated.
   //
   // Inserting several buttons with id = -1 assigns the identifiers 1,
   // 2, 3, etc.

   if (button->fGroup && button->fGroup != this)
      button->fGroup->Remove(button);

   if (button->fGroup == this) {
      if (id == -1)
         return GetId(button);    // the button is already in group
      else
         button->fGroup->Remove(button);  // want to set a new id
   }

   button->fGroup = this;

   static int seq_no = -2;
   int bid;

   if (id < -1)       bid = seq_no--;
   else if (id == -1) bid = GetCount()+1;
   else               bid = id;

   fMapOfButtons->Add(button, (TObject*)bid);
   AddFrame(button);

   SetRadioButtonExclusive(button->IsA()->InheritsFrom(TGRadioButton::Class()));

   Connect(button, "Pressed()" , "TGButtonGroup", this, "ReleaseButtons()");
   Connect(button, "Pressed()" , "TGButtonGroup", this, "ButtonPressed()");
   Connect(button, "Released()", "TGButtonGroup", this, "ButtonReleased()");
   Connect(button, "Clicked()" , "TGButtonGroup", this, "ButtonClicked()");

   return bid;
}

//______________________________________________________________________________
void TGButtonGroup::Remove(TGButton *button)
{
   // Removes a button from the button group.

   TGButton *item = (TGButton*) fMapOfButtons->Remove(button);
   if (item) {
      button->SetGroup(0);
      button->Disconnect(this);
   }

   RemoveFrame(button);
}

//______________________________________________________________________________
TGButton *TGButtonGroup::Find(Int_t id) const
{
   // Finds and returns a pointer to the button with the specified
   // identifier id. Returns null if the button was not found.

   TIter next(fMapOfButtons);
   register TGButton *item = 0;

   while ((item = (TGButton*)next())) {
      if ((Long_t)fMapOfButtons->GetValue(item) == id) break;   // found
   }

   return item;
}

//______________________________________________________________________________
Int_t TGButtonGroup::GetId(TGButton *button) const
{
   // Finds and returns the id of the button.
   // Returns -1 if the button is not a member of this group.

   TAssoc *a = (TAssoc*) fMapOfButtons->FindObject(button);
   if (a)
      return (Int_t)Long_t(a->Value());
   else
      return -1;
}

//______________________________________________________________________________
void TGButtonGroup::ButtonPressed()
{
   // This slot is activated when one of the buttons in the group emits the
   // Pressed() signal.

#if 0
   // Is here for historical purposes and example. Now this is not needed
   // anymore since TGButton has has its own GetSender() method returning
   // the TGButton proper.

   // This is needed since gTQSender points to TQObject part of TGButton
#ifdef R__RTTI
   TGButton *btn = dynamic_cast<TGButton*>((TQObject*)gTQSender);
#else
   TQObject *oq = (TQObject*)gTQSender;
   TGButton *btn = (TGButton*)oq->IsA()->DynamicCast(TQObject::Class(), oq, kFALSE);
#endif
   if (!btn) {
      Error("ButtonPressed", "gTQSender not a TGButton");
      return;
   }
#else
      TGButton *btn = (TGButton*)gTQSender;
#endif

   TAssoc *a = (TAssoc*) fMapOfButtons->FindObject(btn);
   if (a) {
      Int_t id = (Int_t)Long_t(a->Value());
      Pressed(id);
   }
}

//______________________________________________________________________________
void TGButtonGroup::ButtonReleased()
{
   // This slot is activated when one of the buttons in the group emits the
   // Released() signal.

   TGButton *btn = (TGButton*)gTQSender;

   TAssoc *a = (TAssoc*) fMapOfButtons->FindObject(btn);
   if (a) {
      Int_t id = (Int_t)Long_t(a->Value());
      Released(id);
   }
}

//______________________________________________________________________________
void TGButtonGroup::ButtonClicked()
{
   // This slot is activated when one of the buttons in the group emits the
   // Clicked() signal.

   TGButton *btn = (TGButton*)gTQSender;

   TAssoc *a = (TAssoc*) fMapOfButtons->FindObject(btn);
   if (a) {
      Int_t id = (Int_t)Long_t(a->Value());
      Clicked(id);
   }
}

//______________________________________________________________________________
void TGButtonGroup::ReleaseButtons()
{
   // This slot is activated when one of the buttons in the
   // exclusive group emits the Pressed() signal.

   if (!fExclGroup && !fRadioExcl) return;

   TGButton *btn = (TGButton*)gTQSender;

   if (!fExclGroup && !btn->IsA()->InheritsFrom(TGRadioButton::Class()))
      return;

   TIter next(fMapOfButtons);
   register TGButton *item = 0;

   while ((item = (TGButton*)next())) {    // loop over all buttons
      item->SetDown(btn==item);
   }
}

//______________________________________________________________________________
void TGButtonGroup::Show()
{
   // Show group of buttons.

   MapSubwindows();
   Layout();
   Resize(GetLayoutManager()->GetDefaultSize());
   MapRaised();
   fClient->NeedRedraw(this);
}

//______________________________________________________________________________
void TGButtonGroup::Hide()
{
   // Hide group of buttons.

   UnmapWindow();
}

//______________________________________________________________________________
void TGButtonGroup::SetTitle(TGString *title)
{
   // Set or change title.

   if (!title) {
      Error("SetTitle", "title cannot be 0, try \"\"");
      return;
   }

   if (strcmp(fText->GetString(), title->GetString())) {
      SetBorderDrawn(title->GetLength() ? kTRUE : kFALSE);
      TGGroupFrame::SetTitle(title);
      ChangedBy("SetTitle");
   }
}

//______________________________________________________________________________
void TGButtonGroup::SetTitle(const char *title)
{
   // Set or change title.

   if (!title) {
      Error("SetTitle", "title cannot be 0, try \"\"");
      return;
   }

   if (strcmp(fText->GetString(), title)) {
      SetBorderDrawn(title && strlen(title));
      TGGroupFrame::SetTitle(title);
      ChangedBy("SetTitle");
   }
}

//______________________________________________________________________________
void TGButtonGroup::SetLayoutHints(TGLayoutHints *l, TGButton *button)
{
   // Set layout hints for the specified button or if button=0 for all
   // buttons.

   TGFrameElement *el;
   TIter next(fList);

   while ((el = (TGFrameElement *)next())) {
      if ((el->fFrame==(TGFrame*)button) || !button) {
         el->fLayout = l ? l : fgDefaultHints;
      }
   }
   Layout();
}

<|endoftext|>