<commit_before>/**
 * bufferdata.tcc -
 * @author: Jonathan Beard
 * @version: Fri May 16 13:08:25 2014
 *
 * Copyright 2014 Jonathan Beard
 *
 * 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.
 */
#ifndef _BUFFERDATA_TCC_
#define _BUFFERDATA_TCC_  1
#include <cstdint>
#include <cstddef>
#include <cstring>
#include <cassert>
#include <thread>
#include <cinttypes>
#include <iostream>
#include <sys/mman.h>
#include "shm.hpp"
#include "signalvars.hpp"
#include "pointer.hpp"
#include "ringbuffertypes.hpp"

#include "signal.hpp"

#include "database.tcc"

namespace Buffer
{

/** buffer structure for "heap" storage class **/
template < class T,
           Type::RingBufferType B = Type::Heap,
           std::size_t SIZE = 0 > struct Data : public DataBase< T >
{

   Data( T  * const ptr,
         const std::size_t max_cap,
         const std::size_t start_position ) : DataBase< T >( max_cap )
   {
      assert( ptr != nullptr );
      (this)->store  = ptr;
      (this)->signal = (Signal*)       calloc( 1,
                                               sizeof( Signal ) );
      if( (this)->signal == nullptr )
      {
         perror( "Failed to allocate signal queue!" );
         exit( EXIT_FAILURE );
      }
      /** set index to be start_position **/
      (this)->signal[ 0 ].index  = start_position;
      /** allocate read and write pointers **/
      (this)->read_pt   = new Pointer( max_cap );
      (this)->write_pt  = new Pointer( max_cap, 1 );

      (this)->external_alloc = true;
   }

   Data( const std::size_t max_cap ,
         const std::size_t align = 16 ) : DataBase< T >( max_cap )
   {
      int ret_val( posix_memalign( (void**)&((this)->store),
                                   align,
                                   (this)->length_store ) );
      if( ret_val != 0 )
      {
         std::cerr << "posix_memalign returned error code (" << ret_val << ")";
         std::cerr << " with message: \n" << strerror( ret_val ) << "\n";
         exit( EXIT_FAILURE );
      }

      posix_madvise( (this)->store, (this)->length_store,  POSIX_MADV_SEQUENTIAL );

      errno = 0;
      (this)->signal = (Signal*)       calloc( (this)->max_cap,
                                               sizeof( Signal ) );
      if( (this)->signal == nullptr )
      {
         perror( "Failed to allocate signal queue!" );
         exit( EXIT_FAILURE );
      }
      /** allocate read and write pointers **/
      /** TODO, see if there are optimizations to be made with sizing and alignment **/
      (this)->read_pt   = new Pointer( max_cap );
      (this)->write_pt  = new Pointer( max_cap );
   }

   virtual void copyFrom( DataBase< T > *other )
   {
      //TODO, figure something better out for here
      if( other->external_alloc )
      {
         assert( false );
      }
      delete( (this)->read_pt );
      (this)->read_pt = new Pointer( (other->read_pt),   (this)->max_cap );
      delete( (this)->write_pt );
      (this)->write_pt = new Pointer( (other->write_pt), (this)->max_cap );

      (this)->src_kernel = other->src_kernel;
      (this)->dst_kernel = other->dst_kernel;

      (this)->is_valid = other->is_valid;

      /** buffer is already alloc'd, copy **/
      std::memcpy( (void*)(this)->store /* dst */,
                   (void*)other->store  /* src */,
                   other->length_store );
      /** copy signal buff **/
      std::memcpy( (void*)(this)->signal /* dst */,
                   (void*)other->signal  /* src */,
                   other->length_signal );
      /** everything should be put back together now **/
   }

   virtual ~Data()
   {
      //DELETE USED HERE
      delete( (this)->read_pt );
      delete( (this)->write_pt );

      //FREE USED HERE
      if( ! (this)->external_alloc )
      {
         free( (this)->store );
      }
      free( (this)->signal );
   }

}; /** end heap **/

template < class T > struct Data< T, Type::SharedMemory > :
   public DataBase< T >
{
   /**
    * Data - Constructor for SHM based ringbuffer.  Allocates store, signal and
    * ptr structures in separate SHM segments.  Could have been a single one but
    * makes reading the ptr arithmatic a bit more difficult.  TODO, reevaluate
    * if performance wise that might be a good idea, also decide how best to
    * align data elements.
    * @param   max_cap, size_t with number of items to allocate queue for
    * @param   shm_key, const std::string key for opening the SHM,
                        must be same for both ends of the queue
    * @param   dir,     Direction enum for letting this queue know
                        which side we're allocating
    * @param   alignment, size_t with alignment NOTE: haven't implemented yet
    */
   Data( size_t max_cap,
         const std::string shm_key,
         Direction dir,
         const size_t alignment ) : DataBase< T >( max_cap ),
                                    store_key( shm_key + "_store" ),
                                    signal_key( shm_key + "_key" ),
                                    ptr_key( shm_key + "_ptr" )
   {
      /** now work through opening SHM **/
      switch( dir )
      {
         case( Direction::Producer ):
         {
            auto alloc_with_error =
            [&]( void **ptr, const size_t length, const char *key )
            {
               try
               {
                  *ptr = SHM::Init( key, length );
               }catch( bad_shm_alloc &ex )
               {
                  std::cerr <<
                  "Bad SHM allocate for key (" <<
                     key << ") with length (" << length << ")\n";
                  std::cerr << "Message: " << ex.what() << ", exiting.\n";
                  exit( EXIT_FAILURE );
               }
               assert( *ptr != nullptr );
            };
            alloc_with_error( (void**)&(this)->store,
                              (this)->length_store,
                              store_key.c_str() );
            alloc_with_error( (void**)&(this)->signal,
                              (this)->length_signal,
                              signal_key.c_str() );
            alloc_with_error( (void**)&(this)->read_pt,
                              (sizeof( Pointer ) * 2 ) + sizeof( Cookie ),
                              ptr_key.c_str() );

            (this)->write_pt = &(this)->read_pt[ 1 ];

            Pointer temp( max_cap );
            std::memcpy( (this)->read_pt,  &temp, sizeof( Pointer ) );
            std::memcpy( (this)->write_pt, &temp, sizeof( Pointer ) );

            (this)->cookie   = (Cookie*) &(this)->read_pt[ 2 ];
            (this)->cookie->producer = 0x1337;
            while( (this)->cookie->consumer != 0x1337 )
            {
               std::this_thread::yield();
            }
         }
         break;
         case( Direction::Consumer ):
         {
            auto retry_func = [&]( void **ptr, const char *str )
            {
               std::string error_copy;
               std::int32_t timeout( 1000 );
               while( timeout-- )
               {
                  try
                  {
                     *ptr = SHM::Open( str );
                  }
                  catch( bad_shm_alloc &ex )
                  {
                     //do nothing
                     timeout--;
                     error_copy = ex.what();
                     std::this_thread::yield();
                     continue;
                  }
                  goto SUCCESS;
               }
               /** timeout reached **/
               std::cerr << "Failed to open shared memory for \"" <<
                  str << "\", exiting!!\n";
               std::cerr << "Error message: " << error_copy << "\n";
               exit( EXIT_FAILURE );
               SUCCESS:;
            };
            retry_func( (void**) &(this)->store,  store_key.c_str() );
            retry_func( (void**) &(this)->signal, signal_key.c_str() );
            retry_func( (void**) &(this)->read_pt, ptr_key.c_str() );

            assert( (this)->store != nullptr );
            assert( (this)->signal != nullptr );
            assert( (this)->read_pt   != nullptr );

            /** fix write_pt **/
            (this)->write_pt  = &(this)->read_pt[ 1 ];
            assert( (this)->write_pt  != nullptr );
            (this)->cookie    = (Cookie*)&(this)->read_pt[ 2 ];

            Pointer temp( max_cap );
            std::memcpy( (this)->read_pt,  &temp, sizeof( Pointer ) );
            std::memcpy( (this)->write_pt, &temp, sizeof( Pointer ) );

            (this)->cookie->consumer = 0x1337;
            while( (this)->cookie->producer != 0x1337 )
            {
               std::this_thread::yield();
            }
         }
         break;
         default:
         {
            //TODO, add signal handler to cleanup
            std::cerr << "Invalid direction, exiting\n";
            exit( EXIT_FAILURE );
         }
      }
      /** should be all set now **/
   }

   virtual void copyFrom( DataBase< T > *other )
   {
      assert( false );
      /** TODO, implement me **/
   }

   ~Data()
   {
      /** three segments of SHM to close **/
      SHM::Close( store_key.c_str(),
                  (void*) (this)->store,
                  (this)->length_store,
                  false,
                  true );
      SHM::Close( signal_key.c_str(),
                  (void*) (this)->signal,
                  (this)->length_signal,
                  false,
                  true );
      SHM::Close( ptr_key.c_str(),
                  (void*) (this)->read_pt,
                  (sizeof( Pointer ) * 2) + sizeof( Cookie ),
                  false,
                  true );
   }
   struct Cookie
   {
      std::int32_t producer;
      std::int32_t consumer;;
   };

   volatile Cookie         *cookie;

   /** process local key copies **/
   const std::string store_key;
   const std::string signal_key;
   const std::string ptr_key;
};
}
#endif /* END _BUFFERDATA_TCC_ */
<commit_msg>updates<commit_after>/**
 * bufferdata.tcc -
 * @author: Jonathan Beard
 * @version: Fri May 16 13:08:25 2014
 *
 * Copyright 2014 Jonathan Beard
 *
 * 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.
 */
