<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: misc.hxx,v $
 * $Revision: 1.14 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _LINGUISTIC_MISC_HXX_
#define _LINGUISTIC_MISC_HXX_

#include <com/sun/star/uno/Sequence.h>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/beans/PropertyValues.hpp>
#include <com/sun/star/frame/XTerminateListener.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/linguistic2/XDictionaryEntry.hpp>
#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
#include <com/sun/star/linguistic2/XHyphenatedWord.hpp>

#include <uno/lbnames.h>            // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type
#include <cppuhelper/implbase1.hxx> // helper for implementations
#include <svtools/pathoptions.hxx>
#include <i18npool/lang.h>
#include <tools/string.hxx>
#include <unotools/charclass.hxx>
#include <osl/thread.h>
#include <osl/mutex.hxx>
#include <vcl/svapp.hxx>

namespace com { namespace sun { namespace star { namespace beans {
    class XPropertySet;
    class XFastPropertySet;
}}}}

namespace com { namespace sun { namespace star { namespace frame {
    class XDesktop;
}}}}

class LocaleDataWrapper;

///////////////////////////////////////////////////////////////////////////

#define SN_SPELLCHECKER             "com.sun.star.linguistic2.SpellChecker"
#define SN_HYPHENATOR               "com.sun.star.linguistic2.Hyphenator"
#define SN_THESAURUS                "com.sun.star.linguistic2.Thesaurus"
#define SN_LINGU_SERVCICE_MANAGER   "com.sun.star.linguistic2.LinguServiceManager"
#define SN_LINGU_PROPERTIES         "com.sun.star.linguistic2.LinguProperties"
#define SN_DICTIONARY_LIST          "com.sun.star.linguistic2.DictionaryList"
#define SN_OTHER_LINGU              "com.sun.star.linguistic2.OtherLingu"
#define SN_DESKTOP                  "com.sun.star.frame.Desktop"

namespace linguistic
{

// ascii to OUString conversion
#define A2OU(x) ::rtl::OUString::createFromAscii( x )

/// Flags to be used with the multi-path related functions
/// @see GetDictionaryPaths, GetLinguisticPaths
#define PATH_FLAG_INTERNAL  0x01
#define PATH_FLAG_USER      0x02
#define PATH_FLAG_WRITABLE  0x04
#define PATH_FLAG_ALL       (PATH_FLAG_INTERNAL | PATH_FLAG_USER | PATH_FLAG_WRITABLE)

// AddEntryToDic return values
#define DIC_ERR_NONE        0
#define DIC_ERR_FULL        1
#define DIC_ERR_READONLY    2
#define DIC_ERR_UNKNOWN     3
#define DIC_ERR_NOT_EXISTS  4

///////////////////////////////////////////////////////////////////////////

::osl::Mutex &  GetLinguMutex();

LocaleDataWrapper & GetLocaleDataWrapper( INT16 nLang );

///////////////////////////////////////////////////////////////////////////

rtl_TextEncoding GetTextEncoding( INT16 nLanguage );

inline ::rtl::OUString BS2OU(const ByteString &rText, rtl_TextEncoding nEnc)
{
    return ::rtl::OUString( rText.GetBuffer(), rText.Len(), nEnc );
}

inline ByteString OU2BS(const ::rtl::OUString &rText, rtl_TextEncoding nEnc)
{
    return ByteString( rText.getStr(), nEnc );
}

rtl::OUString StripTrailingChars( rtl::OUString &rTxt, sal_Unicode cChar );

///////////////////////////////////////////////////////////////////////////

sal_Int32 LevDistance( const rtl::OUString &rTxt1, const rtl::OUString &rTxt2 );

///////////////////////////////////////////////////////////////////////////

::com::sun::star::lang::Locale
    CreateLocale( LanguageType eLang );

LanguageType
     LocaleToLanguage( const ::com::sun::star::lang::Locale& rLocale );

::com::sun::star::lang::Locale&
    LanguageToLocale( ::com::sun::star::lang::Locale& rLocale, LanguageType eLang );

::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale >
    LangSeqToLocaleSeq( const ::com::sun::star::uno::Sequence< INT16 > &rLangSeq );

::com::sun::star::uno::Sequence< INT16 >
    LocaleSeqToLangSeq( ::com::sun::star::uno::Sequence<
        ::com::sun::star::lang::Locale > &rLocaleSeq );

///////////////////////////////////////////////////////////////////////////

// checks if file pointed to by rURL is readonly
// and may also check return if such a file exists or not
BOOL    IsReadOnly( const String &rURL, BOOL *pbExist = 0 );

// checks if a file with the given URL exists
BOOL    FileExists( const String &rURL );

#ifdef TL_OUTDATED
// returns complete file URL for given filename that is to be searched in
// the specified path
String  GetFileURL( SvtPathOptions::Pathes ePath, const String &rFileName );

String  GetModulePath( SvtPathOptions::Pathes ePath, BOOL bAddAccessDelim = TRUE );
#endif

///////////////////////////////////////////////////////////////////////////

::rtl::OUString     GetDictionaryWriteablePath();
::com::sun::star::uno::Sequence< ::rtl::OUString > GetDictionaryPaths( sal_Int16 nPathFlags = PATH_FLAG_ALL );
::com::sun::star::uno::Sequence< ::rtl::OUString > GetLinguisticPaths( sal_Int16 nPathFlags = PATH_FLAG_ALL );

/// @returns an URL for a new and writable dictionary rDicName.
///     The URL will point to the path given by 'GetDictionaryWriteablePath'
String  GetWritableDictionaryURL( const String &rDicName );

// looks for the specified file in the list of paths.
// In case of multiple occurences only the first found is returned.
String     SearchFileInPaths( const String &rFile, const ::com::sun::star::uno::Sequence< ::rtl::OUString > &rPaths );

///////////////////////////////////////////////////////////////////////////

INT32       GetPosInWordToCheck( const rtl::OUString &rTxt, INT32 nPos );

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XHyphenatedWord >
            RebuildHyphensAndControlChars( const rtl::OUString &rOrigWord,
                ::com::sun::star::uno::Reference<
                    ::com::sun::star::linguistic2::XHyphenatedWord > &rxHyphWord );

///////////////////////////////////////////////////////////////////////////

BOOL        IsUpper( const String &rText, xub_StrLen nPos, xub_StrLen nLen, INT16 nLanguage );
BOOL        IsLower( const String &rText, xub_StrLen nPos, xub_StrLen nLen, INT16 nLanguage );

inline BOOL        IsUpper( const String &rText, INT16 nLanguage )     { return IsUpper( rText, 0, rText.Len(), nLanguage ); }
inline BOOL        IsLower( const String &rText, INT16 nLanguage )     { return IsLower( rText, 0, rText.Len(), nLanguage ); }

String      ToLower( const String &rText, INT16 nLanguage );
String      ToUpper( const String &rText, INT16 nLanguage );
String      ToTitle( const String &rText, INT16 nLanguage );
sal_Unicode ToLower( const sal_Unicode cChar, INT16 nLanguage );
sal_Unicode ToUpper( const sal_Unicode cChar, INT16 nLanguage );
BOOL        HasDigits( const String &rText );
BOOL        IsNumeric( const String &rText );

///////////////////////////////////////////////////////////////////////////

::com::sun::star::uno::Reference<
    ::com::sun::star::uno::XInterface >
        GetOneInstanceService( const char *pServiceName );

::com::sun::star::uno::Reference<
    ::com::sun::star::beans::XPropertySet >
        GetLinguProperties();

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XSearchableDictionaryList >
        GetSearchableDictionaryList();

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XDictionaryList >
        GetDictionaryList();

///////////////////////////////////////////////////////////////////////////

BOOL IsUseDicList( const ::com::sun::star::beans::PropertyValues &rProperties,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet > &rxPropSet );

BOOL IsIgnoreControlChars( const ::com::sun::star::beans::PropertyValues &rProperties,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet > &rxPropSet );

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XDictionaryEntry >
        SearchDicList(
            const ::com::sun::star::uno::Reference< ::com::sun::star::linguistic2::XDictionaryList >& rDicList,
            const ::rtl::OUString& rWord, INT16 nLanguage,
            BOOL bSearchPosDics, BOOL bSearchSpellEntry );

sal_uInt8 AddEntryToDic(
    ::com::sun::star::uno::Reference< ::com::sun::star::linguistic2::XDictionary >  &rxDic,
    const ::rtl::OUString &rWord, sal_Bool bIsNeg,
    const ::rtl::OUString &rRplcTxt, sal_Int16 nRplcLang,
    sal_Bool bStripDot = sal_True );

sal_Bool SaveDictionaries( const ::com::sun::star::uno::Reference< ::com::sun::star::linguistic2::XDictionaryList > &xDicList );

///////////////////////////////////////////////////////////////////////////
//
// AppExitLstnr:
// virtual base class that calls it AtExit function when the application
// (ie the Desktop) is about to terminate
//

class AppExitListener :
    public cppu::WeakImplHelper1
    <
        ::com::sun::star::frame::XTerminateListener
    >
{
    ::com::sun::star::uno::Reference<
        ::com::sun::star::frame::XDesktop >     xDesktop;

public:
    AppExitListener();
    virtual ~AppExitListener();

    virtual void    AtExit() = 0;

    void            Activate();
    void            Deactivate();

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

    // XTerminateListener
    virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
};

///////////////////////////////////////////////////////////////////////////

}   // namespace linguistic

#endif

<commit_msg>INTEGRATION: CWS tl55 (1.14.8); FILE MERGED 2008/05/21 09:59:51 tl 1.14.8.1: #158047# customer specific extension<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: misc.hxx,v $
 * $Revision: 1.15 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _LINGUISTIC_MISC_HXX_
#define _LINGUISTIC_MISC_HXX_

#include <com/sun/star/uno/Sequence.h>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/beans/PropertyValues.hpp>
#include <com/sun/star/frame/XTerminateListener.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/linguistic2/XDictionaryEntry.hpp>
#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
#include <com/sun/star/linguistic2/XHyphenatedWord.hpp>

#include <uno/lbnames.h>            // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type
#include <cppuhelper/implbase1.hxx> // helper for implementations
#include <svtools/pathoptions.hxx>
#include <i18npool/lang.h>
#include <tools/string.hxx>
#include <unotools/charclass.hxx>
#include <osl/thread.h>
#include <osl/mutex.hxx>
#include <vcl/svapp.hxx>

namespace com { namespace sun { namespace star { namespace beans {
    class XPropertySet;
    class XFastPropertySet;
}}}}

namespace com { namespace sun { namespace star { namespace frame {
    class XDesktop;
}}}}

class LocaleDataWrapper;

///////////////////////////////////////////////////////////////////////////
#define SN_GRAMMARCHECKER           "com.sun.star.linguistic2.GrammarChecker"
#define SN_SPELLCHECKER             "com.sun.star.linguistic2.SpellChecker"
#define SN_HYPHENATOR               "com.sun.star.linguistic2.Hyphenator"
#define SN_THESAURUS                "com.sun.star.linguistic2.Thesaurus"
#define SN_LINGU_SERVCICE_MANAGER   "com.sun.star.linguistic2.LinguServiceManager"
#define SN_LINGU_PROPERTIES         "com.sun.star.linguistic2.LinguProperties"
#define SN_DICTIONARY_LIST          "com.sun.star.linguistic2.DictionaryList"
#define SN_OTHER_LINGU              "com.sun.star.linguistic2.OtherLingu"
#define SN_DESKTOP                  "com.sun.star.frame.Desktop"

