/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 * 
 *************************************************************/



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

#include "rtl/bootstrap.h"
#include "rtl/bootstrap.hxx"
#include <osl/diagnose.h>
#include <osl/module.h>
#include <osl/process.h>
#include <osl/file.hxx>
#include <osl/mutex.hxx>
#include <osl/profile.hxx>
#include <osl/security.hxx>
#include <rtl/alloc.h>
#include <rtl/string.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/ustring.hxx>
#include <rtl/byteseq.hxx>
#include <rtl/instance.hxx>
#include <rtl/malformeduriexception.hxx>
#include <rtl/uri.hxx>

#include "macro.hxx"

#include <hash_map>
#include <list>

#define MY_STRING_(x) # x
#define MY_STRING(x) MY_STRING_(x)

//----------------------------------------------------------------------------

using osl::DirectoryItem;
using osl::FileStatus;

using rtl::OString;
using rtl::OUString;
using rtl::OUStringToOString;

struct Bootstrap_Impl;

namespace {

static char const VND_SUN_STAR_PATHNAME[] = "vnd.sun.star.pathname:";

bool isPathnameUrl(rtl::OUString const & url) {
    return url.matchIgnoreAsciiCaseAsciiL(
        RTL_CONSTASCII_STRINGPARAM(VND_SUN_STAR_PATHNAME));
}

bool resolvePathnameUrl(rtl::OUString * url) {
    OSL_ASSERT(url !=  NULL);
    if (!isPathnameUrl(*url) ||
        (osl::FileBase::getFileURLFromSystemPath(
            url->copy(RTL_CONSTASCII_LENGTH(VND_SUN_STAR_PATHNAME)), *url) ==
         osl::FileBase::E_None))
    {
        return true;
    } else {
        *url = rtl::OUString();
        return false;
    }
}

enum LookupMode {
    LOOKUP_MODE_NORMAL, LOOKUP_MODE_URE_BOOTSTRAP,
    LOOKUP_MODE_URE_BOOTSTRAP_EXPANSION };

struct ExpandRequestLink {
    ExpandRequestLink const * next;
    Bootstrap_Impl const * file;
    rtl::OUString key;
};

rtl::OUString expandMacros(
    Bootstrap_Impl const * file, rtl::OUString const & text, LookupMode mode,
    ExpandRequestLink const * requestStack);

rtl::OUString recursivelyExpandMacros(
    Bootstrap_Impl const * file, rtl::OUString const & text, LookupMode mode,
    Bootstrap_Impl const * requestFile, rtl::OUString const & requestKey,
    ExpandRequestLink const * requestStack)
{
    for (; requestStack != NULL; requestStack = requestStack->next) {
        if (requestStack->file == requestFile &&
            requestStack->key == requestKey)
        {
            return rtl::OUString(
                RTL_CONSTASCII_USTRINGPARAM("***RECURSION DETECTED***"));
        }
    }
    ExpandRequestLink link = { requestStack, requestFile, requestKey };
    return expandMacros(file, text, mode, &link);
}

}

//----------------------------------------------------------------------------

struct rtl_bootstrap_NameValue
{
	OUString sName;
	OUString sValue;

    inline rtl_bootstrap_NameValue() SAL_THROW( () )
        {}
    inline rtl_bootstrap_NameValue(
        OUString const & name, OUString const & value ) SAL_THROW( () )
        : sName( name ),
          sValue( value )
        {}
};

typedef std::list<rtl_bootstrap_NameValue> NameValueList;

bool find(
    NameValueList const & list, rtl::OUString const & key,
    rtl::OUString * value)
{
    OSL_ASSERT(value != NULL);
    for (NameValueList::const_iterator i(list.begin()); i != list.end(); ++i) {
        if (i->sName == key) {
            *value = i->sValue;
            return true;
        }
    }
    return false;
}

namespace {
	struct rtl_bootstrap_set_list :
		public rtl::Static< NameValueList, rtl_bootstrap_set_list > {};
}

//----------------------------------------------------------------------------

