lavu: add snprintf(), vsnprint() and strtod() replacements for MS runtime.
[libav.git] / compat / strtod.c
CommitLineData
4fa661a8
RB
1/*
2 * C99-compatible strtod() implementation
3 * Copyright (c) 2012 Ronald S. Bultje <rsbultje@gmail.com>
4 *
5 * This file is part of Libav.
6 *
7 * Libav is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * Libav is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include <ctype.h>
23#include <limits.h>
24#include <stdlib.h>
25
26#include "libavutil/avstring.h"
27#include "libavutil/mathematics.h"
28
29static char *check_nan_suffix(char *s)
30{
31 char *start = s;
32
33 if (*s++ != '(')
34 return start;
35
36 while ((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') ||
37 (*s >= '0' && *s <= '9') || *s == '_')
38 s++;
39
40 return *s == ')' ? s + 1 : start;
41}
42
43#undef strtod
44double strtod(const char *, char **);
45
46double avpriv_strtod(const char *nptr, char **endptr)
47{
48 char *end;
49 double res;
50
51 /* Skip leading spaces */
52 while (isspace(*nptr))
53 nptr++;
54
55 if (!av_strncasecmp(nptr, "infinity", 8)) {
56 end = nptr + 8;
57 res = INFINITY;
58 } else if (!av_strncasecmp(nptr, "inf", 3)) {
59 end = nptr + 3;
60 res = INFINITY;
61 } else if (!av_strncasecmp(nptr, "+infinity", 9)) {
62 end = nptr + 9;
63 res = INFINITY;
64 } else if (!av_strncasecmp(nptr, "+inf", 4)) {
65 end = nptr + 4;
66 res = INFINITY;
67 } else if (!av_strncasecmp(nptr, "-infinity", 9)) {
68 end = nptr + 9;
69 res = -INFINITY;
70 } else if (!av_strncasecmp(nptr, "-inf", 4)) {
71 end = nptr + 4;
72 res = -INFINITY;
73 } else if (!av_strncasecmp(nptr, "nan", 3)) {
74 end = check_nan_suffix(nptr + 3);
75 res = NAN;
76 } else if (!av_strncasecmp(nptr, "+nan", 4) ||
77 !av_strncasecmp(nptr, "-nan", 4)) {
78 end = check_nan_suffix(nptr + 4);
79 res = NAN;
80 } else if (!av_strncasecmp(nptr, "0x", 2) ||
81 !av_strncasecmp(nptr, "-0x", 3) ||
82 !av_strncasecmp(nptr, "+0x", 3)) {
83 /* FIXME this doesn't handle exponents, non-integers (float/double)
84 * and numbers too large for long long */
85 res = strtoll(nptr, &end, 16);
86 } else {
87 res = strtod(nptr, &end);
88 }
89
90 if (endptr)
91 *endptr = end;
92
93 return res;
94}