<commit_before>/*********************************************************************
 *
 * Condor ClassAd library
 * Copyright (C) 1990-2003, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI and Rajesh Raman.
 *
 * This source code is covered by the Condor Public License, which can
 * be found in the accompanying LICENSE file, or online at
 * www.condorproject.org.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
 * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
 * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
 * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
 * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
 * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
 * RIGHT.
 *
 *********************************************************************/

#include "common.h"
#include "util.h"

using namespace std;

BEGIN_NAMESPACE( classad )

#ifdef WIN32
#define BIGGEST_RANDOM_INT RAND_MAX
int get_random_integer(void)
{
    static char initialized = 0;

	if (!initialized) {
        int seed = time(NULL);
        srand(seed);
        initialized = 1;
	}

	return rand();
}
#else
#define BIGGEST_RANDOM_INT INT_MAX
int get_random_integer(void)
{
    static char initialized = 0;

	if (!initialized) {
        int seed = time(NULL);
        srand48(seed);
        initialized = 1;
	}
	return (int) (lrand48() & INT_MAX);
}
#endif

double get_random_real(void)
{
    return (get_random_integer() / (double) BIGGEST_RANDOM_INT);
}

long timezone_offset(void)
{
#ifdef __APPLE_CC__
    static long tz_offset = 0;
    static bool have_tz_offset = false;

    if (!have_tz_offset) {
        struct tm  *tms;
        time_t     clock;

        time(&clock);
        tms = localtime(&clock);
        tz_offset = -tms->tm_gmtoff;
        if (0 != tms->tm_isdst) {
            tz_offset += 3600;
        }
    }
    return tz_offset;
#else

    extern DLL_IMPORT_MAGIC long timezone;

    return timezone;
#endif
}

void convert_escapes(string &text, bool &validStr)
{
	char *copy;
	int  length;
	int  source, dest;

	// We now it will be no longer than the original.
	length = text.length();
	copy = new char[length + 1];

	// We scan up to one less than the length, because we ignore
	// a terminating slash: it can't be an escape.
	dest = 0;
	for (source = 0; source < length - 1; source++) {
		if (text[source] != '\\' || source == length - 1) {
			copy[dest++]= text[source];
		}
		else {
			source++;

			char new_char;
			switch(text[source]) {
			case 'a':	new_char = '\a'; break;
			case 'b':	new_char = '\b'; break;
			case 'f':	new_char = '\f'; break;
			case 'n':	new_char = '\n'; break;
			case 'r':	new_char = '\r'; break;
			case 't':	new_char = '\t'; break;
			case 'v':	new_char = '\v'; break;
			case '\\':	new_char = '\\'; break;
			case '\?':	new_char = '\?'; break;
			case '\'':	new_char = '\''; break;
			case '\"':	new_char = '\"'; break;
			default:
				if (isodigit(text[source])) {
					int  number;
					// There are three allowed ways to have octal escape characters:
					//  \[0..3]nn or \nn or \n. We check for them in that order.
					if (   source <= length - 3
						&& text[source] >= '0' && text[source] <= '3'
						&& isodigit(text[source+1])
						&& isodigit(text[source+2])) {

						// We have the \[0..3]nn case
						char octal[4];
						octal[0] = text[source];
						octal[1] = text[source+1];
						octal[2] = text[source+2];
						octal[3] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
						source += 2; // to account for the two extra digits
					} else if (   source <= length -2
							   && isodigit(text[source+1])) {

						// We have the \nn case
						char octal[3];
						octal[0] = text[source];
						octal[1] = text[source+1];
						octal[2] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
						source += 1; // to account for the extra digit
					} else if (source <= length - 1) {
						char octal[2];
						octal[0] = text[source];
						octal[1] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
					} else {
						new_char = text[source];
					}
					if(number == 0) { // "\\0" is an invalid substring within a string literal
					  validStr = false;
					  delete [] copy;
					  return;
					}
				} else {
					new_char = text[source];
				}
				break;
			}
			copy[dest++] = new_char;
		}
	}
	copy[dest] = 0;
	text = copy;
	delete [] copy;
	return;
}

void
getLocalTime(time_t *now, struct tm *localtm)
{

#ifndef WIN32
	localtime_r( now, localtm );
#else
	// there is no localtime_r() on Windows, so for now
	// we just call localtime() and deep copy the result.

	struct tm *lt_ptr;

	lt_ptr = localtime(now);

	if (localtm == NULL) { return; }

	localtm->tm_sec   = lt_ptr->tm_sec;    /* seconds */
	localtm->tm_min   = lt_ptr->tm_min;    /* minutes */
	localtm->tm_hour  = lt_ptr->tm_hour;   /* hours */
	localtm->tm_mday  = lt_ptr->tm_mday;   /* day of the month */
	localtm->tm_mon   = lt_ptr->tm_mon;    /* month */
	localtm->tm_year  = lt_ptr->tm_year;   /* year */
	localtm->tm_wday  = lt_ptr->tm_wday;   /* day of the week */
	localtm->tm_yday  = lt_ptr->tm_yday;   /* day in the year */
	localtm->tm_isdst = lt_ptr->tm_isdst;  /* daylight saving time */

#endif
	return;
}

void
getGMTime(time_t *now, struct tm *gtm)
{

#ifndef WIN32
	gmtime_r( now, gtm );
#else
	// there is no localtime_r() on Windows, so for now
	// we just call localtime() and deep copy the result.

	struct tm *gt_ptr;

	gt_ptr = gmtime(now);

	if (gtm == NULL) { return; }

	gtm->tm_sec   = gt_ptr->tm_sec;    /* seconds */
	gtm->tm_min   = gt_ptr->tm_min;    /* minutes */
	gtm->tm_hour  = gt_ptr->tm_hour;   /* hours */
	gtm->tm_mday  = gt_ptr->tm_mday;   /* day of the month */
	gtm->tm_mon   = gt_ptr->tm_mon;    /* month */
	gtm->tm_year  = gt_ptr->tm_year;   /* year */
	gtm->tm_wday  = gt_ptr->tm_wday;   /* day of the week */
	gtm->tm_yday  = gt_ptr->tm_yday;   /* day in the year */
	gtm->tm_isdst = gt_ptr->tm_isdst;  /* daylight saving time */

#endif
	return;
}

void absTimeToString(const abstime_t &atime, string &buffer)
{
    int       tzsecs;
    time_t    epoch_time;
    char      timebuf[32], sign;
    struct tm tms;

    tzsecs = atime.offset;
    epoch_time = atime.secs;
    if (tzsecs > 0) {
        sign = '+';         // timezone offset's sign
    } else {
        sign = '-';
        tzsecs = -tzsecs;
    }
    getGMTime(&epoch_time, &tms);
    strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S", &tms);
    buffer += timebuf;
    sprintf(timebuf, "%c%02d%02d", sign, tzsecs / 3600, (tzsecs / 60) % 60);
    buffer += timebuf;
    return;
}

void relTimeToString(double rsecs, string &buffer)
{
    double  fractional_seconds;
    int     days, hrs, mins;
    double  secs;
    char    timebuf[128];

    if( rsecs < 0 ) {
        buffer += "-";
        rsecs = -rsecs;
    }
    fractional_seconds = rsecs - floor(rsecs);

    days = (int) rsecs;
    hrs  = days % 86400;
    mins = hrs  % 3600;
    secs = (mins % 60) + fractional_seconds;
    days = days / 86400;
    hrs  = hrs  / 3600;
    mins = mins / 60;

    if (days) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%d+%02d:%02d:%02d", days, hrs, mins, (int) secs);
        } else {
            sprintf(timebuf, "%d+%02d:%02d:%02g", days, hrs, mins, secs);
        }
        buffer += timebuf;
    } else if (hrs) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d:%02d:%02d", hrs, mins, (int) secs);
        } else {
            sprintf(timebuf, "%02d:%02d:%02g", hrs, mins, secs);
        }
        buffer += timebuf;
    } else if (mins) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d:%02d", mins, (int) secs);
        } else {
            sprintf(timebuf, "%02d:%02g", mins, secs);
        }
        buffer += timebuf;
        return;
    } else {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d", (int) secs);
        } else {
            sprintf(timebuf, "%02g", secs);
        }
        buffer += timebuf;
    }
    return;
}

#ifdef WIN32
int classad_isinf(double x)
{

	int result;
	result = _fpclass(x);

	if (result == _FPCLASS_NINF ) {
		/* negative infinity */
		return -1;
	} else if ( result == _FPCLASS_PINF ) {
		/* positive infinity */
		return 1;
	} else {
		/* otherwise */
		return 0;
	}
}
#elif (defined (__SVR4) && defined (__sun)) || defined(__APPLE_CC__)
#ifndef __APPLE_CC__
#include <ieeefp.h>
#endif
int classad_isinf(double x)
{
    if (finite(x) || x != x) {
        return 0;
    } else if (x > 0) {
        return 1;
    } else {
        return -1;
    }
}
#else
int classad_isinf(double x)
{
    return isinf(x);
}
#endif

#ifdef  __APPLE_CC__
int classad_isnan(double x)
{
    return __isnan(x);
}
#else
int classad_isnan(double x)
{
    return isnan(x);
}
#endif

END_NAMESPACE // classad
<commit_msg>Fixed namespace problem when compiling with the ClassAd namespace.<commit_after>/*********************************************************************
 *
 * Condor ClassAd library
 * Copyright (C) 1990-2003, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI and Rajesh Raman.
 *
 * This source code is covered by the Condor Public License, which can
 * be found in the accompanying LICENSE file, or online at
 * www.condorproject.org.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
 * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
 * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
 * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
 * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
 * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
 * RIGHT.
 *
 *********************************************************************/

#include "common.h"
#include "util.h"

using namespace std;

BEGIN_NAMESPACE( classad )