static sal_Bool getFromCommandLineArgs(
	rtl::OUString const & key, rtl::OUString * value )
{
    OSL_ASSERT(value != NULL);
	static NameValueList *pNameValueList = 0;
	if( ! pNameValueList )
	{
		static NameValueList nameValueList;

		sal_Int32 nArgCount = osl_getCommandArgCount();
		for(sal_Int32 i = 0; i < nArgCount; ++ i)
		{
			rtl_uString *pArg = 0;
			osl_getCommandArg( i, &pArg );
			if( ('-' == pArg->buffer[0] || '/' == pArg->buffer[0] ) &&
				'e' == pArg->buffer[1] &&
				'n' == pArg->buffer[2] &&
				'v' == pArg->buffer[3] &&
				':' == pArg->buffer[4] )
			{
				sal_Int32 nIndex = rtl_ustr_indexOfChar( pArg->buffer, '=' );
				if( nIndex >= 0 )
				{

					rtl_bootstrap_NameValue nameValue;
					nameValue.sName = OUString( &(pArg->buffer[5]), nIndex - 5  );
					nameValue.sValue = OUString( &(pArg->buffer[nIndex+1]) );
					if( i == nArgCount-1 &&
						nameValue.sValue.getLength() &&
						nameValue.sValue[nameValue.sValue.getLength()-1] == 13 )
					{
						// avoid the 13 linefeed for the last argument,
						// when the executable is started from a script,
						// that was edited on windows
						nameValue.sValue = nameValue.sValue.copy(0,nameValue.sValue.getLength()-1);
					}
					nameValueList.push_back( nameValue );
				}
			}
			rtl_uString_release( pArg );
		}
		pNameValueList = &nameValueList;
	}

	sal_Bool found = sal_False;

	for( NameValueList::iterator ii = pNameValueList->begin() ;
		 ii != pNameValueList->end() ;
		 ++ii )
	{
		if( (*ii).sName.equals(key) )
		{
			*value = (*ii).sValue;
			found = sal_True;
			break;
		}
	}

	return found;
}

//----------------------------------------------------------------------------

extern "C" oslProcessError SAL_CALL osl_bootstrap_getExecutableFile_Impl (
	rtl_uString ** ppFileURL) SAL_THROW_EXTERN_C();

inline void getExecutableFile_Impl (rtl_uString ** ppFileURL)
{
    osl_bootstrap_getExecutableFile_Impl (ppFileURL);
}

//----------------------------------------------------------------------------

static void getExecutableDirectory_Impl (rtl_uString ** ppDirURL)
{
    OUString fileName;
    getExecutableFile_Impl (&(fileName.pData));

    sal_Int32 nDirEnd = fileName.lastIndexOf('/');
    OSL_ENSURE(nDirEnd >= 0, "Cannot locate executable directory");

    rtl_uString_newFromStr_WithLength(ppDirURL,fileName.getStr(),nDirEnd);
}

//----------------------------------------------------------------------------

static OUString & getIniFileName_Impl()
{
	static OUString *pStaticName = 0;
	if( ! pStaticName )
	{
		OUString fileName;

		if(getFromCommandLineArgs(
               OUString(RTL_CONSTASCII_USTRINGPARAM("INIFILENAME")), &fileName))
        {
            resolvePathnameUrl(&fileName);
        }
        else
		{
			getExecutableFile_Impl (&(fileName.pData));

			// get rid of a potential executable extension
			OUString progExt (RTL_CONSTASCII_USTRINGPARAM(".bin"));
			if(fileName.getLength() > progExt.getLength()
		    && fileName.copy(fileName.getLength() - progExt.getLength()).equalsIgnoreAsciiCase(progExt))
				fileName = fileName.copy(0, fileName.getLength() - progExt.getLength());

			progExt = OUString::createFromAscii(".exe");
			if(fileName.getLength() > progExt.getLength()
			&& fileName.copy(fileName.getLength() - progExt.getLength()).equalsIgnoreAsciiCase(progExt))
				fileName = fileName.copy(0, fileName.getLength() - progExt.getLength());

			// append config file suffix
			fileName += OUString(RTL_CONSTASCII_USTRINGPARAM(SAL_CONFIGFILE("")));
		}

		static OUString theFileName;
		if(fileName.getLength())
			theFileName = fileName;

		pStaticName = &theFileName;
	}

	return *pStaticName;
}

//----------------------------------------------------------------------------

