<commit_before>#include <aleph/topology/io/LexicographicTriangulation.hh>

#include <aleph/persistentHomology/Calculation.hh>
#include <aleph/persistentHomology/PhiPersistence.hh>

#include <aleph/topology/BarycentricSubdivision.hh>
#include <aleph/topology/Simplex.hh>
#include <aleph/topology/SimplicialComplex.hh>
#include <aleph/topology/Skeleton.hh>

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

using DataType          = bool;
using VertexType        = unsigned short;

using Simplex           = aleph::topology::Simplex<DataType, VertexType>;
using SimplicialComplex = aleph::topology::SimplicialComplex<Simplex>;

/**
  Models a signature consisting of Betti numbers, i.e. a set of natural
  numbers. Signatures are comparable and are ordered lexicographically,
  i.e. in the manner one would expect.
*/

class Signature
{
public:
  template <class InputIterator> Signature( InputIterator begin, InputIterator end )
    : _betti( begin, end )
  {
  }

  bool operator<( const Signature& other ) const noexcept
  {
    return std::lexicographical_compare( _betti.begin(), _betti.end(),
                                         other._betti.begin(), other._betti.end() );
  }

  long eulerCharacteristic() const noexcept
  {
    long chi = 0;
    bool s   = true;

    for( auto&& betti : _betti )
    {
      chi = s ? chi + betti : chi - betti;
      s   = !s;
    }

    return chi;
  }

  using const_iterator = typename std::vector<std::size_t>::const_iterator;

  const_iterator begin() const noexcept { return _betti.begin(); }
  const_iterator end()   const noexcept { return _betti.end() ;  }

private:
  std::vector<std::size_t> _betti;
};

std::ostream& operator<<( std::ostream& o, const Signature& s )
{
  o << "[";

  for( auto it = s.begin(); it != s.end(); ++it )
  {
    if( it != s.begin() )
      o << ",";

    o << *it;
  }

  o << "]";

  return o;
}

/**
  Converts a vector of persistence diagrams into a Betti signature. The
  maximum dimension needs to be specified in order to ensure that empty
  or missing persistence diagrams can still be handled correctly.
*/

template <class PersistenceDiagram> Signature makeSignature( const std::vector<PersistenceDiagram>& diagrams, std::size_t D )
{
  std::vector<std::size_t> bettiNumbers( D+1 );

  for( auto&& diagram : diagrams )
  {
    auto d = diagram.dimension();
    auto b = diagram.betti();

    bettiNumbers.at(d) = b;
  }

  return Signature( bettiNumbers.begin(), bettiNumbers.end() );
}

/**
  Enumerates all possible perversities for a given dimension. One could
  say that this function is as wicked as possible.
*/

std::vector<aleph::Perversity> getPerversities( unsigned dimension )
{
  std::vector<aleph::Perversity> perversities;

  std::map< unsigned, std::vector<int> > possibleValues;

  for( unsigned d = 0; d < dimension; d++ )
  {
    // Note that no shift in dimensions is required: as the dimension is
    // zero-based, the maximum value of the perversity in dimension zero
    // is zero. This is identical to demanding
    //
    //   -1 \leq p_k \leq k-1
    //
    // for k = [1,...,d].
    for( int k = -1; k <= static_cast<int>( d ); k++ )
      possibleValues[d].push_back( k );
  }

  std::size_t numCombinations = 1;

  for( auto&& pair : possibleValues )
    numCombinations *= pair.second.size();

  // Stores the current index that was reached while traversing all
  // possible values of the perversity. The idea is that to add one
  // to the last index upon adding a new value. If the index is too
  // large, it goes back to zero and the previous index is modified
  // by one.
  std::vector<std::size_t> indices( possibleValues.size() );

  for( std::size_t i = 0; i < numCombinations; i++ )
  {
    std::vector<int> values;

    for( unsigned d = 0; d < dimension; d++ )
    {
      auto index = indices.at(d);
      values.emplace_back( possibleValues.at(d).at(index) );
    }

    // Always increase the last used index by one. If an overflow
    // occurs, the previous indices are updated as well.
    {
      auto last        = dimension - 1;
      indices.at(last) = indices.at(last) + 1;

      // Check & propagate potential overflows to the previous indices
      // in the range. The index vector is reset to zero only when all
      // combinations have been visited.
      if( indices.at(last) >= possibleValues.at(last).size() )
      {
        indices.at(last) = 0;
        for( unsigned d = 1; d < dimension; d++ )
        {
          auto D        = dimension - 1 - d;
          indices.at(D) = indices.at(D) + 1;

          if( indices.at(D) < possibleValues.at(D).size() )
            break;
          else
            indices.at(D) = 0;
        }
      }
    }

    perversities.emplace_back( aleph::Perversity( values.begin(), values.end() ) );
  }

  return perversities;
}

int main(int argc, char* argv[])
{
  if( argc <= 1 )
    return -1;

  std::string filename = argv[1];
  std::vector<SimplicialComplex> simplicialComplexes;

  aleph::topology::io::LexicographicTriangulationReader reader;
  reader( filename, simplicialComplexes );

  // Create missing faces ----------------------------------------------
  //
  // The triangulations are only specified by their top-level simplices,
  // so they need to be converted before being valid inputs for homology
  // calculations.

  for( auto&& K : simplicialComplexes )
  {
    K.createMissingFaces();
    K.sort();
  }

  // Calculate homology ------------------------------------------------
  //
  // We are only interested in the Betti numbers of the diagrams here as
  // the triangulations are not endowed with any weights or values.

  for( auto&& K : simplicialComplexes )
  {
    std::cout << "{\n";

    bool dualize                    = true;
    bool includeAllUnpairedCreators = true;

    auto diagrams
      = aleph::calculatePersistenceDiagrams( K,
                                            dualize,
                                            includeAllUnpairedCreators );

    auto signature = makeSignature( diagrams, K.dimension() );

    std::cout << "  " << "betti:" << "  " << signature << "\n"
              << "  " << "euler:" << "  " << signature.eulerCharacteristic() << "\n";

    std::cout << "}\n";
  }

  // Calculate intersection homology -----------------------------------
  //
  // The basic idea is to first decompose the given simplicial complex
  // into its skeletons. These skeletons then serve as a filtration of
  // the complex. In addition to this, we also calculate a barycentric
  // subdivision of the simplicial complex. The triangulation is hence
  // always "flag-like" following the paper:
  //
  //   Elementary construction of perverse sheaves
  //   Robert MacPhersonl and Kari Vilonen
  //   Inventiones Mathematicae, Volume 84, pp. 403--435, 1986
  //
  // As a last step, we iterate over all possible perversities for the
  // given triangulation and calculate their intersection homology.

  std::vector< std::vector<Signature> > allIntersectionHomologySignatures;
  allIntersectionHomologySignatures.reserve( simplicialComplexes.size() );

  for( auto&& K : simplicialComplexes )
  {
    std::vector<SimplicialComplex> skeletons;
    skeletons.reserve( K.dimension() + 1 );

    aleph::topology::Skeleton skeleton;
    for( std::size_t d = 0; d <= K.dimension(); d++ )
      skeletons.emplace_back( skeleton( d, K ) );

    aleph::topology::BarycentricSubdivision subdivision;
    auto L = subdivision( K );

    // TODO: this is not optimal because the simplicial complexes may
    // share the same dimensionality.
    auto perversities = getPerversities( static_cast<unsigned>( K.dimension() ) );

    std::vector<Signature> signatures;
    signatures.reserve( perversities.size() );

    for( auto&& perversity : perversities )
    {
      auto diagrams  = aleph::calculateIntersectionHomology( L, skeletons, perversity );
      auto signature = makeSignature( diagrams, K.dimension() );

      std::cout << signature << " " << std::flush;

      signatures.push_back( signature );
    }

    std::sort( signatures.begin(), signatures.end() );
    allIntersectionHomologySignatures.emplace_back( signatures );

    std::cout << "\n";
  }
}
<commit_msg>Proper JSON output for triangulation tool<commit_after>#include <aleph/topology/io/LexicographicTriangulation.hh>

#include <aleph/persistentHomology/Calculation.hh>
#include <aleph/persistentHomology/PhiPersistence.hh>

#include <aleph/topology/BarycentricSubdivision.hh>
#include <aleph/topology/Simplex.hh>
#include <aleph/topology/SimplicialComplex.hh>
#include <aleph/topology/Skeleton.hh>

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

using DataType          = bool;
using VertexType        = unsigned short;

using Simplex           = aleph::topology::Simplex<DataType, VertexType>;
using SimplicialComplex = aleph::topology::SimplicialComplex<Simplex>;

/**
  Models a signature consisting of Betti numbers, i.e. a set of natural
  numbers. Signatures are comparable and are ordered lexicographically,
  i.e. in the manner one would expect.
*/

class Signature
{
public:
  template <class InputIterator> Signature( InputIterator begin, InputIterator end )
    : _betti( begin, end )
  {
  }

  bool operator<( const Signature& other ) const noexcept
  {
    return std::lexicographical_compare( _betti.begin(), _betti.end(),
                                         other._betti.begin(), other._betti.end() );
  }