#ifndef _BUFFERDATA_TCC_
#define _BUFFERDATA_TCC_  1
#include <cstdint>
#include <cstddef>
#include <cstring>
#include <cassert>
#include <thread>
#include <cinttypes>
#include <iostream>
#include <sys/mman.h>
#include "shm.hpp"
#include "signalvars.hpp"
#include "pointer.hpp"
#include "ringbuffertypes.hpp"

#include "signal.hpp"

#include "database.tcc"

namespace Buffer
{

/** buffer structure for "heap" storage class **/
template < class T,
           Type::RingBufferType B = Type::Heap,
           std::size_t SIZE = 0 > struct Data : public DataBase< T >
{

   Data( T  * const ptr,
         const std::size_t max_cap,
         const std::size_t start_position ) : DataBase< T >( max_cap )
   {
      assert( ptr != nullptr );
      (this)->store  = ptr;
      (this)->signal = (Signal*)       calloc( 1,
                                               sizeof( Signal ) );
      if( (this)->signal == nullptr )
      {
         perror( "Failed to allocate signal queue!" );
         exit( EXIT_FAILURE );
      }
      /** set index to be start_position **/
      (this)->signal[ 0 ].index  = start_position;
      /** allocate read and write pointers **/
      (this)->read_pt   = new Pointer( max_cap );
      (this)->write_pt  = new Pointer( max_cap, 1 );

      (this)->external_alloc = true;
   }

   Data( const std::size_t max_cap ,
         const std::size_t align = 16 ) : DataBase< T >( max_cap )
   {
      int ret_val( 0 );

#if (defined __LINUX__) || (defined __APPLE__ )
      ret_val = posix_memalign( (void**)&((this)->store),
                                 align,
                                (this)->length_store );
#elif defined _WINDOWS
      (this)->store = _aligned_malloc( align, (this)->length_store );
#else
      /**
       * would use the array allocate, but well...we'd have to
       * figure out how to free it
       */
      (this)->store = reinterpret_cast< T* >( malloc( (this)->length_store ) );
#endif
      if( ret_val != 0 )
      {
         std::cerr << "posix_memalign returned error code (" << ret_val << ")";
         std::cerr << " with message: \n" << strerror( ret_val ) << "\n";
         exit( EXIT_FAILURE );
      }
      assert( (this)->store != nullptr );

#if (defined __LINUX__) || (defined __APPLE__ )
      posix_madvise( (this)->store,
                     (this)->length_store,
                     POSIX_MADV_SEQUENTIAL );
#endif
      errno = 0;
      (this)->signal = (Signal*)       calloc( (this)->max_cap,
                                               sizeof( Signal ) );
      if( (this)->signal == nullptr )
      {
         perror( "Failed to allocate signal queue!" );
         exit( EXIT_FAILURE );
      }
      /** allocate read and write pointers **/
      /** TODO, see if there are optimizations to be made with sizing and alignment **/
      (this)->read_pt   = new Pointer( max_cap );
      (this)->write_pt  = new Pointer( max_cap );
   }

   virtual void copyFrom( DataBase< T > *other )
   {
      //TODO, figure something better out for here
      if( other->external_alloc )
      {
         assert( false );
      }
      delete( (this)->read_pt );
      (this)->read_pt = new Pointer( (other->read_pt),   (this)->max_cap );
      delete( (this)->write_pt );
      (this)->write_pt = new Pointer( (other->write_pt), (this)->max_cap );

      (this)->src_kernel = other->src_kernel;
      (this)->dst_kernel = other->dst_kernel;

      (this)->is_valid = other->is_valid;

      /** buffer is already alloc'd, copy **/
      std::memcpy( (void*)(this)->store /* dst */,
                   (void*)other->store  /* src */,
                   other->length_store );
      /** copy signal buff **/
      std::memcpy( (void*)(this)->signal /* dst */,
                   (void*)other->signal  /* src */,
                   other->length_signal );
      /** everything should be put back together now **/
   }

   virtual ~Data()
   {
      //DELETE USED HERE
      delete( (this)->read_pt );
      delete( (this)->write_pt );

      //FREE USED HERE
      if( ! (this)->external_alloc )
      {
         free( (this)->store );
      }
      free( (this)->signal );
   }

}; /** end heap **/

template < class T > struct Data< T, Type::SharedMemory > :
   public DataBase< T >
{
   /**
    * Data - Constructor for SHM based ringbuffer.  Allocates store, signal and
    * ptr structures in separate SHM segments.  Could have been a single one but
    * makes reading the ptr arithmatic a bit more difficult.  TODO, reevaluate
    * if performance wise that might be a good idea, also decide how best to
    * align data elements.
    * @param   max_cap, size_t with number of items to allocate queue for
    * @param   shm_key, const std::string key for opening the SHM,
                        must be same for both ends of the queue
    * @param   dir,     Direction enum for letting this queue know
                        which side we're allocating
    * @param   alignment, size_t with alignment NOTE: haven't implemented yet
    */
   Data( size_t max_cap,
         const std::string shm_key,
         Direction dir,
         const size_t alignment ) : DataBase< T >( max_cap ),
                                    store_key( shm_key + "_store" ),
                                    signal_key( shm_key + "_key" ),
                                    ptr_key( shm_key + "_ptr" )
   {
      /** now work through opening SHM **/
      switch( dir )
      {
         case( Direction::Producer ):
         {
            auto alloc_with_error =
            [&]( void **ptr, const size_t length, const char *key )
            {
               try
               {
                  *ptr = SHM::Init( key, length );
               }catch( bad_shm_alloc &ex )
               {
                  std::cerr <<
                  "Bad SHM allocate for key (" <<
                     key << ") with length (" << length << ")\n";
                  std::cerr << "Message: " << ex.what() << ", exiting.\n";
                  exit( EXIT_FAILURE );
               }
               assert( *ptr != nullptr );
            };
            alloc_with_error( (void**)&(this)->store,
                              (this)->length_store,
                              store_key.c_str() );
            alloc_with_error( (void**)&(this)->signal,
                              (this)->length_signal,
                              signal_key.c_str() );
            alloc_with_error( (void**)&(this)->read_pt,
                              (sizeof( Pointer ) * 2 ) + sizeof( Cookie ),
                              ptr_key.c_str() );

            (this)->write_pt = &(this)->read_pt[ 1 ];

            Pointer temp( max_cap );
            std::memcpy( (this)->read_pt,  &temp, sizeof( Pointer ) );
            std::memcpy( (this)->write_pt, &temp, sizeof( Pointer ) );

            (this)->cookie   = (Cookie*) &(this)->read_pt[ 2 ];
            (this)->cookie->producer = 0x1337;
            while( (this)->cookie->consumer != 0x1337 )
            {
               std::this_thread::yield();
            }
         }
         break;
         case( Direction::Consumer ):
         {
            auto retry_func = [&]( void **ptr, const char *str )
            {
               std::string error_copy;
               std::int32_t timeout( 1000 );
               while( timeout-- )
               {
                  try
                  {
                     *ptr = SHM::Open( str );
                  }
                  catch( bad_shm_alloc &ex )
                  {
                     //do nothing
                     timeout--;
                     error_copy = ex.what();
                     std::this_thread::yield();
                     continue;
                  }
                  goto SUCCESS;
               }
               /** timeout reached **/
               std::cerr << "Failed to open shared memory for \"" <<
                  str << "\", exiting!!\n";
               std::cerr << "Error message: " << error_copy << "\n";
               exit( EXIT_FAILURE );
               SUCCESS:;
            };
            retry_func( (void**) &(this)->store,  store_key.c_str() );
            retry_func( (void**) &(this)->signal, signal_key.c_str() );
            retry_func( (void**) &(this)->read_pt, ptr_key.c_str() );

            assert( (this)->store != nullptr );
            assert( (this)->signal != nullptr );
            assert( (this)->read_pt   != nullptr );

            /** fix write_pt **/
            (this)->write_pt  = &(this)->read_pt[ 1 ];
            assert( (this)->write_pt  != nullptr );
            (this)->cookie    = (Cookie*)&(this)->read_pt[ 2 ];

            Pointer temp( max_cap );
            std::memcpy( (this)->read_pt,  &temp, sizeof( Pointer ) );
            std::memcpy( (this)->write_pt, &temp, sizeof( Pointer ) );

            (this)->cookie->consumer = 0x1337;
            while( (this)->cookie->producer != 0x1337 )
            {
               std::this_thread::yield();
            }
         }
         break;
         default:
         {
            //TODO, add signal handler to cleanup
            std::cerr << "Invalid direction, exiting\n";
            exit( EXIT_FAILURE );
         }
      }
      /** should be all set now **/
   }

   virtual void copyFrom( DataBase< T > *other )
   {
      assert( false );
      /** TODO, implement me **/
   }

   ~Data()
   {
      /** three segments of SHM to close **/
      SHM::Close( store_key.c_str(),
                  (void*) (this)->store,
                  (this)->length_store,
                  false,
                  true );
      SHM::Close( signal_key.c_str(),
                  (void*) (this)->signal,
                  (this)->length_signal,
                  false,
                  true );
      SHM::Close( ptr_key.c_str(),
                  (void*) (this)->read_pt,
                  (sizeof( Pointer ) * 2) + sizeof( Cookie ),
                  false,
                  true );
   }
   struct Cookie
   {
      std::int32_t producer;
      std::int32_t consumer;;
   };

   volatile Cookie         *cookie;

   /** process local key copies **/
   const std::string store_key;
   const std::string signal_key;
   const std::string ptr_key;
};
}
#endif /* END _BUFFERDATA_TCC_ */
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

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

#include "sal/config.h"

#include <cppuhelper/bootstrap.hxx>
#include <comphelper/processfactory.hxx>