static inline bool path_exists( OUString const & path )
{
    DirectoryItem dirItem;
    return (DirectoryItem::E_None == DirectoryItem::get( path, dirItem ));
}

//----------------------------------------------------------------------------
// #111772#
// ensure the given file url has no final slash

inline void EnsureNoFinalSlash (rtl::OUString & url)
{
    sal_Int32 i = url.getLength();
    if (i > 0 && url[i - 1] == '/') {
        url = url.copy(0, i - 1);
    }
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

struct Bootstrap_Impl
{
    sal_Int32 _nRefCount;
    Bootstrap_Impl * _base_ini;
    
	NameValueList _nameValueList;
	OUString      _iniName;
    
	explicit Bootstrap_Impl (OUString const & rIniName);
	~Bootstrap_Impl();
    
	static void * operator new (std::size_t n) SAL_THROW(())
        { return rtl_allocateMemory (sal_uInt32(n)); }
	static void operator delete (void * p , std::size_t) SAL_THROW(())
        { rtl_freeMemory (p); }
    
    bool getValue(
        rtl::OUString const & key, rtl_uString ** value,
        rtl_uString * defaultValue, LookupMode mode, bool override,
        ExpandRequestLink const * requestStack) const;
    bool getDirectValue(
        rtl::OUString const & key, rtl_uString ** value, LookupMode mode,
        ExpandRequestLink const * requestStack) const;
    bool getAmbienceValue(
        rtl::OUString const & key, rtl_uString ** value, LookupMode mode,
        ExpandRequestLink const * requestStack) const;
    void expandValue(
        rtl_uString ** value, rtl::OUString const & text, LookupMode mode,
        Bootstrap_Impl const * requestFile, rtl::OUString const & requestKey,
        ExpandRequestLink const * requestStack) const;
};

//----------------------------------------------------------------------------

Bootstrap_Impl::Bootstrap_Impl( OUString const & rIniName )
	: _nRefCount( 0 ),
      _base_ini( 0 ),
      _iniName (rIniName)
{
    OUString base_ini( getIniFileName_Impl() );
    // normalize path
    FileStatus status( FileStatusMask_FileURL );
    DirectoryItem dirItem;
    if (DirectoryItem::E_None == DirectoryItem::get( base_ini, dirItem ) &&
        DirectoryItem::E_None == dirItem.getFileStatus( status ))
    {
        base_ini = status.getFileURL();
        if (! rIniName.equals( base_ini ))
        {
            _base_ini = static_cast< Bootstrap_Impl * >(
                rtl_bootstrap_args_open( base_ini.pData ) );
        }
    }
    
#if OSL_DEBUG_LEVEL > 1    
	OString sFile = OUStringToOString(_iniName, RTL_TEXTENCODING_ASCII_US);
	OSL_TRACE(__FILE__" -- Bootstrap_Impl() - %s\n", sFile.getStr());
#endif /* OSL_DEBUG_LEVEL > 1 */

	oslFileHandle handle;
	if (_iniName.getLength() &&
        osl_File_E_None == osl_openFile(_iniName.pData, &handle, osl_File_OpenFlag_Read))
	{
		rtl::ByteSequence seq;

		while (osl_File_E_None == osl_readLine(handle , (sal_Sequence **)&seq))
		{
			OString line( (const sal_Char *) seq.getConstArray(), seq.getLength() );
			sal_Int32 nIndex = line.indexOf('=');
			if (nIndex >= 1)
			{
				struct rtl_bootstrap_NameValue nameValue;
				nameValue.sName = OStringToOUString(
                    line.copy(0,nIndex).trim(), RTL_TEXTENCODING_ASCII_US );
				nameValue.sValue = OStringToOUString(
                    line.copy(nIndex+1).trim(), RTL_TEXTENCODING_UTF8 );

#if OSL_DEBUG_LEVEL > 1
				OString name_tmp = OUStringToOString(nameValue.sName, RTL_TEXTENCODING_ASCII_US);
				OString value_tmp = OUStringToOString(nameValue.sValue, RTL_TEXTENCODING_UTF8);
				OSL_TRACE(
                    __FILE__" -- pushing: name=%s value=%s\n",
                    name_tmp.getStr(), value_tmp.getStr() );
#endif /* OSL_DEBUG_LEVEL > 1 */

				_nameValueList.push_back(nameValue);
			}
		}
		osl_closeFile(handle);
	}
#if OSL_DEBUG_LEVEL > 1
	else
	{
		OString file_tmp = OUStringToOString(_iniName, RTL_TEXTENCODING_ASCII_US);
		OSL_TRACE( __FILE__" -- couldn't open file: %s", file_tmp.getStr() );
	}
#endif /* OSL_DEBUG_LEVEL > 1 */
}

//----------------------------------------------------------------------------

Bootstrap_Impl::~Bootstrap_Impl()
{
    if (_base_ini != 0)
        rtl_bootstrap_args_close( _base_ini );
}

//----------------------------------------------------------------------------

namespace {

Bootstrap_Impl * get_static_bootstrap_handle() SAL_THROW(())
{
	osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );
    static Bootstrap_Impl * s_handle = 0;
    if (s_handle == 0)
    {
		OUString iniName (getIniFileName_Impl());
        s_handle = static_cast< Bootstrap_Impl * >(
            rtl_bootstrap_args_open( iniName.pData ) );
        if (s_handle == 0)
        {
            Bootstrap_Impl * that = new Bootstrap_Impl( iniName );
            ++that->_nRefCount;
            s_handle = that;
        }
    }
    return s_handle;
}

struct FundamentalIniData {
    rtlBootstrapHandle ini;

    FundamentalIniData() {
        OUString uri;
        ini =
            ((static_cast< Bootstrap_Impl * >(get_static_bootstrap_handle())->
              getValue(
                  rtl::OUString(
                      RTL_CONSTASCII_USTRINGPARAM("URE_BOOTSTRAP")),
                  &uri.pData, 0, LOOKUP_MODE_NORMAL, false, 0)) &&
             resolvePathnameUrl(&uri))
            ? rtl_bootstrap_args_open(uri.pData) : NULL;
    }

    ~FundamentalIniData() { rtl_bootstrap_args_close(ini); }

private:
    FundamentalIniData(FundamentalIniData &); // not defined
    void operator =(FundamentalIniData &); // not defined
};

struct FundamentalIni: public rtl::Static< FundamentalIniData, FundamentalIni >
{};

}