  long eulerCharacteristic() const noexcept
  {
    long chi = 0;
    bool s   = true;

    for( auto&& betti : _betti )
    {
      chi = s ? chi + betti : chi - betti;
      s   = !s;
    }

    return chi;
  }

  using const_iterator = typename std::vector<std::size_t>::const_iterator;

  const_iterator begin() const noexcept { return _betti.begin(); }
  const_iterator end()   const noexcept { return _betti.end() ;  }

private:
  std::vector<std::size_t> _betti;
};

std::ostream& operator<<( std::ostream& o, const Signature& s )
{
  o << "[";

  for( auto it = s.begin(); it != s.end(); ++it )
  {
    if( it != s.begin() )
      o << ",";

    o << *it;
  }

  o << "]";

  return o;
}

/**
  Converts a vector of persistence diagrams into a Betti signature. The
  maximum dimension needs to be specified in order to ensure that empty
  or missing persistence diagrams can still be handled correctly.
*/

template <class PersistenceDiagram> Signature makeSignature( const std::vector<PersistenceDiagram>& diagrams, std::size_t D )
{
  std::vector<std::size_t> bettiNumbers( D+1 );

  for( auto&& diagram : diagrams )
  {
    auto d = diagram.dimension();
    auto b = diagram.betti();

    bettiNumbers.at(d) = b;
  }

  return Signature( bettiNumbers.begin(), bettiNumbers.end() );
}

/**
  Enumerates all possible perversities for a given dimension. One could
  say that this function is as wicked as possible.
*/

std::vector<aleph::Perversity> getPerversities( unsigned dimension )
{
  std::vector<aleph::Perversity> perversities;

  std::map< unsigned, std::vector<int> > possibleValues;

  for( unsigned d = 0; d < dimension; d++ )
  {
    // Note that no shift in dimensions is required: as the dimension is
    // zero-based, the maximum value of the perversity in dimension zero
    // is zero. This is identical to demanding
    //
    //   -1 \leq p_k \leq k-1
    //
    // for k = [1,...,d].
    for( int k = -1; k <= static_cast<int>( d ); k++ )
      possibleValues[d].push_back( k );
  }

  std::size_t numCombinations = 1;

  for( auto&& pair : possibleValues )
    numCombinations *= pair.second.size();

  // Stores the current index that was reached while traversing all
  // possible values of the perversity. The idea is that to add one
  // to the last index upon adding a new value. If the index is too
  // large, it goes back to zero and the previous index is modified
  // by one.
  std::vector<std::size_t> indices( possibleValues.size() );

  for( std::size_t i = 0; i < numCombinations; i++ )
  {
    std::vector<int> values;

    for( unsigned d = 0; d < dimension; d++ )
    {
      auto index = indices.at(d);
      values.emplace_back( possibleValues.at(d).at(index) );
    }

    // Always increase the last used index by one. If an overflow
    // occurs, the previous indices are updated as well.
    {
      auto last        = dimension - 1;
      indices.at(last) = indices.at(last) + 1;

      // Check & propagate potential overflows to the previous indices
      // in the range. The index vector is reset to zero only when all
      // combinations have been visited.
      if( indices.at(last) >= possibleValues.at(last).size() )
      {
        indices.at(last) = 0;
        for( unsigned d = 1; d < dimension; d++ )
        {
          auto D        = dimension - 1 - d;
          indices.at(D) = indices.at(D) + 1;

          if( indices.at(D) < possibleValues.at(D).size() )
            break;
          else
            indices.at(D) = 0;
        }
      }
    }

    perversities.emplace_back( aleph::Perversity( values.begin(), values.end() ) );
  }

  return perversities;
}

