summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2007-09-17 22:39:51 +0000
committerLennart Poettering <lennart@poettering.net>2007-09-17 22:39:51 +0000
commit8ff7d567d364e60283a73486889876c454566eea (patch)
tree6c21c4dc9cedf0f50379afa347e98b1ee2eb46e5
parent4cdf2ce202d5e5c55db2387610a9bbff4b039bd8 (diff)
add a locale-independant pa_atof() implementation
git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1846 fefdeb5f-60dc-0310-8127-8f9354f1896f
-rw-r--r--configure.ac2
-rw-r--r--src/pulsecore/core-util.c61
-rw-r--r--src/pulsecore/core-util.h1
3 files changed, 61 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index c1666084..5b6c6474 100644
--- a/configure.ac
+++ b/configure.ac
@@ -291,7 +291,7 @@ AC_CHECK_FUNCS([lstat])
# Non-standard
-AC_CHECK_FUNCS([setresuid setresgid setreuid setregid seteuid setegid ppoll strsignal sig2str])
+AC_CHECK_FUNCS([setresuid setresgid setreuid setregid seteuid setegid ppoll strsignal sig2str strtof_l])
#### POSIX threads ####
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 37e7f183..aac7629e 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -42,6 +42,10 @@
#include <sys/stat.h>
#include <sys/time.h>
+#ifdef HAVE_STRTOF_L
+#include <locale.h>
+#endif
+
#ifdef HAVE_SCHED_H
#include <sched.h>
#endif
@@ -1221,11 +1225,15 @@ int pa_atoi(const char *s, int32_t *ret_i) {
pa_assert(s);
pa_assert(ret_i);
+ errno = 0;
l = strtol(s, &x, 0);
- if (!x || *x)
+ if (!x || *x || errno != 0)
return -1;
+ if ((int32_t) l != l)
+ return -1;
+
*ret_i = (int32_t) l;
return 0;
@@ -1239,9 +1247,13 @@ int pa_atou(const char *s, uint32_t *ret_u) {
pa_assert(s);
pa_assert(ret_u);
+ errno = 0;
l = strtoul(s, &x, 0);
- if (!x || *x)
+ if (!x || *x || errno != 0)
+ return -1;
+
+ if ((uint32_t) l != l)
return -1;
*ret_u = (uint32_t) l;
@@ -1249,6 +1261,51 @@ int pa_atou(const char *s, uint32_t *ret_u) {
return 0;
}
+#ifdef HAVE_STRTOF_L
+static locale_t c_locale = NULL;
+
+static void c_locale_destroy(void) {
+ freelocale(c_locale);
+}
+#endif
+
+int pa_atof(const char *s, float *ret_f) {
+ char *x = NULL;
+ float f;
+ int r = 0;
+
+ pa_assert(s);
+ pa_assert(ret_f);
+
+ /* This should be locale independent */
+
+#ifdef HAVE_STRTOF_L
+
+ PA_ONCE_BEGIN {
+
+ if ((c_locale = newlocale(LC_ALL_MASK, "C", NULL)))
+ atexit(c_locale_destroy);
+
+ } PA_ONCE_END;
+
+ if (c_locale) {
+ errno = 0;
+ f = strtof_l(s, &x, c_locale);
+ } else
+#endif
+ {
+ errno = 0;
+ f = strtof(s, &x);
+ }
+
+ if (!x || *x || errno != 0)
+ r = -1;
+ else
+ *ret_f = f;
+
+ return r;
+}
+
/* Same as snprintf, but guarantees NUL-termination on every platform */
int pa_snprintf(char *str, size_t size, const char *format, ...) {
int ret;
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index 4429f418..b8ef464e 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -92,6 +92,7 @@ char *pa_runtime_path(const char *fn, char *s, size_t l);
int pa_atoi(const char *s, int32_t *ret_i);
int pa_atou(const char *s, uint32_t *ret_u);
+int pa_atof(const char *s, float *ret_f);
int pa_snprintf(char *str, size_t size, const char *format, ...);