bool Bootstrap_Impl::getValue(
    rtl::OUString const & key, rtl_uString ** value, rtl_uString * defaultValue,
    LookupMode mode, bool override, ExpandRequestLink const * requestStack)
    const
{
    if (mode == LOOKUP_MODE_NORMAL &&
        key.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("URE_BOOTSTRAP")))
    {
        mode = LOOKUP_MODE_URE_BOOTSTRAP;
    }
    if (override && getDirectValue(key, value, mode, requestStack)) {
        return true;
    }
    if (key.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("_OS"))) {
        rtl_uString_assign(
            value, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(THIS_OS)).pData);
        return true;
    }
    if (key.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("_ARCH"))) {
        rtl_uString_assign(
            value, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(THIS_ARCH)).pData);
        return true;
    }
    if (key.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("_CPPU_ENV"))) {
        rtl_uString_assign(
            value,
            (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(MY_STRING(CPPU_ENV))).
             pData));
        return true;
    }
    if (key.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ORIGIN"))) {
        rtl_uString_assign(
            value,
            _iniName.copy(
                0, std::max<sal_Int32>(0, _iniName.lastIndexOf('/'))).pData);
        return true;
    }
    if (getAmbienceValue(key, value, mode, requestStack)) {
        return true;
    }
    if (key.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("SYSUSERCONFIG"))) {
        rtl::OUString v;
        bool b = osl::Security().getConfigDir(v);
        EnsureNoFinalSlash(v);
        rtl_uString_assign(value, v.pData);
        return b;
    }
    if (key.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("SYSUSERHOME"))) {
        rtl::OUString v;
        bool b = osl::Security().getHomeDir(v);
        EnsureNoFinalSlash(v);
        rtl_uString_assign(value, v.pData);
        return b;
    }
    if (key.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("SYSBINDIR"))) {
        getExecutableDirectory_Impl(value);
        return true;
    }
    if (_base_ini != NULL &&
        _base_ini->getDirectValue(key, value, mode, requestStack))
    {
        return true;
    }
    if (!override && getDirectValue(key, value, mode, requestStack)) {
        return true;
    }
    if (mode == LOOKUP_MODE_NORMAL) {
        FundamentalIniData const & d = FundamentalIni::get();
        Bootstrap_Impl const * b = static_cast<Bootstrap_Impl const *>(d.ini);
        if (b != NULL && b != this &&
            b->getDirectValue(key, value, mode, requestStack))
        {
            return true;
        }
    }
    if (defaultValue != NULL) {
        rtl_uString_assign(value, defaultValue);
        return true;
    }
    rtl_uString_new(value);
    return false;
}