int main(int argc, char* argv[])
{
  if( argc <= 1 )
    return -1;

  std::string filename = argv[1];
  std::vector<SimplicialComplex> simplicialComplexes;

  aleph::topology::io::LexicographicTriangulationReader reader;
  reader( filename, simplicialComplexes );

  // Create missing faces ----------------------------------------------
  //
  // The triangulations are only specified by their top-level simplices,
  // so they need to be converted before being valid inputs for homology
  // calculations.

  for( auto&& K : simplicialComplexes )
  {
    K.createMissingFaces();
    K.sort();
  }

  // Calculate homology ------------------------------------------------
  //
  // We are only interested in the Betti numbers of the diagrams here as
  // the triangulations are not endowed with any weights or values.

  std::size_t index = 0;
  std::string level = "  "; // separator to make JSON more readable

  std::cout << "{\n"
            << level << "\"homology\":" << level << "{\n";

  for( auto&& K : simplicialComplexes )
  {
    std::cout << level << level << "\"" << index << "\":" << level << "{\n";

    bool dualize                    = true;
    bool includeAllUnpairedCreators = true;

    auto diagrams
      = aleph::calculatePersistenceDiagrams( K,
                                            dualize,
                                            includeAllUnpairedCreators );

    auto signature = makeSignature( diagrams, K.dimension() );

    std::cout << level << level << level << "\"betti\":" << level << signature << ",\n"
              << level << level << level << "\"euler\":" << level << signature.eulerCharacteristic() << "\n";

    std::cout << level << level << "}";

    if( index + 1 < simplicialComplexes.size() )
         std::cout << ",";

    std::cout << "\n";

    ++index;
  }

  std::cout << level << "},\n"
            << level << "\"intersection_homology\":" << level << "{\n";

  // Calculate intersection homology -----------------------------------
  //
  // The basic idea is to first decompose the given simplicial complex
  // into its skeletons. These skeletons then serve as a filtration of
  // the complex. In addition to this, we also calculate a barycentric
  // subdivision of the simplicial complex. The triangulation is hence
  // always "flag-like" following the paper:
  //
  //   Elementary construction of perverse sheaves
  //   Robert MacPhersonl and Kari Vilonen
  //   Inventiones Mathematicae, Volume 84, pp. 403--435, 1986
  //
  // As a last step, we iterate over all possible perversities for the
  // given triangulation and calculate their intersection homology.

  std::vector< std::vector<Signature> > allIntersectionHomologySignatures;
  allIntersectionHomologySignatures.reserve( simplicialComplexes.size() );

  index = 0;

  for( auto&& K : simplicialComplexes )
  {
    std::vector<SimplicialComplex> skeletons;
    skeletons.reserve( K.dimension() + 1 );

    aleph::topology::Skeleton skeleton;
    for( std::size_t d = 0; d <= K.dimension(); d++ )
      skeletons.emplace_back( skeleton( d, K ) );

    aleph::topology::BarycentricSubdivision subdivision;
    auto L = subdivision( K );

    // TODO: this is not optimal because the simplicial complexes may
    // share the same dimensionality.
    auto perversities = getPerversities( static_cast<unsigned>( K.dimension() ) );

    std::vector<Signature> signatures;
    signatures.reserve( perversities.size() );

    std::cout << level << level << "\"" << index << "\":" << level << "{\n";

    std::size_t perversityIndex = 0;

    for( auto&& perversity : perversities )
    {
      std::cout << level << level << level << "\"" << perversityIndex << "\"" << ":" << level << "{\n";

      auto diagrams  = aleph::calculateIntersectionHomology( L, skeletons, perversity );
      auto signature = makeSignature( diagrams, K.dimension() );

      std::cout << level << level << level << level << "\"perversity\":" << "  " << perversity << ",\n"
                << level << level << level << level << "\"betti\":"      << "  " << signature  << "\n";

      std::cout << level << level << level << "}";

      if( perversityIndex + 1 < perversities.size() )
        std::cout<< ",";

      std::cout << "\n";

      signatures.push_back( signature );

      ++perversityIndex;
    }

    std::sort( signatures.begin(), signatures.end() );
    allIntersectionHomologySignatures.emplace_back( signatures );

    std::cout << level << level << "}";

    if( index + 1 < simplicialComplexes.size() )
         std::cout << ",";

    std::cout << "\n";

    ++index;
  }

  std::cout << level << "}\n"
            << "}\n";
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: options.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: lla $ $Date: 2001-01-26 15:01:57 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef CONFIGMGR_MISC_OPTIONS_HXX_
#define CONFIGMGR_MISC_OPTIONS_HXX_

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#include <rtl/ustring.hxx>
#include <com/sun/star/uno/Any.hxx>
#include "hashhelper.hxx"
#include <vos/ref.hxx>

namespace com { namespace sun { namespace star {

    namespace script    { class XTypeConverter; }
}   }   }

namespace configmgr
{
    namespace css  = ::com::sun::star;
    namespace uno  = css::uno;
    namespace script = css::script;

    /**
       class OOptions is created one time per Configuration[update]Access
       all important options should stored in this class.
       The object will be [weiterleiten] to all other objects so we only
       need to extend this classobject and all other class can work with
       the new options or important options etc.
    */

    class OOptions : public vos::OReference
    {
        uno::Reference< script::XTypeConverter > m_xConverter;  // typeconverter used
        rtl::OUString   m_sLocale;                              // current locale used for data
        rtl::OUString   m_sDefaultLocale;                       // default locale set for a user
        rtl::OUString   m_sUser;                                // user key used (could be empty)
        rtl::OUString   m_sDefaultUser;                         // user key used (could be empty)
        sal_Int32       m_nCacheID;                             // set if data should not be fetched from the cache, but reloaded
        bool            m_bLazyWrite;                           // true, if tree use lazy writing
    public:
        OOptions(const uno::Reference< script::XTypeConverter >& _xConverter)
            :m_xConverter(_xConverter)
            ,m_nCacheID(0)
            ,m_bLazyWrite(false)
        {}

        OOptions(const OOptions& _rOptions)
            :m_xConverter(_rOptions.getTypeConverter())
            ,m_sDefaultLocale(_rOptions.getDefaultLocale())
            ,m_sDefaultUser(_rOptions.getDefaultUser())
            ,m_sLocale(_rOptions.m_sLocale)
            ,m_sUser(_rOptions.m_sUser)
            ,m_nCacheID(0),                      // cache identity is not copied
            m_bLazyWrite(_rOptions.m_bLazyWrite)
        {
            if (!_rOptions.canUseCache()) this->setNoCache();
        }

        uno::Reference< script::XTypeConverter > getTypeConverter() const {return m_xConverter;}

        bool canUseCache() const { return m_nCacheID == 0; }

        rtl::OUString getLocale() const {return m_sLocale.getLength() ? m_sLocale : m_sDefaultLocale;}
        const rtl::OUString& getDefaultLocale() const {return m_sDefaultLocale;}
        sal_Bool hasDefaultLocale() const {return !m_sLocale.getLength() || m_sLocale == m_sDefaultLocale;}

        rtl::OUString getUser() const {return m_sUser.getLength() ? m_sUser : m_sDefaultUser;}
        const rtl::OUString& getDefaultUser() const {return m_sDefaultUser;}
        sal_Bool hasDefaultUser() const {return !m_sUser.getLength() || m_sUser == m_sDefaultUser;}

        void setNoCache(bool _bNoCache = true);
        void setUser(const rtl::OUString& _rUser) {m_sUser = _rUser;}
        void setDefaultUser(const rtl::OUString& _rUser) {m_sDefaultUser = _rUser;}
        void setLocale(const rtl::OUString& _rLocale) {m_sLocale = _rLocale;}
        void setDefaultLocale(const rtl::OUString& _rLocale) {m_sDefaultLocale = _rLocale;}
        void setLazyWrite(bool _bLazyWrite = false) {m_bLazyWrite = _bLazyWrite;}
        bool getLazyWrite() {return m_bLazyWrite;}

        friend sal_Int32 compareCacheIdentity(OOptions const& lhs, OOptions const& rhs)
        { return rhs.m_nCacheID - lhs.m_nCacheID; }
    };

    struct ltOptions
    {
        bool operator()(const ::vos::ORef<OOptions> &o1, const ::vos::ORef<OOptions> &o2) const
        {
            sal_Int32 nLt = o1->getUser().compareTo(o2->getUser());
            if (nLt == 0)
                nLt = o1->getLocale().compareTo(o2->getLocale());

            if (nLt == 0)
                nLt = compareCacheIdentity(*o1,*o2);

            return nLt < 0 ? true : false;
        }
    };
} // namespace

#endif
<commit_msg>Added ability to set the 'get all locales' option<commit_after>/*************************************************************************
 *
 *  $RCSfile: options.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: jb $ $Date: 2001-04-10 14:05:28 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef CONFIGMGR_MISC_OPTIONS_HXX_
#define CONFIGMGR_MISC_OPTIONS_HXX_

#ifndef _COM_SUN_STAR_UNO_REFERENCE_HXX_
#include <com/sun/star/uno/Reference.hxx>
#endif

#include <rtl/ustring.hxx>
#include <com/sun/star/uno/Any.hxx>
#include "hashhelper.hxx"
#include <vos/ref.hxx>

namespace com { namespace sun { namespace star {

    namespace script    { class XTypeConverter; }
}   }   }

namespace configmgr
{
    namespace css  = ::com::sun::star;
    namespace uno  = css::uno;
    namespace script = css::script;

    namespace localehelper { void getAnyLocale(OUString& _rsString); }
    /**
       class OOptions is created one time per Configuration[update]Access
       all important options should stored in this class.
       The object will be [weiterleiten] to all other objects so we only
       need to extend this classobject and all other class can work with
       the new options or important options etc.
    */

    class OOptions : public vos::OReference
    {
        uno::Reference< script::XTypeConverter > m_xConverter;  // typeconverter used
        rtl::OUString   m_sLocale;                              // current locale used for data
        rtl::OUString   m_sDefaultLocale;                       // default locale set for a user
        rtl::OUString   m_sUser;                                // user key used (could be empty)
        rtl::OUString   m_sDefaultUser;                         // user key used (could be empty)
        sal_Int32       m_nCacheID;                             // set if data should not be fetched from the cache, but reloaded
        bool            m_bLazyWrite;                           // true, if tree use lazy writing
    public:
        OOptions(const uno::Reference< script::XTypeConverter >& _xConverter)
            :m_xConverter(_xConverter)
            ,m_nCacheID(0)
            ,m_bLazyWrite(false)
        {}

        OOptions(const OOptions& _rOptions)
            :m_xConverter(_rOptions.getTypeConverter())
            ,m_sDefaultLocale(_rOptions.getDefaultLocale())
            ,m_sDefaultUser(_rOptions.getDefaultUser())
            ,m_sLocale(_rOptions.m_sLocale)
            ,m_sUser(_rOptions.m_sUser)
            ,m_nCacheID(0),                      // cache identity is not copied
            m_bLazyWrite(_rOptions.m_bLazyWrite)
        {
            if (!_rOptions.canUseCache()) this->setNoCache();
        }

        uno::Reference< script::XTypeConverter > getTypeConverter() const {return m_xConverter;}

        bool canUseCache() const { return m_nCacheID == 0; }

        rtl::OUString getLocale() const {return m_sLocale.getLength() ? m_sLocale : m_sDefaultLocale;}
        const rtl::OUString& getDefaultLocale() const {return m_sDefaultLocale;}
        sal_Bool hasDefaultLocale() const {return !m_sLocale.getLength() || m_sLocale == m_sDefaultLocale;}

        rtl::OUString getUser() const {return m_sUser.getLength() ? m_sUser : m_sDefaultUser;}
        const rtl::OUString& getDefaultUser() const {return m_sDefaultUser;}
        sal_Bool hasDefaultUser() const {return !m_sUser.getLength() || m_sUser == m_sDefaultUser;}

        void setNoCache(bool _bNoCache = true);
        void setUser(const rtl::OUString& _rUser) {m_sUser = _rUser;}
        void setDefaultUser(const rtl::OUString& _rUser) {m_sDefaultUser = _rUser;}
        void setLocale(const rtl::OUString& _rLocale) {m_sLocale = _rLocale;}
        void setDefaultLocale(const rtl::OUString& _rLocale) {m_sDefaultLocale = _rLocale;}
        void setMultiLocaleMode() { localehelper::getAnyLocale(m_sLocale);}
        void setMultiLocaleDefault() {  localehelper::getAnyLocale(m_sDefaultLocale);}
        void setLazyWrite(bool _bLazyWrite = false) {m_bLazyWrite = _bLazyWrite;}
        bool getLazyWrite() {return m_bLazyWrite;}

        friend sal_Int32 compareCacheIdentity(OOptions const& lhs, OOptions const& rhs)
        { return rhs.m_nCacheID - lhs.m_nCacheID; }
    };

    struct ltOptions
    {
        bool operator()(const ::vos::ORef<OOptions> &o1, const ::vos::ORef<OOptions> &o2) const
        {
            sal_Int32 nLt = o1->getUser().compareTo(o2->getUser());
            if (nLt == 0)
                nLt = o1->getLocale().compareTo(o2->getLocale());

            if (nLt == 0)
                nLt = compareCacheIdentity(*o1,*o2);

            return nLt < 0 ? true : false;
        }
    };
} // namespace

#endif
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(SOLARISDEFINITIONS_HEADER_GUARD_1357924680)
#define SOLARISDEFINITIONS_HEADER_GUARD_1357924680

// ---------------------------------------------------------------------------
//  A define in the build for each project is also used to control whether
//  the export keyword is from the project's viewpoint or the client's.
//  These defines provide the platform specific keywords that they need
//  to do this.
// ---------------------------------------------------------------------------
#define XALAN_PLATFORM_EXPORT
#define XALAN_PLATFORM_IMPORT
#define XALAN_PLATFORM_EXPORT_FUNCTION(T) T XALAN_PLATFORM_EXPORT
#define XALAN_PLATFORM_IMPORT_FUNCTION(T) T XALAN_PLATFORM_IMPORT

// Sun Workshop 4.2 _does_ support new cast syntax, but it's
// broken with extra cv-qualifiers, so we'll use old-style casts.
#define XALAN_OLD_STYLE_CASTS

// Standard allocators don't seem to work correctly with STLport.
// I don't know if this is their bug, or ours...
#define XALAN_NO_STD_ALLOCATORS

#if __SUNPRO_CC_COMPAT >= 5