#include <vcl/svapp.hxx>
#include <smdll.hxx>
#include <document.hxx>

#include <sfx2/bindings.hxx>
#include <sfx2/request.hxx>

#include <svl/stritem.hxx>

#include <editeng/editeng.hxx>
#include <editeng/editview.hxx>

#include "preextstl.h"
#include <cppunit/TestSuite.h>
#include <cppunit/TestFixture.h>
#include <cppunit/TestCase.h>
#include <cppunit/plugin/TestPlugIn.h>
#include <cppunit/extensions/HelperMacros.h>
#include "postextstl.h"

SO2_DECL_REF(SmDocShell)
SO2_IMPL_REF(SmDocShell)

using namespace ::com::sun::star;

namespace {

class Test : public CppUnit::TestFixture {
public:
    // init
    virtual void setUp();
    virtual void tearDown();

    // tests
    void createDocument();

    CPPUNIT_TEST_SUITE(Test);
    CPPUNIT_TEST(createDocument);
    CPPUNIT_TEST_SUITE_END();

private:
    uno::Reference< uno::XComponentContext > m_context;
};

void Test::setUp()
{
    m_context = cppu::defaultBootstrap_InitialComponentContext();

    uno::Reference<lang::XMultiComponentFactory> xFactory(m_context->getServiceManager());
    uno::Reference<lang::XMultiServiceFactory> xSM(xFactory, uno::UNO_QUERY_THROW);

    //Without this we're crashing because callees are using
    //getProcessServiceFactory.  In general those should be removed in favour
    //of retaining references to the root ServiceFactory as its passed around
    comphelper::setProcessServiceFactory(xSM);

    InitVCL(xSM);

    SmDLL::Init();
}

void Test::tearDown()
{
    uno::Reference< lang::XComponent >(m_context, uno::UNO_QUERY_THROW)->dispose();
}

void Test::createDocument()
{
    SmDocShellRef xDocShRef = new SmDocShell(SFXOBJECTSHELL_STD_NORMAL);

    EditEngine &rEditEngine = xDocShRef->GetEditEngine();
    Window aFoo(NULL, 0);
    EditView aEditView(&rEditEngine, &aFoo);
    rEditEngine.SetActiveView(&aEditView);

    rtl::OUString sStringOne(RTL_CONSTASCII_USTRINGPARAM("a under b"));
    {
        rEditEngine.SetText(0, sStringOne);
        xDocShRef->UpdateText();
        rtl::OUString sFinalText = xDocShRef->GetText();
        CPPUNIT_ASSERT_MESSAGE("Strings must match", sStringOne== sFinalText);
    }

    rtl::OUString sStringTwo(RTL_CONSTASCII_USTRINGPARAM("a over b"));
    {
        rEditEngine.SetText(0, sStringTwo);
        xDocShRef->UpdateText();
        rtl::OUString sFinalText = xDocShRef->GetText();
        CPPUNIT_ASSERT_MESSAGE("Strings must match", sStringTwo == sFinalText);
    }

    SfxRequest aUndo(SID_UNDO, SFX_CALLMODE_SYNCHRON, xDocShRef->GetPool());

    {
        xDocShRef->Execute(aUndo);
        rtl::OUString sFoo = rEditEngine.GetText();
        xDocShRef->UpdateText();
        rtl::OUString sFinalText = xDocShRef->GetText();
        CPPUNIT_ASSERT_MESSAGE("Strings much match", sStringOne== sFinalText);
    }

    {
        xDocShRef->Execute(aUndo);
        rtl::OUString sFoo = rEditEngine.GetText();
        xDocShRef->UpdateText();
        rtl::OUString sFinalText = xDocShRef->GetText();
        CPPUNIT_ASSERT_MESSAGE("Must now be empty", !sFinalText.getLength());
    }

    SfxRequest aRedo(SID_REDO, SFX_CALLMODE_SYNCHRON, xDocShRef->GetPool());
    {
        xDocShRef->Execute(aRedo);
        rtl::OUString sFoo = rEditEngine.GetText();
        xDocShRef->UpdateText();
        rtl::OUString sFinalText = xDocShRef->GetText();
        CPPUNIT_ASSERT_MESSAGE("Strings much match", sStringOne== sFinalText);
    }

    xDocShRef.Clear();
}

CPPUNIT_TEST_SUITE_REGISTRATION(Test);

}

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>rename this bit to tmEditUndoRedo<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

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

#include "sal/config.h"

#include <cppuhelper/bootstrap.hxx>
#include <comphelper/processfactory.hxx>

#include <vcl/svapp.hxx>
#include <smdll.hxx>
#include <document.hxx>

#include <sfx2/bindings.hxx>
#include <sfx2/request.hxx>

#include <svl/stritem.hxx>

#include <editeng/editeng.hxx>
#include <editeng/editview.hxx>

#include "preextstl.h"
#include <cppunit/TestSuite.h>
#include <cppunit/TestFixture.h>
#include <cppunit/TestCase.h>
#include <cppunit/plugin/TestPlugIn.h>
#include <cppunit/extensions/HelperMacros.h>
#include "postextstl.h"

SO2_DECL_REF(SmDocShell)
SO2_IMPL_REF(SmDocShell)

using namespace ::com::sun::star;

namespace {

class Test : public CppUnit::TestFixture {
public:
    // init
    virtual void setUp();
    virtual void tearDown();

    // tests
    void createDocument();
    void tmEditUndoRedo(SmDocShellRef &rDocShRef);

    CPPUNIT_TEST_SUITE(Test);
    CPPUNIT_TEST(createDocument);
    CPPUNIT_TEST_SUITE_END();

private:
    uno::Reference< uno::XComponentContext > m_context;
};

void Test::setUp()
{
    m_context = cppu::defaultBootstrap_InitialComponentContext();

    uno::Reference<lang::XMultiComponentFactory> xFactory(m_context->getServiceManager());
    uno::Reference<lang::XMultiServiceFactory> xSM(xFactory, uno::UNO_QUERY_THROW);

    //Without this we're crashing because callees are using
    //getProcessServiceFactory.  In general those should be removed in favour
    //of retaining references to the root ServiceFactory as its passed around
    comphelper::setProcessServiceFactory(xSM);

    InitVCL(xSM);

    SmDLL::Init();
}

void Test::tearDown()
{
    uno::Reference< lang::XComponent >(m_context, uno::UNO_QUERY_THROW)->dispose();
}

void Test::tmEditUndoRedo(SmDocShellRef &rDocShRef)
{
    EditEngine &rEditEngine = rDocShRef->GetEditEngine();

    rtl::OUString sStringOne(RTL_CONSTASCII_USTRINGPARAM("a under b"));
    {
        rEditEngine.SetText(0, sStringOne);
        rDocShRef->UpdateText();
        rtl::OUString sFinalText = rDocShRef->GetText();
        CPPUNIT_ASSERT_MESSAGE("Strings must match", sStringOne== sFinalText);
    }

    rtl::OUString sStringTwo(RTL_CONSTASCII_USTRINGPARAM("a over b"));
    {
        rEditEngine.SetText(0, sStringTwo);
        rDocShRef->UpdateText();
        rtl::OUString sFinalText = rDocShRef->GetText();
        CPPUNIT_ASSERT_MESSAGE("Strings must match", sStringTwo == sFinalText);
    }

    SfxRequest aUndo(SID_UNDO, SFX_CALLMODE_SYNCHRON, rDocShRef->GetPool());

    {
        rDocShRef->Execute(aUndo);
        rtl::OUString sFoo = rEditEngine.GetText();
        rDocShRef->UpdateText();
        rtl::OUString sFinalText = rDocShRef->GetText();
        CPPUNIT_ASSERT_MESSAGE("Strings much match", sStringOne== sFinalText);
    }

    {
        rDocShRef->Execute(aUndo);
        rtl::OUString sFoo = rEditEngine.GetText();
        rDocShRef->UpdateText();
        rtl::OUString sFinalText = rDocShRef->GetText();
        CPPUNIT_ASSERT_MESSAGE("Must now be empty", !sFinalText.getLength());
    }

    SfxRequest aRedo(SID_REDO, SFX_CALLMODE_SYNCHRON, rDocShRef->GetPool());
    {
        rDocShRef->Execute(aRedo);
        rtl::OUString sFoo = rEditEngine.GetText();
        rDocShRef->UpdateText();
        rtl::OUString sFinalText = rDocShRef->GetText();
        CPPUNIT_ASSERT_MESSAGE("Strings much match", sStringOne== sFinalText);
    }
}

void Test::createDocument()
{
    SmDocShellRef xDocShRef = new SmDocShell(SFXOBJECTSHELL_STD_NORMAL);

    EditEngine &rEditEngine = xDocShRef->GetEditEngine();
    Window aFoo(NULL, 0);
    EditView aEditView(&rEditEngine, &aFoo);
    rEditEngine.SetActiveView(&aEditView);

    tmEditUndoRedo(xDocShRef);

    xDocShRef.Clear();
}

CPPUNIT_TEST_SUITE_REGISTRATION(Test);

}

CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>//===--- GlobalObjects.cpp - Statically-initialized objects ---------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
//  Objects that are allocated at global scope instead of on the heap,
//  and statically initialized to avoid synchronization costs, are
//  defined here.
//
//===----------------------------------------------------------------------===//

#include "../SwiftShims/GlobalObjects.h"
#include "swift/Runtime/Metadata.h"
#include "swift/Runtime/Debug.h"
#include <stdlib.h>

