/*
 * libiio - Library for interfacing industrial I/O (IIO) devices
 *
 * Copyright (C) 2014 Analog Devices, Inc.
 * Author: Paul Cercueil <paul.cercueil@analog.com>
 *
 * This library 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.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * */

/* Force the XSI version of strerror_r */
#undef _GNU_SOURCE

#include "iio-config.h"
#include "iio-private.h"

#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(_WIN32) || (defined(__USE_XOPEN2K8) && \
		(!defined(__UCLIBC__) || defined(__UCLIBC_HAS_LOCALE__)))
#define LOCALE_SUPPORT
#endif

#ifdef LOCALE_SUPPORT
#if defined(__MINGW32__) || (!defined(_WIN32) && !defined(HAS_NEWLOCALE))
static int read_double_locale(const char *str, double *val)
{
	char *end, *old_locale;
	double value;

	/* XXX: This is not thread-safe, but it's the only way we have to
	 * support locales under MinGW without linking with Visual Studio
	 * libraries. */
	old_locale = iio_strdup(setlocale(LC_NUMERIC, NULL));
	if (!old_locale)
		return -ENOMEM;

	setlocale(LC_NUMERIC, "C");
	value = strtod(str, &end);
	setlocale(LC_NUMERIC, old_locale);
	free(old_locale);

	if (end == str)
		return -EINVAL;

	*val = value;
	return 0;
}

static int write_double_locale(char *buf, size_t len, double val)
{
	/* XXX: Not thread-safe, see above */
	char *old_locale = iio_strdup(setlocale(LC_NUMERIC, NULL));
	if (!old_locale)
		return -ENOMEM;

	setlocale(LC_NUMERIC, "C");
	iio_snprintf(buf, len, "%f", val);
	setlocale(LC_NUMERIC, old_locale);
	free(old_locale);
	return 0;
}
#elif defined(_WIN32)
static int read_double_locale(const char *str, double *val)
{
	char *end;
	double value;
	_locale_t locale = _create_locale(LC_NUMERIC, "C");
	if (!locale)
		return -ENOMEM;

	value = _strtod_l(str, &end, locale);
	_free_locale(locale);

	if (end == str)
		return -EINVAL;

	*val = value;
	return 0;
}

static int write_double_locale(char *buf, size_t len, double val)
{
	_locale_t locale = _create_locale(LC_NUMERIC, "C");
	if (!locale)
		return -ENOMEM;

	_snprintf_l(buf, len, "%f", locale, val);
	_free_locale(locale);
	return 0;
}
#else
static int read_double_locale(const char *str, double *val)
{
	char *end;
	double value;
	locale_t old_locale, new_locale;

	new_locale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
	if (!new_locale)
		return -errno;

	old_locale = uselocale(new_locale);

	value = strtod(str, &end);
	uselocale(old_locale);
	freelocale(new_locale);

	if (end == str)
		return -EINVAL;

	*val = value;
	return 0;
}

static int write_double_locale(char *buf, size_t len, double val)
{
	locale_t old_locale, new_locale;

	new_locale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
	if (!new_locale)
		return -errno;

	old_locale = uselocale(new_locale);

	iio_snprintf(buf, len, "%f", val);

	uselocale(old_locale);
	freelocale(new_locale);
	return 0;
}
#endif
#endif

int read_double(const char *str, double *val)
{
#ifdef LOCALE_SUPPORT
	return read_double_locale(str, val);
#else
	char *end;
	double value = strtod(str, &end);

	if (end == str)
		return -EINVAL;

	*val = value;
	return 0;
#endif
}

int write_double(char *buf, size_t len, double val)
{
#ifdef LOCALE_SUPPORT
	return write_double_locale(buf, len, val);
#else
	iio_snprintf(buf, len, "%f", val);
	return 0;
#endif
}

void iio_library_get_version(unsigned int *major,
		unsigned int *minor, char git_tag[8])
{
	if (major)
		*major = LIBIIO_VERSION_MAJOR;
	if (minor)
		*minor = LIBIIO_VERSION_MINOR;
	if (git_tag) {
		strncpy(git_tag, LIBIIO_VERSION_GIT, 8);
		git_tag[7] = '\0';
	}
}

void iio_strerror(int err, char *buf, size_t len)
{
#if defined(_WIN32)
	int ret = strerror_s(buf, len, err);
#elif defined(HAS_STRERROR_R)
	int ret = strerror_r(err, buf, len);
#else
	/* no strerror_s, no strerror_r... just use the default message */
	int ret = 0xf7de;
#endif
	if (ret != 0)
		iio_snprintf(buf, len, "Unknown error %i", err);
}

char *iio_strdup(const char *str)
{
#if defined(_WIN32)
	return _strdup(str);
#elif defined(HAS_STRDUP)
	return strdup(str);
#else
	size_t len = strlen(str);
	char *buf = malloc(len + 1);

	if (buf)
		memcpy(buf, str, len + 1);
	return buf;
#endif
}