bool Bootstrap_Impl::getDirectValue(
    rtl::OUString const & key, rtl_uString ** value, LookupMode mode,
    ExpandRequestLink const * requestStack) const
{
    rtl::OUString v;
    if (find(_nameValueList, key, &v)) {
        expandValue(value, v, mode, this, key, requestStack);
        return true;
    } else {
        return false;
    }
}

bool Bootstrap_Impl::getAmbienceValue(
    rtl::OUString const & key, rtl_uString ** value, LookupMode mode,
    ExpandRequestLink const * requestStack) const
{
    rtl::OUString v;
    bool f;
    {
        osl::MutexGuard g(osl::Mutex::getGlobalMutex());
        f = find(rtl_bootstrap_set_list::get(), key, &v);
    }
    if (f || getFromCommandLineArgs(key, &v) ||
        osl_getEnvironment(key.pData, &v.pData) == osl_Process_E_None)
    {
        expandValue(value, v, mode, NULL, key, requestStack);
        return true;
    } else {
        return false;
    }
}

void Bootstrap_Impl::expandValue(
    rtl_uString ** value, rtl::OUString const & text, LookupMode mode,
    Bootstrap_Impl const * requestFile, rtl::OUString const & requestKey,
    ExpandRequestLink const * requestStack) const
{
    rtl_uString_assign(
        value,
        (mode == LOOKUP_MODE_URE_BOOTSTRAP && isPathnameUrl(text) ?
         text :
         recursivelyExpandMacros(
             this, text,
             (mode == LOOKUP_MODE_URE_BOOTSTRAP ?
              LOOKUP_MODE_URE_BOOTSTRAP_EXPANSION : mode),
             requestFile, requestKey, requestStack)).pData);
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

namespace {

struct bootstrap_map {
    typedef std::hash_map< const rtl::OUString, Bootstrap_Impl*, rtl::OUStringHash > t;

    // get and release must only be called properly synchronized via some mutex
    // (e.g., osl::Mutex::getGlobalMutex()):

    static t * get() {
        if (m_map == NULL) {
            m_map = new t;
        }
        return m_map;
    }

    static void release() {
        if (m_map != NULL && m_map->empty()) {
            delete m_map;
            m_map = NULL;
        }
    }

private:
    bootstrap_map(); // not defined

    static t * m_map;
};

bootstrap_map::t * bootstrap_map::m_map = NULL;

}

//----------------------------------------------------------------------------

rtlBootstrapHandle SAL_CALL rtl_bootstrap_args_open (
	rtl_uString * pIniName
) SAL_THROW_EXTERN_C()
{
	OUString iniName( pIniName );

    // normalize path
    FileStatus status( FileStatusMask_FileURL );
    DirectoryItem dirItem;
    if (DirectoryItem::E_None != DirectoryItem::get( iniName, dirItem ) ||
        DirectoryItem::E_None != dirItem.getFileStatus( status ))
    {
        return 0;
    }
    iniName = status.getFileURL();
    
    Bootstrap_Impl * that;
    osl::ResettableMutexGuard guard( osl::Mutex::getGlobalMutex() );
    bootstrap_map::t* p_bootstrap_map = bootstrap_map::get();
    bootstrap_map::t::const_iterator iFind( p_bootstrap_map->find( iniName ) );
    if (iFind == p_bootstrap_map->end())
    {
        bootstrap_map::release();
        guard.clear();
        that = new Bootstrap_Impl( iniName );
        guard.reset();
        p_bootstrap_map = bootstrap_map::get();
        iFind = p_bootstrap_map->find( iniName );
        if (iFind == p_bootstrap_map->end())
        {
            ++that->_nRefCount;
            ::std::pair< bootstrap_map::t::iterator, bool > insertion(
                p_bootstrap_map->insert(
                    bootstrap_map::t::value_type( iniName, that ) ) );
            OSL_ASSERT( insertion.second );
        }
        else
        {
            Bootstrap_Impl * obsolete = that;
            that = iFind->second;
            ++that->_nRefCount;
            guard.clear();
            delete obsolete;
        }
    }
    else
    {
        that = iFind->second;
        ++that->_nRefCount;
    }
	return static_cast< rtlBootstrapHandle >( that );
}

//----------------------------------------------------------------------------

void SAL_CALL rtl_bootstrap_args_close (
	rtlBootstrapHandle handle
) SAL_THROW_EXTERN_C()
{
    if (handle == 0)
        return;
    Bootstrap_Impl * that = static_cast< Bootstrap_Impl * >( handle );
    
    osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );
    bootstrap_map::t* p_bootstrap_map = bootstrap_map::get();
    OSL_ASSERT(
        p_bootstrap_map->find( that->_iniName )->second == that );
    --that->_nRefCount;
    if (that->_nRefCount == 0)
    {
        ::std::size_t nLeaking = 8; // only hold up to 8 files statically

#if OSL_DEBUG_LEVEL == 1 // nonpro
        nLeaking = 0;
#elif OSL_DEBUG_LEVEL > 1 // debug
        nLeaking = 1;
#endif /* OSL_DEBUG_LEVEL */

        if (p_bootstrap_map->size() > nLeaking)
        {
            ::std::size_t erased = p_bootstrap_map->erase( that->_iniName );
            if (erased != 1) {
                OSL_ASSERT( false );
            }
            delete that;
        }
        bootstrap_map::release();
    }
}

