<commit_before>/*************************************************************************
 *
 *  $RCSfile: Edit.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: rt $ $Date: 2004-05-07 16:06:52 $
 *
 *  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 _FORMS_EDIT_HXX_
#define _FORMS_EDIT_HXX_

#ifndef _FORMS_EDITBASE_HXX_
#include "EditBase.hxx"
#endif
#ifndef _CPPUHELPER_IMPLBASE3_HXX_
#include <cppuhelper/implbase3.hxx>
#endif

//.........................................................................
namespace frm
{

//==================================================================
//= OEditModel
//==================================================================
class OEditModel
                :public OEditBaseModel
                ,public ::comphelper::OAggregationArrayUsageHelper< OEditModel >
{
    ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter>         m_xFormatter;
    ::rtl::OUString                 m_aSaveValue;
    sal_Int32                   m_nFormatKey;
    ::com::sun::star::util::Date                m_aNullDate;
    sal_Int32                   m_nFieldType;
    sal_Int16                   m_nKeyType;
    sal_Bool                    m_bMaxTextLenModified : 1;  // set to <TRUE/> when we change the MaxTextLen of the aggregate

    sal_Bool                    m_bWritingFormattedFake : 1;
        // are we writing something which should be interpreted as formatted upon reading?
    sal_Bool                    m_bNumericField : 1;
        // are we bound to some kind of numeric field?

protected:
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();

    DECLARE_DEFAULT_LEAF_XTOR( OEditModel );

    void enableFormattedWriteFake() { m_bWritingFormattedFake = sal_True; }
    void disableFormattedWriteFake() { m_bWritingFormattedFake = sal_False; }
    sal_Bool lastReadWasFormattedFake() const { return (getLastReadVersion() & PF_FAKE_FORMATTED_FIELD) != 0; }

    friend InterfaceRef SAL_CALL OEditModel_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
    friend class OFormattedFieldWrapper;
    friend class OFormattedModel;   // temporary

public:
    virtual void SAL_CALL disposing();

    // XPropertySet
    virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
// ::com::sun::star::io::XPersistObject
    virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException);

// ::com::sun::star::beans::XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
    virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

// XReset
    virtual void SAL_CALL reset(  ) throw(::com::sun::star::uno::RuntimeException);

// ::com::sun::star::lang::XServiceInfo
    IMPLEMENTATION_NAME(OEditModel);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw();

// OAggregationArrayUsageHelper
    virtual void fillProperties(
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps,
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
        ) const;
    IMPLEMENT_INFO_SERVICE()

protected:
    // OControlModel overridables
    virtual void writeAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream ) const;
    virtual void readAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream );

    // OBoundControlModel overridables
    virtual ::com::sun::star::uno::Any
                            translateDbColumnToControlValue( );
    virtual sal_Bool        commitControlValueToDbColumn( bool _bPostReset );

    virtual ::com::sun::star::uno::Any
                            getDefaultForReset() const;

    virtual void            onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
    virtual void            onDisconnectedDbColumn();

    virtual sal_Bool        approveValueBinding( const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding );
    virtual sal_Bool        approveDbColumnType( sal_Int32 _nColumnType );

protected:
    virtual sal_Int16 getPersistenceFlags() const;

    DECLARE_XCLONEABLE();

private:
    bool    implActsAsRichText( ) const;
};

//==================================================================
//= OEditControl
//==================================================================
typedef ::cppu::ImplHelper3<    ::com::sun::star::awt::XFocusListener,
                                ::com::sun::star::awt::XKeyListener,
                                ::com::sun::star::form::XChangeBroadcaster > OEditControl_BASE;

class OEditControl : public OBoundControl
                      ,public OEditControl_BASE
{
    ::cppu::OInterfaceContainerHelper
                        m_aChangeListeners;

    ::rtl::OUString         m_aHtmlChangeValue;
    sal_uInt32              m_nKeyEvent;

public:
    OEditControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
    virtual ~OEditControl();

    DECLARE_UNO3_AGG_DEFAULTS(OEditControl, OBoundControl);
    virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();

// OComponentHelper
    virtual void SAL_CALL disposing();

// ::com::sun::star::lang::XEventListener
    virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException);

// ::com::sun::star::lang::XServiceInfo
    IMPLEMENTATION_NAME(OEditControl);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw();

// ::com::sun::star::form::XChangeBroadcaster
    virtual void SAL_CALL addChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XChangeListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XChangeListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException);

// ::com::sun::star::awt::XFocusListener
    virtual void SAL_CALL focusGained( const ::com::sun::star::awt::FocusEvent& e ) throw ( ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL focusLost( const ::com::sun::star::awt::FocusEvent& e ) throw ( ::com::sun::star::uno::RuntimeException);

// ::com::sun::star::awt::XKeyListener
    virtual void SAL_CALL keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL keyReleased(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException);

private:
    DECL_LINK( OnKeyPressed, void* );
};

//.........................................................................
}
//.........................................................................

#endif // _FORMS_EDIT_HXX_

<commit_msg>INTEGRATION: CWS dba12 (1.9.6); FILE MERGED 2004/06/14 20:59:21 fs 1.9.6.2: RESYNC: (1.9-1.10); FILE MERGED 2004/04/26 09:18:43 fs 1.9.6.1: #i27072# disable Java-like text notifications on the peer<commit_after>/*************************************************************************
 *
 *  $RCSfile: Edit.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: hjs $ $Date: 2004-06-28 17:08:39 $
 *
 *  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 _FORMS_EDIT_HXX_
#define _FORMS_EDIT_HXX_

#ifndef _FORMS_EDITBASE_HXX_
#include "EditBase.hxx"
#endif
#ifndef _CPPUHELPER_IMPLBASE3_HXX_
#include <cppuhelper/implbase3.hxx>
#endif

//.........................................................................
namespace frm
{

//==================================================================
//= OEditModel
//==================================================================
class OEditModel
                :public OEditBaseModel
                ,public ::comphelper::OAggregationArrayUsageHelper< OEditModel >
{
    ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter>         m_xFormatter;
    ::rtl::OUString                 m_aSaveValue;
    sal_Int32                   m_nFormatKey;
    ::com::sun::star::util::Date                m_aNullDate;
    sal_Int32                   m_nFieldType;
    sal_Int16                   m_nKeyType;
    sal_Bool                    m_bMaxTextLenModified : 1;  // set to <TRUE/> when we change the MaxTextLen of the aggregate

    sal_Bool                    m_bWritingFormattedFake : 1;
        // are we writing something which should be interpreted as formatted upon reading?
    sal_Bool                    m_bNumericField : 1;
        // are we bound to some kind of numeric field?

protected:
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();

    DECLARE_DEFAULT_LEAF_XTOR( OEditModel );

    void enableFormattedWriteFake() { m_bWritingFormattedFake = sal_True; }
    void disableFormattedWriteFake() { m_bWritingFormattedFake = sal_False; }
    sal_Bool lastReadWasFormattedFake() const { return (getLastReadVersion() & PF_FAKE_FORMATTED_FIELD) != 0; }

    friend InterfaceRef SAL_CALL OEditModel_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
    friend class OFormattedFieldWrapper;
    friend class OFormattedModel;   // temporary

public:
    virtual void SAL_CALL disposing();

    // XPropertySet
    virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const;
// ::com::sun::star::io::XPersistObject
    virtual void SAL_CALL write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual ::rtl::OUString SAL_CALL getServiceName() throw ( ::com::sun::star::uno::RuntimeException);

// ::com::sun::star::beans::XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
    virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

// XReset
    virtual void SAL_CALL reset(  ) throw(::com::sun::star::uno::RuntimeException);

// ::com::sun::star::lang::XServiceInfo
    IMPLEMENTATION_NAME(OEditModel);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw();

// OAggregationArrayUsageHelper
    virtual void fillProperties(
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps,
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
        ) const;
    IMPLEMENT_INFO_SERVICE()

protected:
    // OControlModel overridables
    virtual void writeAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream ) const;
    virtual void readAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream );

    // OBoundControlModel overridables
    virtual ::com::sun::star::uno::Any
                            translateDbColumnToControlValue( );
    virtual sal_Bool        commitControlValueToDbColumn( bool _bPostReset );

    virtual ::com::sun::star::uno::Any
                            getDefaultForReset() const;

    virtual void            onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
    virtual void            onDisconnectedDbColumn();

    virtual sal_Bool        approveValueBinding( const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding );
    virtual sal_Bool        approveDbColumnType( sal_Int32 _nColumnType );

protected:
    virtual sal_Int16 getPersistenceFlags() const;

    DECLARE_XCLONEABLE();

private:
    bool    implActsAsRichText( ) const;
};

//==================================================================
//= OEditControl
//==================================================================
typedef ::cppu::ImplHelper3<    ::com::sun::star::awt::XFocusListener,
                                ::com::sun::star::awt::XKeyListener,
                                ::com::sun::star::form::XChangeBroadcaster > OEditControl_BASE;

class OEditControl : public OBoundControl
                      ,public OEditControl_BASE
{
    ::cppu::OInterfaceContainerHelper
                        m_aChangeListeners;

    ::rtl::OUString         m_aHtmlChangeValue;
    sal_uInt32              m_nKeyEvent;

public:
    OEditControl(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& _rxFactory);
    virtual ~OEditControl();

    DECLARE_UNO3_AGG_DEFAULTS(OEditControl, OBoundControl);
    virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation(const ::com::sun::star::uno::Type& _rType) throw(::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();

// OComponentHelper
    virtual void SAL_CALL disposing();

// ::com::sun::star::lang::XEventListener
    virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& _rSource) throw(::com::sun::star::uno::RuntimeException);

// ::com::sun::star::lang::XServiceInfo
    IMPLEMENTATION_NAME(OEditControl);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw();

// ::com::sun::star::form::XChangeBroadcaster
    virtual void SAL_CALL addChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XChangeListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeChangeListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XChangeListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException);

// ::com::sun::star::awt::XFocusListener
    virtual void SAL_CALL focusGained( const ::com::sun::star::awt::FocusEvent& e ) throw ( ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL focusLost( const ::com::sun::star::awt::FocusEvent& e ) throw ( ::com::sun::star::uno::RuntimeException);

// ::com::sun::star::awt::XKeyListener
    virtual void SAL_CALL keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL keyReleased(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException);

    // XControl
    virtual void SAL_CALL createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit >& _rxToolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& _rxParent ) throw ( ::com::sun::star::uno::RuntimeException );

private:
    DECL_LINK( OnKeyPressed, void* );
};

//.........................................................................
}
//.........................................................................

#endif // _FORMS_EDIT_HXX_

<|endoftext|>


<commit_before>/**
Copyright (c) 2017, Philip Deegan.
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
    * Neither the name of Philip Deegan nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

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

void maiken::Application::link(const kul::hash::set::String& objects)
    KTHROW(kul::Exception) {
  showConfig();
  if (objects.size() > 0) {
    buildDir().mk();
    if (!main.empty())
      buildExecutable(objects);
    else
      buildLibrary(objects);
    if (CommandStateMachine::INSTANCE().commands().count(STR_TEST) &&
        !tests.empty())
      buildTest(objects);
    kul::os::PushDir pushd(this->project().dir());
    kul::Dir build(".mkn/build");
    build.mk();
    kul::File ts("timestamp", build);
    if (ts) ts.rm();
    {
      kul::io::Writer w(ts);
      w << kul::Now::MILLIS();
    }
  } else
    KEXIT(1, "No link objects found, try compile or build.");
}

void maiken::Application::checkErrors(const CompilerProcessCapture& cpc)
    KTHROW(kul::Exception) {
  auto o = [](const std::string& s) {
    if (s.size()) KOUT(NON) << s;
  };
  auto e = [](const std::string& s) {
    if (s.size()) KERR << s;
  };
  if (kul::LogMan::INSTANCE().inf() || cpc.exception()) o(cpc.outs());
  if (kul::LogMan::INSTANCE().err() || cpc.exception()) e(cpc.errs());
  if (cpc.exception()) std::rethrow_exception(cpc.exception());
}

bool maiken::Application::is_build_required() {
  kul::os::PushDir pushd(this->project().dir());
  kul::Dir bDir(".mkn/build");
  return !bDir || bDir.dirs().size() == 0
               || bDir.files().size() == 0;;
}

bool maiken::Application::is_build_stale() {
  kul::os::PushDir pushd(this->project().dir());
  kul::Dir d(".mkn/build");
  kul::File f("timestamp", d);
  if (!d || !f) return true;
  kul::io::Reader r(f);
  try {
    size_t then = (size_t)43200 * ((size_t)60 * (size_t)1000);
    size_t now = kul::Now::MILLIS();
    size_t _MKN_BUILD_IS_STALE_MINUTES = now - then;
    const char* c = r.readLine();
    size_t timestamp = kul::String::UINT64(std::string(c));
    if (_MKN_BUILD_IS_STALE_MINUTES > timestamp) return true;
  } catch (const kul::Exception& e) {
    KERR << e.stack();
  } catch (const std::exception& e) {
    KERR << e.what();
  }
  return false;
}
<commit_msg>to build or not to build (modules<commit_after>/**
Copyright (c) 2017, Philip Deegan.
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
    * Neither the name of Philip Deegan nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

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

void maiken::Application::link(const kul::hash::set::String& objects)
    KTHROW(kul::Exception) {
  showConfig();
  if (objects.size() > 0) {
    buildDir().mk();
    if (!main.empty())
      buildExecutable(objects);
    else
      buildLibrary(objects);
    if (CommandStateMachine::INSTANCE().commands().count(STR_TEST) &&
        !tests.empty())
      buildTest(objects);
    kul::os::PushDir pushd(this->project().dir());
    kul::Dir build(".mkn/build");
    build.mk();
    kul::File ts("timestamp", build);
    if (ts) ts.rm();
    {
      kul::io::Writer w(ts);
      w << kul::Now::MILLIS();
    }
  } else
    KEXIT(1, "No link objects found, try compile or build.");
}

void maiken::Application::checkErrors(const CompilerProcessCapture& cpc)
    KTHROW(kul::Exception) {
  auto o = [](const std::string& s) {
    if (s.size()) KOUT(NON) << s;
  };
  auto e = [](const std::string& s) {
    if (s.size()) KERR << s;
  };
  if (kul::LogMan::INSTANCE().inf() || cpc.exception()) o(cpc.outs());
  if (kul::LogMan::INSTANCE().err() || cpc.exception()) e(cpc.errs());
  if (cpc.exception()) std::rethrow_exception(cpc.exception());
}

bool maiken::Application::is_build_required() {
  kul::os::PushDir pushd(this->project().dir());
  kul::Dir bDir(".mkn/build");
  return !bDir || bDir.files().size() == 0
               || buildDir().dirs().size() == 0
               || buildDir().files().size() == 0;
}

bool maiken::Application::is_build_stale() {
  kul::os::PushDir pushd(this->project().dir());
  kul::Dir d(".mkn/build");
  kul::File f("timestamp", d);
  if (!d || !f) return true;
  kul::io::Reader r(f);
  try {
    size_t then = (size_t)43200 * ((size_t)60 * (size_t)1000);
    size_t now = kul::Now::MILLIS();
    size_t _MKN_BUILD_IS_STALE_MINUTES = now - then;
    const char* c = r.readLine();
    size_t timestamp = kul::String::UINT64(std::string(c));
    if (_MKN_BUILD_IS_STALE_MINUTES > timestamp) return true;
  } catch (const kul::Exception& e) {
    KERR << e.stack();
  } catch (const std::exception& e) {
    KERR << e.what();
  }
  return false;
}
<|endoftext|>


<commit_before>/**
 *  @file DenseMatrix.cpp
 */