namespace linguistic
{

// ascii to OUString conversion
#define A2OU(x) ::rtl::OUString::createFromAscii( x )

/// Flags to be used with the multi-path related functions
/// @see GetDictionaryPaths, GetLinguisticPaths
#define PATH_FLAG_INTERNAL  0x01
#define PATH_FLAG_USER      0x02
#define PATH_FLAG_WRITABLE  0x04
#define PATH_FLAG_ALL       (PATH_FLAG_INTERNAL | PATH_FLAG_USER | PATH_FLAG_WRITABLE)

// AddEntryToDic return values
#define DIC_ERR_NONE        0
#define DIC_ERR_FULL        1
#define DIC_ERR_READONLY    2
#define DIC_ERR_UNKNOWN     3
#define DIC_ERR_NOT_EXISTS  4

///////////////////////////////////////////////////////////////////////////

::osl::Mutex &  GetLinguMutex();

LocaleDataWrapper & GetLocaleDataWrapper( INT16 nLang );

///////////////////////////////////////////////////////////////////////////

rtl_TextEncoding GetTextEncoding( INT16 nLanguage );

inline ::rtl::OUString BS2OU(const ByteString &rText, rtl_TextEncoding nEnc)
{
    return ::rtl::OUString( rText.GetBuffer(), rText.Len(), nEnc );
}

inline ByteString OU2BS(const ::rtl::OUString &rText, rtl_TextEncoding nEnc)
{
    return ByteString( rText.getStr(), nEnc );
}

rtl::OUString StripTrailingChars( rtl::OUString &rTxt, sal_Unicode cChar );

///////////////////////////////////////////////////////////////////////////

sal_Int32 LevDistance( const rtl::OUString &rTxt1, const rtl::OUString &rTxt2 );

///////////////////////////////////////////////////////////////////////////

::com::sun::star::lang::Locale
    CreateLocale( LanguageType eLang );

LanguageType
     LocaleToLanguage( const ::com::sun::star::lang::Locale& rLocale );

::com::sun::star::lang::Locale&
    LanguageToLocale( ::com::sun::star::lang::Locale& rLocale, LanguageType eLang );

::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale >
    LangSeqToLocaleSeq( const ::com::sun::star::uno::Sequence< INT16 > &rLangSeq );

::com::sun::star::uno::Sequence< INT16 >
    LocaleSeqToLangSeq( ::com::sun::star::uno::Sequence<
        ::com::sun::star::lang::Locale > &rLocaleSeq );

///////////////////////////////////////////////////////////////////////////

// checks if file pointed to by rURL is readonly
// and may also check return if such a file exists or not
BOOL    IsReadOnly( const String &rURL, BOOL *pbExist = 0 );

// checks if a file with the given URL exists
BOOL    FileExists( const String &rURL );

#ifdef TL_OUTDATED
// returns complete file URL for given filename that is to be searched in
// the specified path
String  GetFileURL( SvtPathOptions::Pathes ePath, const String &rFileName );

String  GetModulePath( SvtPathOptions::Pathes ePath, BOOL bAddAccessDelim = TRUE );
#endif

///////////////////////////////////////////////////////////////////////////

::rtl::OUString     GetDictionaryWriteablePath();
::com::sun::star::uno::Sequence< ::rtl::OUString > GetDictionaryPaths( sal_Int16 nPathFlags = PATH_FLAG_ALL );
::com::sun::star::uno::Sequence< ::rtl::OUString > GetLinguisticPaths( sal_Int16 nPathFlags = PATH_FLAG_ALL );

/// @returns an URL for a new and writable dictionary rDicName.
///     The URL will point to the path given by 'GetDictionaryWriteablePath'
String  GetWritableDictionaryURL( const String &rDicName );

// looks for the specified file in the list of paths.
// In case of multiple occurences only the first found is returned.
String     SearchFileInPaths( const String &rFile, const ::com::sun::star::uno::Sequence< ::rtl::OUString > &rPaths );

///////////////////////////////////////////////////////////////////////////

INT32       GetPosInWordToCheck( const rtl::OUString &rTxt, INT32 nPos );

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XHyphenatedWord >
            RebuildHyphensAndControlChars( const rtl::OUString &rOrigWord,
                ::com::sun::star::uno::Reference<
                    ::com::sun::star::linguistic2::XHyphenatedWord > &rxHyphWord );

///////////////////////////////////////////////////////////////////////////

BOOL        IsUpper( const String &rText, xub_StrLen nPos, xub_StrLen nLen, INT16 nLanguage );
BOOL        IsLower( const String &rText, xub_StrLen nPos, xub_StrLen nLen, INT16 nLanguage );

inline BOOL        IsUpper( const String &rText, INT16 nLanguage )     { return IsUpper( rText, 0, rText.Len(), nLanguage ); }
inline BOOL        IsLower( const String &rText, INT16 nLanguage )     { return IsLower( rText, 0, rText.Len(), nLanguage ); }

String      ToLower( const String &rText, INT16 nLanguage );
String      ToUpper( const String &rText, INT16 nLanguage );
String      ToTitle( const String &rText, INT16 nLanguage );
sal_Unicode ToLower( const sal_Unicode cChar, INT16 nLanguage );
sal_Unicode ToUpper( const sal_Unicode cChar, INT16 nLanguage );
BOOL        HasDigits( const String &rText );
BOOL        IsNumeric( const String &rText );

///////////////////////////////////////////////////////////////////////////

::com::sun::star::uno::Reference<
    ::com::sun::star::uno::XInterface >
        GetOneInstanceService( const char *pServiceName );

::com::sun::star::uno::Reference<
    ::com::sun::star::beans::XPropertySet >
        GetLinguProperties();

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XSearchableDictionaryList >
        GetSearchableDictionaryList();

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XDictionaryList >
        GetDictionaryList();

///////////////////////////////////////////////////////////////////////////

BOOL IsUseDicList( const ::com::sun::star::beans::PropertyValues &rProperties,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet > &rxPropSet );

BOOL IsIgnoreControlChars( const ::com::sun::star::beans::PropertyValues &rProperties,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet > &rxPropSet );

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XDictionaryEntry >
        SearchDicList(
            const ::com::sun::star::uno::Reference< ::com::sun::star::linguistic2::XDictionaryList >& rDicList,
            const ::rtl::OUString& rWord, INT16 nLanguage,
            BOOL bSearchPosDics, BOOL bSearchSpellEntry );

sal_uInt8 AddEntryToDic(
    ::com::sun::star::uno::Reference< ::com::sun::star::linguistic2::XDictionary >  &rxDic,
    const ::rtl::OUString &rWord, sal_Bool bIsNeg,
    const ::rtl::OUString &rRplcTxt, sal_Int16 nRplcLang,
    sal_Bool bStripDot = sal_True );

sal_Bool SaveDictionaries( const ::com::sun::star::uno::Reference< ::com::sun::star::linguistic2::XDictionaryList > &xDicList );

///////////////////////////////////////////////////////////////////////////
//
// AppExitLstnr:
// virtual base class that calls it AtExit function when the application
// (ie the Desktop) is about to terminate
//

class AppExitListener :
    public cppu::WeakImplHelper1
    <
        ::com::sun::star::frame::XTerminateListener
    >
{
    ::com::sun::star::uno::Reference<
        ::com::sun::star::frame::XDesktop >     xDesktop;

public:
    AppExitListener();
    virtual ~AppExitListener();

    virtual void    AtExit() = 0;

    void            Activate();
    void            Deactivate();

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

    // XTerminateListener
    virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
};

///////////////////////////////////////////////////////////////////////////

}   // namespace linguistic

#endif

<|endoftext|>


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

#ifndef _LINGUISTIC_MISC_HXX_
#define _LINGUISTIC_MISC_HXX_

#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
#include <com/sun/star/uno/Sequence.h>
#endif
#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUES_HPP_
#include <com/sun/star/beans/PropertyValues.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XTERMINATELISTENER_HPP_
#include <com/sun/star/frame/XTerminateListener.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_
#include <com/sun/star/lang/Locale.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_LINGUISTIC2_XDICTIONARYENTRY_HPP_
#include <com/sun/star/linguistic2/XDictionaryEntry.hpp>
#endif
#ifndef _COM_SUN_STAR_LINGUISTIC2_XSEARCHABLEDICTIONARYLIST_HPP_
#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
#endif
#ifndef _COM_SUN_STAR_LINGUISTIC2_XHYPHENATEDWORD_HPP_
#include <com/sun/star/linguistic2/XHyphenatedWord.hpp>
#endif

#include <uno/lbnames.h>            // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type
#include <cppuhelper/implbase1.hxx> // helper for implementations

#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef _ISOLANG_HXX
#include <tools/isolang.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _TOOLS_INTN_HXX
#include <tools/intn.hxx>
#endif
#ifndef _UNOTOOLS_CHARCLASS_HXX
#include <unotools/charclass.hxx>
#endif
#ifndef _OSL_THREAD_H_
#include <osl/thread.h>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

namespace com { namespace sun { namespace star { namespace beans {
    class XPropertySet;
    class XFastPropertySet;
}}}};

namespace com { namespace sun { namespace star { namespace frame {
    class XDesktop;
}}}};

class LocaleDataWrapper;

///////////////////////////////////////////////////////////////////////////

#define SN_SPELLCHECKER             "com.sun.star.linguistic2.SpellChecker"
#define SN_HYPHENATOR               "com.sun.star.linguistic2.Hyphenator"
#define SN_THESAURUS                "com.sun.star.linguistic2.Thesaurus"
#define SN_LINGU_SERVCICE_MANAGER   "com.sun.star.linguistic2.LinguServiceManager"
#define SN_LINGU_PROPERTIES         "com.sun.star.linguistic2.LinguProperties"
#define SN_DICTIONARY_LIST          "com.sun.star.linguistic2.DictionaryList"
#define SN_OTHER_LINGU              "com.sun.star.linguistic2.OtherLingu"
#define SN_DESKTOP                  "com.sun.star.frame.Desktop"