//----------------------------------------------------------------------------

sal_Bool SAL_CALL rtl_bootstrap_get_from_handle(
    rtlBootstrapHandle handle,
	rtl_uString      * pName,
	rtl_uString     ** ppValue,
    rtl_uString      * pDefault
) SAL_THROW_EXTERN_C()
{
	osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );

	sal_Bool found = sal_False;
	if(ppValue && pName)
	{
		if (handle == 0)
            handle = get_static_bootstrap_handle();
        found = static_cast< Bootstrap_Impl * >( handle )->getValue(
            pName, ppValue, pDefault, LOOKUP_MODE_NORMAL, false, NULL );
	}

	return found;
}

//----------------------------------------------------------------------------

void SAL_CALL rtl_bootstrap_get_iniName_from_handle (
    rtlBootstrapHandle handle,
	rtl_uString     ** ppIniName
) SAL_THROW_EXTERN_C()
{
	if(ppIniName)
    {
		if(handle)
        {
			Bootstrap_Impl * pImpl = static_cast<Bootstrap_Impl*>(handle);
			rtl_uString_assign(ppIniName, pImpl->_iniName.pData);
        }
		else
        {
			const OUString & iniName = getIniFileName_Impl();       
			rtl_uString_assign(ppIniName, iniName.pData);
		}
    }
}

//----------------------------------------------------------------------------

void SAL_CALL rtl_bootstrap_setIniFileName (
	rtl_uString * pName
) SAL_THROW_EXTERN_C()
{
	osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );
	OUString & file = getIniFileName_Impl();
	file = pName;
}

//----------------------------------------------------------------------------

sal_Bool SAL_CALL rtl_bootstrap_get (
    rtl_uString  * pName,
	rtl_uString ** ppValue,
	rtl_uString  * pDefault
) SAL_THROW_EXTERN_C()
{
	return rtl_bootstrap_get_from_handle(0, pName, ppValue, pDefault);
}

//----------------------------------------------------------------------------

void SAL_CALL rtl_bootstrap_set (
	rtl_uString * pName,
	rtl_uString * pValue
) SAL_THROW_EXTERN_C()
{
    const OUString name( pName );
    const OUString value( pValue );

    osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );

    NameValueList& r_rtl_bootstrap_set_list = rtl_bootstrap_set_list::get();
    NameValueList::iterator iPos( r_rtl_bootstrap_set_list.begin() );
    NameValueList::iterator iEnd( r_rtl_bootstrap_set_list.end() );
    for ( ; iPos != iEnd; ++iPos )
    {
        if (iPos->sName.equals( name ))
        {
            iPos->sValue = value;
            return;
        }
    }