// Copyright 2001  California Institute of Technology

#ifdef WIN32
#pragma warning(disable:4786)
#pragma warning(disable:4503)
#endif

#include "ct_defs.h"
#include "ctlapack.h"
#include "utilities.h"
#include "DenseMatrix.h"

namespace Cantera {

        /// assignment.
        DenseMatrix& DenseMatrix::operator=(const DenseMatrix& y) {
            if (&y == this) return *this;
            Array2D::operator=(y);
            m_ipiv = y.ipiv();
	    return *this;
        }

        void DenseMatrix::resize(int n, int m, doublereal v) {
            Array2D::resize(n,m,v);
            m_ipiv.resize( max(n,m) );
        }

        void DenseMatrix::mult(const double* b, double* prod) const {
            ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose, nRows(),
                nRows(), 1.0, begin(), nRows(), b, 1, 0.0, prod, 1);
        }

        void DenseMatrix::leftMult(const double* b, double* prod) const {
            int nc = nColumns();
            int nr = nRows();
            int n, i;
            double sum = 0.0;
            for (n = 0; n < nc; n++) {
                sum = 0.0;
                for (i = 0; i < nr; i++) {
                    sum += value(i,n)*b[i];
                }
                prod[n] = sum;
            }
        }

    /**
     * Solve Ax = b. Array b is overwritten on exit with x.
     */
    int solve(DenseMatrix& A, double* b) {
        int info=0;
        ct_dgetrf(A.nRows(), A.nColumns(), A.begin(), A.nRows(),
            A.ipiv().begin(), info);
        if (info != 0)
            throw CanteraError("DenseMatrix::solve",
                "DGETRF returned INFO = "+int2str(info));
        ct_dgetrs(ctlapack::NoTranspose, A.nRows(), 1, A.begin(), A.nRows(),
            A.ipiv().begin(), b, A.nColumns(), info);
        if (info != 0)
            throw CanteraError("DenseMatrix::solve",
                "DGETRS returned INFO = "+int2str(info));
        return 0;
    }

    /**  Solve Ax = b for multiple right-hand-side vectors. */
    int solve(DenseMatrix& A, DenseMatrix& b) {
        int info=0;
        ct_dgetrf(A.nRows(), A.nColumns(), A.begin(), A.nRows(),
            A.ipiv().begin(), info);
        if (info != 0)
            throw CanteraError("DenseMatrix::solve",
                "DGETRF returned INFO = "+int2str(info));
        ct_dgetrs(ctlapack::NoTranspose, A.nRows(), b.nColumns(),
            A.begin(), A.nRows(),
            A.ipiv().begin(), b.begin(), b.nRows(), info);
        if (info != 0)
            throw CanteraError("DenseMatrix::solve",
                "DGETRS returned INFO = "+int2str(info));
        return 0;
    }

    /** @todo fix lwork */
    int leastSquares(DenseMatrix& A, double* b) {
        int info = 0;
        int rank = 0;
        double rcond = -1.0;
        // fix this!
        int lwork = 6000; // 2*(3*min(m,n) + max(2*min(m,n), max(m,n)));
        vector_fp work(lwork);
        vector_fp s(min(A.nRows(),A.nColumns()));
        ct_dgelss(A.nRows(), A.nColumns(), 1, A.begin(),
            A.nRows(), b, A.nColumns(), s.begin(),
            rcond, rank, work.begin(), work.size(), info);
        if (info != 0)
            throw CanteraError("DenseMatrix::leaseSquares",
                "DGELSS returned INFO = "+int2str(info));
        return 0;
    }

    /**
     * Multiply \c A*b and return the result in \c prod. Uses BLAS
     * routine DGEMV.
     */
    void multiply(const DenseMatrix& A, const double* b, double* prod) {
        ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose,
            A.nRows(), A.nRows(), 1.0,
            A.begin(), A.nRows(), b, 1, 0.0, prod, 1);
    }

    void increment(const DenseMatrix& A,
        const double* b, double* prod) {
        ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose,
            A.nRows(), A.nRows(), 1.0,
            A.begin(), A.nRows(), b, 1, 1.0, prod, 1);
    }

    /**
     * invert A. A is overwritten with A^-1.
     */
    int invert(DenseMatrix& A, int nn) {
        integer n = (nn > 0 ? nn : A.nRows());
        integer info=0;
        ct_dgetrf(n, n, A.begin(), A.nRows(), A.ipiv().begin(), info);
        if (info != 0)
            throw CanteraError("invert",
                "DGETRF returned INFO="+int2str(info));

        vector_fp work(n);
        integer lwork = work.size();
        ct_dgetri(n, A.begin(), A.nRows(), A.ipiv().begin(),
            work.begin(), lwork, info);
        if (info != 0)
            throw CanteraError("invert",
                "DGETRI returned INFO="+int2str(info));
        return 0;
    }
}

<commit_msg>static_cast to eliminate VC++ warnings<commit_after>/**
 *  @file DenseMatrix.cpp
 */

// Copyright 2001  California Institute of Technology

#ifdef WIN32
#pragma warning(disable:4786)
#pragma warning(disable:4503)
#endif

#include "ct_defs.h"
#include "ctlapack.h"
#include "utilities.h"
#include "DenseMatrix.h"

namespace Cantera {

        /// assignment.
        DenseMatrix& DenseMatrix::operator=(const DenseMatrix& y) {
            if (&y == this) return *this;
            Array2D::operator=(y);
            m_ipiv = y.ipiv();
	    return *this;
        }

        void DenseMatrix::resize(int n, int m, doublereal v) {
            Array2D::resize(n,m,v);
            m_ipiv.resize( max(n,m) );
        }