namespace swift {
// FIXME(ABI)#76 : does this declaration need SWIFT_RUNTIME_STDLIB_INTERFACE?
// _direct type metadata for Swift._EmptyArrayStorage
SWIFT_RUNTIME_STDLIB_INTERFACE
extern "C" ClassMetadata CLASS_METADATA_SYM(s18_EmptyArrayStorage);

// _direct type metadata for Swift._RawNativeDictionaryStorage
SWIFT_RUNTIME_STDLIB_INTERFACE
extern "C" ClassMetadata CLASS_METADATA_SYM(s27_RawNativeDictionaryStorage);

// _direct type metadata for Swift._RawNativeSetStorage
SWIFT_RUNTIME_STDLIB_INTERFACE
extern "C" ClassMetadata CLASS_METADATA_SYM(s20_RawNativeSetStorage);
}

swift::_SwiftEmptyArrayStorage swift::_swiftEmptyArrayStorage = {
  // HeapObject header;
  {
    &CLASS_METADATA_SYM(s18_EmptyArrayStorage), // isa pointer
  },

  // _SwiftArrayBodyStorage body;
  {
    0, // int count;
    1  // unsigned int _capacityAndFlags; 1 means elementTypeIsBridgedVerbatim
  }
};

swift::_SwiftEmptyDictionaryStorage swift::_swiftEmptyDictionaryStorage = {
  // HeapObject header;
  {
    &CLASS_METADATA_SYM(s27_RawNativeDictionaryStorage), // isa pointer
  },

  // _SwiftDictionaryBodyStorage body;
  {
    // We set the capacity to 1 so that there's an empty hole to search.
    // Any insertion will lead to a real storage being allocated, because
    // Dictionary guarantees there's always another empty hole after insertion.
    1, // int capacity;
    0, // int count;

    // _SwiftUnsafeBitMap initializedEntries
    {
      &swift::_swiftEmptyDictionaryStorage.entries, // unsigned int* values;
      1 // int bitCount; (1 so there's something for iterators to read)
    },

    (void*)1, // void* keys; (non-null garbage)
    (void*)1  // void* values; (non-null garbage)
  },

  0 // int entries; (zero'd bits)
};

swift::_SwiftEmptySetStorage swift::_swiftEmptySetStorage = {
  // HeapObject header;
  {
    &CLASS_METADATA_SYM(s20_RawNativeSetStorage), // isa pointer
  },

  // _SwiftDictionaryBodyStorage body;
  {
    // We set the capacity to 1 so that there's an empty hole to search.
    // Any insertion will lead to a real storage being allocated, because
    // Dictionary guarantees there's always another empty hole after insertion.
    1, // int capacity;
    0, // int count;

    // _SwiftUnsafeBitMap initializedEntries
    {
      &swift::_swiftEmptySetStorage.entries, // unsigned int* values;
      1 // int bitCount; (1 so there's something for iterators to read)
    },

    (void*)1 // void* keys; (non-null garbage)
  },

  0 // int entries; (zero'd bits)
};

static __swift_uint64_t randomUInt64() {
#if defined(__APPLE__)
  return static_cast<__swift_uint64_t>(arc4random()) |
         (static_cast<__swift_uint64_t>(arc4random()) << 32);
#else
  auto devUrandom = fopen("/dev/urandom", "r");
  if (!devUrandom) {
    swift::fatalError(/* flags = */ 0, "Opening \"/dev/urandom\" failed");
  }
  uint64_t result;
  if (fread(&result, sizeof(result), 1, devUrandom) != 1) {
    swift::fatalError(/* flags = */ 0, "Reading from \"/dev/urandom\" failed");
  }
  if (fclose(devUrandom)) {
    swift::fatalError(/* flags = */ 0, "Closing \"/dev/urandom\" failed");
  }
  return result;
#endif
}

SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_BEGIN
swift::_SwiftHashingSecretKey swift::_swift_stdlib_Hashing_secretKey = {
  randomUInt64(), randomUInt64()
};
SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_END

__swift_uint64_t swift::_swift_stdlib_HashingDetail_fixedSeedOverride = 0;

namespace llvm { namespace hashing { namespace detail {
  // An extern variable expected by LLVM's hashing templates. We don't link any
  // LLVM libs into the runtime, so define this here.
  size_t fixed_seed_override = 0;
} } }

<commit_msg>Port stdlib/public/stubs/GlobalObjects to Windows<commit_after>//===--- GlobalObjects.cpp - Statically-initialized objects ---------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
//  Objects that are allocated at global scope instead of on the heap,
//  and statically initialized to avoid synchronization costs, are
//  defined here.
//
//===----------------------------------------------------------------------===//

#include "../SwiftShims/GlobalObjects.h"
#include "swift/Runtime/Metadata.h"
#include "swift/Runtime/Debug.h"
#include <stdlib.h>
#include <random>

namespace swift {
// FIXME(ABI)#76 : does this declaration need SWIFT_RUNTIME_STDLIB_INTERFACE?
// _direct type metadata for Swift._EmptyArrayStorage
SWIFT_RUNTIME_STDLIB_INTERFACE
extern "C" ClassMetadata CLASS_METADATA_SYM(s18_EmptyArrayStorage);

// _direct type metadata for Swift._RawNativeDictionaryStorage
SWIFT_RUNTIME_STDLIB_INTERFACE
extern "C" ClassMetadata CLASS_METADATA_SYM(s27_RawNativeDictionaryStorage);

// _direct type metadata for Swift._RawNativeSetStorage
SWIFT_RUNTIME_STDLIB_INTERFACE
extern "C" ClassMetadata CLASS_METADATA_SYM(s20_RawNativeSetStorage);
}

swift::_SwiftEmptyArrayStorage swift::_swiftEmptyArrayStorage = {
  // HeapObject header;
  {
    &CLASS_METADATA_SYM(s18_EmptyArrayStorage), // isa pointer
  },

  // _SwiftArrayBodyStorage body;
  {
    0, // int count;
    1  // unsigned int _capacityAndFlags; 1 means elementTypeIsBridgedVerbatim
  }
};

swift::_SwiftEmptyDictionaryStorage swift::_swiftEmptyDictionaryStorage = {
  // HeapObject header;
  {
    &CLASS_METADATA_SYM(s27_RawNativeDictionaryStorage), // isa pointer
  },

  // _SwiftDictionaryBodyStorage body;
  {
    // We set the capacity to 1 so that there's an empty hole to search.
    // Any insertion will lead to a real storage being allocated, because
    // Dictionary guarantees there's always another empty hole after insertion.
    1, // int capacity;
    0, // int count;

    // _SwiftUnsafeBitMap initializedEntries
    {
      &swift::_swiftEmptyDictionaryStorage.entries, // unsigned int* values;
      1 // int bitCount; (1 so there's something for iterators to read)
    },

    (void*)1, // void* keys; (non-null garbage)
    (void*)1  // void* values; (non-null garbage)
  },

  0 // int entries; (zero'd bits)
};

swift::_SwiftEmptySetStorage swift::_swiftEmptySetStorage = {
  // HeapObject header;
  {
    &CLASS_METADATA_SYM(s20_RawNativeSetStorage), // isa pointer
  },

  // _SwiftDictionaryBodyStorage body;
  {
    // We set the capacity to 1 so that there's an empty hole to search.
    // Any insertion will lead to a real storage being allocated, because
    // Dictionary guarantees there's always another empty hole after insertion.
    1, // int capacity;
    0, // int count;

    // _SwiftUnsafeBitMap initializedEntries
    {
      &swift::_swiftEmptySetStorage.entries, // unsigned int* values;
      1 // int bitCount; (1 so there's something for iterators to read)
    },

    (void*)1 // void* keys; (non-null garbage)
  },

  0 // int entries; (zero'd bits)
};

static __swift_uint64_t randomUInt64() {
  std::random_device randomDevice;
  std::mt19937_64 twisterEngine(randomDevice());
  std::uniform_int_distribution<__swift_uint64_t> distribution;
  return distribution(twisterEngine);
}

SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_BEGIN
swift::_SwiftHashingSecretKey swift::_swift_stdlib_Hashing_secretKey = {
  randomUInt64(), randomUInt64()
};
SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_END

__swift_uint64_t swift::_swift_stdlib_HashingDetail_fixedSeedOverride = 0;

namespace llvm { namespace hashing { namespace detail {
  // An extern variable expected by LLVM's hashing templates. We don't link any
  // LLVM libs into the runtime, so define this here.
  size_t fixed_seed_override = 0;
} } }

<|endoftext|>


<commit_before>#include "dreal/dreal_main.h"

#include <csignal>
#include <cstdlib>
#include <iostream>

#include "dreal/dr/run.h"
#include "dreal/smt2/run.h"
#include "dreal/solver/context.h"
#include "dreal/util/exception.h"
#include "dreal/util/filesystem.h"
#include "dreal/util/logging.h"

