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