        void DenseMatrix::mult(const double* b, double* prod) const {
            ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose,
				static_cast<int>(nRows()),
                static_cast<int>(nRows()), 1.0, begin(),
				static_cast<int>(nRows()), b, 1, 0.0, prod, 1);
        }

        void DenseMatrix::leftMult(const double* b, double* prod) const {
            int nc = static_cast<int>(nColumns());
            int nr = static_cast<int>(nRows());
            int n, i;
            double sum = 0.0;
            for (n = 0; n < nc; n++) {
                sum = 0.0;
                for (i = 0; i < nr; i++) {
                    sum += value(i,n)*b[i];
                }
                prod[n] = sum;
            }
        }

    /**
     * Solve Ax = b. Array b is overwritten on exit with x.
     */
    int solve(DenseMatrix& A, double* b) {
        int info=0;
        ct_dgetrf(static_cast<int>(A.nRows()),
			static_cast<int>(A.nColumns()), A.begin(),
			static_cast<int>(A.nRows()), A.ipiv().begin(), info);
        if (info != 0)
            throw CanteraError("DenseMatrix::solve",
                "DGETRF returned INFO = "+int2str(info));
        ct_dgetrs(ctlapack::NoTranspose,
			static_cast<int>(A.nRows()), 1, A.begin(),
			static_cast<int>(A.nRows()),
            A.ipiv().begin(), b,
			static_cast<int>(A.nColumns()), info);
        if (info != 0)
            throw CanteraError("DenseMatrix::solve",
                "DGETRS returned INFO = "+int2str(info));
        return 0;
    }

    /**  Solve Ax = b for multiple right-hand-side vectors. */
    int solve(DenseMatrix& A, DenseMatrix& b) {
        int info=0;
        ct_dgetrf(static_cast<int>(A.nRows()),
			static_cast<int>(A.nColumns()), A.begin(),
			static_cast<int>(A.nRows()), A.ipiv().begin(), info);
        if (info != 0)
            throw CanteraError("DenseMatrix::solve",
                "DGETRF returned INFO = "+int2str(info));
        ct_dgetrs(ctlapack::NoTranspose, static_cast<int>(A.nRows()),
			static_cast<int>(b.nColumns()),
            A.begin(), static_cast<int>(A.nRows()),
            A.ipiv().begin(), b.begin(),
			static_cast<int>(b.nRows()), info);
        if (info != 0)
            throw CanteraError("DenseMatrix::solve",
                "DGETRS returned INFO = "+int2str(info));
        return 0;
    }

    /** @todo fix lwork */
    int leastSquares(DenseMatrix& A, double* b) {
        int info = 0;
        int rank = 0;
        double rcond = -1.0;
        // fix this!
        int lwork = 6000; // 2*(3*min(m,n) + max(2*min(m,n), max(m,n)));
        vector_fp work(lwork);
        vector_fp s(min(static_cast<int>(A.nRows()),
					    static_cast<int>(A.nColumns())));
        ct_dgelss(static_cast<int>(A.nRows()),
			static_cast<int>(A.nColumns()), 1, A.begin(),
            static_cast<int>(A.nRows()), b,
			static_cast<int>(A.nColumns()), s.begin(),
            rcond, rank, work.begin(), work.size(), info);
        if (info != 0)
            throw CanteraError("DenseMatrix::leaseSquares",
                "DGELSS returned INFO = "+int2str(info));
        return 0;
    }

    /**
     * Multiply \c A*b and return the result in \c prod. Uses BLAS
     * routine DGEMV.
     */
    void multiply(const DenseMatrix& A, const double* b, double* prod) {
        ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose,
            static_cast<int>(A.nRows()), static_cast<int>(A.nRows()), 1.0,
            A.begin(), static_cast<int>(A.nRows()), b, 1, 0.0, prod, 1);
    }

    void increment(const DenseMatrix& A,
        const double* b, double* prod) {
        ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose,
            static_cast<int>(A.nRows()), static_cast<int>(A.nRows()), 1.0,
            A.begin(), static_cast<int>(A.nRows()), b, 1, 1.0, prod, 1);
    }

    /**
     * invert A. A is overwritten with A^-1.
     */
    int invert(DenseMatrix& A, int nn) {
        integer n = (nn > 0 ? nn : static_cast<int>(A.nRows()));
        integer info=0;
        ct_dgetrf(n, n, A.begin(), static_cast<int>(A.nRows()),
			A.ipiv().begin(), info);
        if (info != 0)
            throw CanteraError("invert",
                "DGETRF returned INFO="+int2str(info));

        vector_fp work(n);
        integer lwork = static_cast<int>(work.size());
        ct_dgetri(n, A.begin(), static_cast<int>(A.nRows()),
			A.ipiv().begin(),
            work.begin(), lwork, info);
        if (info != 0)
            throw CanteraError("invert",
                "DGETRI returned INFO="+int2str(info));
        return 0;
    }
}

<|endoftext|>


<commit_before>#include <sstream>
#include <zorba/item.h>

#include "runtime/core/arithmetic_impl.h"
#include "errors/error_factory.h"
#include "system/globalenv.h"
#include "types/root_typemanager.h"
#include "types/casting.h"
#include "util/Assert.h"
#include "runtime/numerics/NumericsImpl.h"
#include "runtime/dateTime/DurationsDatesTimes.h"
#include "errors/error_factory.h"
#include "system/zorba.h"
#include "store/api/item_factory.h"
#include "system/zorba_engine.h"
#include "context/dynamic_context.h"

namespace zorba {

void ArithOperationsCommons::createError(
  const char* aOp,
  const QueryLoc* aLoc,
  TypeConstants::atomic_type_code_t aType0,
  TypeConstants::atomic_type_code_t aType1
)
{
  AtomicXQType lAType0(aType0, TypeConstants::QUANT_ONE);
  AtomicXQType lAType1(aType1, TypeConstants::QUANT_ONE);
  std::stringstream lStream;
  lStream << "The operation '";
  lStream << aOp;
  lStream << "' is not possible with parameters of the type ";
  lAType0.serialize(lStream);
  lStream << " and ";
  lAType1.serialize(lStream);
  lStream << "!";
  ZORBA_ERROR_ALERT(
    ZorbaError::XPTY0004,
    aLoc,
    DONT_CONTINUE_EXECUTION,
    lStream.str()
  );
}

/* begin class GenericArithIterator */
template< class Operations>
GenericArithIterator<Operations>::GenericArithIterator
( const QueryLoc& loc, PlanIter_t& iter0, PlanIter_t& iter1 )
    :
    BinaryBaseIterator<GenericArithIterator<Operations>, PlanIteratorState > ( loc, iter0, iter1 )
{ }

template < class Operation >
store::Item_t GenericArithIterator<Operation>::nextImpl ( PlanState& planState ) const
{
  store::Item_t n0;
  store::Item_t n1;
  store::Item_t res;

  PlanIteratorState* state;
  DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
  n0 = consumeNext( this->theChild0.getp(), planState );
  if ( n0 != NULL )
  {
    n1 = consumeNext( this->theChild1.getp(), planState );
    if ( n1 != NULL )
    {
      res = compute(this->loc, n0, n1);

      if ( consumeNext(this->theChild0.getp(), planState ) != NULL
           || consumeNext(this->theChild1.getp(), planState ) != NULL )
        ZORBA_ERROR_ALERT(ZorbaError::XPTY0004,
            NULL, DONT_CONTINUE_EXECUTION, "Arithmetic operation has a sequences greater than one as an operator.");
      STACK_PUSH ( res, state );
    }
  }
  STACK_END();
}

template < class Operation >
store::Item_t GenericArithIterator<Operation>::compute(const QueryLoc& aLoc, store::Item_t n0, store::Item_t n1)
{
  n0 = n0->getAtomizationValue();
  n1 = n1->getAtomizationValue();

  xqtref_t type0 = GENV_TYPESYSTEM.create_type ( n0->getType(), TypeConstants::QUANT_ONE );
  xqtref_t type1 = GENV_TYPESYSTEM.create_type ( n1->getType(), TypeConstants::QUANT_ONE );

  if(GENV_TYPESYSTEM.is_subtype ( *type0, *GENV_TYPESYSTEM.DURATION_TYPE_ONE ) )
  {
    if(GENV_TYPESYSTEM.is_numeric(*type1))
    {
       if(GENV_TYPESYSTEM.is_equal( *type0, *GENV_TYPESYSTEM.YM_DURATION_TYPE_ONE) ||
       GENV_TYPESYSTEM.is_equal( *type0, *GENV_TYPESYSTEM.DT_DURATION_TYPE_ONE))
      {
        n1 = GenericCast::instance()->cast ( n1, GENV_TYPESYSTEM.DOUBLE_TYPE_ONE );
        return Operation::template compute<TypeConstants::XS_DURATION,TypeConstants::XS_DOUBLE> ( &aLoc, n0, n1 );
      }
    }
    else
      return Operation::template computeSingleType<TypeConstants::XS_DURATION> ( &aLoc, n0, n1 );
  }
  else if(GENV_TYPESYSTEM.is_subtype ( *type0, *GENV_TYPESYSTEM.DATETIME_TYPE_ONE ))
  {
    if(GENV_TYPESYSTEM.is_subtype ( *type1, *GENV_TYPESYSTEM.DATETIME_TYPE_ONE ))
      return Operation::template compute<TypeConstants::XS_DATETIME,TypeConstants::XS_DATETIME> ( &aLoc, n0, n1 );
    else
      return Operation::template compute<TypeConstants::XS_DATETIME,TypeConstants::XS_DURATION> ( &aLoc, n0, n1 );
  }
  else if(GENV_TYPESYSTEM.is_subtype ( *type0, *GENV_TYPESYSTEM.DATE_TYPE_ONE ))
  {
    if(GENV_TYPESYSTEM.is_subtype ( *type1, *GENV_TYPESYSTEM.DATE_TYPE_ONE ))
      return Operation::template compute<TypeConstants::XS_DATE,TypeConstants::XS_DATE> ( &aLoc, n0, n1 );
    else
      return Operation::template compute<TypeConstants::XS_DATE,TypeConstants::XS_DURATION> ( &aLoc, n0, n1 );
  }
  else if(GENV_TYPESYSTEM.is_subtype ( *type0, *GENV_TYPESYSTEM.TIME_TYPE_ONE ))
  {
    if(GENV_TYPESYSTEM.is_subtype ( *type1, *GENV_TYPESYSTEM.TIME_TYPE_ONE ))
      return Operation::template compute<TypeConstants::XS_TIME,TypeConstants::XS_TIME> ( &aLoc, n0, n1 );
    else
      return Operation::template compute<TypeConstants::XS_TIME,TypeConstants::XS_DURATION> ( &aLoc, n0, n1 );
  }
  else if (( GENV_TYPESYSTEM.is_numeric(*type0)
    || GENV_TYPESYSTEM.is_numeric(*type1)
    || GENV_TYPESYSTEM.is_subtype(*type0, *GENV_TYPESYSTEM.UNTYPED_ATOMIC_TYPE_ONE)
    || GENV_TYPESYSTEM.is_subtype(*type1, *GENV_TYPESYSTEM.UNTYPED_ATOMIC_TYPE_ONE)))
  {
    return NumArithIterator<Operation>::computeAtomic(aLoc, n0, type0, n1, type1);
  }
  else
  {
    ZORBA_ERROR_ALERT(ZorbaError::XPTY0004,
                      NULL, DONT_CONTINUE_EXECUTION, "Arithmetic operation not defined between the given types(" + type0->toString() + " and " + type1->toString() + ").");
  }
  return 0;
}

/**
 * Information: It is not possible to move this function to
 * runtime/visitors/accept.cpp!
 */
template < class Operation >
void GenericArithIterator<Operation>::accept(PlanIterVisitor& v) const {
  v.beginVisit(*this);
  this->theChild0->accept(v);
  this->theChild1->accept(v);
  v.endVisit(*this);
}

// FIXME Why can the following template specializations not be moved to src/runtime/dateTime/DurationsDatesTimes.cpp?
//moved from DurationsDatesTimes
 /* begin class AddOperations */
template<>
store::Item_t AddOperation::compute<TypeConstants::XS_DURATION,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_duration d = *i0->getDurationValue() + *i1->getDurationValue();
  return Zorba::getItemFactory()->createDuration (d);
}