namespace linguistic
{

// ascii to OUString conversion
#define A2OU(x) ::rtl::OUString::createFromAscii( x )

///////////////////////////////////////////////////////////////////////////

::osl::Mutex &  GetLinguMutex();

LocaleDataWrapper & GetLocaleDataWrapper( INT16 nLang );

///////////////////////////////////////////////////////////////////////////

rtl_TextEncoding GetTextEncoding( INT16 nLanguage );

inline ::rtl::OUString BS2OU(const ByteString &rText, rtl_TextEncoding nEnc)
{
    return ::rtl::OUString( rText.GetBuffer(), rText.Len(), nEnc );
}

inline ByteString OU2BS(const ::rtl::OUString &rText, rtl_TextEncoding nEnc)
{
    return ByteString( rText.getStr(), nEnc );
}

rtl::OUString StripTrailingChars( rtl::OUString &rTxt, sal_Unicode cChar );

///////////////////////////////////////////////////////////////////////////

sal_Int32 LevDistance( const rtl::OUString &rTxt1, const rtl::OUString &rTxt2 );

///////////////////////////////////////////////////////////////////////////

::com::sun::star::lang::Locale
    CreateLocale( LanguageType eLang );

LanguageType
     LocaleToLanguage( const ::com::sun::star::lang::Locale& rLocale );

::com::sun::star::lang::Locale&
    LanguageToLocale( ::com::sun::star::lang::Locale& rLocale, LanguageType eLang );

::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale >
    LangSeqToLocaleSeq( const ::com::sun::star::uno::Sequence< INT16 > &rLangSeq );

::com::sun::star::uno::Sequence< INT16 >
    LocaleSeqToLangSeq( ::com::sun::star::uno::Sequence<
        ::com::sun::star::lang::Locale > &rLocaleSeq );

///////////////////////////////////////////////////////////////////////////

// checks if file pointed to by rURL is readonly
// and may also check return if such a file exists or not
BOOL    IsReadOnly( const String &rURL, BOOL *pbExist = 0 );

// checks if a file with the given URL exists
BOOL    FileExists( const String &rURL );

// returns complete file URL for given filename that is to be searched in
// the specified path
String  GetFileURL( SvtPathOptions::Pathes ePath, const String &rFileName );

String  GetModulePath( SvtPathOptions::Pathes ePath, BOOL bAddAccessDelim = TRUE );

///////////////////////////////////////////////////////////////////////////

INT32       GetPosInWordToCheck( const rtl::OUString &rTxt, INT32 nPos );

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XHyphenatedWord >
            RebuildHyphensAndControlChars( const rtl::OUString &rOrigWord,
                ::com::sun::star::uno::Reference<
                    ::com::sun::star::linguistic2::XHyphenatedWord > &rxHyphWord );

///////////////////////////////////////////////////////////////////////////

BOOL        IsUpper( const String &rText, xub_StrLen nPos, xub_StrLen nLen, INT16 nLanguage );
BOOL        IsLower( const String &rText, xub_StrLen nPos, xub_StrLen nLen, INT16 nLanguage );

inline BOOL        IsUpper( const String &rText, INT16 nLanguage )     { return IsUpper( rText, 0, rText.Len(), nLanguage ); }
inline BOOL        IsLower( const String &rText, INT16 nLanguage )     { return IsLower( rText, 0, rText.Len(), nLanguage ); }

String      ToLower( const String &rText, INT16 nLanguage );
String      ToUpper( const String &rText, INT16 nLanguage );
String      ToTitle( const String &rText, INT16 nLanguage );
sal_Unicode ToLower( const sal_Unicode cChar, INT16 nLanguage );
sal_Unicode ToUpper( const sal_Unicode cChar, INT16 nLanguage );
BOOL        HasDigits( const String &rText );
BOOL        IsNumeric( const String &rText );

///////////////////////////////////////////////////////////////////////////

::com::sun::star::uno::Reference<
    ::com::sun::star::uno::XInterface >
        GetOneInstanceService( const char *pServiceName );

::com::sun::star::uno::Reference<
    ::com::sun::star::beans::XPropertySet >
        GetLinguProperties();

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XSearchableDictionaryList >
        GetSearchableDictionaryList();

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XDictionaryList >
        GetDictionaryList();

///////////////////////////////////////////////////////////////////////////

BOOL IsUseDicList( const ::com::sun::star::beans::PropertyValues &rProperties,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet > &rxPropSet );

BOOL IsIgnoreControlChars( const ::com::sun::star::beans::PropertyValues &rProperties,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet > &rxPropSet );

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XDictionaryEntry >
        SearchDicList(
            const ::com::sun::star::uno::Reference<
                ::com::sun::star::linguistic2::XDictionaryList >& rDicList,
            const ::rtl::OUString& rWord, INT16 nLanguage,
            BOOL bSearchPosDics, BOOL bSearchSpellEntry );

///////////////////////////////////////////////////////////////////////////
//
// AppExitLstnr:
// virtual base class that calls it AtExit function when the application
// (ie the Desktop) is about to terminate
//

class AppExitListener :
    public cppu::WeakImplHelper1
    <
        ::com::sun::star::frame::XTerminateListener
    >
{
    ::com::sun::star::uno::Reference<
        ::com::sun::star::frame::XDesktop >     xDesktop;

public:
    AppExitListener();
    virtual ~AppExitListener();

    virtual void    AtExit() = 0;

    void            Activate();
    void            Deactivate();

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

    // XTerminateListener
    virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
};

///////////////////////////////////////////////////////////////////////////

}   // namespace linguistic

#endif

<commit_msg>INTEGRATION: CWS internatiodel (1.9.12); FILE MERGED 2006/02/10 19:27:20 er 1.9.12.3: #i52115# move LangIDs and ISO conversion from tools to i18npool; introduce class MsLangId and libi18nisolang 2006/01/21 15:14:38 er 1.9.12.2: RESYNC: (1.9-1.10); FILE MERGED 2005/06/24 13:08:58 er 1.9.12.1: #i50205# get rid of class International<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: misc.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: vg $ $Date: 2006-04-07 13:45:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _LINGUISTIC_MISC_HXX_
#define _LINGUISTIC_MISC_HXX_

#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
#include <com/sun/star/uno/Sequence.h>
#endif
#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUES_HPP_
#include <com/sun/star/beans/PropertyValues.hpp>
#endif
#ifndef _COM_SUN_STAR_FRAME_XTERMINATELISTENER_HPP_
#include <com/sun/star/frame/XTerminateListener.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_LOCALE_HPP_
#include <com/sun/star/lang/Locale.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_LINGUISTIC2_XDICTIONARYENTRY_HPP_
#include <com/sun/star/linguistic2/XDictionaryEntry.hpp>
#endif
#ifndef _COM_SUN_STAR_LINGUISTIC2_XSEARCHABLEDICTIONARYLIST_HPP_
#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
#endif
#ifndef _COM_SUN_STAR_LINGUISTIC2_XHYPHENATEDWORD_HPP_
#include <com/sun/star/linguistic2/XHyphenatedWord.hpp>
#endif

#include <uno/lbnames.h>            // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type
#include <cppuhelper/implbase1.hxx> // helper for implementations

#ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX
#include <svtools/pathoptions.hxx>
#endif
#ifndef INCLUDED_I18NPOOL_LANG_H
#include <i18npool/lang.h>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _UNOTOOLS_CHARCLASS_HXX
#include <unotools/charclass.hxx>
#endif
#ifndef _OSL_THREAD_H_
#include <osl/thread.h>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

namespace com { namespace sun { namespace star { namespace beans {
    class XPropertySet;
    class XFastPropertySet;
}}}};

namespace com { namespace sun { namespace star { namespace frame {
    class XDesktop;
}}}};

class LocaleDataWrapper;

///////////////////////////////////////////////////////////////////////////

#define SN_SPELLCHECKER             "com.sun.star.linguistic2.SpellChecker"
#define SN_HYPHENATOR               "com.sun.star.linguistic2.Hyphenator"
#define SN_THESAURUS                "com.sun.star.linguistic2.Thesaurus"
#define SN_LINGU_SERVCICE_MANAGER   "com.sun.star.linguistic2.LinguServiceManager"
#define SN_LINGU_PROPERTIES         "com.sun.star.linguistic2.LinguProperties"
#define SN_DICTIONARY_LIST          "com.sun.star.linguistic2.DictionaryList"
#define SN_OTHER_LINGU              "com.sun.star.linguistic2.OtherLingu"
#define SN_DESKTOP                  "com.sun.star.frame.Desktop"