#if OSL_DEBUG_LEVEL > 1
    OString cstr_name( OUStringToOString( name, RTL_TEXTENCODING_ASCII_US ) );
    OString cstr_value( OUStringToOString( value, RTL_TEXTENCODING_ASCII_US ) );
    OSL_TRACE(
        "bootstrap.cxx: explicitly setting: name=%s value=%s\n",
        cstr_name.getStr(), cstr_value.getStr() );
#endif /* OSL_DEBUG_LEVEL > 1 */

    r_rtl_bootstrap_set_list.push_back( rtl_bootstrap_NameValue( name, value ) );
}

//----------------------------------------------------------------------------

void SAL_CALL rtl_bootstrap_expandMacros_from_handle (
    rtlBootstrapHandle handle,
	rtl_uString     ** macro
) SAL_THROW_EXTERN_C()
{
    if (handle == NULL) {
        handle = get_static_bootstrap_handle();
    }
    OUString expanded( expandMacros( static_cast< Bootstrap_Impl * >( handle ),
									 * reinterpret_cast< OUString const * >( macro ),
                                     LOOKUP_MODE_NORMAL, NULL ) );
    rtl_uString_assign( macro, expanded.pData );
}

//----------------------------------------------------------------------------

void SAL_CALL rtl_bootstrap_expandMacros(
    rtl_uString ** macro )
    SAL_THROW_EXTERN_C()
{
    rtl_bootstrap_expandMacros_from_handle(NULL, macro);
}

void rtl_bootstrap_encode( rtl_uString const * value, rtl_uString ** encoded )
    SAL_THROW_EXTERN_C()
{
    OSL_ASSERT(value != NULL);
    rtl::OUStringBuffer b;
    for (sal_Int32 i = 0; i < value->length; ++i) {
        sal_Unicode c = value->buffer[i];
        if (c == '$' || c == '\\') {
            b.append(sal_Unicode('\\'));
        }
        b.append(c);
    }
    rtl_uString_assign(encoded, b.makeStringAndClear().pData);
}