template<>
store::Item_t AddOperation::compute<TypeConstants::XS_DATETIME,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_dateTime d = *i0->getDateTimeValue() + *i1->getDurationValue()->toDuration();
  return Zorba::getItemFactory()->createDateTime (d);
}

template<>
store::Item_t AddOperation::compute<TypeConstants::XS_DATE,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_date d = *i0->getDateValue() + *i1->getDurationValue()->toDuration();
  return Zorba::getItemFactory()->createDate (d);
}

template<>
store::Item_t AddOperation::compute<TypeConstants::XS_TIME,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_time t = *i0->getTimeValue() + *i1->getDurationValue()->toDuration();
  return Zorba::getItemFactory()->createTime (t);
}
 /* end class AddOperations */

/* start class SubtractOperations */
template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_DURATION,TypeConstants::XS_DURATION>
( const QueryLoc* loc, const store::Item* i0, const store::Item* i1 )
{
  xqp_duration d = *i0->getDurationValue() - *i1->getDurationValue();
  return Zorba::getItemFactory()->createDuration (d);
}

template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_DATETIME,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_dateTime d = *i0->getDateTimeValue() + *i1->getDurationValue()->toNegDuration();
  return Zorba::getItemFactory()->createDateTime (d);
}

template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_DATE,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_date d = *i0->getDateValue() + *i1->getDurationValue()->toNegDuration();
  return Zorba::getItemFactory()->createDate (d);
}

template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_TIME,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_time t = *i0->getTimeValue() + *i1->getDurationValue()->toNegDuration();
  return Zorba::getItemFactory()->createTime (t);
}

template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_DATETIME,TypeConstants::XS_DATETIME>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  int timezone_secs = ZORBA_FOR_CURRENT_THREAD()->get_base_dynamic_context()->get_implicit_timezone();
  xqp_duration d = *i0->getDateTimeValue()->normalizeTimeZone(timezone_secs) -
                   *i1->getDateTimeValue()->normalizeTimeZone(timezone_secs);
  return Zorba::getItemFactory()->createDuration (d);
}

template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_DATE,TypeConstants::XS_DATE>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  long timezone_sec = /*18000;*/ ZORBA_FOR_CURRENT_THREAD()->get_base_dynamic_context()->get_implicit_timezone();
  xqp_duration d = *i0->getDateValue()->normalize(timezone_sec) - *i1->getDateValue()->normalize(timezone_sec);
  return Zorba::getItemFactory()->createDuration (d);
}

template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_TIME,TypeConstants::XS_TIME>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  long timezone_sec = /*-18000;*/ ZORBA_FOR_CURRENT_THREAD()->get_base_dynamic_context()->get_implicit_timezone();
  xqp_duration d = *i0->getTimeValue()->normalize(timezone_sec) - * i1->getTimeValue()->normalize(timezone_sec);
  return Zorba::getItemFactory()->createDuration (d);
}
/* end class SubtractOperations */

/* start class MultiplyOperations */
template<>
store::Item_t MultiplyOperation::compute<TypeConstants::XS_DURATION,TypeConstants::XS_DOUBLE>
( const QueryLoc* loc, const store::Item* i0, const store::Item* i1 )
{
  xqp_duration d;

  if( i1->getDoubleValue().isZero() )
  {
    xqtref_t type0 = GENV_TYPESYSTEM.create_type(i0->getType(), TypeConstants::QUANT_ONE);
    if( GENV_TYPESYSTEM.is_subtype(*type0, *GENV_TYPESYSTEM.YM_DURATION_TYPE_ONE))
      d = new YearMonthDuration();
    else
      d = new DayTimeDuration();

    return Zorba::getItemFactory()->createDuration(d);
  }
  else if ( i1->getDoubleValue().isPosInf() || i1->getDoubleValue().isNegInf() )
    ZORBA_ERROR_ALERT( ZorbaError::FODT0002, NULL, DONT_CONTINUE_EXECUTION, "Overflow/underflow in duration operation.");
  else if (  i1->getDoubleValue().isNaN() )
    ZORBA_ERROR_ALERT( ZorbaError::FOCA0005, NULL, DONT_CONTINUE_EXECUTION, "NaN supplied as float/double value");
  else
    d = *i0->getDurationValue() * (i1->getDoubleValue());

  return Zorba::getItemFactory()->createDuration (d);
}
/* end class MultiplyOperations */

/* start class DivideOperations */
template<>
store::Item_t DivideOperation::compute<TypeConstants::XS_DURATION,TypeConstants::XS_DOUBLE>
( const QueryLoc* loc, const store::Item* i0, const store::Item* i1 )
{
  xqp_duration d;

  if( i1->getDoubleValue().isPosInf() || i1->getDoubleValue().isNegInf() )
  {
    xqtref_t type0 = GENV_TYPESYSTEM.create_type(i0->getType(), TypeConstants::QUANT_ONE);
    if( GENV_TYPESYSTEM.is_subtype(*type0, *GENV_TYPESYSTEM.YM_DURATION_TYPE_ONE))
      d = new YearMonthDuration();
    else
      d = new DayTimeDuration();

    return Zorba::getItemFactory()->createDuration(d);
  }
  else if ( i1->getDoubleValue().isZero() )
    ZORBA_ERROR_ALERT( ZorbaError::FODT0002, NULL, DONT_CONTINUE_EXECUTION, "Overflow/underflow in duration operation.");
  else if ( i1->getDoubleValue().isNaN() )
    ZORBA_ERROR_ALERT( ZorbaError::FOCA0005, NULL, DONT_CONTINUE_EXECUTION, "NaN supplied as float/double value");
  else
    d= *i0->getDurationValue() / i1->getDoubleValue();

  return Zorba::getItemFactory()->createDuration (d);
}

template<>
store::Item_t DivideOperation::compute<TypeConstants::XS_DURATION,TypeConstants::XS_DURATION>
( const QueryLoc* loc, const store::Item* i0, const store::Item* i1 )
{
  xqp_decimal d = *i0->getDurationValue() / *i1->getDurationValue();
  return Zorba::getItemFactory()->createDecimal(d);
}
/* end class DivideOperations */

/* instantiate GenericArithIterator for all types */
template class GenericArithIterator<AddOperation>;
template class GenericArithIterator<SubtractOperation>;
template class GenericArithIterator<MultiplyOperation>;
template class GenericArithIterator<DivideOperation>;
template class GenericArithIterator<IntegerDivideOperation>;
template class GenericArithIterator<ModOperation>;
/* end class GenericArithIterator */

}
<commit_msg>Soved trac #278.<commit_after>#include <sstream>
#include <zorba/item.h>

#include "runtime/core/arithmetic_impl.h"
#include "errors/error_factory.h"
#include "system/globalenv.h"
#include "types/root_typemanager.h"
#include "types/casting.h"
#include "util/Assert.h"
#include "runtime/numerics/NumericsImpl.h"
#include "runtime/dateTime/DurationsDatesTimes.h"
#include "errors/error_factory.h"
#include "system/zorba.h"
#include "store/api/item_factory.h"
#include "system/zorba_engine.h"
#include "context/dynamic_context.h"

namespace zorba {

void ArithOperationsCommons::createError(
  const char* aOp,
  const QueryLoc* aLoc,
  TypeConstants::atomic_type_code_t aType0,
  TypeConstants::atomic_type_code_t aType1
)
{
  AtomicXQType lAType0(aType0, TypeConstants::QUANT_ONE);
  AtomicXQType lAType1(aType1, TypeConstants::QUANT_ONE);
  std::stringstream lStream;
  lStream << "The operation '";
  lStream << aOp;
  lStream << "' is not possible with parameters of the type ";
  lAType0.serialize(lStream);
  lStream << " and ";
  lAType1.serialize(lStream);
  lStream << "!";
  ZORBA_ERROR_ALERT(
    ZorbaError::XPTY0004,
    aLoc,
    DONT_CONTINUE_EXECUTION,
    lStream.str()
  );
}

/* begin class GenericArithIterator */
template< class Operations>
GenericArithIterator<Operations>::GenericArithIterator
( const QueryLoc& loc, PlanIter_t& iter0, PlanIter_t& iter1 )
    :
    BinaryBaseIterator<GenericArithIterator<Operations>, PlanIteratorState > ( loc, iter0, iter1 )
{ }

template < class Operation >
store::Item_t GenericArithIterator<Operation>::nextImpl ( PlanState& planState ) const
{
  store::Item_t n0;
  store::Item_t n1;
  store::Item_t res;

  PlanIteratorState* state;
  DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
  n0 = consumeNext( this->theChild0.getp(), planState );
  if ( n0 != NULL )
  {
    n1 = consumeNext( this->theChild1.getp(), planState );
    if ( n1 != NULL )
    {
      res = compute(this->loc, n0, n1);

      if ( consumeNext(this->theChild0.getp(), planState ) != NULL
           || consumeNext(this->theChild1.getp(), planState ) != NULL )
        ZORBA_ERROR_ALERT(ZorbaError::XPTY0004,
            NULL, DONT_CONTINUE_EXECUTION, "Arithmetic operation has a sequences greater than one as an operator.");
      STACK_PUSH ( res, state );
    }
  }
  STACK_END();
}

template < class Operation >
store::Item_t GenericArithIterator<Operation>::compute(const QueryLoc& aLoc, store::Item_t n0, store::Item_t n1)
{
  n0 = n0->getAtomizationValue();
  n1 = n1->getAtomizationValue();

  xqtref_t type0 = GENV_TYPESYSTEM.create_type ( n0->getType(), TypeConstants::QUANT_ONE );
  xqtref_t type1 = GENV_TYPESYSTEM.create_type ( n1->getType(), TypeConstants::QUANT_ONE );

  if(GENV_TYPESYSTEM.is_subtype ( *type0, *GENV_TYPESYSTEM.YM_DURATION_TYPE_ONE )
     || GENV_TYPESYSTEM.is_subtype ( *type0, *GENV_TYPESYSTEM.DT_DURATION_TYPE_ONE ))
  {
    if(GENV_TYPESYSTEM.is_numeric(*type1))
    {
      n1 = GenericCast::instance()->cast ( n1, GENV_TYPESYSTEM.DOUBLE_TYPE_ONE );
      return Operation::template compute<TypeConstants::XS_DURATION,TypeConstants::XS_DOUBLE> ( &aLoc, n0, n1 );
    }
    else if(GENV_TYPESYSTEM.is_equal(*type0, *type1))
      return Operation::template computeSingleType<TypeConstants::XS_DURATION> ( &aLoc, n0, n1 );
    else
      ZORBA_ERROR_ALERT(ZorbaError::XPTY0004,
                        NULL, DONT_CONTINUE_EXECUTION, "Arithmetic operation not defined between the given types(" + type0->toString() + " and " + type1->toString() + ").");
  }
  else if(GENV_TYPESYSTEM.is_subtype ( *type0, *GENV_TYPESYSTEM.DATETIME_TYPE_ONE ))
  {
    if(GENV_TYPESYSTEM.is_subtype ( *type1, *GENV_TYPESYSTEM.DATETIME_TYPE_ONE ))
      return Operation::template compute<TypeConstants::XS_DATETIME,TypeConstants::XS_DATETIME> ( &aLoc, n0, n1 );
    else
      return Operation::template compute<TypeConstants::XS_DATETIME,TypeConstants::XS_DURATION> ( &aLoc, n0, n1 );
  }
  else if(GENV_TYPESYSTEM.is_subtype ( *type0, *GENV_TYPESYSTEM.DATE_TYPE_ONE ))
  {
    if(GENV_TYPESYSTEM.is_subtype ( *type1, *GENV_TYPESYSTEM.DATE_TYPE_ONE ))
      return Operation::template compute<TypeConstants::XS_DATE,TypeConstants::XS_DATE> ( &aLoc, n0, n1 );
    else
      return Operation::template compute<TypeConstants::XS_DATE,TypeConstants::XS_DURATION> ( &aLoc, n0, n1 );
  }
  else if(GENV_TYPESYSTEM.is_subtype ( *type0, *GENV_TYPESYSTEM.TIME_TYPE_ONE ))
  {
    if(GENV_TYPESYSTEM.is_subtype ( *type1, *GENV_TYPESYSTEM.TIME_TYPE_ONE ))
      return Operation::template compute<TypeConstants::XS_TIME,TypeConstants::XS_TIME> ( &aLoc, n0, n1 );
    else
      return Operation::template compute<TypeConstants::XS_TIME,TypeConstants::XS_DURATION> ( &aLoc, n0, n1 );
  }
  else if (
           (GENV_TYPESYSTEM.is_numeric(*type0)
           || GENV_TYPESYSTEM.is_subtype(*type0, *GENV_TYPESYSTEM.UNTYPED_ATOMIC_TYPE_ONE))
           && ( GENV_TYPESYSTEM.is_numeric(*type1)
           || GENV_TYPESYSTEM.is_subtype(*type1, *GENV_TYPESYSTEM.UNTYPED_ATOMIC_TYPE_ONE))
          )
  {
    return NumArithIterator<Operation>::computeAtomic(aLoc, n0, type0, n1, type1);
  }
  else
  {
    ZORBA_ERROR_ALERT(ZorbaError::XPTY0004,
                      NULL, DONT_CONTINUE_EXECUTION, "Arithmetic operation not defined between the given types(" + type0->toString() + " and " + type1->toString() + ").");
  }
  return 0;
}

/**
 * Information: It is not possible to move this function to
 * runtime/visitors/accept.cpp!
 */
template < class Operation >
void GenericArithIterator<Operation>::accept(PlanIterVisitor& v) const {
  v.beginVisit(*this);
  this->theChild0->accept(v);
  this->theChild1->accept(v);
  v.endVisit(*this);
}

// FIXME Why can the following template specializations not be moved to src/runtime/dateTime/DurationsDatesTimes.cpp?
//moved from DurationsDatesTimes
 /* begin class AddOperations */
template<>
store::Item_t AddOperation::compute<TypeConstants::XS_DURATION,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_duration d = *i0->getDurationValue() + *i1->getDurationValue();
  return Zorba::getItemFactory()->createDuration (d);
}