namespace linguistic
{

// ascii to OUString conversion
#define A2OU(x) ::rtl::OUString::createFromAscii( x )

///////////////////////////////////////////////////////////////////////////

::osl::Mutex &  GetLinguMutex();

LocaleDataWrapper & GetLocaleDataWrapper( INT16 nLang );

///////////////////////////////////////////////////////////////////////////

rtl_TextEncoding GetTextEncoding( INT16 nLanguage );

inline ::rtl::OUString BS2OU(const ByteString &rText, rtl_TextEncoding nEnc)
{
    return ::rtl::OUString( rText.GetBuffer(), rText.Len(), nEnc );
}

inline ByteString OU2BS(const ::rtl::OUString &rText, rtl_TextEncoding nEnc)
{
    return ByteString( rText.getStr(), nEnc );
}

rtl::OUString StripTrailingChars( rtl::OUString &rTxt, sal_Unicode cChar );

///////////////////////////////////////////////////////////////////////////

sal_Int32 LevDistance( const rtl::OUString &rTxt1, const rtl::OUString &rTxt2 );

///////////////////////////////////////////////////////////////////////////

::com::sun::star::lang::Locale
    CreateLocale( LanguageType eLang );

LanguageType
     LocaleToLanguage( const ::com::sun::star::lang::Locale& rLocale );

::com::sun::star::lang::Locale&
    LanguageToLocale( ::com::sun::star::lang::Locale& rLocale, LanguageType eLang );

::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale >
    LangSeqToLocaleSeq( const ::com::sun::star::uno::Sequence< INT16 > &rLangSeq );

::com::sun::star::uno::Sequence< INT16 >
    LocaleSeqToLangSeq( ::com::sun::star::uno::Sequence<
        ::com::sun::star::lang::Locale > &rLocaleSeq );

///////////////////////////////////////////////////////////////////////////

// checks if file pointed to by rURL is readonly
// and may also check return if such a file exists or not
BOOL    IsReadOnly( const String &rURL, BOOL *pbExist = 0 );

// checks if a file with the given URL exists
BOOL    FileExists( const String &rURL );

// returns complete file URL for given filename that is to be searched in
// the specified path
String  GetFileURL( SvtPathOptions::Pathes ePath, const String &rFileName );

String  GetModulePath( SvtPathOptions::Pathes ePath, BOOL bAddAccessDelim = TRUE );

///////////////////////////////////////////////////////////////////////////

INT32       GetPosInWordToCheck( const rtl::OUString &rTxt, INT32 nPos );

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XHyphenatedWord >
            RebuildHyphensAndControlChars( const rtl::OUString &rOrigWord,
                ::com::sun::star::uno::Reference<
                    ::com::sun::star::linguistic2::XHyphenatedWord > &rxHyphWord );

///////////////////////////////////////////////////////////////////////////

BOOL        IsUpper( const String &rText, xub_StrLen nPos, xub_StrLen nLen, INT16 nLanguage );
BOOL        IsLower( const String &rText, xub_StrLen nPos, xub_StrLen nLen, INT16 nLanguage );

inline BOOL        IsUpper( const String &rText, INT16 nLanguage )     { return IsUpper( rText, 0, rText.Len(), nLanguage ); }
inline BOOL        IsLower( const String &rText, INT16 nLanguage )     { return IsLower( rText, 0, rText.Len(), nLanguage ); }

String      ToLower( const String &rText, INT16 nLanguage );
String      ToUpper( const String &rText, INT16 nLanguage );
String      ToTitle( const String &rText, INT16 nLanguage );
sal_Unicode ToLower( const sal_Unicode cChar, INT16 nLanguage );
sal_Unicode ToUpper( const sal_Unicode cChar, INT16 nLanguage );
BOOL        HasDigits( const String &rText );
BOOL        IsNumeric( const String &rText );

///////////////////////////////////////////////////////////////////////////

::com::sun::star::uno::Reference<
    ::com::sun::star::uno::XInterface >
        GetOneInstanceService( const char *pServiceName );

::com::sun::star::uno::Reference<
    ::com::sun::star::beans::XPropertySet >
        GetLinguProperties();

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XSearchableDictionaryList >
        GetSearchableDictionaryList();

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XDictionaryList >
        GetDictionaryList();

///////////////////////////////////////////////////////////////////////////

BOOL IsUseDicList( const ::com::sun::star::beans::PropertyValues &rProperties,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet > &rxPropSet );

BOOL IsIgnoreControlChars( const ::com::sun::star::beans::PropertyValues &rProperties,
        const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertySet > &rxPropSet );

::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XDictionaryEntry >
        SearchDicList(
            const ::com::sun::star::uno::Reference<
                ::com::sun::star::linguistic2::XDictionaryList >& rDicList,
            const ::rtl::OUString& rWord, INT16 nLanguage,
            BOOL bSearchPosDics, BOOL bSearchSpellEntry );

///////////////////////////////////////////////////////////////////////////
//
// AppExitLstnr:
// virtual base class that calls it AtExit function when the application
// (ie the Desktop) is about to terminate
//

class AppExitListener :
    public cppu::WeakImplHelper1
    <
        ::com::sun::star::frame::XTerminateListener
    >
{
    ::com::sun::star::uno::Reference<
        ::com::sun::star::frame::XDesktop >     xDesktop;

public:
    AppExitListener();
    virtual ~AppExitListener();

    virtual void    AtExit() = 0;

    void            Activate();
    void            Deactivate();

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

    // XTerminateListener
    virtual void SAL_CALL queryTermination( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL notifyTermination( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException);
};

///////////////////////////////////////////////////////////////////////////

}   // namespace linguistic

#endif

<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
////////////////////////////////////////////////////////////////////////////////

#include "Rest/Version.h"

#ifdef _WIN32
#include "Basics/win-utils.h"
#endif

#include <sstream>

#include <curl/curl.h>
#include <openssl/ssl.h>

#include <rocksdb/convenience.h>
#include <rocksdb/version.h>

#include <velocypack/Builder.h>
#include <velocypack/Version.h>
#include <velocypack/velocypack-aliases.h>

#include "Basics/StringUtils.h"
#include "Basics/Utf8Helper.h"
#include "Basics/asio_ns.h"
#include "Basics/build-date.h"
#include "Basics/build-repository.h"
#include "Basics/conversions.h"

#include "3rdParty/iresearch/core/utils/version_defines.hpp"

using namespace arangodb::rest;

std::map<std::string, std::string> Version::Values;

/// @brief parse a version string into major, minor
/// returns -1, -1 when the version string has an invalid format
/// returns major, -1 when only the major version can be determined
std::pair<int, int> Version::parseVersionString(std::string const& str) {
  std::pair<int, int> result{-1, -1};

  if (!str.empty()) {
    char const* p = str.c_str();
    char const* q = p;
    while (*q >= '0' && *q <= '9') {
      ++q;
    }
    if (p != q) {
      result.first = std::stoi(std::string(p, q - p));
      result.second = 0;

      if (*q == '.') {
        ++q;
      }
      p = q;
      while (*q >= '0' && *q <= '9') {
        ++q;
      }
      if (p != q) {
        result.second = std::stoi(std::string(p, q - p));
      }
    }
  }

  return result;
}

/// @brief initialize
void Version::initialize() {
  if (!Values.empty()) {
    return;
  }

  Values["architecture"] =
      (sizeof(void*) == 4 ? "32" : "64") + std::string("bit");
#ifdef __arm__
  Values["arm"] = "true";
#else
  Values["arm"] = "false";
#endif
  Values["asm-crc32"] = (ENABLE_ASM_CRC32) ? "true" : "false";
  Values["boost-version"] = getBoostVersion();
  Values["build-date"] = getBuildDate();
  Values["compiler"] = getCompiler();
#ifdef _DEBUG
  Values["debug"] = "true";
#else
  Values["debug"] = "false";
#endif
#ifdef NDEBUG
  Values["ndebug"] = "true";
#else
  Values["ndebug"] = "false";
#endif
#if defined(ARCHITECTURE_OPTIMIZATIONS)
  Values["optimization-flags"] = std::string(ARCHITECTURE_OPTIMIZATIONS);
#endif
  Values["endianness"] = getEndianness();
  Values["fd-setsize"] = arangodb::basics::StringUtils::itoa(FD_SETSIZE);
  Values["full-version-string"] = getVerboseVersionString();
  Values["icu-version"] = getICUVersion();
  Values["openssl-version-compile-time"] = getOpenSSLVersion(true);
  Values["openssl-version-run-time"] = getOpenSSLVersion(false);
#ifdef __pie__
  Values["pie"] = std::to_string(__pie__);
#else
  Values["pie"] = "none";
#endif
  Values["platform"] = TRI_PLATFORM;
  Values["reactor-type"] = getBoostReactorType();
  Values["server-version"] = getServerVersion();
  Values["sizeof int"] = arangodb::basics::StringUtils::itoa(sizeof(int));
  Values["sizeof long"] = arangodb::basics::StringUtils::itoa(sizeof(long));
  Values["sizeof void*"] = arangodb::basics::StringUtils::itoa(sizeof(void*));
#ifdef TRI_UNALIGNED_ACCESS
  Values["unaligned-access"] = "true";
#else
  Values["unaligned-access"] = "false";
#endif
  Values["v8-version"] = getV8Version();
  Values["vpack-version"] = getVPackVersion();
  Values["zlib-version"] = getZLibVersion();

#if USE_ENTERPRISE
  Values["enterprise-version"] = ARANGODB_ENTERPRISE_VERSION;
  Values["license"] = "enterprise";
#else
  Values["license"] = "community";
#endif

#if HAVE_ARANGODB_BUILD_REPOSITORY
  Values["build-repository"] = getBuildRepository();
#endif

  Values["curl-version"] = curl_version();

#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
  Values["assertions"] = "true";
#else
  Values["assertions"] = "false";
#endif

  Values["rocksdb-version"] = getRocksDBVersion();

#ifdef __cplusplus
  Values["cplusplus"] = std::to_string(__cplusplus);
#else
  Values["cplusplus"] = "unknown";
#endif

#if defined(__SANITIZE_ADDRESS__) || \
    (defined(__has_feature) && __has_feature(address_sanitizer))
  Values["asan"] = "true";
#else
  Values["asan"] = "false";
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
  Values["asan"] = "true";
#endif
#endif
#endif

#if defined(__SSE4_2__) && !defined(NO_SSE42)
  Values["sse42"] = "true";
#else
  Values["sse42"] = "false";
#endif

#ifdef __AVX2__
  Values["avx2"] = "true";
#else
  Values["avx2"] = "false";
#endif

#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
  Values["maintainer-mode"] = "true";
#else
  Values["maintainer-mode"] = "false";
#endif

#ifdef ARANGODB_ENABLE_FAILURE_TESTS
  Values["failure-tests"] = "true";
#else
  Values["failure-tests"] = "false";
#endif

#ifdef ARANGODB_HAVE_JEMALLOC
  Values["jemalloc"] = "true";
#else
  Values["jemalloc"] = "false";
#endif

#ifdef TRI_HAVE_POLL_H
  Values["fd-client-event-handler"] = "poll";
#else
  Values["fd-client-event-handler"] = "select";
#endif

  Values["iresearch-version"] = getIResearchVersion();

  for (auto& it : Values) {
    arangodb::basics::StringUtils::trimInPlace(it.second);
  }
}

/// @brief get numeric server version
int32_t Version::getNumericServerVersion() {
  char const* apiVersion = ARANGODB_VERSION;
  char const* p = apiVersion;

  // read major version
  while (*p >= '0' && *p <= '9') {
    ++p;
  }

  TRI_ASSERT(*p == '.');
  int32_t major = TRI_Int32String(apiVersion, (p - apiVersion));

  apiVersion = ++p;

  // read minor version
  while (*p >= '0' && *p <= '9') {
    ++p;
  }

  TRI_ASSERT((*p == '.' || *p == '-' || *p == '\0') && p != apiVersion);
  int32_t minor = TRI_Int32String(apiVersion, (p - apiVersion));

  int32_t patch = 0;
  if (*p == '.') {
    apiVersion = ++p;

    // read minor version
    while (*p >= '0' && *p <= '9') {
      ++p;
    }

    if (p != apiVersion) {
      patch = TRI_Int32String(apiVersion, (p - apiVersion));
    }
  }

  return (int32_t)(patch + minor * 100L + major * 10000L);
}

/// @brief get server version
std::string Version::getServerVersion() {
  return std::string(ARANGODB_VERSION);
}

/// @brief get BOOST version
std::string Version::getBoostVersion() {
#ifdef ARANGODB_BOOST_VERSION
  return std::string(ARANGODB_BOOST_VERSION);
#else
  return std::string();
#endif
}

/// @brief get boost reactor type
std::string Version::getBoostReactorType() {
#if defined(BOOST_ASIO_HAS_IOCP)
  return std::string("iocp");
#elif defined(BOOST_ASIO_HAS_EPOLL)
  return std::string("epoll");
#elif defined(BOOST_ASIO_HAS_KQUEUE)
  return std::string("kqueue");
#elif defined(BOOST_ASIO_HAS_DEV_POLL)
  return std::string("/dev/poll");
#else
  return std::string("select");
#endif
}

/// @brief get RocksDB version
std::string Version::getRocksDBVersion() {
  return std::to_string(ROCKSDB_MAJOR) + "." + std::to_string(ROCKSDB_MINOR) +
         "." + std::to_string(ROCKSDB_PATCH);
}

/// @brief get V8 version
std::string Version::getV8Version() {
#ifdef ARANGODB_V8_VERSION
  return std::string(ARANGODB_V8_VERSION);
#else
  return std::string();
#endif
}

/// @brief get OpenSSL version
std::string Version::getOpenSSLVersion(bool compileTime) {
  if (compileTime) {
#ifdef OPENSSL_VERSION_TEXT
    return std::string(OPENSSL_VERSION_TEXT);
#elif defined(ARANGODB_OPENSSL_VERSION)
    return std::string(ARANGODB_OPENSSL_VERSION);
#else
    return std::string("openssl (unknown version)");
#endif
  } else {
    char const* v = SSLeay_version(SSLEAY_VERSION);

    if (v == nullptr) {
      return std::string("openssl (unknown version)");
    }

    return std::string(v);
  }
}

/// @brief get vpack version
std::string Version::getVPackVersion() {
  return arangodb::velocypack::Version::BuildVersion.toString();
}

/// @brief get zlib version
std::string Version::getZLibVersion() {
#ifdef ARANGODB_ZLIB_VERSION
  return std::string(ARANGODB_ZLIB_VERSION);
#else
  return std::string();
#endif
}

/// @brief get ICU version
std::string Version::getICUVersion() {
  UVersionInfo icuVersion;
  char icuVersionString[U_MAX_VERSION_STRING_LENGTH];
  u_getVersion(icuVersion);
  u_versionToString(icuVersion, icuVersionString);

  return icuVersionString;
}

/// @brief get IResearch version
std::string Version::getIResearchVersion() { return IResearch_version; }

/// @brief get compiler
std::string Version::getCompiler() {
#if defined(__clang__)
  return "clang [" + std::string(__VERSION__) + "]";
#elif defined(__GNUC__) || defined(__GNUG__)
  return "gcc [" + std::string(__VERSION__) + "]";
#elif defined(_MSC_VER)
  return "msvc [" + std::to_string(_MSC_VER) + "]";
#else
  return "unknown";
#endif
}

/// @brief get endianness
std::string Version::getEndianness() {
  uint64_t value = 0x12345678abcdef99;
  static_assert(sizeof(value) == 8, "unexpected uint64_t size");

  unsigned char const* p = reinterpret_cast<unsigned char const*>(&value);
  if (p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78 &&
      p[4] == 0xab && p[5] == 0xcd && p[6] == 0xef && p[7] == 0x99) {
    return "big";
  }

  if (p[0] == 0x99 && p[1] == 0xef && p[2] == 0xcd && p[3] == 0xab &&
      p[4] == 0x78 && p[5] == 0x56 && p[6] == 0x34 && p[7] == 0x12) {
    return "little";
  }
  return "unknown";
}

/// @brief get build date
std::string Version::getBuildDate() {
// the OpenSuSE build system does not like it, if __DATE__ is used
#ifdef ARANGODB_BUILD_DATE
  return std::string(ARANGODB_BUILD_DATE);
#else
  return std::string(__DATE__).append(" ").append(__TIME__);
#endif
}

/// @brief get build repository
std::string Version::getBuildRepository() {
#ifdef HAVE_ARANGODB_BUILD_REPOSITORY
  return std::string(ARANGODB_BUILD_REPOSITORY);
#else
  return std::string();
#endif
}

/// @brief return a server version string
std::string Version::getVerboseVersionString() {
  std::ostringstream version;

  version << "ArangoDB " << ARANGODB_VERSION_FULL << " "
          << (sizeof(void*) == 4 ? "32" : "64") << "bit"
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
          << " maintainer mode"
#endif
#if defined(__SANITIZE_ADDRESS__) || \
    (defined(__has_feature) && __has_feature(address_sanitizer))
          << " with ASAN"
#endif
          << ", using "
#ifdef ARANGODB_HAVE_JEMALLOC
          << "jemalloc, "
#endif
#ifdef HAVE_ARANGODB_BUILD_REPOSITORY
          << "build " << getBuildRepository() << ", "
#endif
          << "VPack " << getVPackVersion() << ", "
          << "RocksDB " << getRocksDBVersion() << ", "
          << "ICU " << getICUVersion() << ", "
          << "V8 " << getV8Version() << ", " << getOpenSSLVersion(false);

  return version.str();
}

/// @brief get detailed version information as a (multi-line) string
std::string Version::getDetailed() {
  std::string result;

  for (auto const& it : Values) {
    std::string const& value = it.second;

    if (!value.empty()) {
      result.append(it.first);
      result.append(": ");
      result.append(it.second);
#ifdef _WIN32
      result += "\r\n";
#else
      result += "\n";
#endif
    }
  }

  return result;
}

/// @brief VelocyPack all data
void Version::getVPack(VPackBuilder& dst) {
  TRI_ASSERT(!dst.isClosed());

  for (auto const& it : Values) {
    std::string const& value = it.second;

    if (!value.empty()) {
      dst.add(it.first, VPackValue(value));
    }
  }
}
<commit_msg>added pic<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
////////////////////////////////////////////////////////////////////////////////

#include "Rest/Version.h"

#ifdef _WIN32
#include "Basics/win-utils.h"
#endif

#include <sstream>

#include <curl/curl.h>
#include <openssl/ssl.h>

#include <rocksdb/convenience.h>
#include <rocksdb/version.h>

#include <velocypack/Builder.h>
#include <velocypack/Version.h>
#include <velocypack/velocypack-aliases.h>

#include "Basics/StringUtils.h"
#include "Basics/Utf8Helper.h"
#include "Basics/asio_ns.h"
#include "Basics/build-date.h"
#include "Basics/build-repository.h"
#include "Basics/conversions.h"

#include "3rdParty/iresearch/core/utils/version_defines.hpp"

using namespace arangodb::rest;

std::map<std::string, std::string> Version::Values;

/// @brief parse a version string into major, minor
/// returns -1, -1 when the version string has an invalid format
/// returns major, -1 when only the major version can be determined
std::pair<int, int> Version::parseVersionString(std::string const& str) {
  std::pair<int, int> result{-1, -1};

  if (!str.empty()) {
    char const* p = str.c_str();
    char const* q = p;
    while (*q >= '0' && *q <= '9') {
      ++q;
    }
    if (p != q) {
      result.first = std::stoi(std::string(p, q - p));
      result.second = 0;

      if (*q == '.') {
        ++q;
      }
      p = q;
      while (*q >= '0' && *q <= '9') {
        ++q;
      }
      if (p != q) {
        result.second = std::stoi(std::string(p, q - p));
      }
    }
  }

  return result;
}

/// @brief initialize
void Version::initialize() {
  if (!Values.empty()) {
    return;
  }

  Values["architecture"] =
      (sizeof(void*) == 4 ? "32" : "64") + std::string("bit");
#ifdef __arm__
  Values["arm"] = "true";
#else
  Values["arm"] = "false";
#endif
  Values["asm-crc32"] = (ENABLE_ASM_CRC32) ? "true" : "false";
  Values["boost-version"] = getBoostVersion();
  Values["build-date"] = getBuildDate();
  Values["compiler"] = getCompiler();
#ifdef _DEBUG
  Values["debug"] = "true";
#else
  Values["debug"] = "false";
#endif
#ifdef NDEBUG
  Values["ndebug"] = "true";
#else
  Values["ndebug"] = "false";
#endif
#if defined(ARCHITECTURE_OPTIMIZATIONS)
  Values["optimization-flags"] = std::string(ARCHITECTURE_OPTIMIZATIONS);
#endif
  Values["endianness"] = getEndianness();
  Values["fd-setsize"] = arangodb::basics::StringUtils::itoa(FD_SETSIZE);
  Values["full-version-string"] = getVerboseVersionString();
  Values["icu-version"] = getICUVersion();
  Values["openssl-version-compile-time"] = getOpenSSLVersion(true);
  Values["openssl-version-run-time"] = getOpenSSLVersion(false);
#ifdef __pic__
  Values["pic"] = std::to_string(__pic__);
#else
  Values["pic"] = "none";
#endif
#ifdef __pie__
  Values["pie"] = std::to_string(__pie__);
#else
  Values["pie"] = "none";
#endif
  Values["platform"] = TRI_PLATFORM;
  Values["reactor-type"] = getBoostReactorType();
  Values["server-version"] = getServerVersion();
  Values["sizeof int"] = arangodb::basics::StringUtils::itoa(sizeof(int));
  Values["sizeof long"] = arangodb::basics::StringUtils::itoa(sizeof(long));
  Values["sizeof void*"] = arangodb::basics::StringUtils::itoa(sizeof(void*));
#ifdef TRI_UNALIGNED_ACCESS
  Values["unaligned-access"] = "true";
#else
  Values["unaligned-access"] = "false";
#endif
  Values["v8-version"] = getV8Version();
  Values["vpack-version"] = getVPackVersion();
  Values["zlib-version"] = getZLibVersion();

#if USE_ENTERPRISE
  Values["enterprise-version"] = ARANGODB_ENTERPRISE_VERSION;
  Values["license"] = "enterprise";
#else
  Values["license"] = "community";
#endif

#if HAVE_ARANGODB_BUILD_REPOSITORY
  Values["build-repository"] = getBuildRepository();
#endif

  Values["curl-version"] = curl_version();

#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
  Values["assertions"] = "true";
#else
  Values["assertions"] = "false";
#endif

  Values["rocksdb-version"] = getRocksDBVersion();

#ifdef __cplusplus
  Values["cplusplus"] = std::to_string(__cplusplus);
#else
  Values["cplusplus"] = "unknown";
#endif

#if defined(__SANITIZE_ADDRESS__) || \
    (defined(__has_feature) && __has_feature(address_sanitizer))
  Values["asan"] = "true";
#else
  Values["asan"] = "false";
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
  Values["asan"] = "true";
#endif
#endif
#endif

#if defined(__SSE4_2__) && !defined(NO_SSE42)
  Values["sse42"] = "true";
#else
  Values["sse42"] = "false";
#endif

#ifdef __AVX2__
  Values["avx2"] = "true";
#else
  Values["avx2"] = "false";
#endif

#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
  Values["maintainer-mode"] = "true";
#else
  Values["maintainer-mode"] = "false";
#endif

#ifdef ARANGODB_ENABLE_FAILURE_TESTS
  Values["failure-tests"] = "true";
#else
  Values["failure-tests"] = "false";
#endif

#ifdef ARANGODB_HAVE_JEMALLOC
  Values["jemalloc"] = "true";
#else
  Values["jemalloc"] = "false";
#endif

#ifdef TRI_HAVE_POLL_H
  Values["fd-client-event-handler"] = "poll";
#else
  Values["fd-client-event-handler"] = "select";
#endif

  Values["iresearch-version"] = getIResearchVersion();

  for (auto& it : Values) {
    arangodb::basics::StringUtils::trimInPlace(it.second);
  }
}

/// @brief get numeric server version
int32_t Version::getNumericServerVersion() {
  char const* apiVersion = ARANGODB_VERSION;
  char const* p = apiVersion;

  // read major version
  while (*p >= '0' && *p <= '9') {
    ++p;
  }

  TRI_ASSERT(*p == '.');
  int32_t major = TRI_Int32String(apiVersion, (p - apiVersion));

  apiVersion = ++p;

  // read minor version
  while (*p >= '0' && *p <= '9') {
    ++p;
  }

  TRI_ASSERT((*p == '.' || *p == '-' || *p == '\0') && p != apiVersion);
  int32_t minor = TRI_Int32String(apiVersion, (p - apiVersion));

  int32_t patch = 0;
  if (*p == '.') {
    apiVersion = ++p;

    // read minor version
    while (*p >= '0' && *p <= '9') {
      ++p;
    }

    if (p != apiVersion) {
      patch = TRI_Int32String(apiVersion, (p - apiVersion));
    }
  }

  return (int32_t)(patch + minor * 100L + major * 10000L);
}

/// @brief get server version
std::string Version::getServerVersion() {
  return std::string(ARANGODB_VERSION);
}

/// @brief get BOOST version
std::string Version::getBoostVersion() {
#ifdef ARANGODB_BOOST_VERSION
  return std::string(ARANGODB_BOOST_VERSION);
#else
  return std::string();
#endif
}

/// @brief get boost reactor type
std::string Version::getBoostReactorType() {
#if defined(BOOST_ASIO_HAS_IOCP)
  return std::string("iocp");
#elif defined(BOOST_ASIO_HAS_EPOLL)
  return std::string("epoll");
#elif defined(BOOST_ASIO_HAS_KQUEUE)
  return std::string("kqueue");
#elif defined(BOOST_ASIO_HAS_DEV_POLL)
  return std::string("/dev/poll");
#else
  return std::string("select");
#endif
}

/// @brief get RocksDB version
std::string Version::getRocksDBVersion() {
  return std::to_string(ROCKSDB_MAJOR) + "." + std::to_string(ROCKSDB_MINOR) +
         "." + std::to_string(ROCKSDB_PATCH);
}

/// @brief get V8 version
std::string Version::getV8Version() {
#ifdef ARANGODB_V8_VERSION
  return std::string(ARANGODB_V8_VERSION);
#else
  return std::string();
#endif
}

/// @brief get OpenSSL version
std::string Version::getOpenSSLVersion(bool compileTime) {
  if (compileTime) {
#ifdef OPENSSL_VERSION_TEXT
    return std::string(OPENSSL_VERSION_TEXT);
#elif defined(ARANGODB_OPENSSL_VERSION)
    return std::string(ARANGODB_OPENSSL_VERSION);
#else
    return std::string("openssl (unknown version)");
#endif
  } else {
    char const* v = SSLeay_version(SSLEAY_VERSION);

    if (v == nullptr) {
      return std::string("openssl (unknown version)");
    }

    return std::string(v);
  }
}

/// @brief get vpack version
std::string Version::getVPackVersion() {
  return arangodb::velocypack::Version::BuildVersion.toString();
}

/// @brief get zlib version
std::string Version::getZLibVersion() {
#ifdef ARANGODB_ZLIB_VERSION
  return std::string(ARANGODB_ZLIB_VERSION);
#else
  return std::string();
#endif
}

/// @brief get ICU version
std::string Version::getICUVersion() {
  UVersionInfo icuVersion;
  char icuVersionString[U_MAX_VERSION_STRING_LENGTH];
  u_getVersion(icuVersion);
  u_versionToString(icuVersion, icuVersionString);

  return icuVersionString;
}

/// @brief get IResearch version
std::string Version::getIResearchVersion() { return IResearch_version; }

/// @brief get compiler
std::string Version::getCompiler() {
#if defined(__clang__)
  return "clang [" + std::string(__VERSION__) + "]";
#elif defined(__GNUC__) || defined(__GNUG__)
  return "gcc [" + std::string(__VERSION__) + "]";
#elif defined(_MSC_VER)
  return "msvc [" + std::to_string(_MSC_VER) + "]";
#else
  return "unknown";
#endif
}

/// @brief get endianness
std::string Version::getEndianness() {
  uint64_t value = 0x12345678abcdef99;
  static_assert(sizeof(value) == 8, "unexpected uint64_t size");

  unsigned char const* p = reinterpret_cast<unsigned char const*>(&value);
  if (p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78 &&
      p[4] == 0xab && p[5] == 0xcd && p[6] == 0xef && p[7] == 0x99) {
    return "big";
  }

  if (p[0] == 0x99 && p[1] == 0xef && p[2] == 0xcd && p[3] == 0xab &&
      p[4] == 0x78 && p[5] == 0x56 && p[6] == 0x34 && p[7] == 0x12) {
    return "little";
  }
  return "unknown";
}

/// @brief get build date
std::string Version::getBuildDate() {
// the OpenSuSE build system does not like it, if __DATE__ is used
#ifdef ARANGODB_BUILD_DATE
  return std::string(ARANGODB_BUILD_DATE);
#else
  return std::string(__DATE__).append(" ").append(__TIME__);
#endif
}

/// @brief get build repository
std::string Version::getBuildRepository() {
#ifdef HAVE_ARANGODB_BUILD_REPOSITORY
  return std::string(ARANGODB_BUILD_REPOSITORY);
#else
  return std::string();
#endif
}

/// @brief return a server version string
std::string Version::getVerboseVersionString() {
  std::ostringstream version;

  version << "ArangoDB " << ARANGODB_VERSION_FULL << " "
          << (sizeof(void*) == 4 ? "32" : "64") << "bit"
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
          << " maintainer mode"
#endif
#if defined(__SANITIZE_ADDRESS__) || \
    (defined(__has_feature) && __has_feature(address_sanitizer))
          << " with ASAN"
#endif
          << ", using "
#ifdef ARANGODB_HAVE_JEMALLOC
          << "jemalloc, "
#endif
#ifdef HAVE_ARANGODB_BUILD_REPOSITORY
          << "build " << getBuildRepository() << ", "
#endif
          << "VPack " << getVPackVersion() << ", "
          << "RocksDB " << getRocksDBVersion() << ", "
          << "ICU " << getICUVersion() << ", "
          << "V8 " << getV8Version() << ", " << getOpenSSLVersion(false);

  return version.str();
}

/// @brief get detailed version information as a (multi-line) string
std::string Version::getDetailed() {
  std::string result;

  for (auto const& it : Values) {
    std::string const& value = it.second;

    if (!value.empty()) {
      result.append(it.first);
      result.append(": ");
      result.append(it.second);
#ifdef _WIN32
      result += "\r\n";
#else
      result += "\n";
#endif
    }
  }

  return result;
}

/// @brief VelocyPack all data
void Version::getVPack(VPackBuilder& dst) {
  TRI_ASSERT(!dst.isClosed());

  for (auto const& it : Values) {
    std::string const& value = it.second;

    if (!value.empty()) {
      dst.add(it.first, VPackValue(value));
    }
  }
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <unistd.h>

int main()
{
    printf("hello world!\n");
    printf("show me the code\n");
    printf("Talk is cheap\n");
    sleep(100);
    // this is first branch.

    // this is the second line.
    return 0;
}

<commit_msg>delete talk is cheap<commit_after>#include <stdio.h>
#include <unistd.h>

int main()
{
    printf("hello world!\n");
    printf("show me the code\n");
    printf("##Tommy##\n");
    sleep(100);
    // this is first branch.

    // this is the second line.
    return 0;
}

<|endoftext|>


<commit_before>//===-- Value.cpp - Implement the Value class -----------------------------===//
//
// This file implements the Value and User classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/InstrTypes.h"
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "Support/LeakDetector.h"
#include <algorithm>

//===----------------------------------------------------------------------===//
//                                Value Class
//===----------------------------------------------------------------------===//

static inline const Type *checkType(const Type *Ty) {
  assert(Ty && "Value defined with a null type: Error!");
  return Ty;
}

Value::Value(const Type *ty, ValueTy vty, const std::string &name)
  : Name(name), Ty(checkType(ty), this) {
  VTy = vty;
}

Value::~Value() {
#ifndef NDEBUG      // Only in -g mode...
  // Check to make sure that there are no uses of this value that are still
  // around when the value is destroyed.  If there are, then we have a dangling
  // reference and something is wrong.  This code is here to print out what is
  // still being referenced.  The value in question should be printed as
  // a <badref>
  //
  if (Uses.begin() != Uses.end()) {
    std::cerr << "While deleting: " << Ty << "%" << Name << "\n";
    for (use_const_iterator I = Uses.begin(); I != Uses.end(); ++I)
      std::cerr << "Use still stuck around after Def is destroyed:"
                << **I << "\n";
  }
#endif
  assert(Uses.begin() == Uses.end());

  // There should be no uses of this object anymore, remove it.
  LeakDetector::removeGarbageObject(this);
}

void Value::replaceAllUsesWith(Value *D) {
  assert(D && "Value::replaceAllUsesWith(<null>) is invalid!");
  assert(D != this && "V->replaceAllUsesWith(V) is NOT valid!");
  assert(D->getType() == getType() &&
         "replaceAllUses of value with new value of different type!");
  while (!Uses.empty()) {
    User *Use = Uses.back();
#ifndef NDEBUG
    unsigned NumUses = Uses.size();
#endif
    Use->replaceUsesOfWith(this, D);

#ifndef NDEBUG      // only in -g mode...
    if (Uses.size() == NumUses)
      std::cerr << "Use: " << *Use << "replace with: " << *D;
#endif
    assert(Uses.size() != NumUses && "Didn't remove definition!");
  }
}

// refineAbstractType - This function is implemented because we use
// potentially abstract types, and these types may be resolved to more
// concrete types after we are constructed.  For the value class, we simply
// change Ty to point to the right type.  :)
//
void Value::refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
  assert(Ty.get() == OldTy && "Can't refine anything but my type!");
  if (OldTy == NewTy && !OldTy->isAbstract())
    Ty.removeUserFromConcrete();
  Ty = NewTy;
}

void Value::killUse(User *i) {
  if (i == 0) return;
  use_iterator I = find(Uses.begin(), Uses.end(), i);

  assert(I != Uses.end() && "Use not in uses list!!");
  Uses.erase(I);
}

User *Value::use_remove(use_iterator &I) {
  assert(I != Uses.end() && "Trying to remove the end of the use list!!!");
  User *i = *I;
  I = Uses.erase(I);
  return i;
}

//===----------------------------------------------------------------------===//
//                                 User Class
//===----------------------------------------------------------------------===//

User::User(const Type *Ty, ValueTy vty, const std::string &name)
  : Value(Ty, vty, name) {
}

// replaceUsesOfWith - Replaces all references to the "From" definition with
// references to the "To" definition.
//
void User::replaceUsesOfWith(Value *From, Value *To) {
  if (From == To) return;   // Duh what?

  for (unsigned i = 0, E = getNumOperands(); i != E; ++i)
    if (getOperand(i) == From) {  // Is This operand is pointing to oldval?
      // The side effects of this setOperand call include linking to
      // "To", adding "this" to the uses list of To, and
      // most importantly, removing "this" from the use list of "From".
      setOperand(i, To); // Fix it now...
    }
}

<commit_msg>Fix NASTY N^2 behavior that was causing the gzip benchmark to take forever to assemble.  Now we scan the use-list from the back when removing users instead of from the front.<commit_after>//===-- Value.cpp - Implement the Value class -----------------------------===//
//
// This file implements the Value and User classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/InstrTypes.h"
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "Support/LeakDetector.h"
#include <algorithm>

//===----------------------------------------------------------------------===//
//                                Value Class
//===----------------------------------------------------------------------===//

static inline const Type *checkType(const Type *Ty) {
  assert(Ty && "Value defined with a null type: Error!");
  return Ty;
}

Value::Value(const Type *ty, ValueTy vty, const std::string &name)
  : Name(name), Ty(checkType(ty), this) {
  VTy = vty;
}

Value::~Value() {
#ifndef NDEBUG      // Only in -g mode...
  // Check to make sure that there are no uses of this value that are still
  // around when the value is destroyed.  If there are, then we have a dangling
  // reference and something is wrong.  This code is here to print out what is
  // still being referenced.  The value in question should be printed as
  // a <badref>
  //
  if (Uses.begin() != Uses.end()) {
    std::cerr << "While deleting: " << Ty << "%" << Name << "\n";
    for (use_const_iterator I = Uses.begin(); I != Uses.end(); ++I)
      std::cerr << "Use still stuck around after Def is destroyed:"
                << **I << "\n";
  }
#endif
  assert(Uses.begin() == Uses.end());

  // There should be no uses of this object anymore, remove it.
  LeakDetector::removeGarbageObject(this);
}

void Value::replaceAllUsesWith(Value *D) {
  assert(D && "Value::replaceAllUsesWith(<null>) is invalid!");
  assert(D != this && "V->replaceAllUsesWith(V) is NOT valid!");
  assert(D->getType() == getType() &&
         "replaceAllUses of value with new value of different type!");
  while (!Uses.empty()) {
    User *Use = Uses.back();
#ifndef NDEBUG
    unsigned NumUses = Uses.size();
#endif
    Use->replaceUsesOfWith(this, D);

#ifndef NDEBUG      // only in -g mode...
    if (Uses.size() == NumUses)
      std::cerr << "Use: " << *Use << "replace with: " << *D;
#endif
    assert(Uses.size() != NumUses && "Didn't remove definition!");
  }
}

// refineAbstractType - This function is implemented because we use
// potentially abstract types, and these types may be resolved to more
// concrete types after we are constructed.  For the value class, we simply
// change Ty to point to the right type.  :)
//
void Value::refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
  assert(Ty.get() == OldTy && "Can't refine anything but my type!");
  if (OldTy == NewTy && !OldTy->isAbstract())
    Ty.removeUserFromConcrete();
  Ty = NewTy;
}

