Home | History | Annotate | Line # | Download | only in locale
fix_grouping.c revision 1.5.6.1
      1  1.5.6.1     yamt /* $NetBSD: fix_grouping.c,v 1.5.6.1 2012/04/17 00:05:20 yamt Exp $ */
      2      1.1  tnozaki 
      3      1.1  tnozaki /*
      4      1.1  tnozaki  * Copyright (c) 2001 Alexey Zelkin <phantom (at) FreeBSD.org>
      5      1.1  tnozaki  * All rights reserved.
      6      1.1  tnozaki  *
      7      1.1  tnozaki  * Redistribution and use in source and binary forms, with or without
      8      1.1  tnozaki  * modification, are permitted provided that the following conditions
      9      1.1  tnozaki  * are met:
     10      1.1  tnozaki  * 1. Redistributions of source code must retain the above copyright
     11      1.1  tnozaki  *    notice, this list of conditions and the following disclaimer.
     12      1.1  tnozaki  * 2. Redistributions in binary form must reproduce the above copyright
     13      1.1  tnozaki  *    notice, this list of conditions and the following disclaimer in the
     14      1.1  tnozaki  *    documentation and/or other materials provided with the distribution.
     15      1.1  tnozaki  *
     16      1.1  tnozaki  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17      1.1  tnozaki  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18      1.1  tnozaki  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19      1.1  tnozaki  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20      1.1  tnozaki  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21      1.1  tnozaki  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22      1.1  tnozaki  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23      1.1  tnozaki  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24      1.1  tnozaki  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25      1.1  tnozaki  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26      1.1  tnozaki  * SUCH DAMAGE.
     27      1.1  tnozaki  *
     28      1.1  tnozaki  * Original version ID:
     29      1.1  tnozaki  *     FreeBSD: fix_grouping.c,v 1.8 2003/06/26 10:46:16 phantom Exp
     30      1.1  tnozaki  */
     31      1.1  tnozaki 
     32      1.3  tnozaki #if HAVE_NBTOOL_CONFIG_H
     33      1.3  tnozaki #include "nbtool_config.h"
     34      1.3  tnozaki #endif
     35      1.3  tnozaki 
     36      1.1  tnozaki #include <sys/cdefs.h>
     37      1.1  tnozaki #if defined(LIBC_SCCS) && !defined(lint)
     38  1.5.6.1     yamt __RCSID("$NetBSD: fix_grouping.c,v 1.5.6.1 2012/04/17 00:05:20 yamt Exp $");
     39      1.1  tnozaki #endif /* LIBC_SCCS and not lint */
     40      1.1  tnozaki 
     41      1.1  tnozaki #include <limits.h>
     42      1.1  tnozaki #include <stddef.h>
     43      1.1  tnozaki 
     44      1.1  tnozaki #include "fix_grouping.h"
     45      1.1  tnozaki 
     46      1.1  tnozaki #ifndef NBCHAR_MAX
     47  1.5.6.1     yamt #define NBCHAR_MAX	(char)CHAR_MAX
     48      1.1  tnozaki #endif
     49      1.1  tnozaki 
     50      1.2   dogcow #ifndef __UNCONST
     51      1.2   dogcow #define __UNCONST(a)    ((void *)(unsigned long)(const void *)(a))
     52      1.2   dogcow #endif
     53      1.2   dogcow 
     54      1.1  tnozaki static const char nogrouping[] = { NBCHAR_MAX, '\0' };
     55      1.1  tnozaki 
     56      1.1  tnozaki /* don't use libc's isdigit, it owes locale. */
     57      1.1  tnozaki #define isdigit(c)	(c >= '0' && c <= '9')
     58      1.1  tnozaki 
     59      1.1  tnozaki /*
     60      1.1  tnozaki  * Internal helper used to convert grouping sequences from string
     61      1.1  tnozaki  * representation into POSIX specified form, i.e.
     62      1.1  tnozaki  *
     63      1.1  tnozaki  * "3;3;-1" -> "\003\003\177\000"
     64      1.1  tnozaki  */
     65      1.1  tnozaki 
     66      1.1  tnozaki const char *
     67      1.1  tnozaki __fix_locale_grouping_str(const char *str)
     68      1.1  tnozaki {
     69      1.1  tnozaki 	char *src, *dst;
     70      1.1  tnozaki 	char n;
     71      1.1  tnozaki 
     72      1.1  tnozaki 	if (str == NULL || *str == '\0') {
     73      1.1  tnozaki 		return nogrouping;
     74      1.1  tnozaki 	}
     75      1.1  tnozaki 
     76      1.1  tnozaki 	for (src = __UNCONST(str), dst = __UNCONST(str); *src != '\0'; src++) {
     77      1.1  tnozaki 
     78      1.1  tnozaki 		/* input string examples: "3;3", "3;2;-1" */
     79      1.1  tnozaki 		if (*src == ';')
     80      1.1  tnozaki 			continue;
     81      1.1  tnozaki 
     82      1.1  tnozaki 		if (*src == '-' && *(src+1) == '1') {
     83      1.1  tnozaki 			*dst++ = NBCHAR_MAX;
     84      1.1  tnozaki 			src++;
     85      1.1  tnozaki 			continue;
     86      1.1  tnozaki 		}
     87      1.1  tnozaki 
     88      1.1  tnozaki 		if (!isdigit((unsigned char)*src)) {
     89      1.1  tnozaki 			/* broken grouping string */
     90      1.1  tnozaki 			return nogrouping;
     91      1.1  tnozaki 		}
     92      1.1  tnozaki 
     93      1.1  tnozaki 		/* assume all numbers <= 99 */
     94      1.1  tnozaki 		n = *src - '0';
     95      1.1  tnozaki 		if (isdigit((unsigned char)*(src+1))) {
     96      1.1  tnozaki 			src++;
     97      1.1  tnozaki 			n *= 10;
     98      1.1  tnozaki 			n += *src - '0';
     99      1.1  tnozaki 		}
    100      1.1  tnozaki 
    101      1.1  tnozaki 		*dst = n;
    102      1.1  tnozaki 		/* NOTE: assume all input started with "0" as 'no grouping' */
    103      1.1  tnozaki 		if (*dst == '\0')
    104      1.1  tnozaki 			return (dst == __UNCONST(str)) ? nogrouping : str;
    105      1.1  tnozaki 		dst++;
    106      1.1  tnozaki 	}
    107      1.1  tnozaki 	*dst = '\0';
    108      1.1  tnozaki 	return str;
    109      1.1  tnozaki }
    110