#ifdef WIN32
#define BIGGEST_RANDOM_INT RAND_MAX
int get_random_integer(void)
{
    static char initialized = 0;

	if (!initialized) {
        int seed = time(NULL);
        srand(seed);
        initialized = 1;
	}

	return rand();
}
#else
#define BIGGEST_RANDOM_INT INT_MAX
int get_random_integer(void)
{
    static char initialized = 0;

	if (!initialized) {
        int seed = time(NULL);
        srand48(seed);
        initialized = 1;
	}
	return (int) (lrand48() & INT_MAX);
}
#endif

double get_random_real(void)
{
    return (get_random_integer() / (double) BIGGEST_RANDOM_INT);
}

long timezone_offset(void)
{
#ifdef __APPLE_CC__
    static long tz_offset = 0;
    static bool have_tz_offset = false;

    if (!have_tz_offset) {
        struct tm  *tms;
        time_t     clock;

        time(&clock);
        tms = localtime(&clock);
        tz_offset = -tms->tm_gmtoff;
        if (0 != tms->tm_isdst) {
            tz_offset += 3600;
        }
    }
    return tz_offset;
#else

    extern DLL_IMPORT_MAGIC long timezone;

    return ::timezone;
#endif
}

void convert_escapes(string &text, bool &validStr)
{
	char *copy;
	int  length;
	int  source, dest;

	// We now it will be no longer than the original.
	length = text.length();
	copy = new char[length + 1];

	// We scan up to one less than the length, because we ignore
	// a terminating slash: it can't be an escape.
	dest = 0;
	for (source = 0; source < length - 1; source++) {
		if (text[source] != '\\' || source == length - 1) {
			copy[dest++]= text[source];
		}
		else {
			source++;

			char new_char;
			switch(text[source]) {
			case 'a':	new_char = '\a'; break;
			case 'b':	new_char = '\b'; break;
			case 'f':	new_char = '\f'; break;
			case 'n':	new_char = '\n'; break;
			case 'r':	new_char = '\r'; break;
			case 't':	new_char = '\t'; break;
			case 'v':	new_char = '\v'; break;
			case '\\':	new_char = '\\'; break;
			case '\?':	new_char = '\?'; break;
			case '\'':	new_char = '\''; break;
			case '\"':	new_char = '\"'; break;
			default:
				if (isodigit(text[source])) {
					int  number;
					// There are three allowed ways to have octal escape characters:
					//  \[0..3]nn or \nn or \n. We check for them in that order.
					if (   source <= length - 3
						&& text[source] >= '0' && text[source] <= '3'
						&& isodigit(text[source+1])
						&& isodigit(text[source+2])) {

						// We have the \[0..3]nn case
						char octal[4];
						octal[0] = text[source];
						octal[1] = text[source+1];
						octal[2] = text[source+2];
						octal[3] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
						source += 2; // to account for the two extra digits
					} else if (   source <= length -2
							   && isodigit(text[source+1])) {

						// We have the \nn case
						char octal[3];
						octal[0] = text[source];
						octal[1] = text[source+1];
						octal[2] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
						source += 1; // to account for the extra digit
					} else if (source <= length - 1) {
						char octal[2];
						octal[0] = text[source];
						octal[1] = 0;
						sscanf(octal, "%o", &number);
						new_char = number;
					} else {
						new_char = text[source];
					}
					if(number == 0) { // "\\0" is an invalid substring within a string literal
					  validStr = false;
					  delete [] copy;
					  return;
					}
				} else {
					new_char = text[source];
				}
				break;
			}
			copy[dest++] = new_char;
		}
	}
	copy[dest] = 0;
	text = copy;
	delete [] copy;
	return;
}

void
getLocalTime(time_t *now, struct tm *localtm)
{

#ifndef WIN32
	localtime_r( now, localtm );
#else
	// there is no localtime_r() on Windows, so for now
	// we just call localtime() and deep copy the result.

	struct tm *lt_ptr;

	lt_ptr = localtime(now);

	if (localtm == NULL) { return; }

	localtm->tm_sec   = lt_ptr->tm_sec;    /* seconds */
	localtm->tm_min   = lt_ptr->tm_min;    /* minutes */
	localtm->tm_hour  = lt_ptr->tm_hour;   /* hours */
	localtm->tm_mday  = lt_ptr->tm_mday;   /* day of the month */
	localtm->tm_mon   = lt_ptr->tm_mon;    /* month */
	localtm->tm_year  = lt_ptr->tm_year;   /* year */
	localtm->tm_wday  = lt_ptr->tm_wday;   /* day of the week */
	localtm->tm_yday  = lt_ptr->tm_yday;   /* day in the year */
	localtm->tm_isdst = lt_ptr->tm_isdst;  /* daylight saving time */

#endif
	return;
}

void
getGMTime(time_t *now, struct tm *gtm)
{

#ifndef WIN32
	gmtime_r( now, gtm );
#else
	// there is no localtime_r() on Windows, so for now
	// we just call localtime() and deep copy the result.

	struct tm *gt_ptr;

	gt_ptr = gmtime(now);

	if (gtm == NULL) { return; }

	gtm->tm_sec   = gt_ptr->tm_sec;    /* seconds */
	gtm->tm_min   = gt_ptr->tm_min;    /* minutes */
	gtm->tm_hour  = gt_ptr->tm_hour;   /* hours */
	gtm->tm_mday  = gt_ptr->tm_mday;   /* day of the month */
	gtm->tm_mon   = gt_ptr->tm_mon;    /* month */
	gtm->tm_year  = gt_ptr->tm_year;   /* year */
	gtm->tm_wday  = gt_ptr->tm_wday;   /* day of the week */
	gtm->tm_yday  = gt_ptr->tm_yday;   /* day in the year */
	gtm->tm_isdst = gt_ptr->tm_isdst;  /* daylight saving time */

#endif
	return;
}

void absTimeToString(const abstime_t &atime, string &buffer)
{
    int       tzsecs;
    time_t    epoch_time;
    char      timebuf[32], sign;
    struct tm tms;

    tzsecs = atime.offset;
    epoch_time = atime.secs;
    if (tzsecs > 0) {
        sign = '+';         // timezone offset's sign
    } else {
        sign = '-';
        tzsecs = -tzsecs;
    }
    getGMTime(&epoch_time, &tms);
    strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S", &tms);
    buffer += timebuf;
    sprintf(timebuf, "%c%02d%02d", sign, tzsecs / 3600, (tzsecs / 60) % 60);
    buffer += timebuf;
    return;
}

void relTimeToString(double rsecs, string &buffer)
{
    double  fractional_seconds;
    int     days, hrs, mins;
    double  secs;
    char    timebuf[128];

    if( rsecs < 0 ) {
        buffer += "-";
        rsecs = -rsecs;
    }
    fractional_seconds = rsecs - floor(rsecs);

    days = (int) rsecs;
    hrs  = days % 86400;
    mins = hrs  % 3600;
    secs = (mins % 60) + fractional_seconds;
    days = days / 86400;
    hrs  = hrs  / 3600;
    mins = mins / 60;

    if (days) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%d+%02d:%02d:%02d", days, hrs, mins, (int) secs);
        } else {
            sprintf(timebuf, "%d+%02d:%02d:%02g", days, hrs, mins, secs);
        }
        buffer += timebuf;
    } else if (hrs) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d:%02d:%02d", hrs, mins, (int) secs);
        } else {
            sprintf(timebuf, "%02d:%02d:%02g", hrs, mins, secs);
        }
        buffer += timebuf;
    } else if (mins) {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d:%02d", mins, (int) secs);
        } else {
            sprintf(timebuf, "%02d:%02g", mins, secs);
        }
        buffer += timebuf;
        return;
    } else {
        if (fractional_seconds == 0) {
            sprintf(timebuf, "%02d", (int) secs);
        } else {
            sprintf(timebuf, "%02g", secs);
        }
        buffer += timebuf;
    }
    return;
}

#ifdef WIN32
int classad_isinf(double x)
{

	int result;
	result = _fpclass(x);

	if (result == _FPCLASS_NINF ) {
		/* negative infinity */
		return -1;
	} else if ( result == _FPCLASS_PINF ) {
		/* positive infinity */
		return 1;
	} else {
		/* otherwise */
		return 0;
	}
}
#elif (defined (__SVR4) && defined (__sun)) || defined(__APPLE_CC__)
#ifndef __APPLE_CC__
#include <ieeefp.h>
#endif
int classad_isinf(double x)
{
    if (finite(x) || x != x) {
        return 0;
    } else if (x > 0) {
        return 1;
    } else {
        return -1;
    }
}
#else
int classad_isinf(double x)
{
    return isinf(x);
}
#endif

#ifdef  __APPLE_CC__
int classad_isnan(double x)
{
    return __isnan(x);
}
#else
int classad_isnan(double x)
{
    return isnan(x);
}
#endif

END_NAMESPACE // classad
<|endoftext|>


<commit_before>//===-- HostInfoBase.cpp ----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Host/Config.h"

#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostInfoBase.h"

#include "llvm/ADT/Triple.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/raw_ostream.h"

#include <thread>
#include <mutex> // std::once

using namespace lldb;
using namespace lldb_private;

namespace
{
    void
    CleanupProcessSpecificLLDBTempDir()
    {
        // Get the process specific LLDB temporary directory and delete it.
        FileSpec tmpdir_file_spec;
        if (!HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
            return;

        // Remove the LLDB temporary directory if we have one. Set "recurse" to
        // true to all files that were created for the LLDB process can be cleaned up.
        FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), true);
    }

    //----------------------------------------------------------------------
    // The HostInfoBaseFields is a work around for windows not supporting
    // static variables correctly in a thread safe way. Really each of the
    // variables in HostInfoBaseFields should live in the functions in which
    // they are used and each one should be static, but the work around is
    // in place to avoid this restriction. Ick.
    //----------------------------------------------------------------------

    struct HostInfoBaseFields
    {
        uint32_t m_number_cpus;
        std::string m_vendor_string;
        std::string m_os_string;
        std::string m_host_triple;

        ArchSpec m_host_arch_32;
        ArchSpec m_host_arch_64;

        FileSpec m_lldb_so_dir;
        FileSpec m_lldb_support_exe_dir;
        FileSpec m_lldb_headers_dir;
        FileSpec m_lldb_python_dir;
        FileSpec m_lldb_clang_resource_dir;
        FileSpec m_lldb_system_plugin_dir;
        FileSpec m_lldb_user_plugin_dir;
        FileSpec m_lldb_tmp_dir;
    };

    HostInfoBaseFields *g_fields = nullptr;
}