template<>
store::Item_t AddOperation::compute<TypeConstants::XS_DATETIME,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_dateTime d = *i0->getDateTimeValue() + *i1->getDurationValue()->toDuration();
  return Zorba::getItemFactory()->createDateTime (d);
}

template<>
store::Item_t AddOperation::compute<TypeConstants::XS_DATE,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_date d = *i0->getDateValue() + *i1->getDurationValue()->toDuration();
  return Zorba::getItemFactory()->createDate (d);
}

template<>
store::Item_t AddOperation::compute<TypeConstants::XS_TIME,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_time t = *i0->getTimeValue() + *i1->getDurationValue()->toDuration();
  return Zorba::getItemFactory()->createTime (t);
}
 /* end class AddOperations */

/* start class SubtractOperations */
template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_DURATION,TypeConstants::XS_DURATION>
( const QueryLoc* loc, const store::Item* i0, const store::Item* i1 )
{
  xqp_duration d = *i0->getDurationValue() - *i1->getDurationValue();
  return Zorba::getItemFactory()->createDuration (d);
}

template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_DATETIME,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_dateTime d = *i0->getDateTimeValue() + *i1->getDurationValue()->toNegDuration();
  return Zorba::getItemFactory()->createDateTime (d);
}

template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_DATE,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_date d = *i0->getDateValue() + *i1->getDurationValue()->toNegDuration();
  return Zorba::getItemFactory()->createDate (d);
}

template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_TIME,TypeConstants::XS_DURATION>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  xqp_time t = *i0->getTimeValue() + *i1->getDurationValue()->toNegDuration();
  return Zorba::getItemFactory()->createTime (t);
}

template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_DATETIME,TypeConstants::XS_DATETIME>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  int timezone_secs = ZORBA_FOR_CURRENT_THREAD()->get_base_dynamic_context()->get_implicit_timezone();
  xqp_duration d = *i0->getDateTimeValue()->normalizeTimeZone(timezone_secs) -
                   *i1->getDateTimeValue()->normalizeTimeZone(timezone_secs);
  return Zorba::getItemFactory()->createDuration (d);
}

template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_DATE,TypeConstants::XS_DATE>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  long timezone_sec = /*18000;*/ ZORBA_FOR_CURRENT_THREAD()->get_base_dynamic_context()->get_implicit_timezone();
  xqp_duration d = *i0->getDateValue()->normalize(timezone_sec) - *i1->getDateValue()->normalize(timezone_sec);
  return Zorba::getItemFactory()->createDuration (d);
}

template<>
store::Item_t SubtractOperation::compute<TypeConstants::XS_TIME,TypeConstants::XS_TIME>
( const QueryLoc* loc,  const store::Item* i0, const store::Item* i1 )
{
  long timezone_sec = /*-18000;*/ ZORBA_FOR_CURRENT_THREAD()->get_base_dynamic_context()->get_implicit_timezone();
  xqp_duration d = *i0->getTimeValue()->normalize(timezone_sec) - * i1->getTimeValue()->normalize(timezone_sec);
  return Zorba::getItemFactory()->createDuration (d);
}
/* end class SubtractOperations */

/* start class MultiplyOperations */
template<>
store::Item_t MultiplyOperation::compute<TypeConstants::XS_DURATION,TypeConstants::XS_DOUBLE>
( const QueryLoc* loc, const store::Item* i0, const store::Item* i1 )
{
  xqp_duration d;

  if( i1->getDoubleValue().isZero() )
  {
    xqtref_t type0 = GENV_TYPESYSTEM.create_type(i0->getType(), TypeConstants::QUANT_ONE);
    if( GENV_TYPESYSTEM.is_subtype(*type0, *GENV_TYPESYSTEM.YM_DURATION_TYPE_ONE))
      d = new YearMonthDuration();
    else
      d = new DayTimeDuration();

    return Zorba::getItemFactory()->createDuration(d);
  }
  else if ( i1->getDoubleValue().isPosInf() || i1->getDoubleValue().isNegInf() )
    ZORBA_ERROR_ALERT( ZorbaError::FODT0002, NULL, DONT_CONTINUE_EXECUTION, "Overflow/underflow in duration operation.");
  else if (  i1->getDoubleValue().isNaN() )
    ZORBA_ERROR_ALERT( ZorbaError::FOCA0005, NULL, DONT_CONTINUE_EXECUTION, "NaN supplied as float/double value");
  else
    d = *i0->getDurationValue() * (i1->getDoubleValue());

  return Zorba::getItemFactory()->createDuration (d);
}
/* end class MultiplyOperations */

/* start class DivideOperations */
template<>
store::Item_t DivideOperation::compute<TypeConstants::XS_DURATION,TypeConstants::XS_DOUBLE>
( const QueryLoc* loc, const store::Item* i0, const store::Item* i1 )
{
  xqp_duration d;

  if( i1->getDoubleValue().isPosInf() || i1->getDoubleValue().isNegInf() )
  {
    xqtref_t type0 = GENV_TYPESYSTEM.create_type(i0->getType(), TypeConstants::QUANT_ONE);
    if( GENV_TYPESYSTEM.is_subtype(*type0, *GENV_TYPESYSTEM.YM_DURATION_TYPE_ONE))
      d = new YearMonthDuration();
    else
      d = new DayTimeDuration();

    return Zorba::getItemFactory()->createDuration(d);
  }
  else if ( i1->getDoubleValue().isZero() )
    ZORBA_ERROR_ALERT( ZorbaError::FODT0002, NULL, DONT_CONTINUE_EXECUTION, "Overflow/underflow in duration operation.");
  else if ( i1->getDoubleValue().isNaN() )
    ZORBA_ERROR_ALERT( ZorbaError::FOCA0005, NULL, DONT_CONTINUE_EXECUTION, "NaN supplied as float/double value");
  else
    d= *i0->getDurationValue() / i1->getDoubleValue();

  return Zorba::getItemFactory()->createDuration (d);
}

template<>
store::Item_t DivideOperation::compute<TypeConstants::XS_DURATION,TypeConstants::XS_DURATION>
( const QueryLoc* loc, const store::Item* i0, const store::Item* i1 )
{
  xqp_decimal d = *i0->getDurationValue() / *i1->getDurationValue();
  return Zorba::getItemFactory()->createDecimal(d);
}
/* end class DivideOperations */

/* instantiate GenericArithIterator for all types */
template class GenericArithIterator<AddOperation>;
template class GenericArithIterator<SubtractOperation>;
template class GenericArithIterator<MultiplyOperation>;
template class GenericArithIterator<DivideOperation>;
template class GenericArithIterator<IntegerDivideOperation>;
template class GenericArithIterator<ModOperation>;
/* end class GenericArithIterator */

}
<|endoftext|>


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

#include "zorbaerrors/error_manager.h"

#include "runtime/core/var_iterators.h"
#include "runtime/core/fncall_iterator.h"
#include "runtime/misc/MiscImpl.h"  // for ExitException
#include "runtime/api/plan_iterator_wrapper.h"
#include "functions/function.h"

#include "api/unmarshaller.h"