#define XALAN_SIZE_T_IN_NAMESPACE_STD

#else

#define XALAN_STLPORT_STL
#define XALAN_NO_DEFAULT_BUILTIN_ARRAY_INITIALIZATION
#define XALAN_OLD_STREAMS
#define XALAN_NO_NAMESPACES
#define XALAN_NO_MUTABLE
#define XALAN_SGI_BASED_STL
#define XALAN_NO_MEMBER_TEMPLATES
//#define XALAN_CANNOT_DELETE_CONST
#define XALAN_BOOL_AS_INT
#define XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS
#define XALAN_NO_COVARIANT_RETURN_TYPE

// STL Port Definitions
#define __STL_NO_SGI_IOSTREAMS
#include <stl/_config.h>

#endif

#define XALAN_XALANDOMCHAR_USHORT_MISMATCH
#define XALAN_BIG_ENDIAN
#define XALAN_POSIX2_AVAILABLE

#define XALAN_UNALIGNED

#endif	// SOLARISDEFINITIONS_HEADER_GUARD_1357924680
<commit_msg>Added new #define.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(SOLARISDEFINITIONS_HEADER_GUARD_1357924680)
#define SOLARISDEFINITIONS_HEADER_GUARD_1357924680

// ---------------------------------------------------------------------------
//  A define in the build for each project is also used to control whether
//  the export keyword is from the project's viewpoint or the client's.
//  These defines provide the platform specific keywords that they need
//  to do this.
// ---------------------------------------------------------------------------
#define XALAN_PLATFORM_EXPORT
#define XALAN_PLATFORM_IMPORT
#define XALAN_PLATFORM_EXPORT_FUNCTION(T) T XALAN_PLATFORM_EXPORT
#define XALAN_PLATFORM_IMPORT_FUNCTION(T) T XALAN_PLATFORM_IMPORT

// Sun Workshop 4.2 _does_ support new cast syntax, but it's
// broken with extra cv-qualifiers, so we'll use old-style casts.
#define XALAN_OLD_STYLE_CASTS

// Standard allocators don't seem to work correctly with STLport.
// I don't know if this is their bug, or ours...
#define XALAN_NO_STD_ALLOCATORS

#if __SUNPRO_CC_COMPAT >= 5

#define XALAN_SIZE_T_IN_NAMESPACE_STD

// A copy constructor should not need to be accessible to allow
// implicit construction from a conversion constructor.  However,
// later versions of the Sun compiler do not agree...
#define XALAN_IMPLICIT_CONSTRUCTION_REQUIRES_COPY_CONSTRUCTOR

#else

#define XALAN_STLPORT_STL
#define XALAN_NO_DEFAULT_BUILTIN_ARRAY_INITIALIZATION
#define XALAN_OLD_STREAMS
#define XALAN_NO_NAMESPACES
#define XALAN_NO_MUTABLE
#define XALAN_SGI_BASED_STL
#define XALAN_NO_MEMBER_TEMPLATES
#define XALAN_BOOL_AS_INT
#define XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS
#define XALAN_NO_COVARIANT_RETURN_TYPE

// STL Port Definitions
#define __STL_NO_SGI_IOSTREAMS
#include <stl/_config.h>

#endif

#define XALAN_XALANDOMCHAR_USHORT_MISMATCH
#define XALAN_BIG_ENDIAN
#define XALAN_POSIX2_AVAILABLE

#define XALAN_UNALIGNED

#endif	// SOLARISDEFINITIONS_HEADER_GUARD_1357924680
<|endoftext|>


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

#include "TMath.h"
#include "TRandom2.h"

using namespace std;

const int maxint = 20;
const int minsize = 20;
const int maxsize = 500;

#ifndef ROOT_TMath

template<typename T>
struct CompareDesc {

   CompareDesc(T d) : fData(d) {}

   bool operator()(int i1, int i2) {
      return *(fData + i1) > *(fData + i2);
   }

   T fData;
};

template<typename T>
struct CompareAsc {

   CompareAsc(T d) : fData(d) {}

   bool operator()(int i1, int i2) {
      return *(fData + i1) < *(fData + i2);
   }

   T fData;
};

#endif

template <typename T> bool testSort(const int n)
{
   vector<T> k(n);
   vector<T> indexM(n);
   vector<T> indexS(n);

   bool equals = true;

   TRandom2 r( time( 0 ) );

   cout << "k: ";
   for ( Int_t i = 0; i < n; i++) {
      k[i] = (T) r.Integer( maxint );
      cout << k[i] << ' ';
   }
   cout << endl;

   for(Int_t i = 0; i < n; i++) { indexM[i] = i; }
   TMath::Sort(n,&k[0],&indexM[0],kTRUE);

   cout << "TMath[kTRUE]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexM[i]] << ' ';
   cout << endl;

   for(Int_t i = 0; i < n; i++) { indexS[i] = i; }
   std::sort(&indexS[0],&indexS[0]+n, CompareDesc<const T*>(&k[0]) );

   cout << "std::sort[CompareDesc]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexS[i]] << ' ';
   cout << endl;

   equals &= std::equal(indexM.begin(), indexM.end(), indexS.begin());
   cout << "Equals? " << (char*) (equals?"OK":"FAILED") << endl;

   for(Int_t i = 0; i < n; i++) { indexM[i] = i; }
   TMath::Sort(n,&k[0],&indexM[0],kFALSE);

   cout << "TMath[kFALSE]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexM[i]] << ' ';
   cout << endl;

   for(Int_t i = 0; i < n; i++) { indexS[i] = i; }
   std::sort(&indexS[0],&indexS[0]+n, CompareAsc<const T*>(&k[0]) );

   cout << "std::sort[CompareAsc]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexS[i]] << ' ';
   cout << endl;

   equals &= std::equal(indexM.begin(), indexM.end(), indexS.begin());
   cout << "Equals? " << (char*) (equals?"OK":"FAILED") << endl;

   return equals;
}

bool stdsort()
{
   return testSort<Int_t>(20);
}

int main(int /* argc */ , char ** /* argv */ )
{
   bool equals = stdsort();

   if ( !equals )
      return 1;
   else
      return 0;
}
<commit_msg>More suppression of warnings in tests<commit_after>#include <iostream>
#include <algorithm>
#include <ctime>
#include <vector>

#include "TMath.h"
#include "TRandom2.h"

using namespace std;

const int maxint = 20;

#ifndef ROOT_TMath

template<typename T>
struct CompareDesc {

   CompareDesc(T d) : fData(d) {}

   bool operator()(int i1, int i2) {
      return *(fData + i1) > *(fData + i2);
   }

   T fData;
};

template<typename T>
struct CompareAsc {

   CompareAsc(T d) : fData(d) {}

   bool operator()(int i1, int i2) {
      return *(fData + i1) < *(fData + i2);
   }

   T fData;
};

#endif

template <typename T> bool testSort(const int n)
{
   vector<T> k(n);
   vector<T> indexM(n);
   vector<T> indexS(n);

   bool equals = true;

   TRandom2 r( time( 0 ) );

   cout << "k: ";
   for ( Int_t i = 0; i < n; i++) {
      k[i] = (T) r.Integer( maxint );
      cout << k[i] << ' ';
   }
   cout << endl;

   for(Int_t i = 0; i < n; i++) { indexM[i] = i; }
   TMath::Sort(n,&k[0],&indexM[0],kTRUE);

   cout << "TMath[kTRUE]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexM[i]] << ' ';
   cout << endl;

   for(Int_t i = 0; i < n; i++) { indexS[i] = i; }
   std::sort(&indexS[0],&indexS[0]+n, CompareDesc<const T*>(&k[0]) );

   cout << "std::sort[CompareDesc]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexS[i]] << ' ';
   cout << endl;

   equals &= std::equal(indexM.begin(), indexM.end(), indexS.begin());
   cout << "Equals? " << (char*) (equals?"OK":"FAILED") << endl;

   for(Int_t i = 0; i < n; i++) { indexM[i] = i; }
   TMath::Sort(n,&k[0],&indexM[0],kFALSE);

   cout << "TMath[kFALSE]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexM[i]] << ' ';
   cout << endl;

   for(Int_t i = 0; i < n; i++) { indexS[i] = i; }
   std::sort(&indexS[0],&indexS[0]+n, CompareAsc<const T*>(&k[0]) );

   cout << "std::sort[CompareAsc]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexS[i]] << ' ';
   cout << endl;

   equals &= std::equal(indexM.begin(), indexM.end(), indexS.begin());
   cout << "Equals? " << (char*) (equals?"OK":"FAILED") << endl;

   return equals;
}

bool stdsort()
{
   return testSort<Int_t>(20);
}

int main(int /* argc */ , char ** /* argv */ )
{
   bool equals = stdsort();

   if ( !equals )
      return 1;
   else
      return 0;
}
<|endoftext|>


<commit_before>/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */

#include <gflags/gflags.h>

#include "mcsema/Arch/X86/Decode.h"
#include "mcsema/Arch/X86/RegisterAnalysis.h"
#include "mcsema/CFG/CFG.h"

DECLARE_bool(aggressive_dataflow_analysis);