void
HostInfoBase::Initialize()
{
    g_fields = new HostInfoBaseFields();
}

uint32_t
HostInfoBase::GetNumberCPUS()
{
    static std::once_flag g_once_flag;
    std::call_once(g_once_flag,  []() {
        g_fields->m_number_cpus = std::thread::hardware_concurrency();
    });
    return g_fields->m_number_cpus;
}

uint32_t
HostInfoBase::GetMaxThreadNameLength()
{
    return 0;
}

llvm::StringRef
HostInfoBase::GetVendorString()
{
    static std::once_flag g_once_flag;
    std::call_once(g_once_flag,  []() {
        g_fields->m_vendor_string = std::move(HostInfo::GetArchitecture().GetTriple().getVendorName().str());
    });
    return g_fields->m_vendor_string;
}

llvm::StringRef
HostInfoBase::GetOSString()
{
    static std::once_flag g_once_flag;
    std::call_once(g_once_flag,  []() {
        g_fields->m_os_string = std::move(HostInfo::GetArchitecture().GetTriple().getOSName());
    });
    return g_fields->m_os_string;
}

llvm::StringRef
HostInfoBase::GetTargetTriple()
{
    static std::once_flag g_once_flag;
    std::call_once(g_once_flag,  []() {
        g_fields->m_host_triple = HostInfo::GetArchitecture().GetTriple().getTriple();
    });
    return g_fields->m_host_triple;
}

const ArchSpec &
HostInfoBase::GetArchitecture(ArchitectureKind arch_kind)
{
    static std::once_flag g_once_flag;
    std::call_once(g_once_flag,  []() {
        HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32, g_fields->m_host_arch_64);
    });

    // If an explicit 32 or 64-bit architecture was requested, return that.
    if (arch_kind == eArchKind32)
        return g_fields->m_host_arch_32;
    if (arch_kind == eArchKind64)
        return g_fields->m_host_arch_64;

    // Otherwise prefer the 64-bit architecture if it is valid.
    return (g_fields->m_host_arch_64.IsValid()) ? g_fields->m_host_arch_64 : g_fields->m_host_arch_32;
}

bool
HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec)
{
    file_spec.Clear();

#if defined(LLDB_DISABLE_PYTHON)
    if (type == lldb::ePathTypePythonDir)
        return false;
#endif

    FileSpec *result = nullptr;
    switch (type)
    {
        case lldb::ePathTypeLLDBShlibDir:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeSharedLibraryDirectory (g_fields->m_lldb_so_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_fields->m_lldb_so_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_so_dir;
            }
            break;
        case lldb::ePathTypeSupportExecutableDir:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeSupportExeDirectory (g_fields->m_lldb_support_exe_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'",
                                    g_fields->m_lldb_support_exe_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_support_exe_dir;
            }
            break;
        case lldb::ePathTypeHeaderDir:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeHeaderDirectory (g_fields->m_lldb_headers_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_fields->m_lldb_headers_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_headers_dir;
            }
            break;
        case lldb::ePathTypePythonDir:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputePythonDirectory (g_fields->m_lldb_python_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", g_fields->m_lldb_python_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_python_dir;
            }
            break;
        case lldb::ePathTypeClangDir:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeClangDirectory (g_fields->m_lldb_clang_resource_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeClangResourceDir) => '%s'", g_fields->m_lldb_clang_resource_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_clang_resource_dir;
            }
            break;
        case lldb::ePathTypeLLDBSystemPlugins:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeSystemPluginsDirectory (g_fields->m_lldb_system_plugin_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'",
                                    g_fields->m_lldb_system_plugin_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_system_plugin_dir;
            }
            break;
        case lldb::ePathTypeLLDBUserPlugins:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeUserPluginsDirectory (g_fields->m_lldb_user_plugin_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'",
                                    g_fields->m_lldb_user_plugin_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_user_plugin_dir;
            }
            break;
        case lldb::ePathTypeLLDBTempSystemDir:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeTempFileDirectory (g_fields->m_lldb_tmp_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_fields->m_lldb_tmp_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_tmp_dir;
            }
            break;
    }

    if (!result)
        return false;
    file_spec = *result;
    return true;
}

bool
HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec)
{
    // To get paths related to LLDB we get the path to the executable that
    // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
    // on linux this is assumed to be the "lldb" main executable. If LLDB on
    // linux is actually in a shared library (liblldb.so) then this function will
    // need to be modified to "do the right thing".

    FileSpec lldb_file_spec(
        Host::GetModuleFileSpecForHostAddress(reinterpret_cast<void *>(reinterpret_cast<intptr_t>(HostInfoBase::GetLLDBPath))));

    // Remove the filename so that this FileSpec only represents the directory.
    file_spec.GetDirectory() = lldb_file_spec.GetDirectory();

    return (bool)file_spec.GetDirectory();
}

bool
HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec)
{
    return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec);
}

bool
HostInfoBase::ComputeTempFileDirectory(FileSpec &file_spec)
{
    const char *tmpdir_cstr = getenv("TMPDIR");
    if (tmpdir_cstr == NULL)
    {
        tmpdir_cstr = getenv("TMP");
        if (tmpdir_cstr == NULL)
            tmpdir_cstr = getenv("TEMP");
    }
    if (!tmpdir_cstr)
        return false;

    FileSpec temp_file_spec(tmpdir_cstr, false);
    temp_file_spec.AppendPathComponent("lldb");
    if (!FileSystem::MakeDirectory(temp_file_spec.GetPath().c_str(), eFilePermissionsDirectoryDefault).Success())
        return false;

    std::string pid_str;
    llvm::raw_string_ostream pid_stream(pid_str);
    pid_stream << Host::GetCurrentProcessID();
    temp_file_spec.AppendPathComponent(pid_stream.str().c_str());
    std::string final_path = temp_file_spec.GetPath();
    if (!FileSystem::MakeDirectory(final_path.c_str(), eFilePermissionsDirectoryDefault).Success())
        return false;

    // Make an atexit handler to clean up the process specify LLDB temp dir
    // and all of its contents.
    ::atexit(CleanupProcessSpecificLLDBTempDir);
    file_spec.GetDirectory().SetCStringWithLength(final_path.c_str(), final_path.size());
    return true;
}

bool
HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec)
{
    // TODO(zturner): Figure out how to compute the header directory for all platforms.
    return false;
}

bool
HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec)
{
    // TODO(zturner): Figure out how to compute the system plugins directory for all platforms.
    return false;
}

bool
HostInfoBase::ComputeClangDirectory(FileSpec &file_spec)
{
    return false;
}

bool
HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec)
{
    // TODO(zturner): Figure out how to compute the user plugins directory for all platforms.
    return false;
}

void
HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64)
{
    llvm::Triple triple(llvm::sys::getDefaultTargetTriple());

    arch_32.Clear();
    arch_64.Clear();

    switch (triple.getArch())
    {
        default:
            arch_32.SetTriple(triple);
            break;

        case llvm::Triple::ppc64:
        case llvm::Triple::x86_64:
            arch_64.SetTriple(triple);
            arch_32.SetTriple(triple.get32BitArchVariant());
            break;

        case llvm::Triple::aarch64:
        case llvm::Triple::mips64:
        case llvm::Triple::sparcv9:
            arch_64.SetTriple(triple);
            break;
    }
}
<commit_msg>Use getProcessTriple inside HostInfoBase::ComputeHostArchitectureSupport instead of getDefaultTargetTriple.<commit_after>//===-- HostInfoBase.cpp ----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Host/Config.h"

#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostInfoBase.h"

#include "llvm/ADT/Triple.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/raw_ostream.h"

#include <thread>
#include <mutex> // std::once

using namespace lldb;
using namespace lldb_private;

namespace
{
    void
    CleanupProcessSpecificLLDBTempDir()
    {
        // Get the process specific LLDB temporary directory and delete it.
        FileSpec tmpdir_file_spec;
        if (!HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
            return;

        // Remove the LLDB temporary directory if we have one. Set "recurse" to
        // true to all files that were created for the LLDB process can be cleaned up.
        FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), true);
    }

    //----------------------------------------------------------------------
    // The HostInfoBaseFields is a work around for windows not supporting
    // static variables correctly in a thread safe way. Really each of the
    // variables in HostInfoBaseFields should live in the functions in which
    // they are used and each one should be static, but the work around is
    // in place to avoid this restriction. Ick.
    //----------------------------------------------------------------------

    struct HostInfoBaseFields
    {
        uint32_t m_number_cpus;
        std::string m_vendor_string;
        std::string m_os_string;
        std::string m_host_triple;

        ArchSpec m_host_arch_32;
        ArchSpec m_host_arch_64;

        FileSpec m_lldb_so_dir;
        FileSpec m_lldb_support_exe_dir;
        FileSpec m_lldb_headers_dir;
        FileSpec m_lldb_python_dir;
        FileSpec m_lldb_clang_resource_dir;
        FileSpec m_lldb_system_plugin_dir;
        FileSpec m_lldb_user_plugin_dir;
        FileSpec m_lldb_tmp_dir;
    };

    HostInfoBaseFields *g_fields = nullptr;
}

void
HostInfoBase::Initialize()
{
    g_fields = new HostInfoBaseFields();
}

uint32_t
HostInfoBase::GetNumberCPUS()
{
    static std::once_flag g_once_flag;
    std::call_once(g_once_flag,  []() {
        g_fields->m_number_cpus = std::thread::hardware_concurrency();
    });
    return g_fields->m_number_cpus;
}

uint32_t
HostInfoBase::GetMaxThreadNameLength()
{
    return 0;
}

