1331722Seadler/* 288278Sphantom * Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org> 372321Sphantom * All rights reserved. 472321Sphantom * 572321Sphantom * Redistribution and use in source and binary forms, with or without 672321Sphantom * modification, are permitted provided that the following conditions 772321Sphantom * are met: 872321Sphantom * 1. Redistributions of source code must retain the above copyright 972321Sphantom * notice, this list of conditions and the following disclaimer. 1072321Sphantom * 2. Redistributions in binary form must reproduce the above copyright 1172321Sphantom * notice, this list of conditions and the following disclaimer in the 1272321Sphantom * documentation and/or other materials provided with the distribution. 1372321Sphantom * 1472321Sphantom * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1572321Sphantom * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1672321Sphantom * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1772321Sphantom * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1872321Sphantom * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1972321Sphantom * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2072321Sphantom * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2172321Sphantom * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2272321Sphantom * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2372321Sphantom * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2472321Sphantom * SUCH DAMAGE. 2572321Sphantom */ 2672321Sphantom 2792986Sobrien#include <sys/cdefs.h> 2892986Sobrien__FBSDID("$FreeBSD$"); 2992986Sobrien 3072333Sphantom#include <ctype.h> 3172321Sphantom#include <limits.h> 3272407Sphantom#include <stddef.h> 3372321Sphantom 3472321Sphantomstatic const char nogrouping[] = { CHAR_MAX, '\0' }; 3572321Sphantom 3672321Sphantom/* 37116875Sphantom * Internal helper used to convert grouping sequences from string 38116875Sphantom * representation into POSIX specified form, i.e. 39116875Sphantom * 40116875Sphantom * "3;3;-1" -> "\003\003\177\000" 4172321Sphantom */ 4272321Sphantom 4372321Sphantomconst char * 44116875Sphantom__fix_locale_grouping_str(const char *str) 45116875Sphantom{ 4672321Sphantom char *src, *dst; 4772333Sphantom char n; 4872321Sphantom 4972407Sphantom if (str == NULL || *str == '\0') { 5072321Sphantom return nogrouping; 5172321Sphantom } 5272321Sphantom 5372407Sphantom for (src = (char*)str, dst = (char*)str; *src != '\0'; src++) { 5472407Sphantom 5572321Sphantom /* input string examples: "3;3", "3;2;-1" */ 5672321Sphantom if (*src == ';') 5772321Sphantom continue; 5872321Sphantom 5972321Sphantom if (*src == '-' && *(src+1) == '1') { 6072321Sphantom *dst++ = CHAR_MAX; 6172321Sphantom src++; 6272321Sphantom continue; 6372321Sphantom } 6472321Sphantom 6572333Sphantom if (!isdigit((unsigned char)*src)) { 6672321Sphantom /* broken grouping string */ 6772321Sphantom return nogrouping; 6872321Sphantom } 6972321Sphantom 7087657Sphantom /* assume all numbers <= 99 */ 7187657Sphantom n = *src - '0'; 7287657Sphantom if (isdigit((unsigned char)*(src+1))) { 7387657Sphantom src++; 7472333Sphantom n *= 10; 7572333Sphantom n += *src - '0'; 7672333Sphantom } 7772333Sphantom 7872686Sache *dst = n; 7972686Sache /* NOTE: assume all input started with "0" as 'no grouping' */ 8072686Sache if (*dst == '\0') 8172686Sache return (dst == (char*)str) ? nogrouping : str; 8272686Sache dst++; 8372321Sphantom } 8472321Sphantom *dst = '\0'; 8572321Sphantom return str; 8672321Sphantom} 87