void Value::killUse(User *U) {
  if (U == 0) return;
  unsigned i;

  // Scan backwards through the uses list looking for the user.  We do this
  // because vectors like to be accessed on the end.  This is incredibly
  // important from a performance perspective.
  for (i = Uses.size()-1; Uses[i] != U; --i)
    /* empty */;

  assert(i < Uses.size() && "Use not in uses list!!");
  Uses.erase(Uses.begin()+i);
}

User *Value::use_remove(use_iterator &I) {
  assert(I != Uses.end() && "Trying to remove the end of the use list!!!");
  User *i = *I;
  I = Uses.erase(I);
  return i;
}

//===----------------------------------------------------------------------===//
//                                 User Class
//===----------------------------------------------------------------------===//

User::User(const Type *Ty, ValueTy vty, const std::string &name)
  : Value(Ty, vty, name) {
}

// replaceUsesOfWith - Replaces all references to the "From" definition with
// references to the "To" definition.
//
void User::replaceUsesOfWith(Value *From, Value *To) {
  if (From == To) return;   // Duh what?

  for (unsigned i = 0, E = getNumOperands(); i != E; ++i)
    if (getOperand(i) == From) {  // Is This operand is pointing to oldval?
      // The side effects of this setOperand call include linking to
      // "To", adding "this" to the uses list of To, and
      // most importantly, removing "this" from the use list of "From".
      setOperand(i, To); // Fix it now...
    }
}

