141b152c5f6ec3a5a6e51b4f8f0f90291a5895edcdarylm/** @file 241b152c5f6ec3a5a6e51b4f8f0f90291a5895edcdarylm stringlib: locale related helpers implementation. 341b152c5f6ec3a5a6e51b4f8f0f90291a5895edcdarylm 441b152c5f6ec3a5a6e51b4f8f0f90291a5895edcdarylm Copyright (c) 2011, Intel Corporation. All rights reserved.<BR> 541b152c5f6ec3a5a6e51b4f8f0f90291a5895edcdarylm This program and the accompanying materials are licensed and made available under 641b152c5f6ec3a5a6e51b4f8f0f90291a5895edcdarylm the terms and conditions of the BSD License that accompanies this distribution. 741b152c5f6ec3a5a6e51b4f8f0f90291a5895edcdarylm The full text of the license may be found at 841b152c5f6ec3a5a6e51b4f8f0f90291a5895edcdarylm http://opensource.org/licenses/bsd-license. 941b152c5f6ec3a5a6e51b4f8f0f90291a5895edcdarylm 1041b152c5f6ec3a5a6e51b4f8f0f90291a5895edcdarylm THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 1141b152c5f6ec3a5a6e51b4f8f0f90291a5895edcdarylm WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 1241b152c5f6ec3a5a6e51b4f8f0f90291a5895edcdarylm**/ 136c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 146c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm#ifndef STRINGLIB_LOCALEUTIL_H 156c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm#define STRINGLIB_LOCALEUTIL_H 166c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 176c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm#include <locale.h> 186c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 196c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm// Prevent conflicts with EFI 206c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm#undef MAX 216c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm#undef MIN 226c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 236c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm#define MAX(x, y) ((x) < (y) ? (y) : (x)) 246c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm#define MIN(x, y) ((x) < (y) ? (x) : (y)) 256c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 266c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylmtypedef struct { 276c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm const char *grouping; 286c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm char previous; 296c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t i; /* Where we're currently pointing in grouping. */ 306c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm} GroupGenerator; 316c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 326c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylmstatic void 336c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm_GroupGenerator_init(GroupGenerator *self, const char *grouping) 346c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm{ 356c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm self->grouping = grouping; 366c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm self->i = 0; 376c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm self->previous = 0; 386c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm} 396c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 406c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm/* Returns the next grouping, or 0 to signify end. */ 416c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylmstatic Py_ssize_t 426c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm_GroupGenerator_next(GroupGenerator *self) 436c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm{ 446c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm /* Note that we don't really do much error checking here. If a 456c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm grouping string contains just CHAR_MAX, for example, then just 466c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm terminate the generator. That shouldn't happen, but at least we 476c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm fail gracefully. */ 486c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm switch (self->grouping[self->i]) { 496c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm case 0: 506c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm return self->previous; 516c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm case CHAR_MAX: 526c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm /* Stop the generator. */ 536c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm return 0; 546c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm default: { 556c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm char ch = self->grouping[self->i]; 566c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm self->previous = ch; 576c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm self->i++; 586c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm return (Py_ssize_t)ch; 596c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm } 606c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm } 616c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm} 626c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 636c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm/* Fill in some digits, leading zeros, and thousands separator. All 646c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm are optional, depending on when we're called. */ 656c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylmstatic void 666c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylmfill(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end, 676c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t n_chars, Py_ssize_t n_zeros, const char* thousands_sep, 686c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t thousands_sep_len) 696c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm{ 706c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm#if STRINGLIB_IS_UNICODE 716c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t i; 726c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm#endif 736c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 746c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm if (thousands_sep) { 756c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm *buffer_end -= thousands_sep_len; 766c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 776c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm /* Copy the thousands_sep chars into the buffer. */ 786c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm#if STRINGLIB_IS_UNICODE 796c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm /* Convert from the char's of the thousands_sep from 806c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm the locale into unicode. */ 816c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm for (i = 0; i < thousands_sep_len; ++i) 826c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm (*buffer_end)[i] = thousands_sep[i]; 836c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm#else 846c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm /* No conversion, just memcpy the thousands_sep. */ 856c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm memcpy(*buffer_end, thousands_sep, thousands_sep_len); 866c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm#endif 876c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm } 886c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 896c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm *buffer_end -= n_chars; 906c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm *digits_end -= n_chars; 916c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm memcpy(*buffer_end, *digits_end, n_chars * sizeof(STRINGLIB_CHAR)); 926c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 936c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm *buffer_end -= n_zeros; 946c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm STRINGLIB_FILL(*buffer_end, '0', n_zeros); 956c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm} 966c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 976c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm/** 986c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * _Py_InsertThousandsGrouping: 996c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * @buffer: A pointer to the start of a string. 1006c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * @n_buffer: Number of characters in @buffer. 1016c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * @digits: A pointer to the digits we're reading from. If count 1026c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * is non-NULL, this is unused. 1036c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * @n_digits: The number of digits in the string, in which we want 1046c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * to put the grouping chars. 1056c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * @min_width: The minimum width of the digits in the output string. 1066c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * Output will be zero-padded on the left to fill. 1076c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * @grouping: see definition in localeconv(). 1086c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * @thousands_sep: see definition in localeconv(). 1096c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * 1106c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * There are 2 modes: counting and filling. If @buffer is NULL, 1116c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * we are in counting mode, else filling mode. 1126c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * If counting, the required buffer size is returned. 1136c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * If filling, we know the buffer will be large enough, so we don't 1146c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * need to pass in the buffer size. 1156c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * Inserts thousand grouping characters (as defined by grouping and 1166c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * thousands_sep) into the string between buffer and buffer+n_digits. 1176c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * 1186c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * Return value: 0 on error, else 1. Note that no error can occur if 1196c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * count is non-NULL. 1206c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * 1216c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * This name won't be used, the includer of this file should define 1226c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * it to be the actual function name, based on unicode or string. 1236c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * 1246c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * As closely as possible, this code mimics the logic in decimal.py's 1256c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm _insert_thousands_sep(). 1266c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm **/ 1276c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylmPy_ssize_t 1286c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm_Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer, 1296c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t n_buffer, 1306c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm STRINGLIB_CHAR *digits, 1316c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t n_digits, 1326c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t min_width, 1336c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm const char *grouping, 1346c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm const char *thousands_sep) 1356c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm{ 1366c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t count = 0; 1376c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t n_zeros; 1386c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm int loop_broken = 0; 1396c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm int use_separator = 0; /* First time through, don't append the 1406c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm separator. They only go between 1416c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm groups. */ 1426c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm STRINGLIB_CHAR *buffer_end = NULL; 1436c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm STRINGLIB_CHAR *digits_end = NULL; 1446c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t l; 1456c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t n_chars; 1466c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t thousands_sep_len = strlen(thousands_sep); 1476c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t remaining = n_digits; /* Number of chars remaining to 1486c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm be looked at */ 1496c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm /* A generator that returns all of the grouping widths, until it 1506c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm returns 0. */ 1516c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm GroupGenerator groupgen; 1526c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm _GroupGenerator_init(&groupgen, grouping); 1536c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 1546c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm if (buffer) { 1556c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm buffer_end = buffer + n_buffer; 1566c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm digits_end = digits + n_digits; 1576c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm } 1586c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 1596c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm while ((l = _GroupGenerator_next(&groupgen)) > 0) { 1606c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm l = MIN(l, MAX(MAX(remaining, min_width), 1)); 1616c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm n_zeros = MAX(0, l - remaining); 1626c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm n_chars = MAX(0, MIN(remaining, l)); 1636c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 1646c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm /* Use n_zero zero's and n_chars chars */ 1656c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 1666c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm /* Count only, don't do anything. */ 1676c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars; 1686c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 1696c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm if (buffer) { 1706c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm /* Copy into the output buffer. */ 1716c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm fill(&digits_end, &buffer_end, n_chars, n_zeros, 1726c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm use_separator ? thousands_sep : NULL, thousands_sep_len); 1736c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm } 1746c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 1756c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm /* Use a separator next time. */ 1766c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm use_separator = 1; 1776c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 1786c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm remaining -= n_chars; 1796c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm min_width -= l; 1806c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 1816c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm if (remaining <= 0 && min_width <= 0) { 1826c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm loop_broken = 1; 1836c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm break; 1846c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm } 1856c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm min_width -= thousands_sep_len; 1866c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm } 1876c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm if (!loop_broken) { 1886c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm /* We left the loop without using a break statement. */ 1896c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 1906c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm l = MAX(MAX(remaining, min_width), 1); 1916c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm n_zeros = MAX(0, l - remaining); 1926c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm n_chars = MAX(0, MIN(remaining, l)); 1936c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 1946c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm /* Use n_zero zero's and n_chars chars */ 1956c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars; 1966c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm if (buffer) { 1976c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm /* Copy into the output buffer. */ 1986c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm fill(&digits_end, &buffer_end, n_chars, n_zeros, 1996c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm use_separator ? thousands_sep : NULL, thousands_sep_len); 2006c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm } 2016c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm } 2026c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm return count; 2036c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm} 2046c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 2056c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm/** 2066c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * _Py_InsertThousandsGroupingLocale: 2076c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * @buffer: A pointer to the start of a string. 2086c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * @n_digits: The number of digits in the string, in which we want 2096c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * to put the grouping chars. 2106c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * 2116c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm * Reads thee current locale and calls _Py_InsertThousandsGrouping(). 2126c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm **/ 2136c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylmPy_ssize_t 2146c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm_Py_InsertThousandsGroupingLocale(STRINGLIB_CHAR *buffer, 2156c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t n_buffer, 2166c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm STRINGLIB_CHAR *digits, 2176c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t n_digits, 2186c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm Py_ssize_t min_width) 2196c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm{ 2206c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm struct lconv *locale_data = localeconv(); 2216c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm const char *grouping = locale_data->grouping; 2226c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm const char *thousands_sep = locale_data->thousands_sep; 2236c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm 2246c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm return _Py_InsertThousandsGrouping(buffer, n_buffer, digits, n_digits, 2256c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm min_width, grouping, thousands_sep); 2266c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm} 2276c0ebd5f2f53d5c4d6a91fd0b9148ba23e730c39darylm#endif /* STRINGLIB_LOCALEUTIL_H */ 228