namespace dreal {

using std::cerr;
using std::endl;
using std::string;
using std::vector;

MainProgram::MainProgram(int argc, const char* argv[]) {
  AddOptions();
  opt_.parse(argc, argv);  // Parse Options
  is_options_all_valid_ = ValidateOptions();
}

void MainProgram::PrintUsage() {
  string usage;
  opt_.getUsage(usage);
  cerr << usage;
}

void MainProgram::AddOptions() {
#ifndef NDEBUG
  const string build_type{"Debug"};
#else
  const string build_type{"Release"};
#endif
  opt_.overview =
      fmt::format("dReal v{} ({} Build) : delta-complete SMT solver",
                  Context::version(), build_type);
  opt_.syntax = "dreal [OPTIONS] <input file> (.smt2 or .dr)";

  // NOTE: Make sure to match the default values specified here with the ones
  // specified in dreal/solver/config.h.
  opt_.add("" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Display usage instructions.", "-h", "-help", "--help", "--usage");

  auto* const positive_double_option_validator =
      new ez::ezOptionValidator("d" /* double */, "gt", "0");

  auto* const positive_int_option_validator =
      new ez::ezOptionValidator("s4" /* 4byte integer */, "gt", "0");

  opt_.add("0.001" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Precision (default = 0.001)\n", "--precision",
           positive_double_option_validator);

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Produce models if delta-sat\n", "--produce-models", "--model");

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Debug scanning/lexing\n", "--debug-scanning");

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */, "Debug parsing\n",
           "--debug-parsing");

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Read from standard input. Uses smt2 by default.\n", "--in");

  auto* const format_option_validator =
      new ez::ezOptionValidator("t", "in", "auto,dr,smt2", false);
  opt_.add("auto" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "File format. Any one of these (default = auto):\n"
           "smt2, dr, auto (use file extension)\n",
           "--format", format_option_validator);

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Use polytope contractor.\n", "--polytope");

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Use polytope contractor in forall contractor.\n",
           "--forall-polytope");

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Use worklist fixpoint algorithm in ICP.\n", "--worklist-fixpoint");

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Use local optimization algorithm for exist-forall problems.\n",
           "--local-optimization");

  opt_.add("1e-6" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "[NLopt] Relative tolerance on function value (default = 1e-6)\n",
           "--nlopt-ftol-rel", positive_double_option_validator);

  opt_.add("1e-6" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "[NLopt] Absolute tolerance on function value (default = 1e-6)\n",
           "--nlopt-ftol-abs", positive_double_option_validator);

  opt_.add("100" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "[NLopt] Number of maximum function evaluations (default = 100)\n",
           "--nlopt-maxeval", positive_int_option_validator);

  opt_.add(
      "0.1" /* Default */, false /* Required? */,
      1 /* Number of args expected. */,
      0 /* Delimiter if expecting multiple args. */,
      "[NLopt] Maximum optimization time (in second) (default = 0.01 sec)\n",
      "--nlopt-maxtime", positive_double_option_validator);

  auto* const verbose_option_validator = new ez::ezOptionValidator(
      "t", "in", "trace,debug,info,warning,error,critical,off", true);
  opt_.add(
      "error",  // Default.
      0,        // Required?
      1,        // Number of args expected.
      0,        // Delimiter if expecting multiple args.
      "Verbosity level. Either one of these (default = error):\n"
      "trace, debug, info, warning, error, critical, off",  // Help description.
      "--verbose",                                          // Flag token.
      verbose_option_validator);

  opt_.add("2" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Set default initial phase for SAT solver.\n"
           "  0 = false\n"
           "  1 = true\n"
           "  2 = Jeroslow-Wang (default)\n"
           "  3 = random initial phase\n",
           "--sat-default-phase");

  opt_.add("0" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Set a seed for the random number generator.", "--random-seed");
}

bool MainProgram::ValidateOptions() {
  // Checks bad options and bad arguments.
  vector<string> bad_options;
  vector<string> bad_args;
  if (!opt_.gotRequired(bad_options)) {
    for (const auto& bad_option : bad_options) {
      cerr << "ERROR: Missing required option " << bad_option << ".\n\n";
    }
    PrintUsage();
    return false;
  }
  if (!opt_.gotExpected(bad_options)) {
    for (const auto& bad_option : bad_options) {
      cerr << "ERROR: Got unexpected number of arguments for option "
           << bad_option << ".\n\n";
    }
    PrintUsage();
    return false;
  }
  if (!opt_.gotValid(bad_options, bad_args)) {
    for (size_t i = 0; i < bad_options.size(); ++i) {
      cerr << "ERROR: Got invalid argument \"" << bad_args[i]
           << "\" for option " << bad_options[i] << ".\n\n";
    }
    PrintUsage();
    return false;
  }
  // After filtering out bad options/arguments, save the valid ones in `args_`.
  args_.insert(args_.end(), opt_.firstArgs.begin() + 1, opt_.firstArgs.end());
  args_.insert(args_.end(), opt_.unknownArgs.begin(), opt_.unknownArgs.end());
  args_.insert(args_.end(), opt_.lastArgs.begin(), opt_.lastArgs.end());
  if (opt_.isSet("-h") || (args_.empty() && !opt_.isSet("--in")) ||
      args_.size() > 1) {
    PrintUsage();
    return false;
  }
  return true;
}

void MainProgram::ExtractOptions() {
  // Temporary variables used to set options.
  string verbosity;
  opt_.get("--verbose")->getString(verbosity);
  if (verbosity == "trace") {
    log()->set_level(spdlog::level::trace);
  } else if (verbosity == "debug") {
    log()->set_level(spdlog::level::debug);
  } else if (verbosity == "info") {
    log()->set_level(spdlog::level::info);
  } else if (verbosity == "warning") {
    log()->set_level(spdlog::level::warn);
  } else if (verbosity == "error") {
    log()->set_level(spdlog::level::err);
  } else if (verbosity == "critical") {
    log()->set_level(spdlog::level::critical);
  } else {
    log()->set_level(spdlog::level::off);
  }

  // --precision
  if (opt_.isSet("--precision")) {
    double precision{0.0};
    opt_.get("--precision")->getDouble(precision);
    config_.mutable_precision().set_from_command_line(precision);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --precision = {}",
                    config_.precision());
  }

  // --produce-model
  if (opt_.isSet("--produce-models")) {
    config_.mutable_produce_models().set_from_command_line(true);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --produce-models = {}",
                    config_.produce_models());
  }

  // --polytope
  if (opt_.isSet("--polytope")) {
    config_.mutable_use_polytope().set_from_command_line(true);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --polytope = {}",
                    config_.use_polytope());
  }

  // --forall-polytope
  if (opt_.isSet("--forall-polytope")) {
    config_.mutable_use_polytope_in_forall().set_from_command_line(true);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --forall-polytope = {}",
                    config_.use_polytope_in_forall());
  }

  // --worklist-fixpoint
  if (opt_.isSet("--worklist-fixpoint")) {
    config_.mutable_use_worklist_fixpoint().set_from_command_line(true);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --worklist-fixpoint = {}",
                    config_.use_worklist_fixpoint());
  }

  // --local-optimization
  if (opt_.isSet("--local-optimization")) {
    config_.mutable_use_local_optimization().set_from_command_line(true);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --local-optimization = {}",
                    config_.use_local_optimization());
  }

  // --nlopt-ftol-rel
  double nlopt_ftol_rel{0.0};
  if (opt_.isSet("--nlopt-ftol-rel")) {
    opt_.get("--nlopt-ftol-rel")->getDouble(nlopt_ftol_rel);
    config_.mutable_nlopt_ftol_rel().set_from_command_line(nlopt_ftol_rel);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --nlopt-ftol-rel = {}",
                    config_.nlopt_ftol_rel());
  }

  // --nlopt-ftol-abs
  if (opt_.isSet("--nlopt-ftol-abs")) {
    double nlopt_ftol_abs{0.0};
    opt_.get("--nlopt-ftol-abs")->getDouble(nlopt_ftol_abs);
    config_.mutable_nlopt_ftol_abs().set_from_command_line(nlopt_ftol_abs);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --nlopt-ftol-abs = {}",
                    config_.nlopt_ftol_abs());
  }

  // --nlopt-maxeval
  if (opt_.isSet("--nlopt-maxeval")) {
    int nlopt_maxeval{0};
    opt_.get("--nlopt-maxeval")->getInt(nlopt_maxeval);
    config_.mutable_nlopt_maxeval().set_from_command_line(nlopt_maxeval);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --nlopt-maxeval = {}",
                    config_.nlopt_maxeval());
  }

  // --nlopt-maxtime
  if (opt_.isSet("--nlopt-maxtime")) {
    double nlopt_maxtime{0.0};
    opt_.get("--nlopt-maxtime")->getDouble(nlopt_maxtime);
    config_.mutable_nlopt_maxtime().set_from_command_line(nlopt_maxtime);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --nlopt-maxtime = {}",
                    config_.nlopt_maxtime());
  }

  // --sat-default-phase
  if (opt_.isSet("--sat-default-phase")) {
    int sat_default_phase{2};
    opt_.get("--sat-default-phase")->getInt(sat_default_phase);
    config_.mutable_sat_default_phase().set_from_command_line(
        static_cast<Config::SatDefaultPhase>(sat_default_phase));
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --sat-default-phase = {}",
                    config_.sat_default_phase());
  }

  // --random-seed
  if (opt_.isSet("--random-seed")) {
    // NOLINTNEXTLINE(runtime/int)
    static_assert(sizeof(unsigned long) == sizeof(std::uint64_t),
                  "sizeof(unsigned long) != sizeof(std::uint64_t).");
    // NOLINTNEXTLINE(runtime/int)
    unsigned long random_seed{0};
    opt_.get("--random-seed")->getULong(random_seed);
    config_.mutable_random_seed().set_from_command_line(random_seed);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --random-seed = {}",
                    config_.random_seed());
  }
}

int MainProgram::Run() {
  if (!is_options_all_valid_) {
    return 1;
  }
  ExtractOptions();
  string filename;
  if (!args_.empty()) {
    filename = *args_[0];
    if (filename.empty()) {
      PrintUsage();
      return 1;
    }
  }
  if (!opt_.isSet("--in") && !file_exists(filename)) {
    cerr << "File not found: " << filename << "\n" << endl;
    PrintUsage();
    return 1;
  }
  const string extension{get_extension(filename)};
  string format_opt;
  opt_.get("--format")->getString(format_opt);
  if (format_opt == "smt2" ||
      (format_opt == "auto" && (extension == "smt2" || opt_.isSet("--in")))) {
    RunSmt2(filename, config_, opt_.isSet("--debug-scanning"),
            opt_.isSet("--debug-parsing"));
  } else if (format_opt == "dr" ||
             (format_opt == "auto" && extension == "dr")) {
    RunDr(filename, config_, opt_.isSet("--debug-scanning"),
          opt_.isSet("--debug-parsing"));
  } else {
    cerr << "Unknown extension: " << filename << "\n" << endl;
    PrintUsage();
    return 1;
  }
  return 0;
}
}  // namespace dreal