namespace mcsema {
namespace x86 {

struct Function {
  std::vector<uint64_t> tail_call_source_blocks;
  std::vector<uint64_t> return_target_blocks;
};

namespace {

// Find the successor blocks of an instruction.
static FlowType FindSuccessors(const xed_decoded_inst_t *xedd,
                               uint64_t curr_pc, uint64_t next_pc,
                               std::vector<uint64_t> &succs) {
  auto xedi = xed_decoded_inst_inst(xedd);
  auto xedo = xed_inst_operand(xedi, 0);
  auto op_name = xed_operand_name(xedo);
  auto disp = xed_decoded_inst_get_branch_displacement(xedd);
  auto target_pc = static_cast<uintptr_t>(next_pc + disp);

  switch (auto category = xed_decoded_inst_get_category(xedd)) {
    case XED_CATEGORY_UNCOND_BR:
    case XED_CATEGORY_CALL:
      if (XED_OPERAND_RELBR == op_name) {
        succs.push_back(target_pc);
        if (XED_CATEGORY_CALL == category) {
          return kFlowCall;
        } else {
          return kFlowLocal;
        }
      } else {
        if (XED_CATEGORY_CALL == category) {
          return kFlowIndirectCall;
        } else {
          return kFlowUnknown;
        }
      }

    case XED_CATEGORY_COND_BR:
      if (XED_OPERAND_RELBR == op_name) {
        succs.push_back(target_pc);
        succs.push_back(next_pc);
        return kFlowLocal;
      } else {
        return kFlowUnknown;
      }

    case XED_CATEGORY_RET:
      return kFlowReturn;

    case XED_CATEGORY_SYSCALL:
      return kFlowSysCall;

    case XED_CATEGORY_SYSRET:
      return kFlowUnknown;

    default:
      succs.push_back(next_pc);
      return kFlowLocal;
  }
}

}  // namespace

void RegisterAnalysis::AddFunction(const cfg::Function &func) {
  if (!FLAGS_aggressive_dataflow_analysis) return;
  if (func.is_imported() || func.is_weak()) return;
  auto &f = functions[func.address()];
  if (!f) {
    f = new Function;
  }
}

void RegisterAnalysis::AddBlock(const cfg::Block &block) {
  auto bb = new BasicBlockRegs;
  bb->live_exit.flat = 0U;
  bb->live_entry.flat = 0U;
  bb->keep_alive.flat = 0U;
  bb->address = block.address();
  bb->flow = kFlowUnknown;

  auto it_begin = block.instructions().rbegin();
  auto it_end = block.instructions().rend();
  for (auto it = it_begin; it != it_end; ++it) {
    const auto &instr = *it;
    const auto xedd = DecodeInstruction(instr, arch_name);

    if (it == it_begin) {
      const auto next_pc = instr.address() + instr.size();
      bb->flow = FindSuccessors(
          &xedd, instr.address(), next_pc, bb->successors);

      if (!FLAGS_aggressive_dataflow_analysis) continue;

      // Identify functions as those pieces of code that are observed to be
      // the targets of function calls.
      if (kFlowCall == bb->flow) {
        auto target_pc = bb->successors[0];
        auto &func = functions[target_pc];
        if (!func) {
          func = new Function;
        }

        // Tell functions about where we think they return to, and connect
        // the before/after call blocks so that we can propagate function
        // identification around calls.
        func->return_target_blocks.push_back(next_pc);
        ret_blocks[block.address()] = next_pc;

      // Connect blocks before/after syscalls and indirect calls as being
      // potentially belonging to the same function.
      } else if (kFlowSysCall == bb->flow || kFlowIndirectCall == bb->flow) {
        ret_blocks[block.address()] = next_pc;
      }
    }

    if (const auto rflags = xed_decoded_inst_get_rflags_info(&xedd)) {
      bb->keep_alive.flat |= rflags->written.flat;
      bb->keep_alive.flat |= rflags->undefined.flat;
      bb->keep_alive.flat &= ~(rflags->read.flat);
    }
  }

  bb->keep_alive.flat = ~bb->keep_alive.flat;
  bb->live_entry.flat = bb->live_exit.flat & bb->keep_alive.flat;

  blocks[block.address()] = bb;
}

void RegisterAnalysis::InitWorkList(AnalysisWorkList &work_list) {
  std::set<BasicBlockRegs *> func_wl;

  for (auto b : blocks) {
    auto block_pc = b.first;
    auto block = b.second;

    // Initialize function entry points.
    if (FLAGS_aggressive_dataflow_analysis) {
      if (functions[block_pc]) {
        func_wl.insert(block);
      }
    }

    // Connect successors to predecessors.
    for (auto succ_pc : block->successors) {
      auto succ_block = blocks[succ_pc];
      succ_block->predecessors.push_back(block_pc);

      if (!FLAGS_aggressive_dataflow_analysis) continue;

      // If a successor is marked as a function entry point and if the flow
      // from this block to its successor is "local", i.e. direct jump or
      // conditional branch, then consider it to be a tail-call.
      if (kFlowLocal == block->flow) {
        if (auto succ_func = functions[succ_pc]) {
          succ_func->tail_call_source_blocks.push_back(block_pc);
        }
      }
    }
  }

  // Iteratively "spread" the function assignments.
  while (func_wl.size()) {

    // Propagate function identification through control-flows.
    while (func_wl.size()) {
      std::set<BasicBlockRegs *> next_func_wl;
      for (auto block : next_func_wl) {
        if (kFlowLocal != block->flow) continue;
        for (auto succ_pc : block->successors) {
          auto succ_block = blocks[succ_pc];
          auto &succ_func = functions[succ_pc];
          if (!succ_func) {
            succ_func = functions[block->address];
            next_func_wl.insert(succ_block);
          }
        }
      }
      func_wl.swap(next_func_wl);
    }

    // Try to push the work forward by propagation function identification
    // around function calls.
    for (auto rb : ret_blocks) {
      auto call_block_pc = rb.first;
      auto ret_block_pc = rb.second;
      if (auto call_func = functions[call_block_pc]) {
        if (auto ret_block = blocks[ret_block_pc]) {
          auto &ret_func = functions[ret_block_pc];
          if (!ret_func) {
            ret_func = call_func;
            func_wl.insert(ret_block);
          }
        }
      }
    }
  }

  // Function assignments have been spread.
  for (auto f : functions) {
    auto func = f.second;
    if (!func) continue;

    // Spread return addresses through tail-called functions.
    for (auto tail_call_block_pc : func->tail_call_source_blocks) {
      if (auto caller = functions[tail_call_block_pc]) {
        func->return_target_blocks.insert(func->return_target_blocks.end(),
                                          caller->return_target_blocks.begin(),
                                          caller->return_target_blocks.end());
      }
    }
  }

  // Connect return instructions to their return points.
  if (FLAGS_aggressive_dataflow_analysis) {
    for (auto b : blocks) {
      auto block_pc = b.first;
      auto block = b.second;
      if (!block || kFlowReturn != block->flow) continue;

      if (auto block_func = functions[block_pc]) {
        for (auto target_pc : block_func->return_target_blocks) {
          if (auto target_block = blocks[target_pc]) {
            target_block->predecessors.push_back(block_pc);
            block->successors.push_back(target_pc);
          }
        }
      }
    }
  }

  // Initialize the worklist for dead flags and register analysis across the
  // control-flow graph.
  for (auto b : blocks) {
    auto block_pc = b.first;
    auto block = b.second;
    work_list.insert({block->predecessors.size(), block_pc});
  }
}

void RegisterAnalysis::AnalyzeBlock(AnalysisWorkItem item,
                                    AnalysisWorkList &work_list) {
  auto bb = blocks[item.pc];
  if (!bb) return;

  // If we're not being conservative, then we'll assume that every indirect flow
  // kills all the flags.
  auto incoming_live = FLAGS_aggressive_dataflow_analysis ? 0U : ~0U;

  for (auto succ_pc : bb->successors) {
    incoming_live |= LiveFlags(succ_pc);
  }

  auto live_entry = incoming_live & bb->keep_alive.flat;
  if (live_entry != bb->live_entry.flat) {
    bb->live_entry.flat = live_entry;

    // Update the work list.
    for (auto pred_pc : bb->predecessors) {
      auto pred_bb = blocks[pred_pc];
      work_list.insert({pred_bb->predecessors.size(), pred_pc});
    }
  }
}

uint32_t RegisterAnalysis::LiveFlags(uint64_t pc) {
  if (const auto block = blocks[pc]) {
    return block->live_entry.flat;

  // This is basically an error case anyway, i.e. we have a direct flow that
  // we can't resolve. This will be warned about during the lifting phase.
  } else {
    return ~0U;
  }
}

}  // namespace x86
}  // namespace mcsema
<commit_msg>Extra aggressiveness for flags on syscall, indirect call, and unknown flows.<commit_after>/* Copyright 2016 Peter Goodman (peter@trailofbits.com), all rights reserved. */

#include <gflags/gflags.h>

#include "mcsema/Arch/X86/Decode.h"
#include "mcsema/Arch/X86/RegisterAnalysis.h"
#include "mcsema/CFG/CFG.h"