<|endoftext|>


<commit_before>//===-- Value.cpp - Implement the Value class -----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Value and User classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/Constant.h"
#include "llvm/DerivedTypes.h"
#include "llvm/InstrTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/LeakDetector.h"
#include <algorithm>
using namespace llvm;

//===----------------------------------------------------------------------===//
//                                Value Class
//===----------------------------------------------------------------------===//

static inline const Type *checkType(const Type *Ty) {
  assert(Ty && "Value defined with a null type: Error!");
  return Ty;
}

Value::Value(const Type *ty, unsigned scid)
  : SubclassID(scid), SubclassData(0), Ty(checkType(ty)),
    UseList(0), Name(0) {
  if (isa<CallInst>(this) || isa<InvokeInst>(this))
    assert((Ty->isFirstClassType() || Ty == Type::VoidTy ||
            isa<OpaqueType>(ty) || Ty->getTypeID() == Type::StructTyID) &&
           "invalid CallInst  type!");
  else if (!isa<Constant>(this) && !isa<BasicBlock>(this))
    assert((Ty->isFirstClassType() || Ty == Type::VoidTy ||
           isa<OpaqueType>(ty)) &&
           "Cannot create non-first-class values except for constants!");
}

Value::~Value() {
#ifndef NDEBUG      // Only in -g mode...
  // Check to make sure that there are no uses of this value that are still
  // around when the value is destroyed.  If there are, then we have a dangling
  // reference and something is wrong.  This code is here to print out what is
  // still being referenced.  The value in question should be printed as
  // a <badref>
  //
  if (!use_empty()) {
    DOUT << "While deleting: " << *Ty << " %" << getNameStr() << "\n";
    for (use_iterator I = use_begin(), E = use_end(); I != E; ++I)
      DOUT << "Use still stuck around after Def is destroyed:"
           << **I << "\n";
  }
#endif
  assert(use_empty() && "Uses remain when a value is destroyed!");

  // If this value is named, destroy the name.  This should not be in a symtab
  // at this point.
  if (Name)
    Name->Destroy();

  // There should be no uses of this object anymore, remove it.
  LeakDetector::removeGarbageObject(this);
}