llvm::StringRef
HostInfoBase::GetVendorString()
{
    static std::once_flag g_once_flag;
    std::call_once(g_once_flag,  []() {
        g_fields->m_vendor_string = std::move(HostInfo::GetArchitecture().GetTriple().getVendorName().str());
    });
    return g_fields->m_vendor_string;
}

llvm::StringRef
HostInfoBase::GetOSString()
{
    static std::once_flag g_once_flag;
    std::call_once(g_once_flag,  []() {
        g_fields->m_os_string = std::move(HostInfo::GetArchitecture().GetTriple().getOSName());
    });
    return g_fields->m_os_string;
}

llvm::StringRef
HostInfoBase::GetTargetTriple()
{
    static std::once_flag g_once_flag;
    std::call_once(g_once_flag,  []() {
        g_fields->m_host_triple = HostInfo::GetArchitecture().GetTriple().getTriple();
    });
    return g_fields->m_host_triple;
}

const ArchSpec &
HostInfoBase::GetArchitecture(ArchitectureKind arch_kind)
{
    static std::once_flag g_once_flag;
    std::call_once(g_once_flag,  []() {
        HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32, g_fields->m_host_arch_64);
    });

    // If an explicit 32 or 64-bit architecture was requested, return that.
    if (arch_kind == eArchKind32)
        return g_fields->m_host_arch_32;
    if (arch_kind == eArchKind64)
        return g_fields->m_host_arch_64;

    // Otherwise prefer the 64-bit architecture if it is valid.
    return (g_fields->m_host_arch_64.IsValid()) ? g_fields->m_host_arch_64 : g_fields->m_host_arch_32;
}

bool
HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec)
{
    file_spec.Clear();

#if defined(LLDB_DISABLE_PYTHON)
    if (type == lldb::ePathTypePythonDir)
        return false;
#endif

    FileSpec *result = nullptr;
    switch (type)
    {
        case lldb::ePathTypeLLDBShlibDir:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeSharedLibraryDirectory (g_fields->m_lldb_so_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_fields->m_lldb_so_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_so_dir;
            }
            break;
        case lldb::ePathTypeSupportExecutableDir:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeSupportExeDirectory (g_fields->m_lldb_support_exe_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'",
                                    g_fields->m_lldb_support_exe_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_support_exe_dir;
            }
            break;
        case lldb::ePathTypeHeaderDir:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeHeaderDirectory (g_fields->m_lldb_headers_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_fields->m_lldb_headers_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_headers_dir;
            }
            break;
        case lldb::ePathTypePythonDir:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputePythonDirectory (g_fields->m_lldb_python_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", g_fields->m_lldb_python_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_python_dir;
            }
            break;
        case lldb::ePathTypeClangDir:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeClangDirectory (g_fields->m_lldb_clang_resource_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeClangResourceDir) => '%s'", g_fields->m_lldb_clang_resource_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_clang_resource_dir;
            }
            break;
        case lldb::ePathTypeLLDBSystemPlugins:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeSystemPluginsDirectory (g_fields->m_lldb_system_plugin_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'",
                                    g_fields->m_lldb_system_plugin_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_system_plugin_dir;
            }
            break;
        case lldb::ePathTypeLLDBUserPlugins:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeUserPluginsDirectory (g_fields->m_lldb_user_plugin_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'",
                                    g_fields->m_lldb_user_plugin_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_user_plugin_dir;
            }
            break;
        case lldb::ePathTypeLLDBTempSystemDir:
            {
                static std::once_flag g_once_flag;
                static bool success = false;
                std::call_once(g_once_flag,  []() {
                    success = HostInfo::ComputeTempFileDirectory (g_fields->m_lldb_tmp_dir);
                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                    if (log)
                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_fields->m_lldb_tmp_dir.GetPath().c_str());
                });
                if (success)
                    result = &g_fields->m_lldb_tmp_dir;
            }
            break;
    }

    if (!result)
        return false;
    file_spec = *result;
    return true;
}

bool
HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec)
{
    // To get paths related to LLDB we get the path to the executable that
    // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
    // on linux this is assumed to be the "lldb" main executable. If LLDB on
    // linux is actually in a shared library (liblldb.so) then this function will
    // need to be modified to "do the right thing".

    FileSpec lldb_file_spec(
        Host::GetModuleFileSpecForHostAddress(reinterpret_cast<void *>(reinterpret_cast<intptr_t>(HostInfoBase::GetLLDBPath))));

    // Remove the filename so that this FileSpec only represents the directory.
    file_spec.GetDirectory() = lldb_file_spec.GetDirectory();

    return (bool)file_spec.GetDirectory();
}

bool
HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec)
{
    return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec);
}

bool
HostInfoBase::ComputeTempFileDirectory(FileSpec &file_spec)
{
    const char *tmpdir_cstr = getenv("TMPDIR");
    if (tmpdir_cstr == NULL)
    {
        tmpdir_cstr = getenv("TMP");
        if (tmpdir_cstr == NULL)
            tmpdir_cstr = getenv("TEMP");
    }
    if (!tmpdir_cstr)
        return false;

    FileSpec temp_file_spec(tmpdir_cstr, false);
    temp_file_spec.AppendPathComponent("lldb");
    if (!FileSystem::MakeDirectory(temp_file_spec.GetPath().c_str(), eFilePermissionsDirectoryDefault).Success())
        return false;

    std::string pid_str;
    llvm::raw_string_ostream pid_stream(pid_str);
    pid_stream << Host::GetCurrentProcessID();
    temp_file_spec.AppendPathComponent(pid_stream.str().c_str());
    std::string final_path = temp_file_spec.GetPath();
    if (!FileSystem::MakeDirectory(final_path.c_str(), eFilePermissionsDirectoryDefault).Success())
        return false;

    // Make an atexit handler to clean up the process specify LLDB temp dir
    // and all of its contents.
    ::atexit(CleanupProcessSpecificLLDBTempDir);
    file_spec.GetDirectory().SetCStringWithLength(final_path.c_str(), final_path.size());
    return true;
}

bool
HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec)
{
    // TODO(zturner): Figure out how to compute the header directory for all platforms.
    return false;
}

bool
HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec)
{
    // TODO(zturner): Figure out how to compute the system plugins directory for all platforms.
    return false;
}

bool
HostInfoBase::ComputeClangDirectory(FileSpec &file_spec)
{
    return false;
}

bool
HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec)
{
    // TODO(zturner): Figure out how to compute the user plugins directory for all platforms.
    return false;
}

void
HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64)
{
    llvm::Triple triple(llvm::sys::getProcessTriple());

    arch_32.Clear();
    arch_64.Clear();

    switch (triple.getArch())
    {
        default:
            arch_32.SetTriple(triple);
            break;

        case llvm::Triple::ppc64:
        case llvm::Triple::x86_64:
            arch_64.SetTriple(triple);
            arch_32.SetTriple(triple.get32BitArchVariant());
            break;

        case llvm::Triple::aarch64:
        case llvm::Triple::mips64:
        case llvm::Triple::sparcv9:
            arch_64.SetTriple(triple);
            break;
    }
}
<|endoftext|>


<commit_before>// $Id: solventParameter.C,v 1.3 2000/10/17 17:20:45 anker Exp $

#include <BALL/SOLVATION/solventParameter.h>

using namespace std;

namespace BALL
{

	SolventParameter::SolventParameter() throw()
		: ParameterSection(),
			name_(),
			number_density_(0.0),
			solvent_atoms_(),
			solvent_descriptor_()
	{
	}

	SolventParameter::SolventParameter(const SolventParameter& param) throw()
		: ParameterSection(param),
			name_(param.name_),
			number_density_(param.number_density_),
			solvent_atoms_(param.solvent_atoms_),
			solvent_descriptor_(param.solvent_descriptor_)
	{
	}

	SolventParameter::~SolventParameter() throw()
	{
		clear();

		valid_ = false;
	}

	void SolventParameter::clear() throw()
	{
		ParameterSection::clear();
		name_ = "";
		number_density_ = 0.0;
		solvent_descriptor_.clear();
		solvent_atoms_.clear();
	}

	const SolventParameter& SolventParameter::operator =
		(const SolventParameter& param) throw()
	{
		ParameterSection::operator = (param);
		name_ = param.name_;
		number_density_ = param.number_density_;
		solvent_atoms_ = param.solvent_atoms_;
		solvent_descriptor_ = param.solvent_descriptor_;

		return *this;
	}

	bool SolventParameter::operator == (const SolventParameter& param) const
		throw()
	{
		// BAUSTELLE
		return ((ParameterSection::operator == (param))
			&& (name_ == param.name_)
			&& (number_density_ == param.number_density_));
			// && (solvent_atoms_ == param.solvent_atoms_)
			// && (solvent_descriptor_ == param.solvent_descriptor_));
	}

	SolventDescriptor SolventParameter::getSolventDescriptor() const throw()
	{
		return solvent_descriptor_;
	}

	bool SolventParameter::extractSection(ForceFieldParameters& parameters,
			const String& section_name) throw()
	{
		// BAUSTELLE
		if (!parameters.isValid())
		{
			return false;
		}

		// extract the basis information
		ParameterSection::extractSection(parameters, section_name);

		// check whether all variables we need are defined, terminate otherwi
		if (!hasVariable("radius") || !hasVariable("number_of_atoms") || !hasVariable("element_symbol"))
		{
			Log.error() << "SolventParameter::extractSection(): Variable missing."
				<< endl;
			return false;
		}
		else
		{
			if (options.has("name"))
			{
				name_ = options.get("name");
			}
			else
			{
				Log.warn() << "SolventParameter::extractSection(): no name given."
					<< endl;
			}
			if (options.has("number_density"))
			{
				number_density_ = options.getReal("number_density");
			}
			else
			{
				Log.warn() << "SolventParameter::extractSection(): "
					<< "no number density given." << endl;
			}

			AtomTypes& atom_types = parameters.getAtomTypes();

			Size number_of_keys = getNumberOfKeys();
			solvent_atoms_.resize(number_of_keys);

			Size index_element_symbol = getColumnIndex("element_symbol");
			Size index_radius = getColumnIndex("radius");
			Size index_number_of_atoms = getColumnIndex("number_of_atoms");

			for (Size i = 0; i < number_of_keys; ++i)
			{
				String type_name = getKey(i);
				if (atom_types.has(type_name))
				{
					solvent_atoms_[i].type = atom_types.getType(type_name);
					solvent_atoms_[i].element_symbol = getValue(i, index_element_symbol);
					solvent_atoms_[i].radius = getValue(i, index_radius).toFloat();
					solvent_atoms_[i].number_of_atoms = getValue(i, index_number_of_atoms).toInt();
				}
				else
				{
					Log.error() << "SolventParameter::extractSection(): "
						<< "Cannot assign atom type." << endl;
				}
			}
			// build descriptor
			solvent_descriptor_ = SolventDescriptor(name_, number_density_,
					solvent_atoms_);
			return true;
		}
		// control flow should not reach this point
		Log.error() << "SolventParameter::extractSection(): "
			<< "reached unreachable part of program" << endl;
		return false;

	}

}
<commit_msg>fixed: removed unreachable code<commit_after>// $Id: solventParameter.C,v 1.4 2000/10/20 15:20:44 anker Exp $