DECLARE_bool(aggressive_dataflow_analysis);

namespace mcsema {
namespace x86 {

struct Function {
  std::vector<uint64_t> tail_call_source_blocks;
  std::vector<uint64_t> return_target_blocks;
};

namespace {

// Find the successor blocks of an instruction.
static FlowType FindSuccessors(const xed_decoded_inst_t *xedd,
                               uint64_t curr_pc, uint64_t next_pc,
                               std::vector<uint64_t> &succs) {
  auto xedi = xed_decoded_inst_inst(xedd);
  auto xedo = xed_inst_operand(xedi, 0);
  auto op_name = xed_operand_name(xedo);
  auto disp = xed_decoded_inst_get_branch_displacement(xedd);
  auto target_pc = static_cast<uintptr_t>(next_pc + disp);

  switch (auto category = xed_decoded_inst_get_category(xedd)) {
    case XED_CATEGORY_UNCOND_BR:
    case XED_CATEGORY_CALL:
      if (XED_OPERAND_RELBR == op_name) {
        succs.push_back(target_pc);
        if (XED_CATEGORY_CALL == category) {
          return kFlowCall;
        } else {
          return kFlowLocal;
        }
      } else {
        if (XED_CATEGORY_CALL == category) {
          return kFlowIndirectCall;
        } else {
          return kFlowUnknown;
        }
      }

    case XED_CATEGORY_COND_BR:
      if (XED_OPERAND_RELBR == op_name) {
        succs.push_back(target_pc);
        succs.push_back(next_pc);
        return kFlowLocal;
      } else {
        return kFlowUnknown;
      }

    case XED_CATEGORY_RET:
      return kFlowReturn;

    case XED_CATEGORY_SYSCALL:
    case XED_CATEGORY_INTERRUPT:
      return kFlowSysCall;

    case XED_CATEGORY_SYSRET:
      return kFlowUnknown;

    default:
      succs.push_back(next_pc);
      return kFlowLocal;
  }
}

}  // namespace

void RegisterAnalysis::AddFunction(const cfg::Function &func) {
  if (!FLAGS_aggressive_dataflow_analysis) return;
  if (func.is_imported() || func.is_weak()) return;
  auto &f = functions[func.address()];
  if (!f) {
    f = new Function;
  }
}

void RegisterAnalysis::AddBlock(const cfg::Block &block) {
  auto bb = new BasicBlockRegs;
  bb->live_exit.flat = 0U;
  bb->live_entry.flat = 0U;
  bb->keep_alive.flat = 0U;
  bb->address = block.address();
  bb->flow = kFlowUnknown;

  auto it_begin = block.instructions().rbegin();
  auto it_end = block.instructions().rend();
  for (auto it = it_begin; it != it_end; ++it) {
    const auto &instr = *it;
    const auto xedd = DecodeInstruction(instr, arch_name);

    if (it == it_begin) {
      const auto next_pc = instr.address() + instr.size();
      bb->flow = FindSuccessors(
          &xedd, instr.address(), next_pc, bb->successors);

      if (!FLAGS_aggressive_dataflow_analysis) continue;

      // Identify functions as those pieces of code that are observed to be
      // the targets of function calls.
      if (kFlowCall == bb->flow) {
        auto target_pc = bb->successors[0];
        auto &func = functions[target_pc];
        if (!func) {
          func = new Function;
        }

        // Tell functions about where we think they return to, and connect
        // the before/after call blocks so that we can propagate function
        // identification around calls.
        func->return_target_blocks.push_back(next_pc);
        ret_blocks[block.address()] = next_pc;

      // Connect blocks before/after syscalls and indirect calls as being
      // potentially belonging to the same function.
      } else if (kFlowSysCall == bb->flow || kFlowIndirectCall == bb->flow) {
        ret_blocks[block.address()] = next_pc;
      }
    }

    if (const auto rflags = xed_decoded_inst_get_rflags_info(&xedd)) {
      bb->keep_alive.flat |= rflags->written.flat;
      bb->keep_alive.flat |= rflags->undefined.flat;
      bb->keep_alive.flat &= ~(rflags->read.flat);
    }
  }

  bb->keep_alive.flat = ~bb->keep_alive.flat;
  bb->live_entry.flat = bb->live_exit.flat & bb->keep_alive.flat;

  if (FLAGS_aggressive_dataflow_analysis) {
    if (kFlowSysCall == bb->flow ||
        kFlowIndirectCall == bb->flow ||
        kFlowUnknown == bb->flow) {
      bb->live_entry.flat = 0U;
      bb->keep_alive.flat = 0U;
    }
  }

  blocks[block.address()] = bb;
}

void RegisterAnalysis::InitWorkList(AnalysisWorkList &work_list) {
  std::set<BasicBlockRegs *> func_wl;

  for (auto b : blocks) {
    auto block_pc = b.first;
    auto block = b.second;

    // Initialize function entry points.
    if (FLAGS_aggressive_dataflow_analysis) {
      if (functions[block_pc]) {
        func_wl.insert(block);
      }
    }

    // Connect successors to predecessors.
    for (auto succ_pc : block->successors) {
      auto succ_block = blocks[succ_pc];
      succ_block->predecessors.push_back(block_pc);

      if (!FLAGS_aggressive_dataflow_analysis) continue;

      // If a successor is marked as a function entry point and if the flow
      // from this block to its successor is "local", i.e. direct jump or
      // conditional branch, then consider it to be a tail-call.
      if (kFlowLocal == block->flow) {
        if (auto succ_func = functions[succ_pc]) {
          succ_func->tail_call_source_blocks.push_back(block_pc);
        }
      }
    }
  }

  // Iteratively "spread" the function assignments.
  while (func_wl.size()) {

    // Propagate function identification through control-flows.
    while (func_wl.size()) {
      std::set<BasicBlockRegs *> next_func_wl;
      for (auto block : next_func_wl) {
        if (kFlowLocal != block->flow) continue;
        for (auto succ_pc : block->successors) {
          auto succ_block = blocks[succ_pc];
          auto &succ_func = functions[succ_pc];
          if (!succ_func) {
            succ_func = functions[block->address];
            next_func_wl.insert(succ_block);
          }
        }
      }
      func_wl.swap(next_func_wl);
    }

    // Try to push the work forward by propagation function identification
    // around function calls.
    for (auto rb : ret_blocks) {
      auto call_block_pc = rb.first;
      auto ret_block_pc = rb.second;
      if (auto call_func = functions[call_block_pc]) {
        if (auto ret_block = blocks[ret_block_pc]) {
          auto &ret_func = functions[ret_block_pc];
          if (!ret_func) {
            ret_func = call_func;
            func_wl.insert(ret_block);
          }
        }
      }
    }
  }

  // Function assignments have been spread.
  for (auto f : functions) {
    auto func = f.second;
    if (!func) continue;

    // Spread return addresses through tail-called functions.
    for (auto tail_call_block_pc : func->tail_call_source_blocks) {
      if (auto caller = functions[tail_call_block_pc]) {
        func->return_target_blocks.insert(func->return_target_blocks.end(),
                                          caller->return_target_blocks.begin(),
                                          caller->return_target_blocks.end());
      }
    }
  }

  // Connect return instructions to their return points.
  if (FLAGS_aggressive_dataflow_analysis) {
    for (auto b : blocks) {
      auto block_pc = b.first;
      auto block = b.second;
      if (!block || kFlowReturn != block->flow) continue;

      if (auto block_func = functions[block_pc]) {
        for (auto target_pc : block_func->return_target_blocks) {
          if (auto target_block = blocks[target_pc]) {
            target_block->predecessors.push_back(block_pc);
            block->successors.push_back(target_pc);
          }
        }
      }
    }
  }

  // Initialize the worklist for dead flags and register analysis across the
  // control-flow graph.
  for (auto b : blocks) {
    auto block_pc = b.first;
    auto block = b.second;
    work_list.insert({block->predecessors.size(), block_pc});
  }
}

void RegisterAnalysis::AnalyzeBlock(AnalysisWorkItem item,
                                    AnalysisWorkList &work_list) {
  auto bb = blocks[item.pc];
  if (!bb) return;

  // If we're not being conservative, then we'll assume that every indirect flow
  // kills all the flags.
  auto incoming_live = FLAGS_aggressive_dataflow_analysis ? 0U : ~0U;

  for (auto succ_pc : bb->successors) {
    incoming_live |= LiveFlags(succ_pc);
  }

  auto live_entry = incoming_live & bb->keep_alive.flat;
  if (live_entry != bb->live_entry.flat) {
    bb->live_entry.flat = live_entry;

    // Update the work list.
    for (auto pred_pc : bb->predecessors) {
      auto pred_bb = blocks[pred_pc];
      work_list.insert({pred_bb->predecessors.size(), pred_pc});
    }
  }
}

uint32_t RegisterAnalysis::LiveFlags(uint64_t pc) {
  if (const auto block = blocks[pc]) {
    return block->live_entry.flat;

  // This is basically an error case anyway, i.e. we have a direct flow that
  // we can't resolve. This will be warned about during the lifting phase.
  } else {
    return ~0U;
  }
}

}  // namespace x86
}  // namespace mcsema
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: vclxtopwindow.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 12:15:39 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"