namespace zorba {

UDFunctionCallIteratorState::UDFunctionCallIteratorState()
  :
  theFnBodyStateBlock(NULL),
  thePlan(NULL),
  thePlanStateSize(0),
  thePlanOpen(false)
{
}

UDFunctionCallIteratorState::~UDFunctionCallIteratorState()
{
}

void UDFunctionCallIteratorState::openPlan()
{
  uint32_t planOffset = 0;
  if (!thePlanOpen) {
    thePlan->open(*theFnBodyStateBlock, planOffset);
  }
  thePlanOpen = true;
}

void UDFunctionCallIteratorState::closePlan()
{
  if (thePlanOpen) {
    thePlan->close(*theFnBodyStateBlock);
  }
  thePlanOpen = false;
}

void UDFunctionCallIteratorState::resetPlan()
{
  if (thePlanOpen) {
    thePlan->reset(*theFnBodyStateBlock);
  }
}

void UDFunctionCallIteratorState::resetChildIters()
{
  std::vector<store::Iterator_t>::const_iterator lIter = theChildIterators.begin();
  std::vector<store::Iterator_t>::const_iterator lEnd = theChildIterators.end();
  for ( ; lIter != lEnd; ++lIter)
    (*lIter)->close();

  theChildIterators.clear();
}

bool UDFunctionCallIterator::isUpdating() const
{
  return theUDF->isUpdating();
}

void UDFunctionCallIterator::openImpl(PlanState& planState, uint32_t& offset)
{
  NaryBaseIterator<UDFunctionCallIterator, UDFunctionCallIteratorState>::openImpl(planState, offset);

  UDFunctionCallIteratorState *state = StateTraitsImpl<UDFunctionCallIteratorState>::getState(planState, this->stateOffset);

  state->thePlan = theUDF->get_plan(planState.theCompilerCB).getp();
  state->thePlanStateSize = state->thePlan->getStateSizeOfSubtree();
  state->theFnBodyStateBlock = new PlanState(state->thePlanStateSize, planState.theStackDepth + 1);
  state->theFnBodyStateBlock->checkDepth (loc);
  state->theFnBodyStateBlock->theRuntimeCB = planState.theRuntimeCB;
  state->theFnBodyStateBlock->theCompilerCB = planState.theCompilerCB;
}

void UDFunctionCallIterator::closeImpl(PlanState& planState)
{
  UDFunctionCallIteratorState *state = StateTraitsImpl<UDFunctionCallIteratorState>::getState(planState, this->stateOffset);

  state->closePlan();
  delete state->theFnBodyStateBlock;
  state->resetChildIters();

  NaryBaseIterator<UDFunctionCallIterator, UDFunctionCallIteratorState>::closeImpl(planState);
}

void UDFunctionCallIterator::resetImpl(PlanState& planState) const
{
  NaryBaseIterator<UDFunctionCallIterator, UDFunctionCallIteratorState>::resetImpl(planState);
  UDFunctionCallIteratorState *state = StateTraitsImpl<UDFunctionCallIteratorState>::getState(planState, this->stateOffset);

  state->resetPlan();
  state->resetChildIters();
}

bool UDFunctionCallIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  UDFunctionCallIteratorState *state;
  bool success;

  DEFAULT_STACK_INIT(UDFunctionCallIteratorState, state, planState);

  {
    // Bind the args.
    state->openPlan();
    std::vector<LetVarIter_t>& iters = theUDF->get_param_iters();
    for (uint32_t i = 0; i < iters.size (); ++i)
    {
      LetVarIter_t& ref = iters[i];
      if ( ref != NULL)
      {
        state->theChildIterators.push_back(new PlanIteratorWrapper(theChildren[i], planState));
        state->theChildIterators.back()->open();
        ref->bind(state->theChildIterators.back(), *state->theFnBodyStateBlock);
      }
    }
  }

  for (;;) {
    try {
      success = consumeNext (result, state->thePlan, *state->theFnBodyStateBlock);
    } catch (FlowCtlIterator::ExitException &e) {
      state->exitValue = e.val;
      success = false;
    }

    if (success)
      STACK_PUSH(true, state);
    else break;
  }

  if (state->exitValue != NULL)
    while (state->exitValue->next (result))
      STACK_PUSH(true, state);

  STACK_END (state);
}

// external functions
class ExtFuncArgItemSequence : public ItemSequence
{
  public:
    ExtFuncArgItemSequence(PlanIter_t child, PlanState& stateBlock)
      : m_child(child),
      m_stateBlock(stateBlock) { }

    bool next(Item& item)
    {
      store::Item_t result;
      bool status = m_child->consumeNext(result, m_child.getp(), m_stateBlock);
      item = status ? result : NULL;
      return status;
    }

  private:
    PlanIter_t m_child;
    PlanState& m_stateBlock;
};

StatelessExtFunctionCallIteratorState::StatelessExtFunctionCallIteratorState() { }

StatelessExtFunctionCallIteratorState::~StatelessExtFunctionCallIteratorState() { }

void StatelessExtFunctionCallIteratorState::reset(PlanState& planState)
{
  PlanIteratorState::reset(planState);
  m_result.reset();
}

StatelessExtFunctionCallIterator::StatelessExtFunctionCallIterator(const QueryLoc& loc,
    std::vector<PlanIter_t>& args,
    const StatelessExternalFunction *function,
    bool aIsUpdating)
  :
  NaryBaseIterator<StatelessExtFunctionCallIterator,
                   StatelessExtFunctionCallIteratorState>(loc, args),
  m_function(function),
  theIsUpdating(aIsUpdating)
{
}

void StatelessExtFunctionCallIterator::openImpl(PlanState& planState, uint32_t& offset)
{
  NaryBaseIterator<StatelessExtFunctionCallIterator,
                   StatelessExtFunctionCallIteratorState>::openImpl(planState, offset);

  StatelessExtFunctionCallIteratorState
    *state = StateTraitsImpl<StatelessExtFunctionCallIteratorState>::getState(planState,
                                                                              this->stateOffset);
  int n = theChildren.size();
  state->m_extArgs.resize(n);
  for(int i = 0; i < n; ++i)
  {
    state->m_extArgs[i] = new ExtFuncArgItemSequence(theChildren[i], planState);
  }
}

bool StatelessExtFunctionCallIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  StatelessExtFunctionCallIteratorState *state;
  Item lOutsideItem;
  DEFAULT_STACK_INIT(StatelessExtFunctionCallIteratorState, state, planState);

  state->m_result = m_function->evaluate(state->m_extArgs);
  while (state->m_result->next(lOutsideItem))
  {
    result = Unmarshaller::getInternalItem(lOutsideItem);
    if (theIsUpdating)
    {
      if (!result->isPul())
      {
        ZORBA_ERROR_LOC(XUDY0019, loc);
      }
    }
    else
    {
      if (result->isPul())
      {
        ZORBA_ERROR_LOC(XUDY0018, loc);
      }
    }
    STACK_PUSH(true, state);
  }

  STACK_END (state);
}

void StatelessExtFunctionCallIterator::closeImpl(PlanState& planState)
{
  StatelessExtFunctionCallIteratorState *state =
    StateTraitsImpl<StatelessExtFunctionCallIteratorState>::getState(planState, this->stateOffset);

  // we have the ownership for the item sequences
  int n = theChildren.size();
  for(int i = 0; i < n; ++i) {
    delete state->m_extArgs[i];
  }

  NaryBaseIterator<StatelessExtFunctionCallIterator,
                   StatelessExtFunctionCallIteratorState>::closeImpl(planState);
}

}

/* vim:set ts=2 sw=2: */
<commit_msg>Added error reporting ability to external functions<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <zorba/item.h>
#include <zorba/item_sequence.h>
#include <zorba/stateless_function.h>
#include <zorba/exception.h>

#include "zorbaerrors/error_manager.h"

#include "runtime/core/var_iterators.h"
#include "runtime/core/fncall_iterator.h"
#include "runtime/misc/MiscImpl.h"  // for ExitException
#include "runtime/api/plan_iterator_wrapper.h"
#include "functions/function.h"

#include "api/unmarshaller.h"

namespace zorba {

UDFunctionCallIteratorState::UDFunctionCallIteratorState()
  :
  theFnBodyStateBlock(NULL),
  thePlan(NULL),
  thePlanStateSize(0),
  thePlanOpen(false)
{
}

UDFunctionCallIteratorState::~UDFunctionCallIteratorState()
{
}

void UDFunctionCallIteratorState::openPlan()
{
  uint32_t planOffset = 0;
  if (!thePlanOpen) {
    thePlan->open(*theFnBodyStateBlock, planOffset);
  }
  thePlanOpen = true;
}

void UDFunctionCallIteratorState::closePlan()
{
  if (thePlanOpen) {
    thePlan->close(*theFnBodyStateBlock);
  }
  thePlanOpen = false;
}

void UDFunctionCallIteratorState::resetPlan()
{
  if (thePlanOpen) {
    thePlan->reset(*theFnBodyStateBlock);
  }
}

void UDFunctionCallIteratorState::resetChildIters()
{
  std::vector<store::Iterator_t>::const_iterator lIter = theChildIterators.begin();
  std::vector<store::Iterator_t>::const_iterator lEnd = theChildIterators.end();
  for ( ; lIter != lEnd; ++lIter)
    (*lIter)->close();

  theChildIterators.clear();
}

bool UDFunctionCallIterator::isUpdating() const
{
  return theUDF->isUpdating();
}

void UDFunctionCallIterator::openImpl(PlanState& planState, uint32_t& offset)
{
  NaryBaseIterator<UDFunctionCallIterator, UDFunctionCallIteratorState>::openImpl(planState, offset);

  UDFunctionCallIteratorState *state = StateTraitsImpl<UDFunctionCallIteratorState>::getState(planState, this->stateOffset);

  state->thePlan = theUDF->get_plan(planState.theCompilerCB).getp();
  state->thePlanStateSize = state->thePlan->getStateSizeOfSubtree();
  state->theFnBodyStateBlock = new PlanState(state->thePlanStateSize, planState.theStackDepth + 1);
  state->theFnBodyStateBlock->checkDepth (loc);
  state->theFnBodyStateBlock->theRuntimeCB = planState.theRuntimeCB;
  state->theFnBodyStateBlock->theCompilerCB = planState.theCompilerCB;
}

void UDFunctionCallIterator::closeImpl(PlanState& planState)
{
  UDFunctionCallIteratorState *state = StateTraitsImpl<UDFunctionCallIteratorState>::getState(planState, this->stateOffset);

  state->closePlan();
  delete state->theFnBodyStateBlock;
  state->resetChildIters();

  NaryBaseIterator<UDFunctionCallIterator, UDFunctionCallIteratorState>::closeImpl(planState);
}

void UDFunctionCallIterator::resetImpl(PlanState& planState) const
{
  NaryBaseIterator<UDFunctionCallIterator, UDFunctionCallIteratorState>::resetImpl(planState);
  UDFunctionCallIteratorState *state = StateTraitsImpl<UDFunctionCallIteratorState>::getState(planState, this->stateOffset);

  state->resetPlan();
  state->resetChildIters();
}

bool UDFunctionCallIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  UDFunctionCallIteratorState *state;
  bool success;

  DEFAULT_STACK_INIT(UDFunctionCallIteratorState, state, planState);

  {
    // Bind the args.
    state->openPlan();
    std::vector<LetVarIter_t>& iters = theUDF->get_param_iters();
    for (uint32_t i = 0; i < iters.size (); ++i)
    {
      LetVarIter_t& ref = iters[i];
      if ( ref != NULL)
      {
        state->theChildIterators.push_back(new PlanIteratorWrapper(theChildren[i], planState));
        state->theChildIterators.back()->open();
        ref->bind(state->theChildIterators.back(), *state->theFnBodyStateBlock);
      }
    }
  }

  for (;;) {
    try {
      success = consumeNext (result, state->thePlan, *state->theFnBodyStateBlock);
    } catch (FlowCtlIterator::ExitException &e) {
      state->exitValue = e.val;
      success = false;
    }

    if (success)
      STACK_PUSH(true, state);
    else break;
  }

  if (state->exitValue != NULL)
    while (state->exitValue->next (result))
      STACK_PUSH(true, state);

  STACK_END (state);
}

// external functions
class ExtFuncArgItemSequence : public ItemSequence
{
  public:
    ExtFuncArgItemSequence(PlanIter_t child, PlanState& stateBlock)
      : m_child(child),
      m_stateBlock(stateBlock) { }

    bool next(Item& item)
    {
      store::Item_t result;
      bool status = m_child->consumeNext(result, m_child.getp(), m_stateBlock);
      item = status ? result : NULL;
      return status;
    }