/// hasNUses - Return true if this Value has exactly N users.
///
bool Value::hasNUses(unsigned N) const {
  use_const_iterator UI = use_begin(), E = use_end();

  for (; N; --N, ++UI)
    if (UI == E) return false;  // Too few.
  return UI == E;
}

/// hasNUsesOrMore - Return true if this value has N users or more.  This is
/// logically equivalent to getNumUses() >= N.
///
bool Value::hasNUsesOrMore(unsigned N) const {
  use_const_iterator UI = use_begin(), E = use_end();

  for (; N; --N, ++UI)
    if (UI == E) return false;  // Too few.

  return true;
}

/// getNumUses - This method computes the number of uses of this Value.  This
/// is a linear time operation.  Use hasOneUse or hasNUses to check for specific
/// values.
unsigned Value::getNumUses() const {
  return (unsigned)std::distance(use_begin(), use_end());
}

static bool getSymTab(Value *V, ValueSymbolTable *&ST) {
  ST = 0;
  if (Instruction *I = dyn_cast<Instruction>(V)) {
    if (BasicBlock *P = I->getParent())
      if (Function *PP = P->getParent())
        ST = &PP->getValueSymbolTable();
  } else if (BasicBlock *BB = dyn_cast<BasicBlock>(V)) {
    if (Function *P = BB->getParent())
      ST = &P->getValueSymbolTable();
  } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
    if (Module *P = GV->getParent())
      ST = &P->getValueSymbolTable();
  } else if (Argument *A = dyn_cast<Argument>(V)) {
    if (Function *P = A->getParent())
      ST = &P->getValueSymbolTable();
  } else {
    assert(isa<Constant>(V) && "Unknown value type!");
    return true;  // no name is setable for this.
  }
  return false;
}

/// getNameStart - Return a pointer to a null terminated string for this name.
/// Note that names can have null characters within the string as well as at
/// their end.  This always returns a non-null pointer.
const char *Value::getNameStart() const {
  if (Name == 0) return "";
  return Name->getKeyData();
}

/// getNameLen - Return the length of the string, correctly handling nul
/// characters embedded into them.
unsigned Value::getNameLen() const {
  return Name ? Name->getKeyLength() : 0;
}

/// isName - Return true if this value has the name specified by the provided
/// nul terminated string.
bool Value::isName(const char *N) const {
  unsigned InLen = strlen(N);
  return InLen = getNameLen() && memcmp(getNameStart(), N, InLen) == 0;
}

std::string Value::getNameStr() const {
  if (Name == 0) return "";
  return std::string(Name->getKeyData(),
                     Name->getKeyData()+Name->getKeyLength());
}

void Value::setName(const std::string &name) {
  setName(&name[0], name.size());
}

void Value::setName(const char *Name) {
  setName(Name, Name ? strlen(Name) : 0);
}

void Value::setName(const char *NameStr, unsigned NameLen) {
  if (NameLen == 0 && !hasName()) return;
  assert(getType() != Type::VoidTy && "Cannot assign a name to void values!");

  // Get the symbol table to update for this object.
  ValueSymbolTable *ST;
  if (getSymTab(this, ST))
    return;  // Cannot set a name on this value (e.g. constant).

  if (!ST) { // No symbol table to update?  Just do the change.
    if (NameLen == 0) {
      // Free the name for this value.
      Name->Destroy();
      Name = 0;
      return;
    }

    if (Name) {
      // Name isn't changing?
      if (NameLen == Name->getKeyLength() &&
          !memcmp(Name->getKeyData(), NameStr, NameLen))
        return;
      Name->Destroy();
    }

    // NOTE: Could optimize for the case the name is shrinking to not deallocate
    // then reallocated.

    // Create the new name.
    Name = ValueName::Create(NameStr, NameStr+NameLen);
    Name->setValue(this);
    return;
  }

  // NOTE: Could optimize for the case the name is shrinking to not deallocate
  // then reallocated.
  if (hasName()) {
    // Name isn't changing?
    if (NameLen == Name->getKeyLength() &&
        !memcmp(Name->getKeyData(), NameStr, NameLen))
      return;

    // Remove old name.
    ST->removeValueName(Name);
    Name->Destroy();
    Name = 0;

    if (NameLen == 0)
      return;
  }

  // Name is changing to something new.
  Name = ST->createValueName(NameStr, NameLen, this);
}

/// takeName - transfer the name from V to this value, setting V's name to
/// empty.  It is an error to call V->takeName(V).
void Value::takeName(Value *V) {
  ValueSymbolTable *ST = 0;
  // If this value has a name, drop it.
  if (hasName()) {
    // Get the symtab this is in.
    if (getSymTab(this, ST)) {
      // We can't set a name on this value, but we need to clear V's name if
      // it has one.
      if (V->hasName()) V->setName(0, 0);
      return;  // Cannot set a name on this value (e.g. constant).
    }

    // Remove old name.
    if (ST)
      ST->removeValueName(Name);
    Name->Destroy();
    Name = 0;
  }

  // Now we know that this has no name.

  // If V has no name either, we're done.
  if (!V->hasName()) return;

  // Get this's symtab if we didn't before.
  if (!ST) {
    if (getSymTab(this, ST)) {
      // Clear V's name.
      V->setName(0, 0);
      return;  // Cannot set a name on this value (e.g. constant).
    }
  }

  // Get V's ST, this should always succed, because V has a name.
  ValueSymbolTable *VST;
  bool Failure = getSymTab(V, VST);
  assert(!Failure && "V has a name, so it should have a ST!");

  // If these values are both in the same symtab, we can do this very fast.
  // This works even if both values have no symtab yet.
  if (ST == VST) {
    // Take the name!
    Name = V->Name;
    V->Name = 0;
    Name->setValue(this);
    return;
  }

  // Otherwise, things are slightly more complex.  Remove V's name from VST and
  // then reinsert it into ST.

  if (VST)
    VST->removeValueName(V->Name);
  Name = V->Name;
  V->Name = 0;
  Name->setValue(this);

  if (ST)
    ST->reinsertValue(this);
}

// uncheckedReplaceAllUsesWith - This is exactly the same as replaceAllUsesWith,
// except that it doesn't have all of the asserts.  The asserts fail because we
// are half-way done resolving types, which causes some types to exist as two
// different Type*'s at the same time.  This is a sledgehammer to work around
// this problem.
//
void Value::uncheckedReplaceAllUsesWith(Value *New) {
  while (!use_empty()) {
    Use &U = *UseList;
    // Must handle Constants specially, we cannot call replaceUsesOfWith on a
    // constant because they are uniqued.
    if (Constant *C = dyn_cast<Constant>(U.getUser())) {
      if (!isa<GlobalValue>(C)) {
        C->replaceUsesOfWithOnConstant(this, New, &U);
        continue;
      }
    }

    U.set(New);
  }
}