#ifndef _COM_SUN_STAR_LANG_SYSTEMDEPENDENT_HPP_
#include <com/sun/star/lang/SystemDependent.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_SYSTEMDEPENDENTXWINDOW_HPP_
#include <com/sun/star/awt/SystemDependentXWindow.hpp>
#endif

#ifndef UNX
#include <tools/prewin.h>
#include <windows.h>
#include <tools/postwin.h>
#endif

#include <vcl/syschild.hxx>
#include <vcl/sysdata.hxx>
#include <cppuhelper/typeprovider.hxx>

#include <toolkit/awt/vclxtopwindow.hxx>
#include <toolkit/awt/vclxmenu.hxx>
#include <toolkit/helper/macros.hxx>

#include <vcl/wrkwin.hxx>
#include <vcl/syswin.hxx>
#include <vcl/menu.hxx>

#include <tools/debug.hxx>

//  ----------------------------------------------------
//  class VCLXTopWindow
//  ----------------------------------------------------

VCLXTopWindow::VCLXTopWindow(bool bWHWND)
    : m_bWHWND(bWHWND)
{
}

VCLXTopWindow::~VCLXTopWindow()
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXTopWindow::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
    ::com::sun::star::uno::Any aRet;
    if(! m_bWHWND) {
        aRet = ::cppu::queryInterface( rType,
                                       SAL_STATIC_CAST( ::com::sun::star::awt::XTopWindow*, this ) );
    }
    else {
        aRet = ::cppu::queryInterface( rType,
                                       SAL_STATIC_CAST( ::com::sun::star::awt::XTopWindow*, this ),
                                       SAL_STATIC_CAST( ::com::sun::star::awt::XSystemDependentWindowPeer*, this ) );
    }
    return (aRet.hasValue() ? aRet : VCLXContainer::queryInterface( rType ));
}

::com::sun::star::uno::Sequence< sal_Int8 > VCLXTopWindow::getImplementationId() throw(::com::sun::star::uno::RuntimeException)
{
    static ::cppu::OImplementationId* pId = NULL;
    static ::cppu::OImplementationId* pIdWithHandle = NULL;
    if ( m_bWHWND )
    {
        if( !pIdWithHandle )
        {
            ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
            if( !pIdWithHandle )
            {
                static ::cppu::OImplementationId idWithHandle( sal_False );
                pIdWithHandle = &idWithHandle;
            }
        }

        return (*pIdWithHandle).getImplementationId();
    }
    else
    {
        if( !pId )
        {
            ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
            if( !pId )
            {
                static ::cppu::OImplementationId id( sal_False );
                pId = &id;
            }
        }

        return (*pId).getImplementationId();
    }
}

::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > VCLXTopWindow::getTypes() throw(::com::sun::star::uno::RuntimeException)
{
    static ::cppu::OTypeCollection* pCollection = NULL;
    static ::cppu::OTypeCollection* pCollectionWithHandle = NULL;

    if ( m_bWHWND )
    {
        if( !pCollectionWithHandle )
        {
            ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
            if( !pCollectionWithHandle )
            {
                static ::cppu::OTypeCollection collectionWithHandle(
                getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XTypeProvider>* ) NULL ),
                getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindow>* ) NULL ),
                getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XSystemDependentWindowPeer>* ) NULL ),
                VCLXContainer::getTypes() );
                pCollectionWithHandle = &collectionWithHandle;
            }
        }

        return (*pCollectionWithHandle).getTypes();
    }
    else
    {
        if( !pCollection )
        {
            ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
            if( !pCollection )
            {
                static ::cppu::OTypeCollection collection(
                getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XTypeProvider>* ) NULL ),
                getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindow>* ) NULL ),
                VCLXContainer::getTypes() );
                pCollection = &collection;
            }
        }
        return (*pCollection).getTypes();
    }
}

::com::sun::star::uno::Any VCLXTopWindow::getWindowHandle( const ::com::sun::star::uno::Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 SystemType ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    // TODO, check the process id
    ::com::sun::star::uno::Any aRet;
    Window* pWindow = GetWindow();
    if ( pWindow )
    {
        const SystemEnvData* pSysData = ((SystemWindow *)pWindow)->GetSystemData();
        if( pSysData )
        {
#ifdef UNX
            if( SystemType == ::com::sun::star::lang::SystemDependent::SYSTEM_XWINDOW )
            {
                ::com::sun::star::awt::SystemDependentXWindow aSD;
                aSD.DisplayPointer = sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_IntPtr >(pSysData->pDisplay));
                aSD.WindowHandle = pSysData->aWindow;
                aRet <<= aSD;
            }
#elif (defined WNT)
            if( SystemType == ::com::sun::star::lang::SystemDependent::SYSTEM_WIN32 )
            {
                 aRet <<= (sal_Int32)pSysData->hWnd;
            }
#elif (defined OS2)
            if( SystemType == ::com::sun::star::lang::SystemDependent::SYSTEM_OS2 )
            {
                 aRet <<= (sal_Int32)pSysData->hWnd;
            }
#endif
        }
    }
    return aRet;
}

void VCLXTopWindow::addTopWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindowListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    GetTopWindowListeners().addInterface( rxListener );
}

void VCLXTopWindow::removeTopWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindowListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    GetTopWindowListeners().removeInterface( rxListener );
}

void VCLXTopWindow::toFront(  ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    Window* pWindow = GetWindow();
    if ( pWindow )
        ((WorkWindow*)pWindow)->ToTop( TOTOP_RESTOREWHENMIN );
}

void VCLXTopWindow::toBack(  ) throw(::com::sun::star::uno::RuntimeException)
{
/* Not possible in VCL...

    ::vos::OGuard aGuard( GetMutex() );

    Window* pWindow = GetWindow();
    if ( pWindow )
    {
        ((WorkWindow*)pWindow)->ToBack();
    }
*/
}

void VCLXTopWindow::setMenuBar( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMenuBar >& rxMenu ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    SystemWindow* pWindow = (SystemWindow*) GetWindow();
    if ( pWindow )
    {
        pWindow->SetMenuBar( NULL );
        if ( rxMenu.is() )
        {
            VCLXMenu* pMenu = VCLXMenu::GetImplementation( rxMenu );
            if ( pMenu && !pMenu->IsPopupMenu() )
                pWindow->SetMenuBar( (MenuBar*) pMenu->GetMenu() );
        }
    }
    mxMenuBar = rxMenu;
}

<commit_msg>INTEGRATION: CWS aquavcl01 (1.8.46); FILE MERGED 2006/12/30 19:38:02 pjanik 1.8.46.1: #i72385#: Add Quartz/AQUA specific part.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: vclxtopwindow.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-05 08:04:41 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"

#ifndef _COM_SUN_STAR_LANG_SYSTEMDEPENDENT_HPP_
#include <com/sun/star/lang/SystemDependent.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_SYSTEMDEPENDENTXWINDOW_HPP_
#include <com/sun/star/awt/SystemDependentXWindow.hpp>
#endif

#ifndef UNX
#include <tools/prewin.h>
#include <windows.h>
#include <tools/postwin.h>
#endif

#include <vcl/syschild.hxx>
#include <vcl/sysdata.hxx>
#include <cppuhelper/typeprovider.hxx>

#include <toolkit/awt/vclxtopwindow.hxx>
#include <toolkit/awt/vclxmenu.hxx>
#include <toolkit/helper/macros.hxx>

#include <vcl/wrkwin.hxx>
#include <vcl/syswin.hxx>
#include <vcl/menu.hxx>

#include <tools/debug.hxx>

//  ----------------------------------------------------
//  class VCLXTopWindow
//  ----------------------------------------------------

VCLXTopWindow::VCLXTopWindow(bool bWHWND)
    : m_bWHWND(bWHWND)
{
}

VCLXTopWindow::~VCLXTopWindow()
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXTopWindow::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
    ::com::sun::star::uno::Any aRet;
    if(! m_bWHWND) {
        aRet = ::cppu::queryInterface( rType,
                                       SAL_STATIC_CAST( ::com::sun::star::awt::XTopWindow*, this ) );
    }
    else {
        aRet = ::cppu::queryInterface( rType,
                                       SAL_STATIC_CAST( ::com::sun::star::awt::XTopWindow*, this ),
                                       SAL_STATIC_CAST( ::com::sun::star::awt::XSystemDependentWindowPeer*, this ) );
    }
    return (aRet.hasValue() ? aRet : VCLXContainer::queryInterface( rType ));
}

::com::sun::star::uno::Sequence< sal_Int8 > VCLXTopWindow::getImplementationId() throw(::com::sun::star::uno::RuntimeException)
{
    static ::cppu::OImplementationId* pId = NULL;
    static ::cppu::OImplementationId* pIdWithHandle = NULL;
    if ( m_bWHWND )
    {
        if( !pIdWithHandle )
        {
            ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
            if( !pIdWithHandle )
            {
                static ::cppu::OImplementationId idWithHandle( sal_False );
                pIdWithHandle = &idWithHandle;
            }
        }

        return (*pIdWithHandle).getImplementationId();
    }
    else
    {
        if( !pId )
        {
            ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
            if( !pId )
            {
                static ::cppu::OImplementationId id( sal_False );
                pId = &id;
            }
        }

        return (*pId).getImplementationId();
    }
}