#include <BALL/SOLVATION/solventParameter.h>

using namespace std;

namespace BALL
{

	SolventParameter::SolventParameter() throw()
		: ParameterSection(),
			name_(),
			number_density_(0.0),
			solvent_atoms_(),
			solvent_descriptor_()
	{
	}

	SolventParameter::SolventParameter(const SolventParameter& param) throw()
		: ParameterSection(param),
			name_(param.name_),
			number_density_(param.number_density_),
			solvent_atoms_(param.solvent_atoms_),
			solvent_descriptor_(param.solvent_descriptor_)
	{
	}

	SolventParameter::~SolventParameter() throw()
	{
		clear();

		valid_ = false;
	}

	void SolventParameter::clear() throw()
	{
		ParameterSection::clear();
		name_ = "";
		number_density_ = 0.0;
		solvent_descriptor_.clear();
		solvent_atoms_.clear();
	}

	const SolventParameter& SolventParameter::operator =
		(const SolventParameter& param) throw()
	{
		ParameterSection::operator = (param);
		name_ = param.name_;
		number_density_ = param.number_density_;
		solvent_atoms_ = param.solvent_atoms_;
		solvent_descriptor_ = param.solvent_descriptor_;

		return *this;
	}

	bool SolventParameter::operator == (const SolventParameter& param) const
		throw()
	{
		// BAUSTELLE
		return ((ParameterSection::operator == (param))
			&& (name_ == param.name_)
			&& (number_density_ == param.number_density_));
			// && (solvent_atoms_ == param.solvent_atoms_)
			// && (solvent_descriptor_ == param.solvent_descriptor_));
	}

	SolventDescriptor SolventParameter::getSolventDescriptor() const throw()
	{
		return solvent_descriptor_;
	}

	bool SolventParameter::extractSection(ForceFieldParameters& parameters,
			const String& section_name) throw()
	{
		// BAUSTELLE
		if (!parameters.isValid())
		{
			return false;
		}

		// extract the basis information
		ParameterSection::extractSection(parameters, section_name);

		// check whether all variables we need are defined, terminate otherwi
		if (!hasVariable("radius") || !hasVariable("number_of_atoms") || !hasVariable("element_symbol"))
		{
			Log.error() << "SolventParameter::extractSection(): Variable missing."
				<< endl;
			return false;
		}
		else
		{
			if (options.has("name"))
			{
				name_ = options.get("name");
			}
			else
			{
				Log.warn() << "SolventParameter::extractSection(): no name given."
					<< endl;
			}
			if (options.has("number_density"))
			{
				number_density_ = options.getReal("number_density");
			}
			else
			{
				Log.warn() << "SolventParameter::extractSection(): "
					<< "no number density given." << endl;
			}

			AtomTypes& atom_types = parameters.getAtomTypes();

			Size number_of_keys = getNumberOfKeys();
			solvent_atoms_.resize(number_of_keys);

			Size index_element_symbol = getColumnIndex("element_symbol");
			Size index_radius = getColumnIndex("radius");
			Size index_number_of_atoms = getColumnIndex("number_of_atoms");

			for (Size i = 0; i < number_of_keys; ++i)
			{
				String type_name = getKey(i);
				if (atom_types.has(type_name))
				{
					solvent_atoms_[i].type = atom_types.getType(type_name);
					solvent_atoms_[i].element_symbol = getValue(i, index_element_symbol);
					solvent_atoms_[i].radius = getValue(i, index_radius).toFloat();
					solvent_atoms_[i].number_of_atoms = getValue(i, index_number_of_atoms).toInt();
				}
				else
				{
					Log.error() << "SolventParameter::extractSection(): "
						<< "Cannot assign atom type." << endl;
				}
			}
			// build descriptor
			solvent_descriptor_ = SolventDescriptor(name_, number_density_,
					solvent_atoms_);
			return true;
		}
	}
}
<|endoftext|>


<commit_before>#include "poi_parser.h"
#include "type/data.h"
#include "utils/csv.h"
#include "utils/functions.h"

namespace ed{ namespace connectors{
PoiParser::PoiParser(const std::string & path, const ed::connectors::ConvCoord& conv_coord): path(path), conv_coord(conv_coord){
        logger = log4cplus::Logger::getInstance("log");
}

void PoiParser::fill_poi_type(){
    CsvReader reader(this->path + "/poi_type.txt" , ';', true, true);
    if(!reader.is_open()) {
        throw PoiParserException("Error on open file " + reader.filename);
    }
    std::vector<std::string> mandatory_headers = {"poi_type_id" , "poi_type_name"};
    if(!reader.validate(mandatory_headers)) {
        throw PoiParserException("Impossible to parse file " + reader.filename +" . Not find column : " + reader.missing_headers(mandatory_headers));
    }
    int id_c = reader.get_pos_col("poi_type_id");
    int name_c = reader.get_pos_col("poi_type_name");
    while(!reader.eof()){
        std::vector<std::string> row = reader.next();
        if (reader.is_valid(id_c, row) && reader.is_valid(name_c, row)){
            const auto& itm = this->data.poi_types.find(row[id_c]);
            if(itm == this->data.poi_types.end()){
                ed::types::PoiType* poi_type = new ed::types::PoiType;
                poi_type->id = this->data.poi_types.size() + 1;
                poi_type->name = row[name_c];
                this->data.poi_types[row[id_c]] = poi_type;
            }
        }
    }
}

void PoiParser::fill_poi(){
    CsvReader reader(this->path + "/poi.txt", ';', true, true);
    if(!reader.is_open()) {
        throw PoiParserException("Error on open file " + reader.filename);
    }
    std::vector<std::string> mandatory_headers = {"poi_id", "poi_name", "poi_weight", "poi_visible", "poi_lat", "poi_lon", "poi_type_id"};
    if(!reader.validate(mandatory_headers)) {
        throw PoiParserException("Impossible to parse file " + reader.filename +" . Not find column : " + reader.missing_headers(mandatory_headers));
    }
    int id_c = reader.get_pos_col("poi_id");
    int name_c = reader.get_pos_col("poi_name");
    int weight_c = reader.get_pos_col("poi_weight");
    int visible_c = reader.get_pos_col("poi_visible");
    int lat_c = reader.get_pos_col("poi_lat");
    int lon_c = reader.get_pos_col("poi_lon");
    int type_id_c = reader.get_pos_col("poi_type_id");

    while(!reader.eof()){
        std::vector<std::string> row = reader.next();
        if (reader.is_valid(id_c, row) && reader.is_valid(name_c, row)
            && reader.is_valid(weight_c, row) && reader.is_valid(visible_c, row)
            && reader.is_valid(lat_c, row) && reader.is_valid(lon_c, row)
            && reader.is_valid(type_id_c, row)){
            const auto& itm = this->data.pois.find(row[id_c]);
            if(itm == this->data.pois.end()){
                const auto& poi_type = this->data.poi_types.find(row[type_id_c]);
                if(poi_type != this->data.poi_types.end()){
                    ed::types::Poi* poi = new ed::types::Poi;
                    poi->id = this->data.pois.size() + 1;
                    poi->name = row[name_c];
                    try{
                        poi->visible = boost::lexical_cast<bool>(row[visible_c]);
                    }catch(boost::bad_lexical_cast ) {
                        LOG4CPLUS_WARN(logger, "Impossible to parse the visible for " + row[id_c] + " " + row[name_c]);
                        poi->visible = true;
                    }
                    try{
                        poi->weight = boost::lexical_cast<int>(row[weight_c]);
                    }catch(boost::bad_lexical_cast ) {
                        LOG4CPLUS_WARN(logger, "Impossible to parse the weight for " + row[id_c] + " " + row[name_c]);
                        poi->weight = 0;
                    }
                    poi->poi_type = poi_type->second;
                    poi->coord = this->conv_coord.convert_to(navitia::type::GeographicalCoord(str_to_double(row[lon_c]), str_to_double(row[lat_c])));
                    this->data.pois[row[id_c]] = poi;
                }
            }
        }
    }
}

void PoiParser::fill(){
    fill_poi_type();
    fill_poi();
}

}}
<commit_msg>ed : modify message<commit_after>#include "poi_parser.h"
#include "type/data.h"
#include "utils/csv.h"
#include "utils/functions.h"

