1041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner/*
2041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * Copyright (C) 2013 The Android Open Source Project
3041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * All rights reserved.
4041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner *
5041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * Redistribution and use in source and binary forms, with or without
6041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * modification, are permitted provided that the following conditions
7041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * are met:
8041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner *  * Redistributions of source code must retain the above copyright
9041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner *    notice, this list of conditions and the following disclaimer.
10041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner *  * Redistributions in binary form must reproduce the above copyright
11041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner *    notice, this list of conditions and the following disclaimer in
12041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner *    the documentation and/or other materials provided with the
13041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner *    distribution.
14041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner *
15041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner * SUCH DAMAGE.
27041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner */
28041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner#include <ctype.h>
29041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner#include <errno.h>
30041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner#include <limits.h>
31041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner#include <locale.h>
32041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner#include <stdio.h>
33041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner#include <stdlib.h>
34041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner#include <time.h>
35041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner#include <wctype.h>
36041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
37041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner// Contains an implementation of all locale-specific functions (those
38041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner// ending in _l, like strcoll_l()), as simple wrapper to the non-locale
39041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner// specific ones for now.
40041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner//
41041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner// That's because Android's C library doesn't support locales. Or more
42041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner// specifically, only supports the "C" one.
43041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner//
44041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner// TODO(digit): Write a more complete implementation that uses JNI to
45041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner//              invoke the platform APIs to implement proper handling.
46041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner//
47041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
48041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner///////////////////////////////////////////////////////////////////////
49041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner// stdio.h declarations
50041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
51041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turnerint vasprintf_l(char** strp, locale_t l, const char* fmt, va_list args) {
52041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    // Ignore locale.
53041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    return vasprintf(strp, fmt, args);
54041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner}
55041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
56041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turnerint asprintf_l(char** strp, locale_t locale, const char* fmt, ...) {
57041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    va_list args;
58041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    va_start(args, fmt);
59041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    int result = vasprintf_l(strp, locale, fmt, args);
60041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    va_end(args);
61041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    return result;
62041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner}
63041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
64041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turnerint vsprintf_l(char* str, locale_t l, const char* fmt, va_list args) {
65041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    // Ignore locale.
66041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    return vsprintf(str, fmt, args);
67041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner}
68041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
69041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turnerint sprintf_l(char* str, locale_t l, const char* fmt, ...) {
70041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    va_list args;
71041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    va_start(args, fmt);
72041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    int result = vsprintf_l(str, l, fmt, args);
73041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    va_end(args);
74041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    return result;
75041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner}
76041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
77041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turnerint vsnprintf_l(char* str, size_t size, locale_t l, const char* fmt, va_list args) {
78041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    return vsnprintf(str, size, fmt, args);
79041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner}
80041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
81041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turnerint snprintf_l(char* str, size_t size, locale_t l, const char* fmt, ...) {
82041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner  va_list args;
83041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner  va_start(args, fmt);
84041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner  int result = vsnprintf_l(str, size, l, fmt, args);
85041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner  va_end(args);
86041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner  return result;
87041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner}
88041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
89041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turnerint vsscanf_l(const char* str, locale_t l, const char* fmt, va_list args) {
90041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    return vsscanf(str, fmt, args);
91041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner}
92041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
93041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turnerint sscanf_l(const char* str, locale_t l, const char* fmt, ...) {
94041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    va_list args;
95041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    va_start(args, fmt);
96041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    int result = vsscanf_l(str, l, fmt, args);
97041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    va_end(args);
98041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    return result;
99041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner}
100041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
101041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner///////////////////////////////////////////////////////////////////////
102041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner// stdlib.h declarations
103041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
104041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turnerlong strtol_l(const char *nptr, char **endptr, int base, locale_t loc) {
105041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    return strtol(nptr, endptr, base);
106041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner}
107041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
108041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turnerunsigned long strtoul_l(const char *nptr, char **endptr, int base, locale_t loc) {
109041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    return strtoul(nptr, endptr, base);
110041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner}
111041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
112759ea774f2e1a237266dfef6a7cea0891777873bAndrew Hsiehlong long strtoll_l(const char *nptr, char **endptr, int base, locale_t loc) {
1137cd0bc09a50cce63a083e9d9c4555e3bb0dc001eAndrew Hsieh    return strtoll(nptr, endptr, base);
1147cd0bc09a50cce63a083e9d9c4555e3bb0dc001eAndrew Hsieh}
1157cd0bc09a50cce63a083e9d9c4555e3bb0dc001eAndrew Hsieh
116759ea774f2e1a237266dfef6a7cea0891777873bAndrew Hsiehunsigned long long strtoull_l(const char *nptr, char **endptr, int base, locale_t loc) {
117041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    return strtoull(nptr, endptr, base);
118041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner}
119041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner
120041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turnerlong double strtold_l (const char *nptr, char **endptr, locale_t loc) {
121041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner    return strtold(nptr, endptr);
122041656818eb2625982d4b55d176468a4bd07fb32David 'Digit' Turner}
123