namespace {

int hex(sal_Unicode c) {
    return
        c >= '0' && c <= '9' ? c - '0' : 
        c >= 'A' && c <= 'F' ? c - 'A' + 10 :
        c >= 'a' && c <= 'f' ? c - 'a' + 10 : -1;
}

sal_Unicode read(rtl::OUString const & text, sal_Int32 * pos, bool * escaped) {
    OSL_ASSERT(
        pos != NULL && *pos >= 0 && *pos < text.getLength() && escaped != NULL);
    sal_Unicode c = text[(*pos)++];
    if (c == '\\') {
        int n1, n2, n3, n4;
        if (*pos < text.getLength() - 4 && text[*pos] == 'u' &&
            ((n1 = hex(text[*pos + 1])) >= 0) &&
            ((n2 = hex(text[*pos + 2])) >= 0) &&
            ((n3 = hex(text[*pos + 3])) >= 0) &&
            ((n4 = hex(text[*pos + 4])) >= 0))
        {
            *pos += 5;
            *escaped = true;
            return static_cast< sal_Unicode >(
                (n1 << 12) | (n2 << 8) | (n3 << 4) | n4);
        } else if (*pos < text.getLength()) {
            *escaped = true;
            return text[(*pos)++];
        }
    }
    *escaped = false;
    return c;
}

rtl::OUString lookup(
    Bootstrap_Impl const * file, LookupMode mode, bool override,
    rtl::OUString const & key, ExpandRequestLink const * requestStack)
{
    rtl::OUString v;
    (file == NULL ? get_static_bootstrap_handle() : file)->getValue(
        key, &v.pData, NULL, mode, override, requestStack);
    return v;
}

rtl::OUString expandMacros(
    Bootstrap_Impl const * file, rtl::OUString const & text, LookupMode mode,
    ExpandRequestLink const * requestStack)
{
    rtl::OUStringBuffer buf;
    for (sal_Int32 i = 0; i < text.getLength();) {
        bool escaped;
        sal_Unicode c = read(text, &i, &escaped);
        if (escaped || c != '$') {
            buf.append(c);
        } else {
            if (i < text.getLength() && text[i] == '{') {
                ++i;
                sal_Int32 p = i;
                sal_Int32 nesting = 0;
                rtl::OUString seg[3];
                int n = 0;
                while (i < text.getLength()) {
                    sal_Int32 j = i;
                    c = read(text, &i, &escaped);
                    if (!escaped) {
                        switch (c) {
                        case '{':
                            ++nesting;
                            break;
                        case '}':
                            if (nesting == 0) {
                                seg[n++] = text.copy(p, j - p);
                                goto done;
                            } else {
                                --nesting;
                            }
                            break;
                        case ':':
                            if (nesting == 0 && n < 2) {
                                seg[n++] = text.copy(p, j - p);
                                p = i;
                            }
                            break;
                        }
                    }
                }
            done:
                for (int j = 0; j < n; ++j) {
                    seg[j] = expandMacros(file, seg[j], mode, requestStack);
                }
                if (n == 3 && seg[1].getLength() == 0) {
                    // For backward compatibility, treat ${file::key} the same
                    // as just ${file:key}:
                    seg[1] = seg[2];
                    n = 2;
                }
                if (n == 1) {
                    buf.append(lookup(file, mode, false, seg[0], requestStack));
                } else if (n == 2) {
                    if (seg[0].equalsAsciiL(
                            RTL_CONSTASCII_STRINGPARAM(".link")))
                    {
                        osl::File f(seg[1]);
                        rtl::ByteSequence seq;
                        rtl::OUString line;
                        rtl::OUString url;
                        // Silently ignore any errors (is that good?):
                        if (f.open(OpenFlag_Read) == osl::FileBase::E_None &&
                            f.readLine(seq) == osl::FileBase::E_None &&
                            rtl_convertStringToUString(
                                &line.pData,
                                reinterpret_cast< char const * >(
                                    seq.getConstArray()),
                                seq.getLength(), RTL_TEXTENCODING_UTF8,
                                (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
                                 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
                                 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)) &&
                            (osl::File::getFileURLFromSystemPath(line, url) ==
                             osl::FileBase::E_None))
                        {
                            try {
                                buf.append(
                                    rtl::Uri::convertRelToAbs(seg[1], url));
                            } catch (rtl::MalformedUriException &) {}
                        }
                    } else {
                        buf.append(
                            lookup(
                                static_cast< Bootstrap_Impl * >(
                                    rtl::Bootstrap(seg[0]).getHandle()),
                                mode, false, seg[1], requestStack));
                    }
                } else if (seg[0].equalsAsciiL(
                               RTL_CONSTASCII_STRINGPARAM(".override")))
                {
                    rtl::Bootstrap b(seg[1]);
                    Bootstrap_Impl * f = static_cast< Bootstrap_Impl * >(
                        b.getHandle());
                    buf.append(
                        lookup(f, mode, f != NULL, seg[2], requestStack));
                } else {
                    // Going through osl::Profile, this code erroneously does
                    // not recursively expand macros in the resulting
                    // replacement text (and if it did, it would fail to detect
                    // cycles that pass through here):
                    buf.append(
                        rtl::OStringToOUString(
                            osl::Profile(seg[0]).readString(
                                rtl::OUStringToOString(
                                    seg[1], RTL_TEXTENCODING_UTF8),
                                rtl::OUStringToOString(
                                    seg[2], RTL_TEXTENCODING_UTF8),
                                rtl::OString()),
                            RTL_TEXTENCODING_UTF8));
                }
            } else {
                rtl::OUStringBuffer kbuf;
                for (; i < text.getLength();) {
                    sal_Int32 j = i;
                    c = read(text, &j, &escaped);
                    if (!escaped &&
                        (c == ' ' || c == '$' || c == '-' || c == '/' ||
                         c == ';' || c == '\\'))
                    {
                        break;
                    }
                    kbuf.append(c);
                    i = j;
                }
                buf.append(
                    lookup(
                        file, mode, false, kbuf.makeStringAndClear(),
                        requestStack));
            }
        }
    }
    return buf.makeStringAndClear();
}

}