namespace ed{ namespace connectors{
PoiParser::PoiParser(const std::string & path, const ed::connectors::ConvCoord& conv_coord): path(path), conv_coord(conv_coord){
        logger = log4cplus::Logger::getInstance("log");
}

void PoiParser::fill_poi_type(){
    CsvReader reader(this->path + "/poi_type.txt" , ';', true, true);
    if(!reader.is_open()) {
        throw PoiParserException("Cannot open file : " + reader.filename);
    }
    std::vector<std::string> mandatory_headers = {"poi_type_id" , "poi_type_name"};
    if(!reader.validate(mandatory_headers)) {
        throw PoiParserException("Impossible to parse file " + reader.filename +" . Not find column : " + reader.missing_headers(mandatory_headers));
    }
    int id_c = reader.get_pos_col("poi_type_id");
    int name_c = reader.get_pos_col("poi_type_name");
    while(!reader.eof()){
        std::vector<std::string> row = reader.next();
        if (reader.is_valid(id_c, row) && reader.is_valid(name_c, row)){
            const auto& itm = this->data.poi_types.find(row[id_c]);
            if(itm == this->data.poi_types.end()){
                ed::types::PoiType* poi_type = new ed::types::PoiType;
                poi_type->id = this->data.poi_types.size() + 1;
                poi_type->name = row[name_c];
                this->data.poi_types[row[id_c]] = poi_type;
            }
        }
    }
}

void PoiParser::fill_poi(){
    CsvReader reader(this->path + "/poi.txt", ';', true, true);
    if(!reader.is_open()) {
        throw PoiParserException("Cannot open file : " + reader.filename);
    }
    std::vector<std::string> mandatory_headers = {"poi_id", "poi_name", "poi_weight", "poi_visible", "poi_lat", "poi_lon", "poi_type_id"};
    if(!reader.validate(mandatory_headers)) {
        throw PoiParserException("Impossible to parse file " + reader.filename +" . Not find column : " + reader.missing_headers(mandatory_headers));
    }
    int id_c = reader.get_pos_col("poi_id");
    int name_c = reader.get_pos_col("poi_name");
    int weight_c = reader.get_pos_col("poi_weight");
    int visible_c = reader.get_pos_col("poi_visible");
    int lat_c = reader.get_pos_col("poi_lat");
    int lon_c = reader.get_pos_col("poi_lon");
    int type_id_c = reader.get_pos_col("poi_type_id");

    while(!reader.eof()){
        std::vector<std::string> row = reader.next();
        if (reader.is_valid(id_c, row) && reader.is_valid(name_c, row)
            && reader.is_valid(weight_c, row) && reader.is_valid(visible_c, row)
            && reader.is_valid(lat_c, row) && reader.is_valid(lon_c, row)
            && reader.is_valid(type_id_c, row)){
            const auto& itm = this->data.pois.find(row[id_c]);
            if(itm == this->data.pois.end()){
                const auto& poi_type = this->data.poi_types.find(row[type_id_c]);
                if(poi_type != this->data.poi_types.end()){
                    ed::types::Poi* poi = new ed::types::Poi;
                    poi->id = this->data.pois.size() + 1;
                    poi->name = row[name_c];
                    try{
                        poi->visible = boost::lexical_cast<bool>(row[visible_c]);
                    }catch(boost::bad_lexical_cast ) {
                        LOG4CPLUS_WARN(logger, "Impossible to parse the visible for " + row[id_c] + " " + row[name_c]);
                        poi->visible = true;
                    }
                    try{
                        poi->weight = boost::lexical_cast<int>(row[weight_c]);
                    }catch(boost::bad_lexical_cast ) {
                        LOG4CPLUS_WARN(logger, "Impossible to parse the weight for " + row[id_c] + " " + row[name_c]);
                        poi->weight = 0;
                    }
                    poi->poi_type = poi_type->second;
                    poi->coord = this->conv_coord.convert_to(navitia::type::GeographicalCoord(str_to_double(row[lon_c]), str_to_double(row[lat_c])));
                    this->data.pois[row[id_c]] = poi;
                }
            }
        }
    }
}

void PoiParser::fill(){
    fill_poi_type();
    fill_poi();
}

}}
<|endoftext|>