  private:
    PlanIter_t m_child;
    PlanState& m_stateBlock;
};

StatelessExtFunctionCallIteratorState::StatelessExtFunctionCallIteratorState() { }

StatelessExtFunctionCallIteratorState::~StatelessExtFunctionCallIteratorState() { }

void StatelessExtFunctionCallIteratorState::reset(PlanState& planState)
{
  PlanIteratorState::reset(planState);
  m_result.reset();
}

StatelessExtFunctionCallIterator::StatelessExtFunctionCallIterator(const QueryLoc& loc,
    std::vector<PlanIter_t>& args,
    const StatelessExternalFunction *function,
    bool aIsUpdating)
  :
  NaryBaseIterator<StatelessExtFunctionCallIterator,
                   StatelessExtFunctionCallIteratorState>(loc, args),
  m_function(function),
  theIsUpdating(aIsUpdating)
{
}

void StatelessExtFunctionCallIterator::openImpl(PlanState& planState, uint32_t& offset)
{
  NaryBaseIterator<StatelessExtFunctionCallIterator,
                   StatelessExtFunctionCallIteratorState>::openImpl(planState, offset);

  StatelessExtFunctionCallIteratorState
    *state = StateTraitsImpl<StatelessExtFunctionCallIteratorState>::getState(planState,
                                                                              this->stateOffset);
  int n = theChildren.size();
  state->m_extArgs.resize(n);
  for(int i = 0; i < n; ++i)
  {
    state->m_extArgs[i] = new ExtFuncArgItemSequence(theChildren[i], planState);
  }
}

bool StatelessExtFunctionCallIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  StatelessExtFunctionCallIteratorState *state;
  Item lOutsideItem;
  DEFAULT_STACK_INIT(StatelessExtFunctionCallIteratorState, state, planState);

  try {
    state->m_result = m_function->evaluate(state->m_extArgs);
  } catch(const ZorbaException& e) {
    ZORBA_ERROR_LOC(e.getErrorCode(), loc);
  }
  while (true)
  {
    try {
      if (!state->m_result->next(lOutsideItem)) {
        break;
      }
    } catch(const ZorbaException& e) {
      ZORBA_ERROR_LOC(e.getErrorCode(), loc);
    }
    result = Unmarshaller::getInternalItem(lOutsideItem);
    if (theIsUpdating)
    {
      if (!result->isPul())
      {
        ZORBA_ERROR_LOC(XUDY0019, loc);
      }
    }
    else
    {
      if (result->isPul())
      {
        ZORBA_ERROR_LOC(XUDY0018, loc);
      }
    }
    STACK_PUSH(true, state);
  }

  STACK_END (state);
}

void StatelessExtFunctionCallIterator::closeImpl(PlanState& planState)
{
  StatelessExtFunctionCallIteratorState *state =
    StateTraitsImpl<StatelessExtFunctionCallIteratorState>::getState(planState, this->stateOffset);

  // we have the ownership for the item sequences
  int n = theChildren.size();
  for(int i = 0; i < n; ++i) {
    delete state->m_extArgs[i];
  }

  NaryBaseIterator<StatelessExtFunctionCallIterator,
                   StatelessExtFunctionCallIteratorState>::closeImpl(planState);
}

}

/* vim:set ts=2 sw=2: */
<|endoftext|>


<commit_before>/********************************************************************
 * AUTHORS: Vijay Ganesh
 *
 * BEGIN DATE: November, 2005
 *
 * LICENSE: Please view LICENSE file in the home dir of this Program
 ********************************************************************/
// -*- c++ -*-

#include "../AST/AST.h"
namespace BEEV
{
  //some global variables that are set through commandline options. it
  //is best that these variables remain global. Default values set
  //here
  //
  //collect statistics on certain functions
  bool stats_flag = false;
  //print DAG nodes
  bool print_nodes_flag = false;
  //run STP in optimized mode
  bool optimize_flag = true;
  //do sat refinement, i.e. underconstraint the problem, and feed to
  //SAT. if this works, great. else, add a set of suitable constraints
  //to re-constraint the problem correctly, and call SAT again, until
  //all constraints have been added.
  bool arrayread_refinement_flag = true;
  //flag to control write refinement
  bool arraywrite_refinement_flag = true;
  //check the counterexample against the original input to STP
  bool check_counterexample_flag = false;
  //construct the counterexample in terms of original variable based
  //on the counterexample returned by SAT solver
  bool construct_counterexample_flag = true;
  bool print_counterexample_flag = false;
  bool print_binary_flag = false;
  //if this option is true then print the way dawson wants using a
  //different printer. do not use this printer.
  bool print_arrayval_declaredorder_flag = false;
  //flag to decide whether to print "valid/invalid" or not
  bool print_output_flag = false;
  //print the variable order chosen by the sat solver while it is
  //solving.
  bool print_sat_varorder_flag = false;
  //turn on word level bitvector solver
  bool wordlevel_solve_flag = true;
  //turn off XOR flattening
  bool xor_flatten_flag = false;
  //Flag to switch on the smtlib parser
  bool smtlib_parser_flag = false;
  //print the input back
  bool print_STPinput_back_flag = false;

  // If enabled. division, mod and remainder by zero will evaluate to
  // 1.
  bool division_by_zero_returns_one = false;

  enum inputStatus input_status = NOT_DECLARED;

  //global BEEVMGR for the parser
  BeevMgr * GlobalBeevMgr;

  void (*vc_error_hdlr)(const char* err_msg) = NULL;
  /** This is reusable empty vector, for representing empty children
      arrays */
  ASTVec _empty_ASTVec;

  //Some global vars for the Main function.
  const std::string version = "$Id: main.cpp 174 2009-09-03 19:22:47Z vijay_ganesh $";
  const char * prog = "stp";
  int linenum  = 1;
  const char * usage = "Usage: %s [-option] [infile]\n";
  std::string helpstring = "\n\n";
}; //end of namespace BEEV
<commit_msg>Adding SVN property to replace $Id$ with the version number<commit_after>/********************************************************************
 * AUTHORS: Vijay Ganesh
 *
 * BEGIN DATE: November, 2005
 *
 * LICENSE: Please view LICENSE file in the home dir of this Program
 ********************************************************************/
// -*- c++ -*-

#include "../AST/AST.h"
namespace BEEV
{
  //some global variables that are set through commandline options. it
  //is best that these variables remain global. Default values set
  //here
  //
  //collect statistics on certain functions
  bool stats_flag = false;
  //print DAG nodes
  bool print_nodes_flag = false;
  //run STP in optimized mode
  bool optimize_flag = true;
  //do sat refinement, i.e. underconstraint the problem, and feed to
  //SAT. if this works, great. else, add a set of suitable constraints
  //to re-constraint the problem correctly, and call SAT again, until
  //all constraints have been added.
  bool arrayread_refinement_flag = true;
  //flag to control write refinement
  bool arraywrite_refinement_flag = true;
  //check the counterexample against the original input to STP
  bool check_counterexample_flag = false;
  //construct the counterexample in terms of original variable based
  //on the counterexample returned by SAT solver
  bool construct_counterexample_flag = true;
  bool print_counterexample_flag = false;
  bool print_binary_flag = false;
  //if this option is true then print the way dawson wants using a
  //different printer. do not use this printer.
  bool print_arrayval_declaredorder_flag = false;
  //flag to decide whether to print "valid/invalid" or not
  bool print_output_flag = false;
  //print the variable order chosen by the sat solver while it is
  //solving.
  bool print_sat_varorder_flag = false;
  //turn on word level bitvector solver
  bool wordlevel_solve_flag = true;
  //turn off XOR flattening
  bool xor_flatten_flag = false;
  //Flag to switch on the smtlib parser
  bool smtlib_parser_flag = false;
  //print the input back
  bool print_STPinput_back_flag = false;

  // If enabled. division, mod and remainder by zero will evaluate to
  // 1.
  bool division_by_zero_returns_one = false;

  enum inputStatus input_status = NOT_DECLARED;

  //global BEEVMGR for the parser
  BeevMgr * GlobalBeevMgr;

  void (*vc_error_hdlr)(const char* err_msg) = NULL;
  /** This is reusable empty vector, for representing empty children
      arrays */
  ASTVec _empty_ASTVec;

  //Some global vars for the Main function.
  const std::string version = "$Id$";
  const char * prog = "stp";
  int linenum  = 1;
  const char * usage = "Usage: %s [-option] [infile]\n";
  std::string helpstring = "\n\n";
}; //end of namespace BEEV
<|endoftext|>


<commit_before>#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>

// stochasticPerfectHash
// Uses stochastic remainder sampling to derive a Pearson mixing table for small sets of alphabetic keys
// orthopteroid@gmail.com
// g++ -std=c++0x -O3 -lrt sph.cpp -o sph
//
// for background, read:
// http://cs.mwsu.edu/~griffin/courses/2133/downloads/Spring11/p677-pearson.pdf

// stochastic remainder sampler
size_t sample( uint8_t* counts, uint32_t sum )
{
	int32_t target = rand() % sum;
	size_t i = 0;
	while( (target -= counts[ i ]) > 0 ) { i++; }
	return i;
}

// calculates a mixtable for the pearson hash to create a perfect hash.
// restrictions are keys can only be ascii lowercase, but can be of any length.
// keys are seperated in the input string using the ! delimiter. ! must also be at end of string.
size_t calcMixTable( char* sz )
{
	const size_t MAXITER = 25000;

	// special marker '!' in the string designates the end of a key
	size_t keyCount = 0;
	for( size_t i=0;sz[i];i++ ) { if( sz[i] == '!' ) { keyCount++; } }
	bool hashed[ keyCount ];

	// the defualt mix table is a null transform
	uint8_t mix[32] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};

	// these weights influence convergence rate.
	// they are used by the stochastic sampling method that adjusts the mixing table to resolve hash collisions
	const uint8_t DEFAULT = 1;
	const uint8_t SIGNAL = 100;

	// reset flags...
	size_t iterations = 0;
	do {
		// counts will track mix table usage each iteration we evaluate the hashed
		uint8_t counts[32];

		for( size_t i=0;i<32;i++ ) { counts[i] = DEFAULT; }
		for( size_t i=0;i<keyCount;i++ ) { hashed[i] = false; }

		// compute the pearson hash using the current mix table.
		uint8_t hash = 0;
		bool collision = false;
		for( size_t i=0;sz[i];i++ )
		{
			if( sz[i] == '!' ) // end of key detected
			{
				size_t j = hash % keyCount; // mod with keyCount as we are trying to find the perfect hash function;
				if( hashed[ j ] ) { collision = true; }
				hashed[ j ] = true;
				hash = 0;
			}
			else
			{
				uint8_t j = 31 & ( hash ^ ( sz[i] - 'a' ) );
				hash = mix[ j ];
				counts[ j ] = SIGNAL; // inc the mix item that was used to compute the hashs this iteration.
			}
		}
		if( !collision ) { break; }

		// calc sum and swap items
		uint32_t countsum = 0;
		for( size_t i=0;i<32;i++ ) { countsum += counts[i]; }

		size_t i = sample( counts, countsum );				// select item i.
		countsum -= counts[i]; counts[i] = 0;				// remove from possible selection set
		size_t j = sample( counts, countsum );				// select item j
		uint8_t t = mix[i]; mix[i] = mix[j]; mix[j] = t;	// swap i and j

	} while( ++iterations < MAXITER );

	if( iterations < MAXITER )
		{ printf("uint_8 mix[] = {"); for( size_t i=0;i<32;i++ ) { printf("%d, ",mix[i]); } printf("};\n"); }
	else
		{ printf("ack! can't do it.\n"); }

	return iterations;
}

