Paul Cercueil / libiio

Dependencies:   libserialport libxml2

Committer:
pcercuei
Date:
Mon Jun 26 14:30:10 2017 +0000
Revision:
4:ad69b39bf124
Parent:
3:d147beabba0e
Update to upstream version v0.10

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pcercuei 0:df031b60ca29 1 /*
pcercuei 0:df031b60ca29 2 * libiio - Library for interfacing industrial I/O (IIO) devices
pcercuei 0:df031b60ca29 3 *
pcercuei 0:df031b60ca29 4 * Copyright (C) 2014 Analog Devices, Inc.
pcercuei 0:df031b60ca29 5 * Author: Paul Cercueil <paul.cercueil@analog.com>
pcercuei 0:df031b60ca29 6 *
pcercuei 0:df031b60ca29 7 * This library is free software; you can redistribute it and/or
pcercuei 0:df031b60ca29 8 * modify it under the terms of the GNU Lesser General Public
pcercuei 0:df031b60ca29 9 * License as published by the Free Software Foundation; either
pcercuei 0:df031b60ca29 10 * version 2.1 of the License, or (at your option) any later version.
pcercuei 0:df031b60ca29 11 *
pcercuei 0:df031b60ca29 12 * This library is distributed in the hope that it will be useful,
pcercuei 0:df031b60ca29 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
pcercuei 0:df031b60ca29 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
pcercuei 0:df031b60ca29 15 * Lesser General Public License for more details.
pcercuei 0:df031b60ca29 16 *
pcercuei 0:df031b60ca29 17 * */
pcercuei 0:df031b60ca29 18
pcercuei 0:df031b60ca29 19 /* Force the XSI version of strerror_r */
pcercuei 0:df031b60ca29 20 #undef _GNU_SOURCE
pcercuei 0:df031b60ca29 21
pcercuei 0:df031b60ca29 22 #include "iio-config.h"
pcercuei 0:df031b60ca29 23 #include "iio-private.h"
pcercuei 0:df031b60ca29 24
pcercuei 2:9eb0a9a1f958 25 #include <errno.h>
pcercuei 0:df031b60ca29 26 #include <locale.h>
pcercuei 0:df031b60ca29 27 #include <stdio.h>
pcercuei 0:df031b60ca29 28 #include <stdlib.h>
pcercuei 0:df031b60ca29 29 #include <string.h>
pcercuei 0:df031b60ca29 30
pcercuei 0:df031b60ca29 31 #if defined(_WIN32) || (defined(__USE_XOPEN2K8) && \
pcercuei 0:df031b60ca29 32 (!defined(__UCLIBC__) || defined(__UCLIBC_HAS_LOCALE__)))
pcercuei 0:df031b60ca29 33 #define LOCALE_SUPPORT
pcercuei 0:df031b60ca29 34 #endif
pcercuei 0:df031b60ca29 35
pcercuei 0:df031b60ca29 36 #ifdef LOCALE_SUPPORT
pcercuei 4:ad69b39bf124 37 #if defined(__MINGW32__) || (!defined(_WIN32) && !defined(HAS_NEWLOCALE))
pcercuei 0:df031b60ca29 38 static int read_double_locale(const char *str, double *val)
pcercuei 0:df031b60ca29 39 {
pcercuei 0:df031b60ca29 40 char *end, *old_locale;
pcercuei 0:df031b60ca29 41 double value;
pcercuei 0:df031b60ca29 42
pcercuei 0:df031b60ca29 43 /* XXX: This is not thread-safe, but it's the only way we have to
pcercuei 0:df031b60ca29 44 * support locales under MinGW without linking with Visual Studio
pcercuei 0:df031b60ca29 45 * libraries. */
pcercuei 0:df031b60ca29 46 old_locale = iio_strdup(setlocale(LC_NUMERIC, NULL));
pcercuei 0:df031b60ca29 47 if (!old_locale)
pcercuei 0:df031b60ca29 48 return -ENOMEM;
pcercuei 0:df031b60ca29 49
pcercuei 0:df031b60ca29 50 setlocale(LC_NUMERIC, "C");
pcercuei 0:df031b60ca29 51 value = strtod(str, &end);
pcercuei 0:df031b60ca29 52 setlocale(LC_NUMERIC, old_locale);
pcercuei 0:df031b60ca29 53 free(old_locale);
pcercuei 0:df031b60ca29 54
pcercuei 0:df031b60ca29 55 if (end == str)
pcercuei 0:df031b60ca29 56 return -EINVAL;
pcercuei 0:df031b60ca29 57
pcercuei 0:df031b60ca29 58 *val = value;
pcercuei 0:df031b60ca29 59 return 0;
pcercuei 0:df031b60ca29 60 }
pcercuei 0:df031b60ca29 61
pcercuei 0:df031b60ca29 62 static int write_double_locale(char *buf, size_t len, double val)
pcercuei 0:df031b60ca29 63 {
pcercuei 0:df031b60ca29 64 /* XXX: Not thread-safe, see above */
pcercuei 0:df031b60ca29 65 char *old_locale = iio_strdup(setlocale(LC_NUMERIC, NULL));
pcercuei 0:df031b60ca29 66 if (!old_locale)
pcercuei 0:df031b60ca29 67 return -ENOMEM;
pcercuei 0:df031b60ca29 68
pcercuei 0:df031b60ca29 69 setlocale(LC_NUMERIC, "C");
pcercuei 3:d147beabba0e 70 iio_snprintf(buf, len, "%f", val);
pcercuei 0:df031b60ca29 71 setlocale(LC_NUMERIC, old_locale);
pcercuei 0:df031b60ca29 72 free(old_locale);
pcercuei 0:df031b60ca29 73 return 0;
pcercuei 0:df031b60ca29 74 }
pcercuei 0:df031b60ca29 75 #elif defined(_WIN32)
pcercuei 0:df031b60ca29 76 static int read_double_locale(const char *str, double *val)
pcercuei 0:df031b60ca29 77 {
pcercuei 0:df031b60ca29 78 char *end;
pcercuei 0:df031b60ca29 79 double value;
pcercuei 0:df031b60ca29 80 _locale_t locale = _create_locale(LC_NUMERIC, "C");
pcercuei 0:df031b60ca29 81 if (!locale)
pcercuei 0:df031b60ca29 82 return -ENOMEM;
pcercuei 0:df031b60ca29 83
pcercuei 0:df031b60ca29 84 value = _strtod_l(str, &end, locale);
pcercuei 0:df031b60ca29 85 _free_locale(locale);
pcercuei 0:df031b60ca29 86
pcercuei 0:df031b60ca29 87 if (end == str)
pcercuei 0:df031b60ca29 88 return -EINVAL;
pcercuei 0:df031b60ca29 89
pcercuei 0:df031b60ca29 90 *val = value;
pcercuei 0:df031b60ca29 91 return 0;
pcercuei 0:df031b60ca29 92 }
pcercuei 0:df031b60ca29 93
pcercuei 0:df031b60ca29 94 static int write_double_locale(char *buf, size_t len, double val)
pcercuei 0:df031b60ca29 95 {
pcercuei 0:df031b60ca29 96 _locale_t locale = _create_locale(LC_NUMERIC, "C");
pcercuei 0:df031b60ca29 97 if (!locale)
pcercuei 0:df031b60ca29 98 return -ENOMEM;
pcercuei 0:df031b60ca29 99
pcercuei 0:df031b60ca29 100 _snprintf_l(buf, len, "%f", locale, val);
pcercuei 0:df031b60ca29 101 _free_locale(locale);
pcercuei 0:df031b60ca29 102 return 0;
pcercuei 0:df031b60ca29 103 }
pcercuei 0:df031b60ca29 104 #else
pcercuei 0:df031b60ca29 105 static int read_double_locale(const char *str, double *val)
pcercuei 0:df031b60ca29 106 {
pcercuei 0:df031b60ca29 107 char *end;
pcercuei 0:df031b60ca29 108 double value;
pcercuei 0:df031b60ca29 109 locale_t old_locale, new_locale;
pcercuei 0:df031b60ca29 110
pcercuei 0:df031b60ca29 111 new_locale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
pcercuei 0:df031b60ca29 112 if (!new_locale)
pcercuei 0:df031b60ca29 113 return -errno;
pcercuei 0:df031b60ca29 114
pcercuei 0:df031b60ca29 115 old_locale = uselocale(new_locale);
pcercuei 0:df031b60ca29 116
pcercuei 0:df031b60ca29 117 value = strtod(str, &end);
pcercuei 0:df031b60ca29 118 uselocale(old_locale);
pcercuei 0:df031b60ca29 119 freelocale(new_locale);
pcercuei 0:df031b60ca29 120
pcercuei 0:df031b60ca29 121 if (end == str)
pcercuei 0:df031b60ca29 122 return -EINVAL;
pcercuei 0:df031b60ca29 123
pcercuei 0:df031b60ca29 124 *val = value;
pcercuei 0:df031b60ca29 125 return 0;
pcercuei 0:df031b60ca29 126 }
pcercuei 0:df031b60ca29 127
pcercuei 0:df031b60ca29 128 static int write_double_locale(char *buf, size_t len, double val)
pcercuei 0:df031b60ca29 129 {
pcercuei 0:df031b60ca29 130 locale_t old_locale, new_locale;
pcercuei 0:df031b60ca29 131
pcercuei 0:df031b60ca29 132 new_locale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
pcercuei 0:df031b60ca29 133 if (!new_locale)
pcercuei 0:df031b60ca29 134 return -errno;
pcercuei 0:df031b60ca29 135
pcercuei 0:df031b60ca29 136 old_locale = uselocale(new_locale);
pcercuei 0:df031b60ca29 137
pcercuei 3:d147beabba0e 138 iio_snprintf(buf, len, "%f", val);
pcercuei 0:df031b60ca29 139
pcercuei 0:df031b60ca29 140 uselocale(old_locale);
pcercuei 0:df031b60ca29 141 freelocale(new_locale);
pcercuei 0:df031b60ca29 142 return 0;
pcercuei 0:df031b60ca29 143 }
pcercuei 0:df031b60ca29 144 #endif
pcercuei 0:df031b60ca29 145 #endif
pcercuei 0:df031b60ca29 146
pcercuei 0:df031b60ca29 147 int read_double(const char *str, double *val)
pcercuei 0:df031b60ca29 148 {
pcercuei 0:df031b60ca29 149 #ifdef LOCALE_SUPPORT
pcercuei 0:df031b60ca29 150 return read_double_locale(str, val);
pcercuei 0:df031b60ca29 151 #else
pcercuei 0:df031b60ca29 152 char *end;
pcercuei 0:df031b60ca29 153 double value = strtod(str, &end);
pcercuei 0:df031b60ca29 154
pcercuei 0:df031b60ca29 155 if (end == str)
pcercuei 0:df031b60ca29 156 return -EINVAL;
pcercuei 0:df031b60ca29 157
pcercuei 0:df031b60ca29 158 *val = value;
pcercuei 0:df031b60ca29 159 return 0;
pcercuei 0:df031b60ca29 160 #endif
pcercuei 0:df031b60ca29 161 }
pcercuei 0:df031b60ca29 162
pcercuei 0:df031b60ca29 163 int write_double(char *buf, size_t len, double val)
pcercuei 0:df031b60ca29 164 {
pcercuei 0:df031b60ca29 165 #ifdef LOCALE_SUPPORT
pcercuei 0:df031b60ca29 166 return write_double_locale(buf, len, val);
pcercuei 0:df031b60ca29 167 #else
pcercuei 3:d147beabba0e 168 iio_snprintf(buf, len, "%f", val);
pcercuei 0:df031b60ca29 169 return 0;
pcercuei 0:df031b60ca29 170 #endif
pcercuei 0:df031b60ca29 171 }
pcercuei 0:df031b60ca29 172
pcercuei 0:df031b60ca29 173 void iio_library_get_version(unsigned int *major,
pcercuei 0:df031b60ca29 174 unsigned int *minor, char git_tag[8])
pcercuei 0:df031b60ca29 175 {
pcercuei 0:df031b60ca29 176 if (major)
pcercuei 0:df031b60ca29 177 *major = LIBIIO_VERSION_MAJOR;
pcercuei 0:df031b60ca29 178 if (minor)
pcercuei 0:df031b60ca29 179 *minor = LIBIIO_VERSION_MINOR;
pcercuei 0:df031b60ca29 180 if (git_tag) {
pcercuei 0:df031b60ca29 181 strncpy(git_tag, LIBIIO_VERSION_GIT, 8);
pcercuei 0:df031b60ca29 182 git_tag[7] = '\0';
pcercuei 0:df031b60ca29 183 }
pcercuei 0:df031b60ca29 184 }
pcercuei 0:df031b60ca29 185
pcercuei 0:df031b60ca29 186 void iio_strerror(int err, char *buf, size_t len)
pcercuei 0:df031b60ca29 187 {
pcercuei 0:df031b60ca29 188 #if defined(_WIN32)
pcercuei 0:df031b60ca29 189 int ret = strerror_s(buf, len, err);
pcercuei 0:df031b60ca29 190 #elif defined(HAS_STRERROR_R)
pcercuei 0:df031b60ca29 191 int ret = strerror_r(err, buf, len);
pcercuei 0:df031b60ca29 192 #else
pcercuei 0:df031b60ca29 193 /* no strerror_s, no strerror_r... just use the default message */
pcercuei 0:df031b60ca29 194 int ret = 0xf7de;
pcercuei 0:df031b60ca29 195 #endif
pcercuei 0:df031b60ca29 196 if (ret != 0)
pcercuei 3:d147beabba0e 197 iio_snprintf(buf, len, "Unknown error %i", err);
pcercuei 0:df031b60ca29 198 }
pcercuei 0:df031b60ca29 199
pcercuei 0:df031b60ca29 200 char *iio_strdup(const char *str)
pcercuei 0:df031b60ca29 201 {
pcercuei 0:df031b60ca29 202 #if defined(_WIN32)
pcercuei 0:df031b60ca29 203 return _strdup(str);
pcercuei 0:df031b60ca29 204 #elif defined(HAS_STRDUP)
pcercuei 0:df031b60ca29 205 return strdup(str);
pcercuei 0:df031b60ca29 206 #else
pcercuei 0:df031b60ca29 207 size_t len = strlen(str);
pcercuei 0:df031b60ca29 208 char *buf = malloc(len + 1);
pcercuei 0:df031b60ca29 209
pcercuei 0:df031b60ca29 210 if (buf)
pcercuei 0:df031b60ca29 211 memcpy(buf, str, len + 1);
pcercuei 0:df031b60ca29 212 return buf;
pcercuei 0:df031b60ca29 213 #endif
pcercuei 0:df031b60ca29 214 }
pcercuei 0:df031b60ca29 215