namespace {
void HandleSigInt(const int) {
  // Properly exit so that we can see stat information produced by destructors
  // even if a user press C-c.
  std::exit(1);
}
}  // namespace

int main(int argc, const char* argv[]) {
  std::signal(SIGINT, HandleSigInt);
  dreal::MainProgram main_program{argc, argv};
  return main_program.Run();
}
<commit_msg>feat(dreal_main.cc): Add --jobs command-line option<commit_after>#include "dreal/dreal_main.h"

#include <csignal>
#include <cstdlib>
#include <iostream>

#include "dreal/dr/run.h"
#include "dreal/smt2/run.h"
#include "dreal/solver/context.h"
#include "dreal/util/exception.h"
#include "dreal/util/filesystem.h"
#include "dreal/util/logging.h"

namespace dreal {

using std::cerr;
using std::endl;
using std::string;
using std::vector;

MainProgram::MainProgram(int argc, const char* argv[]) {
  AddOptions();
  opt_.parse(argc, argv);  // Parse Options
  is_options_all_valid_ = ValidateOptions();
}

void MainProgram::PrintUsage() {
  string usage;
  opt_.getUsage(usage);
  cerr << usage;
}

void MainProgram::AddOptions() {
#ifndef NDEBUG
  const string build_type{"Debug"};
#else
  const string build_type{"Release"};
#endif
  opt_.overview =
      fmt::format("dReal v{} ({} Build) : delta-complete SMT solver",
                  Context::version(), build_type);
  opt_.syntax = "dreal [OPTIONS] <input file> (.smt2 or .dr)";

  // NOTE: Make sure to match the default values specified here with the ones
  // specified in dreal/solver/config.h.
  opt_.add("" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Display usage instructions.", "-h", "-help", "--help", "--usage");

  auto* const positive_double_option_validator =
      new ez::ezOptionValidator("d" /* double */, "gt", "0");

  auto* const positive_int_option_validator =
      new ez::ezOptionValidator("s4" /* 4byte integer */, "gt", "0");

  opt_.add("0.001" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Precision (default = 0.001)\n", "--precision",
           positive_double_option_validator);

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Produce models if delta-sat\n", "--produce-models", "--model");

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Debug scanning/lexing\n", "--debug-scanning");

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */, "Debug parsing\n",
           "--debug-parsing");

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Read from standard input. Uses smt2 by default.\n", "--in");

  auto* const format_option_validator =
      new ez::ezOptionValidator("t", "in", "auto,dr,smt2", false);
  opt_.add("auto" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "File format. Any one of these (default = auto):\n"
           "smt2, dr, auto (use file extension)\n",
           "--format", format_option_validator);

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Use polytope contractor.\n", "--polytope");

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Use polytope contractor in forall contractor.\n",
           "--forall-polytope");

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Use worklist fixpoint algorithm in ICP.\n", "--worklist-fixpoint");

  opt_.add("false" /* Default */, false /* Required? */,
           0 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Use local optimization algorithm for exist-forall problems.\n",
           "--local-optimization");

  opt_.add("1" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */, "Number of jobs.\n",
           "--jobs", "-j");

  opt_.add("1e-6" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "[NLopt] Relative tolerance on function value (default = 1e-6)\n",
           "--nlopt-ftol-rel", positive_double_option_validator);

  opt_.add("1e-6" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "[NLopt] Absolute tolerance on function value (default = 1e-6)\n",
           "--nlopt-ftol-abs", positive_double_option_validator);

  opt_.add("100" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "[NLopt] Number of maximum function evaluations (default = 100)\n",
           "--nlopt-maxeval", positive_int_option_validator);

  opt_.add(
      "0.1" /* Default */, false /* Required? */,
      1 /* Number of args expected. */,
      0 /* Delimiter if expecting multiple args. */,
      "[NLopt] Maximum optimization time (in second) (default = 0.01 sec)\n",
      "--nlopt-maxtime", positive_double_option_validator);

  auto* const verbose_option_validator = new ez::ezOptionValidator(
      "t", "in", "trace,debug,info,warning,error,critical,off", true);
  opt_.add(
      "error",  // Default.
      0,        // Required?
      1,        // Number of args expected.
      0,        // Delimiter if expecting multiple args.
      "Verbosity level. Either one of these (default = error):\n"
      "trace, debug, info, warning, error, critical, off",  // Help description.
      "--verbose",                                          // Flag token.
      verbose_option_validator);

  opt_.add("2" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Set default initial phase for SAT solver.\n"
           "  0 = false\n"
           "  1 = true\n"
           "  2 = Jeroslow-Wang (default)\n"
           "  3 = random initial phase\n",
           "--sat-default-phase");

  opt_.add("0" /* Default */, false /* Required? */,
           1 /* Number of args expected. */,
           0 /* Delimiter if expecting multiple args. */,
           "Set a seed for the random number generator.", "--random-seed");
}

bool MainProgram::ValidateOptions() {
  // Checks bad options and bad arguments.
  vector<string> bad_options;
  vector<string> bad_args;
  if (!opt_.gotRequired(bad_options)) {
    for (const auto& bad_option : bad_options) {
      cerr << "ERROR: Missing required option " << bad_option << ".\n\n";
    }
    PrintUsage();
    return false;
  }
  if (!opt_.gotExpected(bad_options)) {
    for (const auto& bad_option : bad_options) {
      cerr << "ERROR: Got unexpected number of arguments for option "
           << bad_option << ".\n\n";
    }
    PrintUsage();
    return false;
  }
  if (!opt_.gotValid(bad_options, bad_args)) {
    for (size_t i = 0; i < bad_options.size(); ++i) {
      cerr << "ERROR: Got invalid argument \"" << bad_args[i]
           << "\" for option " << bad_options[i] << ".\n\n";
    }
    PrintUsage();
    return false;
  }
  // After filtering out bad options/arguments, save the valid ones in `args_`.
  args_.insert(args_.end(), opt_.firstArgs.begin() + 1, opt_.firstArgs.end());
  args_.insert(args_.end(), opt_.unknownArgs.begin(), opt_.unknownArgs.end());
  args_.insert(args_.end(), opt_.lastArgs.begin(), opt_.lastArgs.end());
  if (opt_.isSet("-h") || (args_.empty() && !opt_.isSet("--in")) ||
      args_.size() > 1) {
    PrintUsage();
    return false;
  }
  return true;
}

void MainProgram::ExtractOptions() {
  // Temporary variables used to set options.
  string verbosity;
  opt_.get("--verbose")->getString(verbosity);
  if (verbosity == "trace") {
    log()->set_level(spdlog::level::trace);
  } else if (verbosity == "debug") {
    log()->set_level(spdlog::level::debug);
  } else if (verbosity == "info") {
    log()->set_level(spdlog::level::info);
  } else if (verbosity == "warning") {
    log()->set_level(spdlog::level::warn);
  } else if (verbosity == "error") {
    log()->set_level(spdlog::level::err);
  } else if (verbosity == "critical") {
    log()->set_level(spdlog::level::critical);
  } else {
    log()->set_level(spdlog::level::off);
  }

  // --precision
  if (opt_.isSet("--precision")) {
    double precision{0.0};
    opt_.get("--precision")->getDouble(precision);
    config_.mutable_precision().set_from_command_line(precision);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --precision = {}",
                    config_.precision());
  }

  // --produce-model
  if (opt_.isSet("--produce-models")) {
    config_.mutable_produce_models().set_from_command_line(true);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --produce-models = {}",
                    config_.produce_models());
  }

  // --polytope
  if (opt_.isSet("--polytope")) {
    config_.mutable_use_polytope().set_from_command_line(true);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --polytope = {}",
                    config_.use_polytope());
  }

  // --jobs
  if (opt_.isSet("--jobs")) {
    int jobs{};
    opt_.get("--jobs")->getInt(jobs);
    config_.mutable_number_of_jobs().set_from_command_line(jobs);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --jobs = {}",
                    config_.number_of_jobs());
  }

  // --forall-polytope
  if (opt_.isSet("--forall-polytope")) {
    config_.mutable_use_polytope_in_forall().set_from_command_line(true);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --forall-polytope = {}",
                    config_.use_polytope_in_forall());
  }

  // --worklist-fixpoint
  if (opt_.isSet("--worklist-fixpoint")) {
    config_.mutable_use_worklist_fixpoint().set_from_command_line(true);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --worklist-fixpoint = {}",
                    config_.use_worklist_fixpoint());
  }

  // --local-optimization
  if (opt_.isSet("--local-optimization")) {
    config_.mutable_use_local_optimization().set_from_command_line(true);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --local-optimization = {}",
                    config_.use_local_optimization());
  }

  // --nlopt-ftol-rel
  double nlopt_ftol_rel{0.0};
  if (opt_.isSet("--nlopt-ftol-rel")) {
    opt_.get("--nlopt-ftol-rel")->getDouble(nlopt_ftol_rel);
    config_.mutable_nlopt_ftol_rel().set_from_command_line(nlopt_ftol_rel);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --nlopt-ftol-rel = {}",
                    config_.nlopt_ftol_rel());
  }

  // --nlopt-ftol-abs
  if (opt_.isSet("--nlopt-ftol-abs")) {
    double nlopt_ftol_abs{0.0};
    opt_.get("--nlopt-ftol-abs")->getDouble(nlopt_ftol_abs);
    config_.mutable_nlopt_ftol_abs().set_from_command_line(nlopt_ftol_abs);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --nlopt-ftol-abs = {}",
                    config_.nlopt_ftol_abs());
  }

  // --nlopt-maxeval
  if (opt_.isSet("--nlopt-maxeval")) {
    int nlopt_maxeval{0};
    opt_.get("--nlopt-maxeval")->getInt(nlopt_maxeval);
    config_.mutable_nlopt_maxeval().set_from_command_line(nlopt_maxeval);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --nlopt-maxeval = {}",
                    config_.nlopt_maxeval());
  }

  // --nlopt-maxtime
  if (opt_.isSet("--nlopt-maxtime")) {
    double nlopt_maxtime{0.0};
    opt_.get("--nlopt-maxtime")->getDouble(nlopt_maxtime);
    config_.mutable_nlopt_maxtime().set_from_command_line(nlopt_maxtime);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --nlopt-maxtime = {}",
                    config_.nlopt_maxtime());
  }

  // --sat-default-phase
  if (opt_.isSet("--sat-default-phase")) {
    int sat_default_phase{2};
    opt_.get("--sat-default-phase")->getInt(sat_default_phase);
    config_.mutable_sat_default_phase().set_from_command_line(
        static_cast<Config::SatDefaultPhase>(sat_default_phase));
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --sat-default-phase = {}",
                    config_.sat_default_phase());
  }

  // --random-seed
  if (opt_.isSet("--random-seed")) {
    // NOLINTNEXTLINE(runtime/int)
    static_assert(sizeof(unsigned long) == sizeof(std::uint64_t),
                  "sizeof(unsigned long) != sizeof(std::uint64_t).");
    // NOLINTNEXTLINE(runtime/int)
    unsigned long random_seed{0};
    opt_.get("--random-seed")->getULong(random_seed);
    config_.mutable_random_seed().set_from_command_line(random_seed);
    DREAL_LOG_DEBUG("MainProgram::ExtractOptions() --random-seed = {}",
                    config_.random_seed());
  }
}