int main()
{
	time_t ltime;
	time(&ltime);
	srand((unsigned int)ltime);

	char buf[1000]; // a fixed buffer for a sequence of keys we wish to perfect-hash
	for( size_t k=0;k<10;k++)
	{
		const size_t keyCount = 10;
		size_t pos = 0;
		for( size_t i=0;i<keyCount;i++)
		{
			// keys are all ascii lowsercase
			const size_t keyLength = 10;
			for( size_t j=0;j<keyLength;j++) { buf[ pos++ ] = 'a' + rand() % 26; }

			// keys end with special '!' char
			buf[ pos++ ] = '!';
		}
		buf[ pos ] = 0; // zero term buffer

		printf("Finding mix table for %s:\n", buf);
		size_t iter = calcMixTable( buf );
		printf("Took %lu iterations\n",iter);
	}

	return 0;
}
<commit_msg>short int rand fixup<commit_after>#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>

// stochasticPerfectHash
// Uses stochastic remainder sampling to derive a Pearson mixing table for small sets of alphabetic keys
// orthopteroid@gmail.com
// g++ -std=c++0x -O3 -lrt sph.cpp -o sph
//
// for background, read:
// http://cs.mwsu.edu/~griffin/courses/2133/downloads/Spring11/p677-pearson.pdf

// stochastic remainder sampler
size_t sample( uint8_t* counts, uint32_t sum )
{
	int32_t target = (((int32_t)rand() << 20) + ((int32_t)rand() << 10) + (int32_t)rand()) % sum; // impl fix for short int rand()
	size_t i = 0;
	while( (target -= counts[ i ]) > 0 ) { i++; }
	return i;
}

// calculates a mixtable for the pearson hash to create a perfect hash.
// restrictions are keys can only be ascii lowercase, but can be of any length.
// keys are seperated in the input string using the ! delimiter. ! must also be at end of string.
size_t calcMixTable( char* sz )
{
	const size_t MAXITER = 25000;

	// special marker '!' in the string designates the end of a key
	size_t keyCount = 0;
	for( size_t i=0;sz[i];i++ ) { if( sz[i] == '!' ) { keyCount++; } }
	bool hashed[ keyCount ];

	// the defualt mix table is a null transform
	uint8_t mix[32] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};

	// these weights influence convergence rate.
	// they are used by the stochastic sampling method that adjusts the mixing table to resolve hash collisions
	const uint8_t DEFAULT = 1;
	const uint8_t SIGNAL = 100;

	// reset flags...
	size_t iterations = 0;
	do {
		// counts will track mix table usage each iteration we evaluate the hashed
		uint8_t counts[32];

		for( size_t i=0;i<32;i++ ) { counts[i] = DEFAULT; }
		for( size_t i=0;i<keyCount;i++ ) { hashed[i] = false; }

		// compute the pearson hash using the current mix table.
		uint8_t hash = 0;
		bool collision = false;
		for( size_t i=0;sz[i];i++ )
		{
			if( sz[i] == '!' ) // end of key detected
			{
				size_t j = hash % keyCount; // mod with keyCount as we are trying to find the perfect hash function;
				if( hashed[ j ] ) { collision = true; }
				hashed[ j ] = true;
				hash = 0;
			}
			else
			{
				uint8_t j = 31 & ( hash ^ ( sz[i] - 'a' ) );
				hash = mix[ j ];
				counts[ j ] = SIGNAL; // inc the mix item that was used to compute the hashs this iteration.
			}
		}
		if( !collision ) { break; }

		// calc sum and swap items
		uint32_t countsum = 0;
		for( size_t i=0;i<32;i++ ) { countsum += counts[i]; }

		size_t i = sample( counts, countsum );				// select item i.
		countsum -= counts[i]; counts[i] = 0;				// remove from possible selection set
		size_t j = sample( counts, countsum );				// select item j
		uint8_t t = mix[i]; mix[i] = mix[j]; mix[j] = t;	// swap i and j

	} while( ++iterations < MAXITER );

	if( iterations < MAXITER )
		{ printf("uint_8 mix[] = {"); for( size_t i=0;i<32;i++ ) { printf("%d, ",mix[i]); } printf("};\n"); }
	else
		{ printf("ack! can't do it.\n"); }

	return iterations;
}

int main()
{
	time_t ltime;
	time(&ltime);
	srand((unsigned int)ltime);

	char buf[1000]; // a fixed buffer for a sequence of keys we wish to perfect-hash
	for( size_t k=0;k<10;k++)
	{
		const size_t keyCount = 10;
		size_t pos = 0;
		for( size_t i=0;i<keyCount;i++)
		{
			// keys are all ascii lowsercase
			const size_t keyLength = 10;
			for( size_t j=0;j<keyLength;j++) { buf[ pos++ ] = 'a' + rand() % 26; }

			// keys end with special '!' char
			buf[ pos++ ] = '!';
		}
		buf[ pos ] = 0; // zero term buffer

		printf("Finding mix table for %s:\n", buf);
		size_t iter = calcMixTable( buf );
		printf("Took %lu iterations\n",iter);
	}

	return 0;
}
<|endoftext|>


<commit_before>#ifndef __NODE_MAPNIK_FONTS_H__
#define __NODE_MAPNIK_FONTS_H__

// v8
#include <v8.h>

// node
#include <node.h>

// mapnik
#include <mapnik/font_engine_freetype.hpp>

// stl
#include <vector>

#include "utils.hpp"

using namespace v8;
using namespace node;

namespace node_mapnik {

static inline Handle<Value> register_fonts(const Arguments& args)
{
    HandleScope scope;

    try
    {
        if (!args.Length() >= 1 || !args[0]->IsString())
          return ThrowException(Exception::TypeError(
            String::New("first argument must be a path to a directory of fonts")));

        bool found = false;

        std::vector<std::string> const names_before = mapnik::freetype_engine::face_names();

        // option hash
        if (args.Length() == 2){
          if (!args[1]->IsObject())
            return ThrowException(Exception::TypeError(
              String::New("second argument is optional, but if provided must be an object, eg. { recurse:Boolean }")));

            Local<Object> options = args[1]->ToObject();
            if (options->Has(String::New("recurse")))
            {
                Local<Value> recurse_opt = options->Get(String::New("recurse"));
                if (!recurse_opt->IsBoolean())
                  return ThrowException(Exception::TypeError(
                    String::New("'recurse' must be a Boolean")));

                bool recurse = recurse_opt->BooleanValue();
                std::string const& path = TOSTR(args[0]);
                found = mapnik::freetype_engine::register_fonts(path,recurse);
            }
        }
        else
        {
            std::string const& path = TOSTR(args[0]);
            found = mapnik::freetype_engine::register_fonts(path);
        }

        std::vector<std::string> const& names_after = mapnik::freetype_engine::face_names();
        if (names_after.size() == names_before.size())
            found = false;

        return scope.Close(Boolean::New(found));
    }
    catch (const std::exception & ex)
    {
        return ThrowException(Exception::Error(
          String::New(ex.what())));
    }
}

static inline Handle<Value> available_font_faces(const Arguments& args)
{
    HandleScope scope;
    std::vector<std::string> const& names = mapnik::freetype_engine::face_names();
    Local<Array> a = Array::New(names.size());
    for (unsigned i = 0; i < names.size(); ++i)
    {
        a->Set(i, String::New(names[i].c_str()));
    }
    return scope.Close(a);
}

static inline Handle<Value> available_font_files(const Arguments& args)
{
    HandleScope scope;
    std::map<std::string,std::string> const& mapping = mapnik::freetype_engine::get_mapping();
    Local<Object> obj = Object::New();
    std::map<std::string,std::string>::const_iterator itr;
    for (itr = mapping.begin();itr!=mapping.end();++itr)
    {
        obj->Set(String::NewSymbol(itr->first.c_str()),String::New(itr->second.c_str()));
    }
    return scope.Close(obj);
}

}

#endif // __NODE_MAPNIK_FONTS_H__
<commit_msg>upgrade to new mapnik::freetype_engine::get_mapping signature<commit_after>#ifndef __NODE_MAPNIK_FONTS_H__
#define __NODE_MAPNIK_FONTS_H__

// v8
#include <v8.h>

// node
#include <node.h>

// mapnik
#include <mapnik/font_engine_freetype.hpp>

// stl
#include <vector>

#include "utils.hpp"

using namespace v8;
using namespace node;

namespace node_mapnik {

static inline Handle<Value> register_fonts(const Arguments& args)
{
    HandleScope scope;

    try
    {
        if (!args.Length() >= 1 || !args[0]->IsString())
          return ThrowException(Exception::TypeError(
            String::New("first argument must be a path to a directory of fonts")));

        bool found = false;

        std::vector<std::string> const names_before = mapnik::freetype_engine::face_names();

        // option hash
        if (args.Length() == 2){
          if (!args[1]->IsObject())
            return ThrowException(Exception::TypeError(
              String::New("second argument is optional, but if provided must be an object, eg. { recurse:Boolean }")));

            Local<Object> options = args[1]->ToObject();
            if (options->Has(String::New("recurse")))
            {
                Local<Value> recurse_opt = options->Get(String::New("recurse"));
                if (!recurse_opt->IsBoolean())
                  return ThrowException(Exception::TypeError(
                    String::New("'recurse' must be a Boolean")));

                bool recurse = recurse_opt->BooleanValue();
                std::string const& path = TOSTR(args[0]);
                found = mapnik::freetype_engine::register_fonts(path,recurse);
            }
        }
        else
        {
            std::string const& path = TOSTR(args[0]);
            found = mapnik::freetype_engine::register_fonts(path);
        }

        std::vector<std::string> const& names_after = mapnik::freetype_engine::face_names();
        if (names_after.size() == names_before.size())
            found = false;

        return scope.Close(Boolean::New(found));
    }
    catch (const std::exception & ex)
    {
        return ThrowException(Exception::Error(
          String::New(ex.what())));
    }
}

static inline Handle<Value> available_font_faces(const Arguments& args)
{
    HandleScope scope;
    std::vector<std::string> const& names = mapnik::freetype_engine::face_names();
    Local<Array> a = Array::New(names.size());
    for (unsigned i = 0; i < names.size(); ++i)
    {
        a->Set(i, String::New(names[i].c_str()));
    }
    return scope.Close(a);
}

static inline Handle<Value> available_font_files(const Arguments& args)
{
    HandleScope scope;
    std::map<std::string,std::pair<int,std::string> > const& mapping = mapnik::freetype_engine::get_mapping();
    Local<Object> obj = Object::New();
    std::map<std::string,std::pair<int,std::string> >::const_iterator itr;
    for (itr = mapping.begin();itr!=mapping.end();++itr)
    {
        obj->Set(String::NewSymbol(itr->first.c_str()),String::New(itr->second.second.c_str()));
    }
    return scope.Close(obj);
}

}

#endif // __NODE_MAPNIK_FONTS_H__
<|endoftext|>