void Value::replaceAllUsesWith(Value *New) {
  assert(New && "Value::replaceAllUsesWith(<null>) is invalid!");
  assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!");
  assert(New->getType() == getType() &&
         "replaceAllUses of value with new value of different type!");

  uncheckedReplaceAllUsesWith(New);
}

//===----------------------------------------------------------------------===//
//                                 User Class
//===----------------------------------------------------------------------===//

// replaceUsesOfWith - Replaces all references to the "From" definition with
// references to the "To" definition.
//
void User::replaceUsesOfWith(Value *From, Value *To) {
  if (From == To) return;   // Duh what?

  assert((!isa<Constant>(this) || isa<GlobalValue>(this)) &&
         "Cannot call User::replaceUsesofWith on a constant!");

  for (unsigned i = 0, E = getNumOperands(); i != E; ++i)
    if (getOperand(i) == From) {  // Is This operand is pointing to oldval?
      // The side effects of this setOperand call include linking to
      // "To", adding "this" to the uses list of To, and
      // most importantly, removing "this" from the use list of "From".
      setOperand(i, To); // Fix it now...
    }
}

<commit_msg>fix a bug in my previous patch, a classic =/== bug.<commit_after>//===-- Value.cpp - Implement the Value class -----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Value and User classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/Constant.h"
#include "llvm/DerivedTypes.h"
#include "llvm/InstrTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/LeakDetector.h"
#include <algorithm>
using namespace llvm;

//===----------------------------------------------------------------------===//
//                                Value Class
//===----------------------------------------------------------------------===//

static inline const Type *checkType(const Type *Ty) {
  assert(Ty && "Value defined with a null type: Error!");
  return Ty;
}

Value::Value(const Type *ty, unsigned scid)
  : SubclassID(scid), SubclassData(0), Ty(checkType(ty)),
    UseList(0), Name(0) {
  if (isa<CallInst>(this) || isa<InvokeInst>(this))
    assert((Ty->isFirstClassType() || Ty == Type::VoidTy ||
            isa<OpaqueType>(ty) || Ty->getTypeID() == Type::StructTyID) &&
           "invalid CallInst  type!");
  else if (!isa<Constant>(this) && !isa<BasicBlock>(this))
    assert((Ty->isFirstClassType() || Ty == Type::VoidTy ||
           isa<OpaqueType>(ty)) &&
           "Cannot create non-first-class values except for constants!");
}

Value::~Value() {
#ifndef NDEBUG      // Only in -g mode...
  // Check to make sure that there are no uses of this value that are still
  // around when the value is destroyed.  If there are, then we have a dangling
  // reference and something is wrong.  This code is here to print out what is
  // still being referenced.  The value in question should be printed as
  // a <badref>
  //
  if (!use_empty()) {
    DOUT << "While deleting: " << *Ty << " %" << getNameStr() << "\n";
    for (use_iterator I = use_begin(), E = use_end(); I != E; ++I)
      DOUT << "Use still stuck around after Def is destroyed:"
           << **I << "\n";
  }
#endif
  assert(use_empty() && "Uses remain when a value is destroyed!");

  // If this value is named, destroy the name.  This should not be in a symtab
  // at this point.
  if (Name)
    Name->Destroy();

  // There should be no uses of this object anymore, remove it.
  LeakDetector::removeGarbageObject(this);
}

/// hasNUses - Return true if this Value has exactly N users.
///
bool Value::hasNUses(unsigned N) const {
  use_const_iterator UI = use_begin(), E = use_end();

  for (; N; --N, ++UI)
    if (UI == E) return false;  // Too few.
  return UI == E;
}

/// hasNUsesOrMore - Return true if this value has N users or more.  This is
/// logically equivalent to getNumUses() >= N.
///
bool Value::hasNUsesOrMore(unsigned N) const {
  use_const_iterator UI = use_begin(), E = use_end();

  for (; N; --N, ++UI)
    if (UI == E) return false;  // Too few.

  return true;
}

/// getNumUses - This method computes the number of uses of this Value.  This
/// is a linear time operation.  Use hasOneUse or hasNUses to check for specific
/// values.
unsigned Value::getNumUses() const {
  return (unsigned)std::distance(use_begin(), use_end());
}

static bool getSymTab(Value *V, ValueSymbolTable *&ST) {
  ST = 0;
  if (Instruction *I = dyn_cast<Instruction>(V)) {
    if (BasicBlock *P = I->getParent())
      if (Function *PP = P->getParent())
        ST = &PP->getValueSymbolTable();
  } else if (BasicBlock *BB = dyn_cast<BasicBlock>(V)) {
    if (Function *P = BB->getParent())
      ST = &P->getValueSymbolTable();
  } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
    if (Module *P = GV->getParent())
      ST = &P->getValueSymbolTable();
  } else if (Argument *A = dyn_cast<Argument>(V)) {
    if (Function *P = A->getParent())
      ST = &P->getValueSymbolTable();
  } else {
    assert(isa<Constant>(V) && "Unknown value type!");
    return true;  // no name is setable for this.
  }
  return false;
}

/// getNameStart - Return a pointer to a null terminated string for this name.
/// Note that names can have null characters within the string as well as at
/// their end.  This always returns a non-null pointer.
const char *Value::getNameStart() const {
  if (Name == 0) return "";
  return Name->getKeyData();
}

/// getNameLen - Return the length of the string, correctly handling nul
/// characters embedded into them.
unsigned Value::getNameLen() const {
  return Name ? Name->getKeyLength() : 0;
}

/// isName - Return true if this value has the name specified by the provided
/// nul terminated string.
bool Value::isName(const char *N) const {
  unsigned InLen = strlen(N);
  return InLen == getNameLen() && memcmp(getNameStart(), N, InLen) == 0;
}

std::string Value::getNameStr() const {
  if (Name == 0) return "";
  return std::string(Name->getKeyData(),
                     Name->getKeyData()+Name->getKeyLength());
}

void Value::setName(const std::string &name) {
  setName(&name[0], name.size());
}

void Value::setName(const char *Name) {
  setName(Name, Name ? strlen(Name) : 0);
}

void Value::setName(const char *NameStr, unsigned NameLen) {
  if (NameLen == 0 && !hasName()) return;
  assert(getType() != Type::VoidTy && "Cannot assign a name to void values!");

  // Get the symbol table to update for this object.
  ValueSymbolTable *ST;
  if (getSymTab(this, ST))
    return;  // Cannot set a name on this value (e.g. constant).

  if (!ST) { // No symbol table to update?  Just do the change.
    if (NameLen == 0) {
      // Free the name for this value.
      Name->Destroy();
      Name = 0;
      return;
    }

    if (Name) {
      // Name isn't changing?
      if (NameLen == Name->getKeyLength() &&
          !memcmp(Name->getKeyData(), NameStr, NameLen))
        return;
      Name->Destroy();
    }

    // NOTE: Could optimize for the case the name is shrinking to not deallocate
    // then reallocated.

    // Create the new name.
    Name = ValueName::Create(NameStr, NameStr+NameLen);
    Name->setValue(this);
    return;
  }

  // NOTE: Could optimize for the case the name is shrinking to not deallocate
  // then reallocated.
  if (hasName()) {
    // Name isn't changing?
    if (NameLen == Name->getKeyLength() &&
        !memcmp(Name->getKeyData(), NameStr, NameLen))
      return;

    // Remove old name.
    ST->removeValueName(Name);
    Name->Destroy();
    Name = 0;

    if (NameLen == 0)
      return;
  }

  // Name is changing to something new.
  Name = ST->createValueName(NameStr, NameLen, this);
}

/// takeName - transfer the name from V to this value, setting V's name to
/// empty.  It is an error to call V->takeName(V).
void Value::takeName(Value *V) {
  ValueSymbolTable *ST = 0;
  // If this value has a name, drop it.
  if (hasName()) {
    // Get the symtab this is in.
    if (getSymTab(this, ST)) {
      // We can't set a name on this value, but we need to clear V's name if
      // it has one.
      if (V->hasName()) V->setName(0, 0);
      return;  // Cannot set a name on this value (e.g. constant).
    }

    // Remove old name.
    if (ST)
      ST->removeValueName(Name);
    Name->Destroy();
    Name = 0;
  }

  // Now we know that this has no name.

  // If V has no name either, we're done.
  if (!V->hasName()) return;

  // Get this's symtab if we didn't before.
  if (!ST) {
    if (getSymTab(this, ST)) {
      // Clear V's name.
      V->setName(0, 0);
      return;  // Cannot set a name on this value (e.g. constant).
    }
  }

  // Get V's ST, this should always succed, because V has a name.
  ValueSymbolTable *VST;
  bool Failure = getSymTab(V, VST);
  assert(!Failure && "V has a name, so it should have a ST!");

  // If these values are both in the same symtab, we can do this very fast.
  // This works even if both values have no symtab yet.
  if (ST == VST) {
    // Take the name!
    Name = V->Name;
    V->Name = 0;
    Name->setValue(this);
    return;
  }

  // Otherwise, things are slightly more complex.  Remove V's name from VST and
  // then reinsert it into ST.

  if (VST)
    VST->removeValueName(V->Name);
  Name = V->Name;
  V->Name = 0;
  Name->setValue(this);

  if (ST)
    ST->reinsertValue(this);
}

// uncheckedReplaceAllUsesWith - This is exactly the same as replaceAllUsesWith,
// except that it doesn't have all of the asserts.  The asserts fail because we
// are half-way done resolving types, which causes some types to exist as two
// different Type*'s at the same time.  This is a sledgehammer to work around
// this problem.
//
void Value::uncheckedReplaceAllUsesWith(Value *New) {
  while (!use_empty()) {
    Use &U = *UseList;
    // Must handle Constants specially, we cannot call replaceUsesOfWith on a
    // constant because they are uniqued.
    if (Constant *C = dyn_cast<Constant>(U.getUser())) {
      if (!isa<GlobalValue>(C)) {
        C->replaceUsesOfWithOnConstant(this, New, &U);
        continue;
      }
    }

    U.set(New);
  }
}

void Value::replaceAllUsesWith(Value *New) {
  assert(New && "Value::replaceAllUsesWith(<null>) is invalid!");
  assert(New != this && "this->replaceAllUsesWith(this) is NOT valid!");
  assert(New->getType() == getType() &&
         "replaceAllUses of value with new value of different type!");

  uncheckedReplaceAllUsesWith(New);
}

//===----------------------------------------------------------------------===//
//                                 User Class
//===----------------------------------------------------------------------===//

// replaceUsesOfWith - Replaces all references to the "From" definition with
// references to the "To" definition.
//
void User::replaceUsesOfWith(Value *From, Value *To) {
  if (From == To) return;   // Duh what?

  assert((!isa<Constant>(this) || isa<GlobalValue>(this)) &&
         "Cannot call User::replaceUsesofWith on a constant!");

  for (unsigned i = 0, E = getNumOperands(); i != E; ++i)
    if (getOperand(i) == From) {  // Is This operand is pointing to oldval?
      // The side effects of this setOperand call include linking to
      // "To", adding "this" to the uses list of To, and
      // most importantly, removing "this" from the use list of "From".
      setOperand(i, To); // Fix it now...
    }
}

<|endoftext|>