::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > VCLXTopWindow::getTypes() throw(::com::sun::star::uno::RuntimeException)
{
    static ::cppu::OTypeCollection* pCollection = NULL;
    static ::cppu::OTypeCollection* pCollectionWithHandle = NULL;

    if ( m_bWHWND )
    {
        if( !pCollectionWithHandle )
        {
            ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
            if( !pCollectionWithHandle )
            {
                static ::cppu::OTypeCollection collectionWithHandle(
                getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XTypeProvider>* ) NULL ),
                getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindow>* ) NULL ),
                getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XSystemDependentWindowPeer>* ) NULL ),
                VCLXContainer::getTypes() );
                pCollectionWithHandle = &collectionWithHandle;
            }
        }

        return (*pCollectionWithHandle).getTypes();
    }
    else
    {
        if( !pCollection )
        {
            ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
            if( !pCollection )
            {
                static ::cppu::OTypeCollection collection(
                getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XTypeProvider>* ) NULL ),
                getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindow>* ) NULL ),
                VCLXContainer::getTypes() );
                pCollection = &collection;
            }
        }
        return (*pCollection).getTypes();
    }
}

::com::sun::star::uno::Any VCLXTopWindow::getWindowHandle( const ::com::sun::star::uno::Sequence< sal_Int8 >& /*ProcessId*/, sal_Int16 SystemType ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    // TODO, check the process id
    ::com::sun::star::uno::Any aRet;
    Window* pWindow = GetWindow();
    if ( pWindow )
    {
        const SystemEnvData* pSysData = ((SystemWindow *)pWindow)->GetSystemData();
        if( pSysData )
        {
#if (defined WNT)
            if( SystemType == ::com::sun::star::lang::SystemDependent::SYSTEM_WIN32 )
            {
                 aRet <<= (sal_Int32)pSysData->hWnd;
            }
#elif (defined OS2)
            if( SystemType == ::com::sun::star::lang::SystemDependent::SYSTEM_OS2 )
            {
                 aRet <<= (sal_Int32)pSysData->hWnd;
            }
#elif (defined QUARTZ)
            if( SystemType == ::com::sun::star::lang::SystemDependent::SYSTEM_MAC )
            {
                 aRet <<= (sal_IntPtr)pSysData->rWindow;
            }
#elif (defined UNX)
            if( SystemType == ::com::sun::star::lang::SystemDependent::SYSTEM_XWINDOW )
            {
                ::com::sun::star::awt::SystemDependentXWindow aSD;
                aSD.DisplayPointer = sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_IntPtr >(pSysData->pDisplay));
                aSD.WindowHandle = pSysData->aWindow;
                aRet <<= aSD;
            }
#endif
        }
    }
    return aRet;
}

void VCLXTopWindow::addTopWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindowListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    GetTopWindowListeners().addInterface( rxListener );
}

void VCLXTopWindow::removeTopWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindowListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    GetTopWindowListeners().removeInterface( rxListener );
}

void VCLXTopWindow::toFront(  ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    Window* pWindow = GetWindow();
    if ( pWindow )
        ((WorkWindow*)pWindow)->ToTop( TOTOP_RESTOREWHENMIN );
}

void VCLXTopWindow::toBack(  ) throw(::com::sun::star::uno::RuntimeException)
{
/* Not possible in VCL...

    ::vos::OGuard aGuard( GetMutex() );

    Window* pWindow = GetWindow();
    if ( pWindow )
    {
        ((WorkWindow*)pWindow)->ToBack();
    }
*/
}

void VCLXTopWindow::setMenuBar( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMenuBar >& rxMenu ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    SystemWindow* pWindow = (SystemWindow*) GetWindow();
    if ( pWindow )
    {
        pWindow->SetMenuBar( NULL );
        if ( rxMenu.is() )
        {
            VCLXMenu* pMenu = VCLXMenu::GetImplementation( rxMenu );
            if ( pMenu && !pMenu->IsPopupMenu() )
                pWindow->SetMenuBar( (MenuBar*) pMenu->GetMenu() );
        }
    }
    mxMenuBar = rxMenu;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: vclxtopwindow.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: mt $ $Date: 2001-03-01 10:22:50 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <cppuhelper/typeprovider.hxx>

#include <toolkit/awt/vclxtopwindow.hxx>
#include <toolkit/awt/vclxmenu.hxx>
#include <toolkit/helper/macros.hxx>

#include <vcl/wrkwin.hxx>
#include <vcl/syswin.hxx>
#include <vcl/menu.hxx>

#include <tools/debug.hxx>

//  ----------------------------------------------------
//  class VCLXTopWindow
//  ----------------------------------------------------

VCLXTopWindow::VCLXTopWindow()
{
}

VCLXTopWindow::~VCLXTopWindow()
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXTopWindow::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
    ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
                                        SAL_STATIC_CAST( ::com::sun::star::awt::XTopWindow*, this ) );
    return (aRet.hasValue() ? aRet : VCLXContainer::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXTopWindow )
    getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindow>* ) NULL ),
    VCLXContainer::getTypes()
IMPL_XTYPEPROVIDER_END

void VCLXTopWindow::addTopWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindowListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    GetTopWindowListeners().addInterface( rxListener );
}

void VCLXTopWindow::removeTopWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindowListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    GetTopWindowListeners().removeInterface( rxListener );
}

void VCLXTopWindow::toFront(  ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    Window* pWindow = GetWindow();
    if ( pWindow )
        ((WorkWindow*)pWindow)->ToTop( TOTOP_RESTOREWHENMIN );
}

void VCLXTopWindow::toBack(  ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    Window* pWindow = GetWindow();
    if ( pWindow )
    {
        // ((WorkWindow*)pWindow)->ToBack();
        DBG_ERROR( "toBack niy" );
    }
}

void VCLXTopWindow::setMenuBar( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMenuBar >& rxMenu ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    SystemWindow* pWindow = (SystemWindow*) GetWindow();
    if ( pWindow )
    {
        pWindow->SetMenuBar( NULL );
        if ( rxMenu.is() )
        {
            VCLXMenu* pMenu = VCLXMenu::GetImplementation( rxMenu );
            if ( pMenu && !pMenu->IsPopupMenu() )
                pWindow->SetMenuBar( (MenuBar*) pMenu->GetMenu() );
        }
    }
    mxMenuBar = rxMenu;
}

<commit_msg>#88019# No DBG_ERROR in toBack<commit_after>/*************************************************************************
 *
 *  $RCSfile: vclxtopwindow.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: mt $ $Date: 2001-07-17 13:03:51 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <cppuhelper/typeprovider.hxx>

#include <toolkit/awt/vclxtopwindow.hxx>
#include <toolkit/awt/vclxmenu.hxx>
#include <toolkit/helper/macros.hxx>

#include <vcl/wrkwin.hxx>
#include <vcl/syswin.hxx>
#include <vcl/menu.hxx>

#include <tools/debug.hxx>

//  ----------------------------------------------------
//  class VCLXTopWindow
//  ----------------------------------------------------

VCLXTopWindow::VCLXTopWindow()
{
}

VCLXTopWindow::~VCLXTopWindow()
{
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXTopWindow::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
    ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
                                        SAL_STATIC_CAST( ::com::sun::star::awt::XTopWindow*, this ) );
    return (aRet.hasValue() ? aRet : VCLXContainer::queryInterface( rType ));
}

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXTopWindow )
    getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindow>* ) NULL ),
    VCLXContainer::getTypes()
IMPL_XTYPEPROVIDER_END

void VCLXTopWindow::addTopWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindowListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    GetTopWindowListeners().addInterface( rxListener );
}

void VCLXTopWindow::removeTopWindowListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTopWindowListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    GetTopWindowListeners().removeInterface( rxListener );
}

void VCLXTopWindow::toFront(  ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    Window* pWindow = GetWindow();
    if ( pWindow )
        ((WorkWindow*)pWindow)->ToTop( TOTOP_RESTOREWHENMIN );
}

void VCLXTopWindow::toBack(  ) throw(::com::sun::star::uno::RuntimeException)
{
/* Not possible in VCL...

    ::vos::OGuard aGuard( GetMutex() );

    Window* pWindow = GetWindow();
    if ( pWindow )
    {
        ((WorkWindow*)pWindow)->ToBack();
    }
*/
}

void VCLXTopWindow::setMenuBar( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XMenuBar >& rxMenu ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    SystemWindow* pWindow = (SystemWindow*) GetWindow();
    if ( pWindow )
    {
        pWindow->SetMenuBar( NULL );
        if ( rxMenu.is() )
        {
            VCLXMenu* pMenu = VCLXMenu::GetImplementation( rxMenu );
            if ( pMenu && !pMenu->IsPopupMenu() )
                pWindow->SetMenuBar( (MenuBar*) pMenu->GetMenu() );
        }
    }
    mxMenuBar = rxMenu;
}

<|endoftext|>