int MainProgram::Run() {
  if (!is_options_all_valid_) {
    return 1;
  }
  ExtractOptions();
  string filename;
  if (!args_.empty()) {
    filename = *args_[0];
    if (filename.empty()) {
      PrintUsage();
      return 1;
    }
  }
  if (!opt_.isSet("--in") && !file_exists(filename)) {
    cerr << "File not found: " << filename << "\n" << endl;
    PrintUsage();
    return 1;
  }
  const string extension{get_extension(filename)};
  string format_opt;
  opt_.get("--format")->getString(format_opt);
  if (format_opt == "smt2" ||
      (format_opt == "auto" && (extension == "smt2" || opt_.isSet("--in")))) {
    RunSmt2(filename, config_, opt_.isSet("--debug-scanning"),
            opt_.isSet("--debug-parsing"));
  } else if (format_opt == "dr" ||
             (format_opt == "auto" && extension == "dr")) {
    RunDr(filename, config_, opt_.isSet("--debug-scanning"),
          opt_.isSet("--debug-parsing"));
  } else {
    cerr << "Unknown extension: " << filename << "\n" << endl;
    PrintUsage();
    return 1;
  }
  return 0;
}
}  // namespace dreal

namespace {
void HandleSigInt(const int) {
  // Properly exit so that we can see stat information produced by destructors
  // even if a user press C-c.
  std::exit(1);
}
}  // namespace