<commit_before>/* Calf DSP Library
 * Module wrapper methods.
 *
 * Copyright (C) 2001-2007 Krzysztof Foltman
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program 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 program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#include <config.h>
#include <assert.h>
#include <memory.h>
#include <calf/giface.h>
#include <calf/modules.h>
#include <calf/lv2wrap.h>

using namespace synth;
using namespace std;
using namespace calf_utils;

float parameter_properties::from_01(double value01) const
{
    double value = dsp::clip(value01, 0., 1.);
    switch(flags & PF_SCALEMASK)
    {
    case PF_SCALE_DEFAULT:
    case PF_SCALE_LINEAR:
    case PF_SCALE_PERC:
    default:
        value = min + (max - min) * value01;
        break;
    case PF_SCALE_QUAD:
        value = min + (max - min) * value01 * value01;
        break;
    case PF_SCALE_LOG:
        value = min * pow(double(max / min), value01);
        break;
    case PF_SCALE_GAIN:
        if (value01 < 0.00001)
            value = min;
        else {
            float rmin = std::max(1.0f / 1024.0f, min);
            value = rmin * pow(double(max / rmin), value01);
        }
        break;
    case PF_SCALE_LOG_INF:
        assert(step);
        if (value01 > (step - 1.0) / step)
            value = FAKE_INFINITY;
        else
            value = min * pow(double(max / min), value01 * step / (step - 1.0));
        break;
    }
    switch(flags & PF_TYPEMASK)
    {
    case PF_INT:
    case PF_BOOL:
    case PF_ENUM:
    case PF_ENUM_MULTI:
        if (value > 0)
            value = (int)(value + 0.5);
        else
            value = (int)(value - 0.5);
        break;
    }
    return value;
}

double parameter_properties::to_01(float value) const
{
    switch(flags & PF_SCALEMASK)
    {
    case PF_SCALE_DEFAULT:
    case PF_SCALE_LINEAR:
    case PF_SCALE_PERC:
    default:
        return double(value - min) / (max - min);
    case PF_SCALE_QUAD:
        return sqrt(double(value - min) / (max - min));
    case PF_SCALE_LOG:
        value /= min;
        return log((double)value) / log((double)max / min);
    case PF_SCALE_LOG_INF:
        if (IS_FAKE_INFINITY(value))
            return max;
        value /= min;
        assert(step);
        return (step - 1.0) * log((double)value) / (step * log((double)max / min));
    case PF_SCALE_GAIN:
        if (value < 1.0 / 1024.0) // new bottom limit - 60 dB
            return 0;
        double rmin = std::max(1.0f / 1024.0f, min);
        value /= rmin;
        return log((double)value) / log(max / rmin);
    }
}

float parameter_properties::get_increment() const
{
    float increment = 0.01;
    if (step > 1)
        increment = 1.0 / (step - 1);
    else
    if (step > 0 && step < 1)
        increment = step;
    else
    if ((flags & PF_TYPEMASK) != PF_FLOAT)
        increment = 1.0 / (max - min);
    return increment;
}

int parameter_properties::get_char_count() const
{
    if ((flags & PF_SCALEMASK) == PF_SCALE_PERC)
        return 6;
    if ((flags & PF_SCALEMASK) == PF_SCALE_GAIN) {
        char buf[256];
        size_t len = 0;
        sprintf(buf, "%0.0f dB", 6.0 * log(min) / log(2));
        len = strlen(buf);
        sprintf(buf, "%0.0f dB", 6.0 * log(max) / log(2));
        len = std::max(len, strlen(buf)) + 2;
        return (int)len;
    }
    return std::max(to_string(min).length(), std::max(to_string(max).length(), to_string(max * 0.999999).length()));
}

std::string parameter_properties::to_string(float value) const
{
    char buf[32];
    if ((flags & PF_SCALEMASK) == PF_SCALE_PERC) {
        sprintf(buf, "%0.f%%", 100.0 * value);
        return string(buf);
    }
    if ((flags & PF_SCALEMASK) == PF_SCALE_GAIN) {
        if (value < 1.0 / 1024.0) // new bottom limit - 60 dB
            return "-inf dB"; // XXXKF change to utf-8 infinity
        sprintf(buf, "%0.1f dB", 6.0 * log(value) / log(2));
        return string(buf);
    }
    switch(flags & PF_TYPEMASK)
    {
    case PF_INT:
    case PF_BOOL:
    case PF_ENUM:
    case PF_ENUM_MULTI:
        value = (int)value;
        break;
    }

    if ((flags & PF_SCALEMASK) == PF_SCALE_LOG_INF && IS_FAKE_INFINITY(value))
        sprintf(buf, "+inf"); // XXXKF change to utf-8 infinity
    else
        sprintf(buf, "%g", value);

    switch(flags & PF_UNITMASK) {
    case PF_UNIT_DB: return string(buf) + " dB";
    case PF_UNIT_HZ: return string(buf) + " Hz";
    case PF_UNIT_SEC: return string(buf) + " s";
    case PF_UNIT_MSEC: return string(buf) + " ms";
    case PF_UNIT_CENTS: return string(buf) + " ct";
    case PF_UNIT_SEMITONES: return string(buf) + "#";
    case PF_UNIT_BPM: return string(buf) + " bpm";
    case PF_UNIT_RPM: return string(buf) + " rpm";
    case PF_UNIT_DEG: return string(buf) + " deg";
    case PF_UNIT_NOTE:
        {
            static const char *notes = "C C#D D#E F F#G G#A A#B ";
            int note = (int)value;
            if (note < 0 || note > 127)
                return "---";
            return string(notes + 2 * (note % 12), 2) + i2s(note / 12 - 2);
        }
    }

    return string(buf);
}

std::string synth::xml_escape(const std::string &src)
{
    string dest;
    for (size_t i = 0; i < src.length(); i++) {
        // XXXKF take care of string encoding
        if (src[i] < 0 || src[i] == '"' || src[i] == '<' || src[i] == '>' || src[i] == '&')
            dest += "&"+i2s((uint8_t)src[i])+";";
        else
            dest += src[i];
    }
    return dest;
}

<commit_msg>+ Framework: remove unnecessary dependencies of giface.cpp<commit_after>/* Calf DSP Library
 * Module wrapper methods.
 *
 * Copyright (C) 2001-2007 Krzysztof Foltman
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program 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 program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#include <config.h>
#include <assert.h>
#include <memory.h>
#include <calf/giface.h>

using namespace synth;
using namespace std;
using namespace calf_utils;

float parameter_properties::from_01(double value01) const
{
    double value = dsp::clip(value01, 0., 1.);
    switch(flags & PF_SCALEMASK)
    {
    case PF_SCALE_DEFAULT:
    case PF_SCALE_LINEAR:
    case PF_SCALE_PERC:
    default:
        value = min + (max - min) * value01;
        break;
    case PF_SCALE_QUAD:
        value = min + (max - min) * value01 * value01;
        break;
    case PF_SCALE_LOG:
        value = min * pow(double(max / min), value01);
        break;
    case PF_SCALE_GAIN:
        if (value01 < 0.00001)
            value = min;
        else {
            float rmin = std::max(1.0f / 1024.0f, min);
            value = rmin * pow(double(max / rmin), value01);
        }
        break;
    case PF_SCALE_LOG_INF:
        assert(step);
        if (value01 > (step - 1.0) / step)
            value = FAKE_INFINITY;
        else
            value = min * pow(double(max / min), value01 * step / (step - 1.0));
        break;
    }
    switch(flags & PF_TYPEMASK)
    {
    case PF_INT:
    case PF_BOOL:
    case PF_ENUM:
    case PF_ENUM_MULTI:
        if (value > 0)
            value = (int)(value + 0.5);
        else
            value = (int)(value - 0.5);
        break;
    }
    return value;
}

double parameter_properties::to_01(float value) const
{
    switch(flags & PF_SCALEMASK)
    {
    case PF_SCALE_DEFAULT:
    case PF_SCALE_LINEAR:
    case PF_SCALE_PERC:
    default:
        return double(value - min) / (max - min);
    case PF_SCALE_QUAD:
        return sqrt(double(value - min) / (max - min));
    case PF_SCALE_LOG:
        value /= min;
        return log((double)value) / log((double)max / min);
    case PF_SCALE_LOG_INF:
        if (IS_FAKE_INFINITY(value))
            return max;
        value /= min;
        assert(step);
        return (step - 1.0) * log((double)value) / (step * log((double)max / min));
    case PF_SCALE_GAIN:
        if (value < 1.0 / 1024.0) // new bottom limit - 60 dB
            return 0;
        double rmin = std::max(1.0f / 1024.0f, min);
        value /= rmin;
        return log((double)value) / log(max / rmin);
    }
}

float parameter_properties::get_increment() const
{
    float increment = 0.01;
    if (step > 1)
        increment = 1.0 / (step - 1);
    else
    if (step > 0 && step < 1)
        increment = step;
    else
    if ((flags & PF_TYPEMASK) != PF_FLOAT)
        increment = 1.0 / (max - min);
    return increment;
}

int parameter_properties::get_char_count() const
{
    if ((flags & PF_SCALEMASK) == PF_SCALE_PERC)
        return 6;
    if ((flags & PF_SCALEMASK) == PF_SCALE_GAIN) {
        char buf[256];
        size_t len = 0;
        sprintf(buf, "%0.0f dB", 6.0 * log(min) / log(2));
        len = strlen(buf);
        sprintf(buf, "%0.0f dB", 6.0 * log(max) / log(2));
        len = std::max(len, strlen(buf)) + 2;
        return (int)len;
    }
    return std::max(to_string(min).length(), std::max(to_string(max).length(), to_string(max * 0.999999).length()));
}

std::string parameter_properties::to_string(float value) const
{
    char buf[32];
    if ((flags & PF_SCALEMASK) == PF_SCALE_PERC) {
        sprintf(buf, "%0.f%%", 100.0 * value);
        return string(buf);
    }
    if ((flags & PF_SCALEMASK) == PF_SCALE_GAIN) {
        if (value < 1.0 / 1024.0) // new bottom limit - 60 dB
            return "-inf dB"; // XXXKF change to utf-8 infinity
        sprintf(buf, "%0.1f dB", 6.0 * log(value) / log(2));
        return string(buf);
    }
    switch(flags & PF_TYPEMASK)
    {
    case PF_INT:
    case PF_BOOL:
    case PF_ENUM:
    case PF_ENUM_MULTI:
        value = (int)value;
        break;
    }

    if ((flags & PF_SCALEMASK) == PF_SCALE_LOG_INF && IS_FAKE_INFINITY(value))
        sprintf(buf, "+inf"); // XXXKF change to utf-8 infinity
    else
        sprintf(buf, "%g", value);

    switch(flags & PF_UNITMASK) {
    case PF_UNIT_DB: return string(buf) + " dB";
    case PF_UNIT_HZ: return string(buf) + " Hz";
    case PF_UNIT_SEC: return string(buf) + " s";
    case PF_UNIT_MSEC: return string(buf) + " ms";
    case PF_UNIT_CENTS: return string(buf) + " ct";
    case PF_UNIT_SEMITONES: return string(buf) + "#";
    case PF_UNIT_BPM: return string(buf) + " bpm";
    case PF_UNIT_RPM: return string(buf) + " rpm";
    case PF_UNIT_DEG: return string(buf) + " deg";
    case PF_UNIT_NOTE:
        {
            static const char *notes = "C C#D D#E F F#G G#A A#B ";
            int note = (int)value;
            if (note < 0 || note > 127)
                return "---";
            return string(notes + 2 * (note % 12), 2) + i2s(note / 12 - 2);
        }
    }

    return string(buf);
}

std::string synth::xml_escape(const std::string &src)
{
    string dest;
    for (size_t i = 0; i < src.length(); i++) {
        // XXXKF take care of string encoding
        if (src[i] < 0 || src[i] == '"' || src[i] == '<' || src[i] == '>' || src[i] == '&')
            dest += "&"+i2s((uint8_t)src[i])+";";
        else
            dest += src[i];
    }
    return dest;
}

<|endoftext|>


<commit_before>#include "audio_ctx.hpp"

#include "sound.hpp"
#include "music.hpp"
#include "../asset/asset_manager.hpp"

#include <sf2/sf2.hpp>
#include <sf2/FileParser.hpp>

#include <SDL2/SDL_mixer.h>

namespace mo {
	namespace audio {
		namespace {

			struct Sounds_cfg {
				int frequence;
				int channels;
				int buffer_size;
				float music_volume = 0.5;
				float sound_volume = 1;
			};

			sf2_structDef(Sounds_cfg,
				sf2_member(frequence),
				sf2_member(channels),
				sf2_member(buffer_size),
				sf2_member(music_volume),
				sf2_member(sound_volume)
			)

#ifndef EMSCRIPTEN
			constexpr auto default_cfg = Sounds_cfg{44100, 2, 4096, 0.5, 1};
#else
			constexpr auto default_cfg = Sounds_cfg{44100, 2, 2048, 0.5, 1};
#endif

			constexpr auto create_mask(int i) -> uint16_t {
				return i==1 ? 1 : (create_mask(i-1)<<1 | 1);
			}

			constexpr auto static_channels = 16;

			constexpr auto version_bits = 4u;

			constexpr auto version_mask = create_mask(version_bits);

			constexpr auto extract_channel(Channel_id c) {
				return c>>version_bits;
			}
			constexpr auto extract_version(Channel_id c) {
				return c & version_mask;
			}
			constexpr auto build_channel_id(int16_t channel, int8_t version) {
				return channel<<version_bits | version;
			}
		}
	}

	namespace asset {
		template<>
		struct Loader<audio::Sounds_cfg> {
			using RT = std::shared_ptr<audio::Sounds_cfg>;

			static RT load(istream in) throw(Loading_failed) {
				auto r = std::make_shared<audio::Sounds_cfg>();

				sf2::parseStream(in, *r);

				return r;
			}

			static void store(ostream out, const audio::Sounds_cfg& asset) throw (Loading_failed) {
				sf2::writeStream(out, asset);
			}
		};
	}

	namespace audio {

		using namespace unit_literals;

		Audio_ctx::Audio_ctx(asset::Asset_manager& assets)
		    : _channels{}, _channels_last{}, _channel_versions{}, _channel_sounds{}
		{
			_channels.fill(false);
			_channels_last.fill(false);
			_channel_versions.fill(0);
			_channel_sounds.fill(nullptr);
			_free_channels.reserve(_dynamic_channels);
			for(int16_t i=0; i<_dynamic_channels; ++i)
				_free_channels.push_back(i);

			auto& cfg = asset::unpack(assets.load_maybe<Sounds_cfg>("cfg:sounds"_aid)).get_or_other(
				 default_cfg
			);

			if(&cfg==&default_cfg) {
				assets.save<Sounds_cfg>("cfg:sounds"_aid, cfg);
			}

			// Checking if frequence is faulty -> setting to 44100MHz
			int verified_frequence = (cfg.frequence % 22050 == 0) ? cfg.frequence : 44100;
			DEBUG("frequence: " << verified_frequence << " | " << ((cfg.channels == 1) ? "Mono" : "Stereo")
								<< " | buffer: " << cfg.buffer_size);

			// Open SDL Audio Mixer
			if(Mix_OpenAudio(verified_frequence, MIX_DEFAULT_FORMAT, cfg.channels, cfg.buffer_size) == 0) {
				DEBUG("Sound_ctx succesfully initialized!");
			} else {
				FAIL("Initializing Sound incomplete: " << Mix_GetError());
			}

			Mix_AllocateChannels(_dynamic_channels+static_channels);
			Mix_ReserveChannels(_dynamic_channels);

			sound_volume(cfg.sound_volume);
			music_volume(cfg.music_volume);
		}

		Audio_ctx::~Audio_ctx() {
			Mix_CloseAudio();
		}

		void Audio_ctx::flip() {
			for(int16_t i=0; i<_dynamic_channels; ++i) {
				if(!_channels[i] && _channels_last[i]) {
					Mix_Pause(i);
					_free_channels.push_back(i);
				}
			}

			_channels_last = _channels;
			_channels.fill(false);
		}

		void Audio_ctx::play_music(std::shared_ptr<const audio::Music> music, Time fade_time) {
			if(_playing_music==music)
				return;

			if(_playing_music) {
				// TODO: fade
				Mix_HaltMusic();
			}

			_playing_music = music;
			Mix_FadeInMusic(music->getMusic(), -1, fade_time/1_ms);
		}

		auto Audio_ctx::play_static(const audio::Sound& sound) -> Channel_id {
			auto c = Mix_PlayChannel(-1, sound.getSound(), 0);
			return build_channel_id(c, 0);
		}
		auto Audio_ctx::play_dynamic(const audio::Sound& sound, Angle angle, Distance dist,
		                             bool loop, Channel_id id) -> Channel_id {
			int16_t c;
			uint8_t v;

			if(id>=0) {
				c = extract_channel(id);
				v = extract_version(id);

				if(v!=_channel_versions[c])
					id=-1;

				else if(_channels[c]==_channels_last[c] && !_channels[c])
					id=-1;

				else if(&sound == _channel_sounds[c]) {
					if(Mix_Paused(c)) {
						Mix_Resume(c);
						update(id, angle, dist);
						return id;

					} else if(Mix_Playing(c)) {
						update(id, angle, dist);
						return id;
					}
				}
			}

			if(id<0) {
				if(_free_channels.empty()) {
					DEBUG("No free channel left.");
					return -1;
				}

				c = _free_channels.back();
				_free_channels.pop_back();

				v = ++_channel_versions[c];

				id = build_channel_id(c,v);
			}

			_channel_sounds[c] = &sound;
			Mix_PlayChannel(c, sound.getSound(), loop ? -1 : 0);
			update(id, angle, dist);
			return id;
		}

		void Audio_ctx::update(Channel_id id, Angle angle, Distance dist) {
			auto c = extract_channel(id);
			auto v = extract_version(id);
			if(c<_dynamic_channels && _channel_versions[c]==v) {
				Mix_SetPosition(id, angle.value(), dist.value());
				_channels[c] = true;
			}
		}

		void Audio_ctx::stop(Channel_id id) {
			auto c = extract_channel(id);
			auto v = extract_version(id);
			if(c>=_dynamic_channels || _channel_versions[c]==v)
				Mix_HaltChannel(c);
		}

		void Audio_ctx::pause_sounds() {
			Mix_Pause(-1);
		}

		void Audio_ctx::resume_sounds() {
			Mix_Resume(-1);
		}

		void Audio_ctx::stop_sounds() {
			Mix_HaltChannel(-1);
			_channels.fill(false);
			_channels_last.fill(false);
			_channel_versions.fill(0);
			_channel_sounds.fill(nullptr);

			_free_channels.clear();
			for(int i=0; i<_dynamic_channels; ++i)
				_free_channels.push_back(i);
		}

		void Audio_ctx::sound_volume(float volume) {
			_sound_volume = volume;
			Mix_Volume(-1, 128 * _sound_volume);
		}

		void Audio_ctx::music_volume(float volume) {
			_music_volume = volume;
			Mix_VolumeMusic(128 * _music_volume);
		}

	}
}

<commit_msg>fix for Windows<commit_after>#include "audio_ctx.hpp"

#include "sound.hpp"
#include "music.hpp"
#include "../asset/asset_manager.hpp"

#include <sf2/sf2.hpp>
#include <sf2/FileParser.hpp>

#include <SDL2/SDL_mixer.h>

namespace mo {
	namespace audio {
		namespace {

			struct Sounds_cfg {
				int frequence;
				int channels;
				int buffer_size;
				float music_volume;
				float sound_volume;
			};

			sf2_structDef(Sounds_cfg,
				sf2_member(frequence),
				sf2_member(channels),
				sf2_member(buffer_size),
				sf2_member(music_volume),
				sf2_member(sound_volume)
			)

#ifndef EMSCRIPTEN
			constexpr auto default_cfg = Sounds_cfg{44100, 2, 4096, 0.5f, 1.0f};
#else
			constexpr auto default_cfg = Sounds_cfg{44100, 2, 2048, 0.5f, 1.0f};
#endif

			constexpr auto create_mask(int i) -> uint16_t {
				return i==1 ? 1 : (create_mask(i-1)<<1 | 1);
			}

			constexpr auto static_channels = 16;

			constexpr auto version_bits = 4u;

			constexpr auto version_mask = create_mask(version_bits);

			constexpr auto extract_channel(Channel_id c) {
				return c>>version_bits;
			}
			constexpr auto extract_version(Channel_id c) {
				return c & version_mask;
			}
			constexpr auto build_channel_id(int16_t channel, int8_t version) {
				return channel<<version_bits | version;
			}
		}
	}

	namespace asset {
		template<>
		struct Loader<audio::Sounds_cfg> {
			using RT = std::shared_ptr<audio::Sounds_cfg>;

			static RT load(istream in) throw(Loading_failed) {
				auto r = std::make_shared<audio::Sounds_cfg>();

				sf2::parseStream(in, *r);

				return r;
			}

			static void store(ostream out, const audio::Sounds_cfg& asset) throw (Loading_failed) {
				sf2::writeStream(out, asset);
			}
		};
	}

	namespace audio {

		using namespace unit_literals;

		Audio_ctx::Audio_ctx(asset::Asset_manager& assets)
			: _channels{nullptr}, _channels_last{nullptr}, _channel_versions{0}, _channel_sounds{0}
		{
			_channels.fill(false);
			_channels_last.fill(false);
			_channel_versions.fill(0);
			_channel_sounds.fill(nullptr);
			_free_channels.reserve(_dynamic_channels);
			for(int16_t i=0; i<_dynamic_channels; ++i)
				_free_channels.push_back(i);

			auto& cfg = asset::unpack(assets.load_maybe<Sounds_cfg>("cfg:sounds"_aid)).get_or_other(
				 default_cfg
			);

			if(&cfg==&default_cfg) {
				assets.save<Sounds_cfg>("cfg:sounds"_aid, cfg);
			}

			// Checking if frequence is faulty -> setting to 44100MHz
			int verified_frequence = (cfg.frequence % 22050 == 0) ? cfg.frequence : 44100;
			DEBUG("frequence: " << verified_frequence << " | " << ((cfg.channels == 1) ? "Mono" : "Stereo")
								<< " | buffer: " << cfg.buffer_size);

			// Open SDL Audio Mixer
			if(Mix_OpenAudio(verified_frequence, MIX_DEFAULT_FORMAT, cfg.channels, cfg.buffer_size) == 0) {
				DEBUG("Sound_ctx succesfully initialized!");
			} else {
				FAIL("Initializing Sound incomplete: " << Mix_GetError());
			}

			Mix_AllocateChannels(_dynamic_channels+static_channels);
			Mix_ReserveChannels(_dynamic_channels);

			sound_volume(cfg.sound_volume);
			music_volume(cfg.music_volume);
		}

		Audio_ctx::~Audio_ctx() {
			Mix_CloseAudio();
		}

		void Audio_ctx::flip() {
			for(int16_t i=0; i<_dynamic_channels; ++i) {
				if(!_channels[i] && _channels_last[i]) {
					Mix_Pause(i);
					_free_channels.push_back(i);
				}
			}

			_channels_last = _channels;
			_channels.fill(false);
		}

		void Audio_ctx::play_music(std::shared_ptr<const audio::Music> music, Time fade_time) {
			if(_playing_music==music)
				return;

			if(_playing_music) {
				// TODO: fade
				Mix_HaltMusic();
			}

			_playing_music = music;
			Mix_FadeInMusic(music->getMusic(), -1, fade_time/1_ms);
		}

		auto Audio_ctx::play_static(const audio::Sound& sound) -> Channel_id {
			auto c = Mix_PlayChannel(-1, sound.getSound(), 0);
			return build_channel_id(c, 0);
		}
		auto Audio_ctx::play_dynamic(const audio::Sound& sound, Angle angle, Distance dist,
		                             bool loop, Channel_id id) -> Channel_id {
			int16_t c;
			uint8_t v;

			if(id>=0) {
				c = extract_channel(id);
				v = extract_version(id);

				if(v!=_channel_versions[c])
					id=-1;

				else if(_channels[c]==_channels_last[c] && !_channels[c])
					id=-1;

				else if(&sound == _channel_sounds[c]) {
					if(Mix_Paused(c)) {
						Mix_Resume(c);
						update(id, angle, dist);
						return id;

					} else if(Mix_Playing(c)) {
						update(id, angle, dist);
						return id;
					}
				}
			}

			if(id<0) {
				if(_free_channels.empty()) {
					DEBUG("No free channel left.");
					return -1;
				}

				c = _free_channels.back();
				_free_channels.pop_back();

				v = ++_channel_versions[c];

				id = build_channel_id(c,v);
			}

			_channel_sounds[c] = &sound;
			Mix_PlayChannel(c, sound.getSound(), loop ? -1 : 0);
			update(id, angle, dist);
			return id;
		}

		void Audio_ctx::update(Channel_id id, Angle angle, Distance dist) {
			auto c = extract_channel(id);
			auto v = extract_version(id);
			if(c<_dynamic_channels && _channel_versions[c]==v) {
				Mix_SetPosition(id, angle.value(), dist.value());
				_channels[c] = true;
			}
		}

		void Audio_ctx::stop(Channel_id id) {
			auto c = extract_channel(id);
			auto v = extract_version(id);
			if(c>=_dynamic_channels || _channel_versions[c]==v)
				Mix_HaltChannel(c);
		}

		void Audio_ctx::pause_sounds() {
			Mix_Pause(-1);
		}

		void Audio_ctx::resume_sounds() {
			Mix_Resume(-1);
		}

		void Audio_ctx::stop_sounds() {
			Mix_HaltChannel(-1);
			_channels.fill(false);
			_channels_last.fill(false);
			_channel_versions.fill(0);
			_channel_sounds.fill(nullptr);

			_free_channels.clear();
			for(int i=0; i<_dynamic_channels; ++i)
				_free_channels.push_back(i);
		}

		void Audio_ctx::sound_volume(float volume) {
			_sound_volume = volume;
			Mix_Volume(-1, 128 * _sound_volume);
		}

		void Audio_ctx::music_volume(float volume) {
			_music_volume = volume;
			Mix_VolumeMusic(128 * _music_volume);
		}

	}
}

<|endoftext|>