int main(int argc, const char* argv[]) {
  std::signal(SIGINT, HandleSigInt);
  dreal::MainProgram main_program{argc, argv};
  return main_program.Run();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fmtextcontrolshell.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2006-12-01 17:27:35 $
 *
 *  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
 *
 ************************************************************************/
#ifndef SVX_SOURCE_INC_FMTEXTCONTROLSHELL_HXX
#define SVX_SOURCE_INC_FMTEXTCONTROLSHELL_HXX

/** === begin UNO includes === **/
#ifndef _COM_SUN_STAR_FRAME_XDISPATCHPROVIDER_HPP_
#include <com/sun/star/frame/XDispatchProvider.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XTEXTCOMPONENT_HPP_
#include <com/sun/star/awt/XTextComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XSTATUSLISTENER_HPP_
#include <com/sun/star/frame/XStatusListener.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XFOCUSLISTENER_HPP_
#include <com/sun/star/awt/XFocusListener.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XMOUSELISTENER_HPP_
#include <com/sun/star/awt/XMouseListener.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XFORMCONTROLLER_HPP_
#include <com/sun/star/form/XFormController.hpp>
#endif
#ifndef _COM_SUN_STAR_AWT_XCONTROL_HPP_
#include <com/sun/star/awt/XControl.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XURLTRANSFORMER_HPP_
#include <com/sun/star/util/XURLTransformer.hpp>
#endif
/** === end UNO includes === **/

#ifndef _COMPHELPER_IMPLEMENTATIONREFERENCE_HXX
#include <comphelper/implementationreference.hxx>
#endif

#ifndef _LINK_HXX
#include <tools/link.hxx>
#endif

#ifndef _SV_TIMER_HXX
#include <vcl/timer.hxx>
#endif

#ifndef SVX_SOURCE_INC_FMSLOTINVALIDATOR_HXX
#include "fmslotinvalidator.hxx"
#endif

#include <vector>
#include <map>

class SfxRequest;
class SfxItemSet;
class SfxAllItemSet;
class SfxBindings;
class SfxViewFrame;
class Window;
class SfxApplication;

//........................................................................
namespace svx
{
//........................................................................

    class FmFocusListenerAdapter;
    class FmTextControlFeature;
    class FmMouseListenerAdapter;

    //====================================================================
    //= IFocusObserver
    //====================================================================
    class IFocusObserver
    {
    public:
        virtual void    focusGained( const ::com::sun::star::awt::FocusEvent& _rEvent ) = 0;
        virtual void    focusLost( const ::com::sun::star::awt::FocusEvent& _rEvent ) = 0;
    };

    //====================================================================
    //= IFocusObserver
    //====================================================================
    class IContextRequestObserver
    {
    public:
        virtual void    contextMenuRequested( const ::com::sun::star::awt::MouseEvent& _rEvent ) = 0;
    };

    //====================================================================
    //= FmTextControlShell
    //====================================================================
    class FmTextControlShell :public IFocusObserver
                             ,public ISlotInvalidator
                             ,public IContextRequestObserver
    {
    private:
        ::com::sun::star::uno::Reference< ::com::sun::star::util::XURLTransformer > m_xURLTransformer;
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >         m_xActiveControl;
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextComponent >   m_xActiveTextComponent;
        ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormController > m_xActiveController;
#ifndef DONT_REMEMBER_LAST_CONTROL
        // without this define, m_xActiveControl remembers the *last* active control, even
        // if it, in the meantime, already lost the focus
        bool                                                                        m_bActiveControl;
            // so we need an additional boolean flag telling whether the active cotrol
            // is really focused
#endif
        bool                                                                        m_bActiveControlIsReadOnly;
        bool                                                                        m_bActiveControlIsRichText;

        // listening at all controls of the active controller for focus changes
        typedef ::comphelper::ImplementationReference< FmFocusListenerAdapter, ::com::sun::star::awt::XFocusListener >
                                                                                FocusListenerAdapter;
        typedef ::std::vector< FocusListenerAdapter >                               FocusListenerAdapters;
        FocusListenerAdapters                                                       m_aControlObservers;

        typedef ::comphelper::ImplementationReference< FmMouseListenerAdapter, ::com::sun::star::awt::XMouseListener >
                                                                                MouseListenerAdapter;
        MouseListenerAdapter                                                        m_aContextMenuObserver;

        // translating between "slots" of the framework and "features" of the active control
        typedef ::comphelper::ImplementationReference< FmTextControlFeature, ::com::sun::star::frame::XStatusListener >
                                                                                ControlFeature;
        typedef ::std::map< SfxSlotId, ControlFeature, ::std::less< SfxSlotId > >   ControlFeatures;
        ControlFeatures                                                             m_aControlFeatures;

        SfxViewFrame*                                                               m_pViewFrame;
        // invalidating slots
        SfxBindings&                                                                m_rBindings;
        Link                                                                        m_aControlActivationHandler;
        AutoTimer                                                                   m_aClipboardInvalidation;
        bool                                                                        m_bNeedClipboardInvalidation;

    public:
        FmTextControlShell( SfxViewFrame* _pFrame );
        virtual ~FmTextControlShell();

        // clean up any resources associated with this instance
        void    dispose();

        void    ExecuteTextAttribute( SfxRequest& _rReq );
        void    GetTextAttributeState( SfxItemSet& _rSet );
        bool    IsActiveControl( bool _bCountRichTextOnly = false ) const;
        void    ForgetActiveControl();
        void    SetControlActivationHandler( const Link& _rHdl ) { m_aControlActivationHandler = _rHdl; }

        /** to be called when a form in our document has been activated
        */
        void    formActivated( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormController >& _rxController );
        /** to be called when a form in our document has been deactivated
        */
        void    formDeactivated( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormController >& _rxController );

        /** notifies the instance that the design mode has changed
        */
        void    designModeChanged( bool _bNewDesignMode );

    protected:
        // IFocusObserver
        virtual void    focusGained( const ::com::sun::star::awt::FocusEvent& _rEvent );
        virtual void    focusLost( const ::com::sun::star::awt::FocusEvent& _rEvent );

        // IContextRequestObserver
        virtual void    contextMenuRequested( const ::com::sun::star::awt::MouseEvent& _rEvent );

        // ISlotInvalidator
        virtual void    Invalidate( SfxSlotId _nSlot );

    protected:
        enum AttributeSet { eCharAttribs, eParaAttribs };
        void    executeAttributeDialog( AttributeSet _eSet, SfxRequest& _rReq );
        bool    executeSelectAll( );
        bool    executeClipboardSlot( SfxSlotId _nSlot );

    private:
        inline  bool    isControllerListening() const { return !m_aControlObservers.empty(); }

        FmTextControlFeature*
                        implGetFeatureDispatcher(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >& _rxProvider,
                            SfxApplication* _pApplication,
                            SfxSlotId _nSlot
                        );

        // fills the given structure with dispatchers for the given slots, for the given control
        void            fillFeatureDispatchers(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > _rxControl,
                            SfxSlotId* _pZeroTerminatedSlots,
                            ControlFeatures& _rDispatchers
                        );

        /// creates SfxPoolItes for all features in the given set, and puts them into the given SfxAllItemSet
        void            transferFeatureStatesToItemSet(
                            ControlFeatures& _rDispatchers,
                            SfxAllItemSet& _rSet,
                            bool _bTranslateLatin = false
                        );

        /// to be called when a control has been activated
        void    controlActivated( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& _rxControl );
        /// to be called when the currently active control has been deactivated
        void    controlDeactivated( );

        void    implClearActiveControlRef();

        /** starts listening at all controls of the given controller for focus events
        @precond
            we don't have an active controller currently
        */
        void    startControllerListening( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormController >& _rxController );
        /** stops listening at the active controller
        @precond
            we have an active controller currently
        */
        void    stopControllerListening( );

        /** parses the given URL's Complete member, by calling XURLTransformer::parseString
        */
        void    impl_parseURL_nothrow( ::com::sun::star::util::URL& _rURL );

        DECL_LINK( OnInvalidateClipboard, void* );
    };

//........................................................................
} // namespace svx
//........................................................................

#endif // SVX_SOURCE_INC_FMTEXTCONTROLSHELL_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.6.606); FILE MERGED 2008/04/01 15:51:11 thb 1.6.606.3: #i85898# Stripping all external header guards 2008/04/01 12:49:05 thb 1.6.606.2: #i85898# Stripping all external header guards 2008/03/31 14:22:20 rt 1.6.606.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: fmtextcontrolshell.hxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef SVX_SOURCE_INC_FMTEXTCONTROLSHELL_HXX
#define SVX_SOURCE_INC_FMTEXTCONTROLSHELL_HXX

/** === begin UNO includes === **/
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/awt/XTextComponent.hpp>
#include <com/sun/star/frame/XStatusListener.hpp>
#include <com/sun/star/awt/XFocusListener.hpp>
#include <com/sun/star/awt/XMouseListener.hpp>
#include <com/sun/star/form/XFormController.hpp>
#include <com/sun/star/awt/XControl.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
/** === end UNO includes === **/
#include <comphelper/implementationreference.hxx>
#include <tools/link.hxx>
#include <vcl/timer.hxx>
#include "fmslotinvalidator.hxx"

#include <vector>
#include <map>

class SfxRequest;
class SfxItemSet;
class SfxAllItemSet;
class SfxBindings;
class SfxViewFrame;
class Window;
class SfxApplication;

//........................................................................
namespace svx
{
//........................................................................

    class FmFocusListenerAdapter;
    class FmTextControlFeature;
    class FmMouseListenerAdapter;

    //====================================================================
    //= IFocusObserver
    //====================================================================
    class IFocusObserver
    {
    public:
        virtual void    focusGained( const ::com::sun::star::awt::FocusEvent& _rEvent ) = 0;
        virtual void    focusLost( const ::com::sun::star::awt::FocusEvent& _rEvent ) = 0;
    };

    //====================================================================
    //= IFocusObserver
    //====================================================================
    class IContextRequestObserver
    {
    public:
        virtual void    contextMenuRequested( const ::com::sun::star::awt::MouseEvent& _rEvent ) = 0;
    };

    //====================================================================
    //= FmTextControlShell
    //====================================================================
    class FmTextControlShell :public IFocusObserver
                             ,public ISlotInvalidator
                             ,public IContextRequestObserver
    {
    private:
        ::com::sun::star::uno::Reference< ::com::sun::star::util::XURLTransformer > m_xURLTransformer;
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >         m_xActiveControl;
        ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextComponent >   m_xActiveTextComponent;
        ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormController > m_xActiveController;
#ifndef DONT_REMEMBER_LAST_CONTROL
        // without this define, m_xActiveControl remembers the *last* active control, even
        // if it, in the meantime, already lost the focus
        bool                                                                        m_bActiveControl;
            // so we need an additional boolean flag telling whether the active cotrol
            // is really focused
#endif
        bool                                                                        m_bActiveControlIsReadOnly;
        bool                                                                        m_bActiveControlIsRichText;

        // listening at all controls of the active controller for focus changes
        typedef ::comphelper::ImplementationReference< FmFocusListenerAdapter, ::com::sun::star::awt::XFocusListener >
                                                                                FocusListenerAdapter;
        typedef ::std::vector< FocusListenerAdapter >                               FocusListenerAdapters;
        FocusListenerAdapters                                                       m_aControlObservers;

        typedef ::comphelper::ImplementationReference< FmMouseListenerAdapter, ::com::sun::star::awt::XMouseListener >
                                                                                MouseListenerAdapter;
        MouseListenerAdapter                                                        m_aContextMenuObserver;

        // translating between "slots" of the framework and "features" of the active control
        typedef ::comphelper::ImplementationReference< FmTextControlFeature, ::com::sun::star::frame::XStatusListener >
                                                                                ControlFeature;
        typedef ::std::map< SfxSlotId, ControlFeature, ::std::less< SfxSlotId > >   ControlFeatures;
        ControlFeatures                                                             m_aControlFeatures;

        SfxViewFrame*                                                               m_pViewFrame;
        // invalidating slots
        SfxBindings&                                                                m_rBindings;
        Link                                                                        m_aControlActivationHandler;
        AutoTimer                                                                   m_aClipboardInvalidation;
        bool                                                                        m_bNeedClipboardInvalidation;

    public:
        FmTextControlShell( SfxViewFrame* _pFrame );
        virtual ~FmTextControlShell();

        // clean up any resources associated with this instance
        void    dispose();

        void    ExecuteTextAttribute( SfxRequest& _rReq );
        void    GetTextAttributeState( SfxItemSet& _rSet );
        bool    IsActiveControl( bool _bCountRichTextOnly = false ) const;
        void    ForgetActiveControl();
        void    SetControlActivationHandler( const Link& _rHdl ) { m_aControlActivationHandler = _rHdl; }

        /** to be called when a form in our document has been activated
        */
        void    formActivated( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormController >& _rxController );
        /** to be called when a form in our document has been deactivated
        */
        void    formDeactivated( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormController >& _rxController );

        /** notifies the instance that the design mode has changed
        */
        void    designModeChanged( bool _bNewDesignMode );

    protected:
        // IFocusObserver
        virtual void    focusGained( const ::com::sun::star::awt::FocusEvent& _rEvent );
        virtual void    focusLost( const ::com::sun::star::awt::FocusEvent& _rEvent );

        // IContextRequestObserver
        virtual void    contextMenuRequested( const ::com::sun::star::awt::MouseEvent& _rEvent );

        // ISlotInvalidator
        virtual void    Invalidate( SfxSlotId _nSlot );

    protected:
        enum AttributeSet { eCharAttribs, eParaAttribs };
        void    executeAttributeDialog( AttributeSet _eSet, SfxRequest& _rReq );
        bool    executeSelectAll( );
        bool    executeClipboardSlot( SfxSlotId _nSlot );

    private:
        inline  bool    isControllerListening() const { return !m_aControlObservers.empty(); }

        FmTextControlFeature*
                        implGetFeatureDispatcher(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatchProvider >& _rxProvider,
                            SfxApplication* _pApplication,
                            SfxSlotId _nSlot
                        );

        // fills the given structure with dispatchers for the given slots, for the given control
        void            fillFeatureDispatchers(
                            const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > _rxControl,
                            SfxSlotId* _pZeroTerminatedSlots,
                            ControlFeatures& _rDispatchers
                        );

        /// creates SfxPoolItes for all features in the given set, and puts them into the given SfxAllItemSet
        void            transferFeatureStatesToItemSet(
                            ControlFeatures& _rDispatchers,
                            SfxAllItemSet& _rSet,
                            bool _bTranslateLatin = false
                        );

        /// to be called when a control has been activated
        void    controlActivated( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& _rxControl );
        /// to be called when the currently active control has been deactivated
        void    controlDeactivated( );

        void    implClearActiveControlRef();

        /** starts listening at all controls of the given controller for focus events
        @precond
            we don't have an active controller currently
        */
        void    startControllerListening( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormController >& _rxController );
        /** stops listening at the active controller
        @precond
            we have an active controller currently
        */
        void    stopControllerListening( );

        /** parses the given URL's Complete member, by calling XURLTransformer::parseString
        */
        void    impl_parseURL_nothrow( ::com::sun::star::util::URL& _rURL );

        DECL_LINK( OnInvalidateClipboard, void* );
    };

//........................................................................
} // namespace svx
//........................................................................

#endif // SVX_SOURCE_INC_FMTEXTCONTROLSHELL_HXX

<|endoftext|>