diff --git a/src/lib/libc/locale/Makefile b/src/lib/libc/locale/Makefile new file mode 100644 index 0000000..517c68e --- /dev/null +++ b/src/lib/libc/locale/Makefile @@ -0,0 +1,37 @@ +# $Id$ +# The System Makefile (C) 2002 The UbixOS Project + +# Include Global 'Source' Options +include ../../../Makefile.inc +include ../../Makefile.inc +include ../Makefile.inc + +INCLUDES += -I../locale/ + +#Objects +OBJS = big5.o btowc.o collate.o collcmp.o euc.o fix_grouping.o gb18030.o gb2312.o gbk.o isctype.o iswctype.o ldpart.o lmessages.o lmonetary.o lnumeric.o localeconv.o mblen.o mbrlen.o mbrtowc.o mbsinit.o mbsnrtowcs.o mbsrtowcs.o mbstowcs.o mbtowc.o mskanji.o nextwctype.o nl_langinfo.o nomacros.o none.o rpmatch.o rune.o runetype.o setlocale.o setrunelocale.o table.o tolower.o toupper.o utf8.o wcrtomb.o wcsftime.o wcsnrtombs.o wcsrtombs.o wcstod.o wcstof.o wcstoimax.o wcstol.o wcstold.o wcstoll.o wcstombs.o wcstoul.o wcstoull.o wcstoumax.o wctob.o wctomb.o wctrans.o wctype.o wcwidth.o +#Output +OUTPUT = libc.so + +$(OUTPUT): $(OBJS) + +# Compile the source files +.cc.o: + $(CXX) $(CFLAGS) -Wall -nostdlib -O $(INCLUDES) -c -o $@ $< + +.cc.s: + $(CXX) $(CFLAGS) -Wall -nostdlib -O $(INCLUDES) -S -o $@ $< + +.c.o: + $(CC) $(CFLAGS) -Wall -nostdlib -O $(INCLUDES) -c $< + +.c.s: + $(CC) $(CFLAGS) -Wall -nostdlib -O $(INCLUDES) -S -o $@ $< + +.S.o: + $(CC) $(CFLAGS) -Wall -nostdlib -c -o $@ $< + +# Clean up the junk +clean: + $(REMOVE) $(OBJS) $(OUTPUT) + diff --git a/src/lib/libc/locale/big5.c b/src/lib/libc/locale/big5.c new file mode 100644 index 0000000..7837591 --- /dev/null +++ b/src/lib/libc/locale/big5.c @@ -0,0 +1,172 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)big5.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/big5.c,v 1.17 2005/02/27 15:11:09 phantom Exp $"); + +#include +#include +#include +#include +#include +#include +#include "mblocal.h" + +static size_t _BIG5_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _BIG5_mbsinit(const mbstate_t *); +static size_t _BIG5_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); + +typedef struct { + wchar_t ch; +} _BIG5State; + +int +_BIG5_init(_RuneLocale *rl) +{ + + __mbrtowc = _BIG5_mbrtowc; + __wcrtomb = _BIG5_wcrtomb; + __mbsinit = _BIG5_mbsinit; + _CurrentRuneLocale = rl; + __mb_cur_max = 2; + return (0); +} + +static int +_BIG5_mbsinit(const mbstate_t *ps) +{ + + return (ps == NULL || ((const _BIG5State *)ps)->ch == 0); +} + +static __inline int +_big5_check(u_int c) +{ + + c &= 0xff; + return ((c >= 0xa1 && c <= 0xfe) ? 2 : 1); +} + +static size_t +_BIG5_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps) +{ + _BIG5State *bs; + wchar_t wc; + size_t len; + + bs = (_BIG5State *)ps; + + if ((bs->ch & ~0xFF) != 0) { + /* Bad conversion state. */ + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + + if (bs->ch != 0) { + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (bs->ch << 8) | (*s & 0xFF); + if (pwc != NULL) + *pwc = wc; + bs->ch = 0; + return (1); + } + + len = (size_t)_big5_check(*s); + wc = *s++ & 0xff; + if (len == 2) { + if (n < 2) { + /* Incomplete multibyte sequence */ + bs->ch = wc; + return ((size_t)-2); + } + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (wc << 8) | (*s++ & 0xff); + if (pwc != NULL) + *pwc = wc; + return (2); + } else { + if (pwc != NULL) + *pwc = wc; + return (wc == L'\0' ? 0 : 1); + } +} + +static size_t +_BIG5_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) +{ + _BIG5State *bs; + + bs = (_BIG5State *)ps; + + if (bs->ch != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if (wc & 0x8000) { + *s++ = (wc >> 8) & 0xff; + *s = wc & 0xff; + return (2); + } + *s = wc & 0xff; + return (1); +} diff --git a/src/lib/libc/locale/btowc.c b/src/lib/libc/locale/btowc.c new file mode 100644 index 0000000..44b501e --- /dev/null +++ b/src/lib/libc/locale/btowc.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2002, 2003 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/btowc.c,v 1.4 2004/05/12 14:26:54 tjr Exp $"); + +#include +#include +#include "mblocal.h" + +wint_t +btowc(int c) +{ + static const mbstate_t initial; + mbstate_t mbs = initial; + char cc; + wchar_t wc; + + if (c == EOF) + return (WEOF); + /* + * We expect mbrtowc() to return 0 or 1, hence the check for n > 1 + * which detects error return values as well as "impossible" byte + * counts. + */ + cc = (char)c; + if (__mbrtowc(&wc, &cc, 1, &mbs) > 1) + return (WEOF); + return (wc); +} diff --git a/src/lib/libc/locale/collate.c b/src/lib/libc/locale/collate.c new file mode 100644 index 0000000..184fac6 --- /dev/null +++ b/src/lib/libc/locale/collate.c @@ -0,0 +1,298 @@ +/*- + * Copyright (c) 1995 Alex Tatmanjants + * at Electronni Visti IA, Kiev, Ukraine. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/collate.c,v 1.35 2005/02/27 20:31:13 ru Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "collate.h" +#include "setlocale.h" +#include "ldpart.h" + +#include "libc_private.h" + +int __collate_load_error = 1; +int __collate_substitute_nontrivial; + +u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; +struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; +struct __collate_st_chain_pri *__collate_chain_pri_table; + +void __collate_err(int ex, const char *f) __dead2; + +int +__collate_load_tables(const char *encoding) +{ + FILE *fp; + int i, saverr, chains; + uint32_t u32; + char strbuf[STR_LEN], buf[PATH_MAX]; + void *TMP_substitute_table, *TMP_char_pri_table, *TMP_chain_pri_table; + static char collate_encoding[ENCODING_LEN + 1]; + + /* 'encoding' must be already checked. */ + if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { + __collate_load_error = 1; + return (_LDP_CACHE); + } + + /* + * If the locale name is the same as our cache, use the cache. + */ + if (strcmp(encoding, collate_encoding) == 0) { + __collate_load_error = 0; + return (_LDP_CACHE); + } + + /* + * Slurp the locale file into the cache. + */ + + /* 'PathLocale' must be already set & checked. */ + /* Range checking not needed, encoding has fixed size */ + (void)strcpy(buf, _PathLocale); + (void)strcat(buf, "/"); + (void)strcat(buf, encoding); + (void)strcat(buf, "/LC_COLLATE"); + if ((fp = fopen(buf, "r")) == NULL) + return (_LDP_ERROR); + + if (fread(strbuf, sizeof(strbuf), 1, fp) != 1) { + saverr = errno; + (void)fclose(fp); + errno = saverr; + return (_LDP_ERROR); + } + chains = -1; + if (strcmp(strbuf, COLLATE_VERSION) == 0) + chains = 0; + else if (strcmp(strbuf, COLLATE_VERSION1_2) == 0) + chains = 1; + if (chains < 0) { + (void)fclose(fp); + errno = EFTYPE; + return (_LDP_ERROR); + } + if (chains) { + if (fread(&u32, sizeof(u32), 1, fp) != 1) { + saverr = errno; + (void)fclose(fp); + errno = saverr; + return (_LDP_ERROR); + } + if ((chains = (int)ntohl(u32)) < 1) { + (void)fclose(fp); + errno = EFTYPE; + return (_LDP_ERROR); + } + } else + chains = TABLE_SIZE; + + if ((TMP_substitute_table = + malloc(sizeof(__collate_substitute_table))) == NULL) { + saverr = errno; + (void)fclose(fp); + errno = saverr; + return (_LDP_ERROR); + } + if ((TMP_char_pri_table = + malloc(sizeof(__collate_char_pri_table))) == NULL) { + saverr = errno; + free(TMP_substitute_table); + (void)fclose(fp); + errno = saverr; + return (_LDP_ERROR); + } + if ((TMP_chain_pri_table = + malloc(sizeof(*__collate_chain_pri_table) * chains)) == NULL) { + saverr = errno; + free(TMP_substitute_table); + free(TMP_char_pri_table); + (void)fclose(fp); + errno = saverr; + return (_LDP_ERROR); + } + +#define FREAD(a, b, c, d) \ +{ \ + if (fread(a, b, c, d) != c) { \ + saverr = errno; \ + free(TMP_substitute_table); \ + free(TMP_char_pri_table); \ + free(TMP_chain_pri_table); \ + (void)fclose(d); \ + errno = saverr; \ + return (_LDP_ERROR); \ + } \ +} + + FREAD(TMP_substitute_table, sizeof(__collate_substitute_table), 1, fp); + FREAD(TMP_char_pri_table, sizeof(__collate_char_pri_table), 1, fp); + FREAD(TMP_chain_pri_table, + sizeof(*__collate_chain_pri_table), chains, fp); + (void)fclose(fp); + + (void)strcpy(collate_encoding, encoding); + if (__collate_substitute_table_ptr != NULL) + free(__collate_substitute_table_ptr); + __collate_substitute_table_ptr = TMP_substitute_table; + if (__collate_char_pri_table_ptr != NULL) + free(__collate_char_pri_table_ptr); + __collate_char_pri_table_ptr = TMP_char_pri_table; + for (i = 0; i < UCHAR_MAX + 1; i++) { + __collate_char_pri_table[i].prim = + ntohl(__collate_char_pri_table[i].prim); + __collate_char_pri_table[i].sec = + ntohl(__collate_char_pri_table[i].sec); + } + if (__collate_chain_pri_table != NULL) + free(__collate_chain_pri_table); + __collate_chain_pri_table = TMP_chain_pri_table; + for (i = 0; i < chains; i++) { + __collate_chain_pri_table[i].prim = + ntohl(__collate_chain_pri_table[i].prim); + __collate_chain_pri_table[i].sec = + ntohl(__collate_chain_pri_table[i].sec); + } + __collate_substitute_nontrivial = 0; + for (i = 0; i < UCHAR_MAX + 1; i++) { + if (__collate_substitute_table[i][0] != i || + __collate_substitute_table[i][1] != 0) { + __collate_substitute_nontrivial = 1; + break; + } + } + __collate_load_error = 0; + + return (_LDP_LOADED); +} + +u_char * +__collate_substitute(const u_char *s) +{ + int dest_len, len, nlen; + int delta = strlen(s); + u_char *dest_str = NULL; + + if (s == NULL || *s == '\0') + return (__collate_strdup("")); + delta += delta / 8; + dest_str = malloc(dest_len = delta); + if (dest_str == NULL) + __collate_err(EX_OSERR, __func__); + len = 0; + while (*s) { + nlen = len + strlen(__collate_substitute_table[*s]); + if (dest_len <= nlen) { + dest_str = reallocf(dest_str, dest_len = nlen + delta); + if (dest_str == NULL) + __collate_err(EX_OSERR, __func__); + } + (void)strcpy(dest_str + len, __collate_substitute_table[*s++]); + len = nlen; + } + return (dest_str); +} + +void +__collate_lookup(const u_char *t, int *len, int *prim, int *sec) +{ + struct __collate_st_chain_pri *p2; + + *len = 1; + *prim = *sec = 0; + for (p2 = __collate_chain_pri_table; p2->str[0] != '\0'; p2++) { + if (*t == p2->str[0] && + strncmp(t, p2->str, strlen(p2->str)) == 0) { + *len = strlen(p2->str); + *prim = p2->prim; + *sec = p2->sec; + return; + } + } + *prim = __collate_char_pri_table[*t].prim; + *sec = __collate_char_pri_table[*t].sec; +} + +u_char * +__collate_strdup(u_char *s) +{ + u_char *t = strdup(s); + + if (t == NULL) + __collate_err(EX_OSERR, __func__); + return (t); +} + +void +__collate_err(int ex, const char *f) +{ + const char *s; + int serrno = errno; + + s = _getprogname(); + _write(STDERR_FILENO, s, strlen(s)); + _write(STDERR_FILENO, ": ", 2); + s = f; + _write(STDERR_FILENO, s, strlen(s)); + _write(STDERR_FILENO, ": ", 2); + s = strerror(serrno); + _write(STDERR_FILENO, s, strlen(s)); + _write(STDERR_FILENO, "\n", 1); + exit(ex); +} + +#ifdef COLLATE_DEBUG +void +__collate_print_tables() +{ + int i; + struct __collate_st_chain_pri *p2; + + printf("Substitute table:\n"); + for (i = 0; i < UCHAR_MAX + 1; i++) + if (i != *__collate_substitute_table[i]) + printf("\t'%c' --> \"%s\"\n", i, + __collate_substitute_table[i]); + printf("Chain priority table:\n"); + for (p2 = __collate_chain_pri_table; p2->str[0] != '\0'; p2++) + printf("\t\"%s\" : %d %d\n", p2->str, p2->prim, p2->sec); + printf("Char priority table:\n"); + for (i = 0; i < UCHAR_MAX + 1; i++) + printf("\t'%c' : %d %d\n", i, __collate_char_pri_table[i].prim, + __collate_char_pri_table[i].sec); +} +#endif diff --git a/src/lib/libc/locale/collate.h b/src/lib/libc/locale/collate.h new file mode 100644 index 0000000..a8d2176 --- /dev/null +++ b/src/lib/libc/locale/collate.h @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 1995 Alex Tatmanjants + * at Electronni Visti IA, Kiev, Ukraine. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/locale/collate.h,v 1.15 2005/02/27 20:31:13 ru Exp $ + */ + +#ifndef _COLLATE_H_ +#define _COLLATE_H_ + +#include +#include +#include + +#define STR_LEN 10 +#define TABLE_SIZE 100 +#define COLLATE_VERSION "1.0\n" +#define COLLATE_VERSION1_2 "1.2\n" + +struct __collate_st_char_pri { + int prim, sec; +}; +struct __collate_st_chain_pri { + u_char str[STR_LEN]; + int prim, sec; +}; + +extern int __collate_load_error; +extern int __collate_substitute_nontrivial; +#define __collate_substitute_table (*__collate_substitute_table_ptr) +extern u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN]; +#define __collate_char_pri_table (*__collate_char_pri_table_ptr) +extern struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1]; +extern struct __collate_st_chain_pri *__collate_chain_pri_table; + +__BEGIN_DECLS +u_char *__collate_strdup(u_char *); +u_char *__collate_substitute(const u_char *); +int __collate_load_tables(const char *); +void __collate_lookup(const u_char *, int *, int *, int *); +int __collate_range_cmp(int, int); +#ifdef COLLATE_DEBUG +void __collate_print_tables(void); +#endif +__END_DECLS + +#endif /* !_COLLATE_H_ */ diff --git a/src/lib/libc/locale/collcmp.c b/src/lib/libc/locale/collcmp.c new file mode 100644 index 0000000..dde67a4 --- /dev/null +++ b/src/lib/libc/locale/collcmp.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 1996 by Andrey A. Chernov, Moscow, Russia. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/collcmp.c,v 1.18 2005/02/27 14:54:23 phantom Exp $"); + +#include +#include "collate.h" + +/* + * Compare two characters using collate + */ + +int __collate_range_cmp(int c1, int c2) +{ + static char s1[2], s2[2]; + + s1[0] = c1; + s2[0] = c2; + return (strcoll(s1, s2)); +} diff --git a/src/lib/libc/locale/euc.c b/src/lib/libc/locale/euc.c new file mode 100644 index 0000000..32f8fb8 --- /dev/null +++ b/src/lib/libc/locale/euc.c @@ -0,0 +1,265 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)euc.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/euc.c,v 1.21 2005/02/27 15:11:09 phantom Exp $"); + +#include +#include +#include +#include +#include +#include +#include "mblocal.h" + +static size_t _EUC_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _EUC_mbsinit(const mbstate_t *); +static size_t _EUC_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); + +typedef struct { + int count[4]; + wchar_t bits[4]; + wchar_t mask; +} _EucInfo; + +typedef struct { + wchar_t ch; + int set; + int want; +} _EucState; + +int +_EUC_init(_RuneLocale *rl) +{ + _EucInfo *ei; + int x, new__mb_cur_max; + char *v, *e; + + if (rl->__variable == NULL) + return (EFTYPE); + + v = (char *)rl->__variable; + + while (*v == ' ' || *v == '\t') + ++v; + + if ((ei = malloc(sizeof(_EucInfo))) == NULL) + return (errno == 0 ? ENOMEM : errno); + + new__mb_cur_max = 0; + for (x = 0; x < 4; ++x) { + ei->count[x] = (int)strtol(v, &e, 0); + if (v == e || !(v = e)) { + free(ei); + return (EFTYPE); + } + if (new__mb_cur_max < ei->count[x]) + new__mb_cur_max = ei->count[x]; + while (*v == ' ' || *v == '\t') + ++v; + ei->bits[x] = (int)strtol(v, &e, 0); + if (v == e || !(v = e)) { + free(ei); + return (EFTYPE); + } + while (*v == ' ' || *v == '\t') + ++v; + } + ei->mask = (int)strtol(v, &e, 0); + if (v == e || !(v = e)) { + free(ei); + return (EFTYPE); + } + rl->__variable = ei; + rl->__variable_len = sizeof(_EucInfo); + _CurrentRuneLocale = rl; + __mb_cur_max = new__mb_cur_max; + __mbrtowc = _EUC_mbrtowc; + __wcrtomb = _EUC_wcrtomb; + __mbsinit = _EUC_mbsinit; + return (0); +} + +static int +_EUC_mbsinit(const mbstate_t *ps) +{ + + return (ps == NULL || ((const _EucState *)ps)->want == 0); +} + +#define CEI ((_EucInfo *)(_CurrentRuneLocale->__variable)) + +#define _SS2 0x008e +#define _SS3 0x008f + +#define GR_BITS 0x80808080 /* XXX: to be fixed */ + +static __inline int +_euc_set(u_int c) +{ + + c &= 0xff; + return ((c & 0x80) ? c == _SS3 ? 3 : c == _SS2 ? 2 : 1 : 0); +} + +static size_t +_EUC_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps) +{ + _EucState *es; + int i, set, want; + wchar_t wc; + const char *os; + + es = (_EucState *)ps; + + if (es->want < 0 || es->want > MB_CUR_MAX || es->set < 0 || + es->set > 3) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + + os = s; + + if (es->want == 0) { + want = CEI->count[set = _euc_set(*s)]; + if (set == 2 || set == 3) { + --want; + if (--n == 0) { + /* Incomplete multibyte sequence */ + es->set = set; + es->want = want; + es->ch = 0; + return ((size_t)-2); + } + ++s; + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + } + wc = (unsigned char)*s++; + } else { + set = es->set; + want = es->want; + wc = es->ch; + } + for (i = (es->want == 0) ? 1 : 0; i < MIN(want, n); i++) { + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (wc << 8) | (unsigned char)*s++; + } + if (i < want) { + /* Incomplete multibyte sequence */ + es->set = set; + es->want = want - i; + es->ch = wc; + return ((size_t)-2); + } + wc = (wc & ~CEI->mask) | CEI->bits[set]; + if (pwc != NULL) + *pwc = wc; + es->want = 0; + return (wc == L'\0' ? 0 : s - os); +} + +static size_t +_EUC_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) +{ + _EucState *es; + wchar_t m, nm; + int i, len; + + es = (_EucState *)ps; + + if (es->want != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + + m = wc & CEI->mask; + nm = wc & ~m; + + if (m == CEI->bits[1]) { +CodeSet1: + /* Codeset 1: The first byte must have 0x80 in it. */ + i = len = CEI->count[1]; + while (i-- > 0) + *s++ = (nm >> (i << 3)) | 0x80; + } else { + if (m == CEI->bits[0]) + i = len = CEI->count[0]; + else if (m == CEI->bits[2]) { + i = len = CEI->count[2]; + *s++ = _SS2; + --i; + /* SS2 designates G2 into GR */ + nm |= GR_BITS; + } else if (m == CEI->bits[3]) { + i = len = CEI->count[3]; + *s++ = _SS3; + --i; + /* SS3 designates G3 into GR */ + nm |= GR_BITS; + } else + goto CodeSet1; /* Bletch */ + while (i-- > 0) + *s++ = (nm >> (i << 3)) & 0xff; + } + return (len); +} diff --git a/src/lib/libc/locale/fix_grouping.c b/src/lib/libc/locale/fix_grouping.c new file mode 100644 index 0000000..ab08f3f --- /dev/null +++ b/src/lib/libc/locale/fix_grouping.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/fix_grouping.c,v 1.8 2003/06/26 10:46:16 phantom Exp $"); + +#include +#include +#include + +static const char nogrouping[] = { CHAR_MAX, '\0' }; + +/* + * Internal helper used to convert grouping sequences from string + * representation into POSIX specified form, i.e. + * + * "3;3;-1" -> "\003\003\177\000" + */ + +const char * +__fix_locale_grouping_str(const char *str) +{ + char *src, *dst; + char n; + + if (str == NULL || *str == '\0') { + return nogrouping; + } + + for (src = (char*)str, dst = (char*)str; *src != '\0'; src++) { + + /* input string examples: "3;3", "3;2;-1" */ + if (*src == ';') + continue; + + if (*src == '-' && *(src+1) == '1') { + *dst++ = CHAR_MAX; + src++; + continue; + } + + if (!isdigit((unsigned char)*src)) { + /* broken grouping string */ + return nogrouping; + } + + /* assume all numbers <= 99 */ + n = *src - '0'; + if (isdigit((unsigned char)*(src+1))) { + src++; + n *= 10; + n += *src - '0'; + } + + *dst = n; + /* NOTE: assume all input started with "0" as 'no grouping' */ + if (*dst == '\0') + return (dst == (char*)str) ? nogrouping : str; + dst++; + } + *dst = '\0'; + return str; +} diff --git a/src/lib/libc/locale/gb18030.c b/src/lib/libc/locale/gb18030.c new file mode 100644 index 0000000..b5c5240 --- /dev/null +++ b/src/lib/libc/locale/gb18030.c @@ -0,0 +1,218 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * PRC National Standard GB 18030-2000 encoding of Chinese text. + * + * See gb18030(5) for details. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/gb18030.c,v 1.7 2005/02/27 15:11:09 phantom Exp $"); + +#include +#include +#include +#include +#include +#include "mblocal.h" + +static size_t _GB18030_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _GB18030_mbsinit(const mbstate_t *); +static size_t _GB18030_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); + +typedef struct { + int count; + u_char bytes[4]; +} _GB18030State; + +int +_GB18030_init(_RuneLocale *rl) +{ + + __mbrtowc = _GB18030_mbrtowc; + __wcrtomb = _GB18030_wcrtomb; + __mbsinit = _GB18030_mbsinit; + _CurrentRuneLocale = rl; + __mb_cur_max = 4; + + return (0); +} + +static int +_GB18030_mbsinit(const mbstate_t *ps) +{ + + return (ps == NULL || ((const _GB18030State *)ps)->count == 0); +} + +static size_t +_GB18030_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, + size_t n, mbstate_t * __restrict ps) +{ + _GB18030State *gs; + wchar_t wch; + int ch, len, ocount; + size_t ncopy; + + gs = (_GB18030State *)ps; + + if (gs->count < 0 || gs->count > sizeof(gs->bytes)) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + ncopy = MIN(MIN(n, MB_CUR_MAX), sizeof(gs->bytes) - gs->count); + memcpy(gs->bytes + gs->count, s, ncopy); + ocount = gs->count; + gs->count += ncopy; + s = (char *)gs->bytes; + n = gs->count; + + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + + /* + * Single byte: [00-7f] + * Two byte: [81-fe][40-7e,80-fe] + * Four byte: [81-fe][30-39][81-fe][30-39] + */ + ch = (unsigned char)*s++; + if (ch <= 0x7f) { + len = 1; + wch = ch; + } else if (ch >= 0x81 && ch <= 0xfe) { + wch = ch; + if (n < 2) + return ((size_t)-2); + ch = (unsigned char)*s++; + if ((ch >= 0x40 && ch <= 0x7e) || (ch >= 0x80 && ch <= 0xfe)) { + wch = (wch << 8) | ch; + len = 2; + } else if (ch >= 0x30 && ch <= 0x39) { + /* + * Strip high bit off the wide character we will + * eventually output so that it is positive when + * cast to wint_t on 32-bit twos-complement machines. + */ + wch = ((wch & 0x7f) << 8) | ch; + if (n < 3) + return ((size_t)-2); + ch = (unsigned char)*s++; + if (ch < 0x81 || ch > 0xfe) + goto ilseq; + wch = (wch << 8) | ch; + if (n < 4) + return ((size_t)-2); + ch = (unsigned char)*s++; + if (ch < 0x30 || ch > 0x39) + goto ilseq; + wch = (wch << 8) | ch; + len = 4; + } else + goto ilseq; + } else + goto ilseq; + + if (pwc != NULL) + *pwc = wch; + gs->count = 0; + return (wch == L'\0' ? 0 : len - ocount); +ilseq: + errno = EILSEQ; + return ((size_t)-1); +} + +static size_t +_GB18030_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) +{ + _GB18030State *gs; + size_t len; + int c; + + gs = (_GB18030State *)ps; + + if (gs->count != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if ((wc & ~0x7fffffff) != 0) + goto ilseq; + if (wc & 0x7f000000) { + /* Replace high bit that mbrtowc() removed. */ + wc |= 0x80000000; + c = (wc >> 24) & 0xff; + if (c < 0x81 || c > 0xfe) + goto ilseq; + *s++ = c; + c = (wc >> 16) & 0xff; + if (c < 0x30 || c > 0x39) + goto ilseq; + *s++ = c; + c = (wc >> 8) & 0xff; + if (c < 0x81 || c > 0xfe) + goto ilseq; + *s++ = c; + c = wc & 0xff; + if (c < 0x30 || c > 0x39) + goto ilseq; + *s++ = c; + len = 4; + } else if (wc & 0x00ff0000) + goto ilseq; + else if (wc & 0x0000ff00) { + c = (wc >> 8) & 0xff; + if (c < 0x81 || c > 0xfe) + goto ilseq; + *s++ = c; + c = wc & 0xff; + if (c < 0x40 || c == 0x7f || c == 0xff) + goto ilseq; + *s++ = c; + len = 2; + } else if (wc <= 0x7f) { + *s++ = wc; + len = 1; + } else + goto ilseq; + + return (len); +ilseq: + errno = EILSEQ; + return ((size_t)-1); +} diff --git a/src/lib/libc/locale/gb2312.c b/src/lib/libc/locale/gb2312.c new file mode 100644 index 0000000..0f89ddb --- /dev/null +++ b/src/lib/libc/locale/gb2312.c @@ -0,0 +1,154 @@ +/*- + * Copyright (c) 2004 Tim J. Robbins. All rights reserved. + * Copyright (c) 2003 David Xu + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/gb2312.c,v 1.9 2005/02/27 15:11:09 phantom Exp $"); + +#include +#include +#include +#include +#include +#include "mblocal.h" + +static size_t _GB2312_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _GB2312_mbsinit(const mbstate_t *); +static size_t _GB2312_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); + +typedef struct { + int count; + u_char bytes[2]; +} _GB2312State; + +int +_GB2312_init(_RuneLocale *rl) +{ + + _CurrentRuneLocale = rl; + __mbrtowc = _GB2312_mbrtowc; + __wcrtomb = _GB2312_wcrtomb; + __mbsinit = _GB2312_mbsinit; + __mb_cur_max = 2; + return (0); +} + +static int +_GB2312_mbsinit(const mbstate_t *ps) +{ + + return (ps == NULL || ((const _GB2312State *)ps)->count == 0); +} + +static __inline int +_GB2312_check(const char *str, size_t n) +{ + const u_char *s = (const u_char *)str; + + if (n == 0) + /* Incomplete multibyte sequence */ + return (-2); + if (s[0] >= 0xa1 && s[0] <= 0xfe) { + if (n < 2) + /* Incomplete multibyte sequence */ + return (-2); + if (s[1] < 0xa1 || s[1] > 0xfe) + /* Invalid multibyte sequence */ + return (-1); + return (2); + } else if (s[0] & 0x80) { + /* Invalid multibyte sequence */ + return (-1); + } + return (1); +} + +static size_t +_GB2312_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps) +{ + _GB2312State *gs; + wchar_t wc; + int i, len, ocount; + size_t ncopy; + + gs = (_GB2312State *)ps; + + if (gs->count < 0 || gs->count > sizeof(gs->bytes)) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + ncopy = MIN(MIN(n, MB_CUR_MAX), sizeof(gs->bytes) - gs->count); + memcpy(gs->bytes + gs->count, s, ncopy); + ocount = gs->count; + gs->count += ncopy; + s = (char *)gs->bytes; + n = gs->count; + + if ((len = _GB2312_check(s, n)) < 0) + return ((size_t)len); + wc = 0; + i = len; + while (i-- > 0) + wc = (wc << 8) | (unsigned char)*s++; + if (pwc != NULL) + *pwc = wc; + gs->count = 0; + return (wc == L'\0' ? 0 : len - ocount); +} + +static size_t +_GB2312_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) +{ + _GB2312State *gs; + + gs = (_GB2312State *)ps; + + if (gs->count != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if (wc & 0x8000) { + *s++ = (wc >> 8) & 0xff; + *s = wc & 0xff; + return (2); + } + *s = wc & 0xff; + return (1); +} diff --git a/src/lib/libc/locale/gbk.c b/src/lib/libc/locale/gbk.c new file mode 100644 index 0000000..33f5e48 --- /dev/null +++ b/src/lib/libc/locale/gbk.c @@ -0,0 +1,169 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/gbk.c,v 1.12 2005/02/27 15:11:09 phantom Exp $"); + +#include +#include +#include +#include +#include +#include +#include "mblocal.h" + +static size_t _GBK_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _GBK_mbsinit(const mbstate_t *); +static size_t _GBK_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); + +typedef struct { + wchar_t ch; +} _GBKState; + +int +_GBK_init(_RuneLocale *rl) +{ + + __mbrtowc = _GBK_mbrtowc; + __wcrtomb = _GBK_wcrtomb; + __mbsinit = _GBK_mbsinit; + _CurrentRuneLocale = rl; + __mb_cur_max = 2; + return (0); +} + +static int +_GBK_mbsinit(const mbstate_t *ps) +{ + + return (ps == NULL || ((const _GBKState *)ps)->ch == 0); +} + +static __inline int +_gbk_check(u_int c) +{ + + c &= 0xff; + return ((c >= 0x81 && c <= 0xfe) ? 2 : 1); +} + +static size_t +_GBK_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps) +{ + _GBKState *gs; + wchar_t wc; + size_t len; + + gs = (_GBKState *)ps; + + if ((gs->ch & ~0xFF) != 0) { + /* Bad conversion state. */ + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + + if (gs->ch != 0) { + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (gs->ch << 8) | (*s & 0xFF); + if (pwc != NULL) + *pwc = wc; + gs->ch = 0; + return (1); + } + + len = (size_t)_gbk_check(*s); + wc = *s++ & 0xff; + if (len == 2) { + if (n < 2) { + /* Incomplete multibyte sequence */ + gs->ch = wc; + return ((size_t)-2); + } + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (wc << 8) | (*s++ & 0xff); + if (pwc != NULL) + *pwc = wc; + return (2); + } else { + if (pwc != NULL) + *pwc = wc; + return (wc == L'\0' ? 0 : 1); + } +} + +static size_t +_GBK_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) +{ + _GBKState *gs; + + gs = (_GBKState *)ps; + + if (gs->ch != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if (wc & 0x8000) { + *s++ = (wc >> 8) & 0xff; + *s = wc & 0xff; + return (2); + } + *s = wc & 0xff; + return (1); +} diff --git a/src/lib/libc/locale/isctype.c b/src/lib/libc/locale/isctype.c new file mode 100644 index 0000000..d718b77 --- /dev/null +++ b/src/lib/libc/locale/isctype.c @@ -0,0 +1,233 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)isctype.c 8.3 (Berkeley) 2/24/94"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/isctype.c,v 1.9 2002/08/17 20:03:44 ache Exp $"); + +#include + +#undef digittoint +int +digittoint(c) + int c; +{ + return (__maskrune(c, 0xFF)); +} + +#undef isalnum +int +isalnum(c) + int c; +{ + return (__istype(c, _CTYPE_A|_CTYPE_D)); +} + +#undef isalpha +int +isalpha(c) + int c; +{ + return (__istype(c, _CTYPE_A)); +} + +#undef isascii +int +isascii(c) + int c; +{ + return ((c & ~0x7F) == 0); +} + +#undef isblank +int +isblank(c) + int c; +{ + return (__istype(c, _CTYPE_B)); +} + +#undef iscntrl +int +iscntrl(c) + int c; +{ + return (__istype(c, _CTYPE_C)); +} + +#undef isdigit +int +isdigit(c) + int c; +{ + return (__isctype(c, _CTYPE_D)); +} + +#undef isgraph +int +isgraph(c) + int c; +{ + return (__istype(c, _CTYPE_G)); +} + +#undef ishexnumber +int +ishexnumber(c) + int c; +{ + return (__istype(c, _CTYPE_X)); +} + +#undef isideogram +int +isideogram(c) + int c; +{ + return (__istype(c, _CTYPE_I)); +} + +#undef islower +int +islower(c) + int c; +{ + return (__istype(c, _CTYPE_L)); +} + +#undef isnumber +int +isnumber(c) + int c; +{ + return (__istype(c, _CTYPE_D)); +} + +#undef isphonogram +int +isphonogram(c) + int c; +{ + return (__istype(c, _CTYPE_Q)); +} + +#undef isprint +int +isprint(c) + int c; +{ + return (__istype(c, _CTYPE_R)); +} + +#undef ispunct +int +ispunct(c) + int c; +{ + return (__istype(c, _CTYPE_P)); +} + +#undef isrune +int +isrune(c) + int c; +{ + return (__istype(c, 0xFFFFFF00L)); +} + +#undef isspace +int +isspace(c) + int c; +{ + return (__istype(c, _CTYPE_S)); +} + +#undef isspecial +int +isspecial(c) + int c; +{ + return (__istype(c, _CTYPE_T)); +} + +#undef isupper +int +isupper(c) + int c; +{ + return (__istype(c, _CTYPE_U)); +} + +#undef isxdigit +int +isxdigit(c) + int c; +{ + return (__isctype(c, _CTYPE_X)); +} + +#undef toascii +int +toascii(c) + int c; +{ + return (c & 0x7F); +} + +#undef tolower +int +tolower(c) + int c; +{ + return (__tolower(c)); +} + +#undef toupper +int +toupper(c) + int c; +{ + return (__toupper(c)); +} + diff --git a/src/lib/libc/locale/iswctype.c b/src/lib/libc/locale/iswctype.c new file mode 100644 index 0000000..37e2656 --- /dev/null +++ b/src/lib/libc/locale/iswctype.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/iswctype.c,v 1.6 2002/08/17 20:30:34 ache Exp $"); + +#include + +#undef iswalnum +int +iswalnum(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_A|_CTYPE_D)); +} + +#undef iswalpha +int +iswalpha(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_A)); +} + +#undef iswascii +int +iswascii(wc) + wint_t wc; +{ + return ((wc & ~0x7F) == 0); +} + +#undef iswblank +int +iswblank(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_B)); +} + +#undef iswcntrl +int +iswcntrl(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_C)); +} + +#undef iswdigit +int +iswdigit(wc) + wint_t wc; +{ + return (__isctype(wc, _CTYPE_D)); +} + +#undef iswgraph +int +iswgraph(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_G)); +} + +#undef iswhexnumber +int +iswhexnumber(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_X)); +} + +#undef iswideogram +int +iswideogram(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_I)); +} + +#undef iswlower +int +iswlower(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_L)); +} + +#undef iswnumber +int +iswnumber(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_D)); +} + +#undef iswphonogram +int +iswphonogram(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_Q)); +} + +#undef iswprint +int +iswprint(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_R)); +} + +#undef iswpunct +int +iswpunct(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_P)); +} + +#undef iswrune +int +iswrune(wc) + wint_t wc; +{ + return (__istype(wc, 0xFFFFFF00L)); +} + +#undef iswspace +int +iswspace(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_S)); +} + +#undef iswspecial +int +iswspecial(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_T)); +} + +#undef iswupper +int +iswupper(wc) + wint_t wc; +{ + return (__istype(wc, _CTYPE_U)); +} + +#undef iswxdigit +int +iswxdigit(wc) + wint_t wc; +{ + return (__isctype(wc, _CTYPE_X)); +} + +#undef towlower +wint_t +towlower(wc) + wint_t wc; +{ + return (__tolower(wc)); +} + +#undef towupper +wint_t +towupper(wc) + wint_t wc; +{ + return (__toupper(wc)); +} + diff --git a/src/lib/libc/locale/ldpart.c b/src/lib/libc/locale/ldpart.c new file mode 100644 index 0000000..932165f --- /dev/null +++ b/src/lib/libc/locale/ldpart.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/ldpart.c,v 1.15 2004/04/25 19:56:50 ache Exp $"); + +#include "namespace.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "ldpart.h" +#include "setlocale.h" + +static int split_lines(char *, const char *); + +int +__part_load_locale(const char *name, + int *using_locale, + char **locale_buf, + const char *category_filename, + int locale_buf_size_max, + int locale_buf_size_min, + const char **dst_localebuf) +{ + int saverr, fd, i, num_lines; + char *lbuf, *p; + const char *plim; + char filename[PATH_MAX]; + struct stat st; + size_t namesize, bufsize; + + /* 'name' must be already checked. */ + if (strcmp(name, "C") == 0 || strcmp(name, "POSIX") == 0) { + *using_locale = 0; + return (_LDP_CACHE); + } + + /* + * If the locale name is the same as our cache, use the cache. + */ + if (*locale_buf != NULL && strcmp(name, *locale_buf) == 0) { + *using_locale = 1; + return (_LDP_CACHE); + } + + /* + * Slurp the locale file into the cache. + */ + namesize = strlen(name) + 1; + + /* 'PathLocale' must be already set & checked. */ + + /* Range checking not needed, 'name' size is limited */ + strcpy(filename, _PathLocale); + strcat(filename, "/"); + strcat(filename, name); + strcat(filename, "/"); + strcat(filename, category_filename); + if ((fd = _open(filename, O_RDONLY)) < 0) + return (_LDP_ERROR); + if (_fstat(fd, &st) != 0) + goto bad_locale; + if (st.st_size <= 0) { + errno = EFTYPE; + goto bad_locale; + } + bufsize = namesize + st.st_size; + if ((lbuf = malloc(bufsize)) == NULL) { + errno = ENOMEM; + goto bad_locale; + } + (void)strcpy(lbuf, name); + p = lbuf + namesize; + plim = p + st.st_size; + if (_read(fd, p, (size_t) st.st_size) != st.st_size) + goto bad_lbuf; + /* + * Parse the locale file into localebuf. + */ + if (plim[-1] != '\n') { + errno = EFTYPE; + goto bad_lbuf; + } + num_lines = split_lines(p, plim); + if (num_lines >= locale_buf_size_max) + num_lines = locale_buf_size_max; + else if (num_lines >= locale_buf_size_min) + num_lines = locale_buf_size_min; + else { + errno = EFTYPE; + goto bad_lbuf; + } + (void)_close(fd); + /* + * Record the successful parse in the cache. + */ + if (*locale_buf != NULL) + free(*locale_buf); + *locale_buf = lbuf; + for (p = *locale_buf, i = 0; i < num_lines; i++) + dst_localebuf[i] = (p += strlen(p) + 1); + for (i = num_lines; i < locale_buf_size_max; i++) + dst_localebuf[i] = NULL; + *using_locale = 1; + + return (_LDP_LOADED); + +bad_lbuf: + saverr = errno; + free(lbuf); + errno = saverr; +bad_locale: + saverr = errno; + (void)_close(fd); + errno = saverr; + + return (_LDP_ERROR); +} + +static int +split_lines(char *p, const char *plim) +{ + int i; + + i = 0; + while (p < plim) { + if (*p == '\n') { + *p = '\0'; + i++; + } + p++; + } + return (i); +} + diff --git a/src/lib/libc/locale/ldpart.h b/src/lib/libc/locale/ldpart.h new file mode 100644 index 0000000..02e0c95 --- /dev/null +++ b/src/lib/libc/locale/ldpart.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/locale/ldpart.h,v 1.6 2003/06/13 00:14:07 jkh Exp $ + */ + +#ifndef _LDPART_H_ +#define _LDPART_H_ + +#define _LDP_LOADED 0 +#define _LDP_ERROR (-1) +#define _LDP_CACHE 1 + +int __part_load_locale(const char *, int*, char **, const char *, + int, int, const char **); + +#endif /* !_LDPART_H_ */ diff --git a/src/lib/libc/locale/lmessages.c b/src/lib/libc/locale/lmessages.c new file mode 100644 index 0000000..488b572 --- /dev/null +++ b/src/lib/libc/locale/lmessages.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/lmessages.c,v 1.14 2003/06/26 10:46:16 phantom Exp $"); + +#include + +#include "ldpart.h" +#include "lmessages.h" + +#define LCMESSAGES_SIZE_FULL (sizeof(struct lc_messages_T) / sizeof(char *)) +#define LCMESSAGES_SIZE_MIN \ + (offsetof(struct lc_messages_T, yesstr) / sizeof(char *)) + +static char empty[] = ""; + +static const struct lc_messages_T _C_messages_locale = { + "^[yY]" , /* yesexpr */ + "^[nN]" , /* noexpr */ + "yes" , /* yesstr */ + "no" /* nostr */ +}; + +static struct lc_messages_T _messages_locale; +static int _messages_using_locale; +static char *_messages_locale_buf; + +int +__messages_load_locale(const char *name) +{ + int ret; + + ret = __part_load_locale(name, &_messages_using_locale, + &_messages_locale_buf, "LC_MESSAGES", + LCMESSAGES_SIZE_FULL, LCMESSAGES_SIZE_MIN, + (const char **)&_messages_locale); + if (ret == _LDP_LOADED) { + if (_messages_locale.yesstr == NULL) + _messages_locale.yesstr = empty; + if (_messages_locale.nostr == NULL) + _messages_locale.nostr = empty; + } + return (ret); +} + +struct lc_messages_T * +__get_current_messages_locale(void) +{ + return (_messages_using_locale + ? &_messages_locale + : (struct lc_messages_T *)&_C_messages_locale); +} + +#ifdef LOCALE_DEBUG +void +msgdebug() { +printf( "yesexpr = %s\n" + "noexpr = %s\n" + "yesstr = %s\n" + "nostr = %s\n", + _messages_locale.yesexpr, + _messages_locale.noexpr, + _messages_locale.yesstr, + _messages_locale.nostr +); +} +#endif /* LOCALE_DEBUG */ diff --git a/src/lib/libc/locale/lmessages.h b/src/lib/libc/locale/lmessages.h new file mode 100644 index 0000000..ee690ae --- /dev/null +++ b/src/lib/libc/locale/lmessages.h @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/locale/lmessages.h,v 1.3 2001/12/20 18:28:52 phantom Exp $ + */ + +#ifndef _LMESSAGES_H_ +#define _LMESSAGES_H_ + +struct lc_messages_T { + const char *yesexpr; + const char *noexpr; + const char *yesstr; + const char *nostr; +}; + +struct lc_messages_T *__get_current_messages_locale(void); +int __messages_load_locale(const char *); + +#endif /* !_LMESSAGES_H_ */ diff --git a/src/lib/libc/locale/lmonetary.c b/src/lib/libc/locale/lmonetary.c new file mode 100644 index 0000000..e3e7095 --- /dev/null +++ b/src/lib/libc/locale/lmonetary.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/lmonetary.c,v 1.19 2003/06/26 10:46:16 phantom Exp $"); + +#include +#include +#include + +#include "ldpart.h" +#include "lmonetary.h" + +extern int __mlocale_changed; +extern const char * __fix_locale_grouping_str(const char *); + +#define LCMONETARY_SIZE_FULL (sizeof(struct lc_monetary_T) / sizeof(char *)) +#define LCMONETARY_SIZE_MIN \ + (offsetof(struct lc_monetary_T, int_p_cs_precedes) / \ + sizeof(char *)) + +static char empty[] = ""; +static char numempty[] = { CHAR_MAX, '\0'}; + +static const struct lc_monetary_T _C_monetary_locale = { + empty, /* int_curr_symbol */ + empty, /* currency_symbol */ + empty, /* mon_decimal_point */ + empty, /* mon_thousands_sep */ + numempty, /* mon_grouping */ + empty, /* positive_sign */ + empty, /* negative_sign */ + numempty, /* int_frac_digits */ + numempty, /* frac_digits */ + numempty, /* p_cs_precedes */ + numempty, /* p_sep_by_space */ + numempty, /* n_cs_precedes */ + numempty, /* n_sep_by_space */ + numempty, /* p_sign_posn */ + numempty, /* n_sign_posn */ + numempty, /* int_p_cs_precedes */ + numempty, /* int_n_cs_precedes */ + numempty, /* int_p_sep_by_space */ + numempty, /* int_n_sep_by_space */ + numempty, /* int_p_sign_posn */ + numempty /* int_n_sign_posn */ +}; + +static struct lc_monetary_T _monetary_locale; +static int _monetary_using_locale; +static char *_monetary_locale_buf; + +static char +cnv(const char *str) +{ + int i = strtol(str, NULL, 10); + + if (i == -1) + i = CHAR_MAX; + return ((char)i); +} + +int +__monetary_load_locale(const char *name) +{ + int ret; + + ret = __part_load_locale(name, &_monetary_using_locale, + &_monetary_locale_buf, "LC_MONETARY", + LCMONETARY_SIZE_FULL, LCMONETARY_SIZE_MIN, + (const char **)&_monetary_locale); + if (ret != _LDP_ERROR) + __mlocale_changed = 1; + if (ret == _LDP_LOADED) { + _monetary_locale.mon_grouping = + __fix_locale_grouping_str(_monetary_locale.mon_grouping); + +#define M_ASSIGN_CHAR(NAME) (((char *)_monetary_locale.NAME)[0] = \ + cnv(_monetary_locale.NAME)) + + M_ASSIGN_CHAR(int_frac_digits); + M_ASSIGN_CHAR(frac_digits); + M_ASSIGN_CHAR(p_cs_precedes); + M_ASSIGN_CHAR(p_sep_by_space); + M_ASSIGN_CHAR(n_cs_precedes); + M_ASSIGN_CHAR(n_sep_by_space); + M_ASSIGN_CHAR(p_sign_posn); + M_ASSIGN_CHAR(n_sign_posn); + + /* + * The six additional C99 international monetary formatting + * parameters default to the national parameters when + * reading FreeBSD LC_MONETARY data files. + */ +#define M_ASSIGN_ICHAR(NAME) \ + do { \ + if (_monetary_locale.int_##NAME == NULL) \ + _monetary_locale.int_##NAME = \ + _monetary_locale.NAME; \ + else \ + M_ASSIGN_CHAR(int_##NAME); \ + } while (0) + + M_ASSIGN_ICHAR(p_cs_precedes); + M_ASSIGN_ICHAR(n_cs_precedes); + M_ASSIGN_ICHAR(p_sep_by_space); + M_ASSIGN_ICHAR(n_sep_by_space); + M_ASSIGN_ICHAR(p_sign_posn); + M_ASSIGN_ICHAR(n_sign_posn); + } + return (ret); +} + +struct lc_monetary_T * +__get_current_monetary_locale(void) +{ + return (_monetary_using_locale + ? &_monetary_locale + : (struct lc_monetary_T *)&_C_monetary_locale); +} + +#ifdef LOCALE_DEBUG +void +monetdebug() { +printf( "int_curr_symbol = %s\n" + "currency_symbol = %s\n" + "mon_decimal_point = %s\n" + "mon_thousands_sep = %s\n" + "mon_grouping = %s\n" + "positive_sign = %s\n" + "negative_sign = %s\n" + "int_frac_digits = %d\n" + "frac_digits = %d\n" + "p_cs_precedes = %d\n" + "p_sep_by_space = %d\n" + "n_cs_precedes = %d\n" + "n_sep_by_space = %d\n" + "p_sign_posn = %d\n" + "n_sign_posn = %d\n", + "int_p_cs_precedes = %d\n" + "int_p_sep_by_space = %d\n" + "int_n_cs_precedes = %d\n" + "int_n_sep_by_space = %d\n" + "int_p_sign_posn = %d\n" + "int_n_sign_posn = %d\n", + _monetary_locale.int_curr_symbol, + _monetary_locale.currency_symbol, + _monetary_locale.mon_decimal_point, + _monetary_locale.mon_thousands_sep, + _monetary_locale.mon_grouping, + _monetary_locale.positive_sign, + _monetary_locale.negative_sign, + _monetary_locale.int_frac_digits[0], + _monetary_locale.frac_digits[0], + _monetary_locale.p_cs_precedes[0], + _monetary_locale.p_sep_by_space[0], + _monetary_locale.n_cs_precedes[0], + _monetary_locale.n_sep_by_space[0], + _monetary_locale.p_sign_posn[0], + _monetary_locale.n_sign_posn[0], + _monetary_locale.int_p_cs_precedes[0], + _monetary_locale.int_p_sep_by_space[0], + _monetary_locale.int_n_cs_precedes[0], + _monetary_locale.int_n_sep_by_space[0], + _monetary_locale.int_p_sign_posn[0], + _monetary_locale.int_n_sign_posn[0] +); +} +#endif /* LOCALE_DEBUG */ diff --git a/src/lib/libc/locale/lmonetary.h b/src/lib/libc/locale/lmonetary.h new file mode 100644 index 0000000..e278ea5 --- /dev/null +++ b/src/lib/libc/locale/lmonetary.h @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/locale/lmonetary.h,v 1.4 2002/10/09 09:19:28 tjr Exp $ + */ + +#ifndef _LMONETARY_H_ +#define _LMONETARY_H_ + +struct lc_monetary_T { + const char *int_curr_symbol; + const char *currency_symbol; + const char *mon_decimal_point; + const char *mon_thousands_sep; + const char *mon_grouping; + const char *positive_sign; + const char *negative_sign; + const char *int_frac_digits; + const char *frac_digits; + const char *p_cs_precedes; + const char *p_sep_by_space; + const char *n_cs_precedes; + const char *n_sep_by_space; + const char *p_sign_posn; + const char *n_sign_posn; + const char *int_p_cs_precedes; + const char *int_n_cs_precedes; + const char *int_p_sep_by_space; + const char *int_n_sep_by_space; + const char *int_p_sign_posn; + const char *int_n_sign_posn; +}; + +struct lc_monetary_T *__get_current_monetary_locale(void); +int __monetary_load_locale(const char *); + +#endif /* !_LMONETARY_H_ */ diff --git a/src/lib/libc/locale/lnumeric.c b/src/lib/libc/locale/lnumeric.c new file mode 100644 index 0000000..ff9c948 --- /dev/null +++ b/src/lib/libc/locale/lnumeric.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/lnumeric.c,v 1.16 2003/06/26 10:46:16 phantom Exp $"); + +#include + +#include "ldpart.h" +#include "lnumeric.h" + +extern int __nlocale_changed; +extern const char *__fix_locale_grouping_str(const char *); + +#define LCNUMERIC_SIZE (sizeof(struct lc_numeric_T) / sizeof(char *)) + +static char numempty[] = { CHAR_MAX, '\0' }; + +static const struct lc_numeric_T _C_numeric_locale = { + ".", /* decimal_point */ + "", /* thousands_sep */ + numempty /* grouping */ +}; + +static struct lc_numeric_T _numeric_locale; +static int _numeric_using_locale; +static char *_numeric_locale_buf; + +int +__numeric_load_locale(const char *name) +{ + int ret; + + ret = __part_load_locale(name, &_numeric_using_locale, + &_numeric_locale_buf, "LC_NUMERIC", + LCNUMERIC_SIZE, LCNUMERIC_SIZE, + (const char **)&_numeric_locale); + if (ret != _LDP_ERROR) + __nlocale_changed = 1; + if (ret == _LDP_LOADED) { + /* Can't be empty according to C99 */ + if (*_numeric_locale.decimal_point == '\0') + _numeric_locale.decimal_point = + _C_numeric_locale.decimal_point; + _numeric_locale.grouping = + __fix_locale_grouping_str(_numeric_locale.grouping); + } + return (ret); +} + +struct lc_numeric_T * +__get_current_numeric_locale(void) +{ + return (_numeric_using_locale + ? &_numeric_locale + : (struct lc_numeric_T *)&_C_numeric_locale); +} + +#ifdef LOCALE_DEBUG +void +numericdebug(void) { +printf( "decimal_point = %s\n" + "thousands_sep = %s\n" + "grouping = %s\n", + _numeric_locale.decimal_point, + _numeric_locale.thousands_sep, + _numeric_locale.grouping +); +} +#endif /* LOCALE_DEBUG */ diff --git a/src/lib/libc/locale/lnumeric.h b/src/lib/libc/locale/lnumeric.h new file mode 100644 index 0000000..9678c1f --- /dev/null +++ b/src/lib/libc/locale/lnumeric.h @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/locale/lnumeric.h,v 1.3 2001/12/20 18:28:52 phantom Exp $ + */ + +#ifndef _LNUMERIC_H_ +#define _LNUMERIC_H_ + +struct lc_numeric_T { + const char *decimal_point; + const char *thousands_sep; + const char *grouping; +}; + +struct lc_numeric_T *__get_current_numeric_locale(void); +int __numeric_load_locale(const char *); + +#endif /* !_LNUMERIC_H_ */ diff --git a/src/lib/libc/locale/localeconv.c b/src/lib/libc/locale/localeconv.c new file mode 100644 index 0000000..1420aa8 --- /dev/null +++ b/src/lib/libc/locale/localeconv.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2001 Alexey Zelkin + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)localeconv.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/localeconv.c,v 1.13 2003/06/26 10:46:16 phantom Exp $"); + +#include + +#include "lmonetary.h" +#include "lnumeric.h" + +/* + * The localeconv() function constructs a struct lconv from the current + * monetary and numeric locales. + * + * Because localeconv() may be called many times (especially by library + * routines like printf() & strtod()), the approprate members of the + * lconv structure are computed only when the monetary or numeric + * locale has been changed. + */ +int __mlocale_changed = 1; +int __nlocale_changed = 1; + +/* + * Return the current locale conversion. + */ +struct lconv * +localeconv() +{ + static struct lconv ret; + + if (__mlocale_changed) { + /* LC_MONETARY part */ + struct lc_monetary_T * mptr; + +#define M_ASSIGN_STR(NAME) (ret.NAME = (char*)mptr->NAME) +#define M_ASSIGN_CHAR(NAME) (ret.NAME = mptr->NAME[0]) + + mptr = __get_current_monetary_locale(); + M_ASSIGN_STR(int_curr_symbol); + M_ASSIGN_STR(currency_symbol); + M_ASSIGN_STR(mon_decimal_point); + M_ASSIGN_STR(mon_thousands_sep); + M_ASSIGN_STR(mon_grouping); + M_ASSIGN_STR(positive_sign); + M_ASSIGN_STR(negative_sign); + M_ASSIGN_CHAR(int_frac_digits); + M_ASSIGN_CHAR(frac_digits); + M_ASSIGN_CHAR(p_cs_precedes); + M_ASSIGN_CHAR(p_sep_by_space); + M_ASSIGN_CHAR(n_cs_precedes); + M_ASSIGN_CHAR(n_sep_by_space); + M_ASSIGN_CHAR(p_sign_posn); + M_ASSIGN_CHAR(n_sign_posn); + M_ASSIGN_CHAR(int_p_cs_precedes); + M_ASSIGN_CHAR(int_n_cs_precedes); + M_ASSIGN_CHAR(int_p_sep_by_space); + M_ASSIGN_CHAR(int_n_sep_by_space); + M_ASSIGN_CHAR(int_p_sign_posn); + M_ASSIGN_CHAR(int_n_sign_posn); + __mlocale_changed = 0; + } + + if (__nlocale_changed) { + /* LC_NUMERIC part */ + struct lc_numeric_T * nptr; + +#define N_ASSIGN_STR(NAME) (ret.NAME = (char*)nptr->NAME) + + nptr = __get_current_numeric_locale(); + N_ASSIGN_STR(decimal_point); + N_ASSIGN_STR(thousands_sep); + N_ASSIGN_STR(grouping); + __nlocale_changed = 0; + } + + return (&ret); +} diff --git a/src/lib/libc/locale/mblen.c b/src/lib/libc/locale/mblen.c new file mode 100644 index 0000000..2891e90 --- /dev/null +++ b/src/lib/libc/locale/mblen.c @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/mblen.c,v 1.9 2004/07/29 06:18:40 tjr Exp $"); + +#include +#include +#include "mblocal.h" + +int +mblen(const char *s, size_t n) +{ + static const mbstate_t initial; + static mbstate_t mbs; + size_t rval; + + if (s == NULL) { + /* No support for state dependent encodings. */ + mbs = initial; + return (0); + } + rval = __mbrtowc(NULL, s, n, &mbs); + if (rval == (size_t)-1 || rval == (size_t)-2) + return (-1); + return ((int)rval); +} diff --git a/src/lib/libc/locale/mblocal.h b/src/lib/libc/locale/mblocal.h new file mode 100644 index 0000000..63c5b16 --- /dev/null +++ b/src/lib/libc/locale/mblocal.h @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/locale/mblocal.h,v 1.5 2005/02/27 15:11:09 phantom Exp $ + */ + +#ifndef _MBLOCAL_H_ +#define _MBLOCAL_H_ + +/* + * Rune initialization function prototypes. + */ +int _none_init(_RuneLocale *); +int _UTF8_init(_RuneLocale *); +int _EUC_init(_RuneLocale *); +int _GB18030_init(_RuneLocale *); +int _GB2312_init(_RuneLocale *); +int _GBK_init(_RuneLocale *); +int _BIG5_init(_RuneLocale *); +int _MSKanji_init(_RuneLocale *); + +/* + * Conversion function pointers for current encoding. + */ +extern size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +extern int (*__mbsinit)(const mbstate_t *); +extern size_t (*__mbsnrtowcs)(wchar_t * __restrict, const char ** __restrict, + size_t, size_t, mbstate_t * __restrict); +extern size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict); +extern size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict); + +extern size_t __mbsnrtowcs_std(wchar_t * __restrict, const char ** __restrict, + size_t, size_t, mbstate_t * __restrict); +extern size_t __wcsnrtombs_std(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict); + +#endif /* _MBLOCAL_H_ */ diff --git a/src/lib/libc/locale/mbrlen.c b/src/lib/libc/locale/mbrlen.c new file mode 100644 index 0000000..33f7ea0 --- /dev/null +++ b/src/lib/libc/locale/mbrlen.c @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/mbrlen.c,v 1.4 2004/05/12 14:26:54 tjr Exp $"); + +#include +#include "mblocal.h" + +size_t +mbrlen(const char * __restrict s, size_t n, mbstate_t * __restrict ps) +{ + static mbstate_t mbs; + + if (ps == NULL) + ps = &mbs; + return (__mbrtowc(NULL, s, n, ps)); +} diff --git a/src/lib/libc/locale/mbrtowc.c b/src/lib/libc/locale/mbrtowc.c new file mode 100644 index 0000000..9b19d10 --- /dev/null +++ b/src/lib/libc/locale/mbrtowc.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/mbrtowc.c,v 1.7 2004/05/12 14:09:04 tjr Exp $"); + +#include +#include "mblocal.h" + +size_t +mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, + size_t n, mbstate_t * __restrict ps) +{ + static mbstate_t mbs; + + if (ps == NULL) + ps = &mbs; + return (__mbrtowc(pwc, s, n, ps)); +} diff --git a/src/lib/libc/locale/mbsinit.c b/src/lib/libc/locale/mbsinit.c new file mode 100644 index 0000000..cddb567 --- /dev/null +++ b/src/lib/libc/locale/mbsinit.c @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/mbsinit.c,v 1.3 2004/05/12 14:09:04 tjr Exp $"); + +#include +#include "mblocal.h" + +int +mbsinit(const mbstate_t *ps) +{ + + return (__mbsinit(ps)); +} diff --git a/src/lib/libc/locale/mbsnrtowcs.c b/src/lib/libc/locale/mbsnrtowcs.c new file mode 100644 index 0000000..3e65b15 --- /dev/null +++ b/src/lib/libc/locale/mbsnrtowcs.c @@ -0,0 +1,91 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/mbsnrtowcs.c,v 1.1 2004/07/21 10:54:57 tjr Exp $"); + +#include +#include +#include +#include +#include "mblocal.h" + +size_t +mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, + size_t nms, size_t len, mbstate_t * __restrict ps) +{ + static mbstate_t mbs; + + if (ps == NULL) + ps = &mbs; + return (__mbsnrtowcs(dst, src, nms, len, ps)); +} + +size_t +__mbsnrtowcs_std(wchar_t * __restrict dst, const char ** __restrict src, + size_t nms, size_t len, mbstate_t * __restrict ps) +{ + const char *s; + size_t nchr; + wchar_t wc; + size_t nb; + + s = *src; + nchr = 0; + + if (dst == NULL) { + for (;;) { + if ((nb = __mbrtowc(&wc, s, nms, ps)) == (size_t)-1) + /* Invalid sequence - mbrtowc() sets errno. */ + return ((size_t)-1); + else if (nb == 0 || nb == (size_t)-2) + return (nchr); + s += nb; + nms -= nb; + nchr++; + } + /*NOTREACHED*/ + } + + while (len-- > 0) { + if ((nb = __mbrtowc(dst, s, nms, ps)) == (size_t)-1) { + *src = s; + return ((size_t)-1); + } else if (nb == (size_t)-2) { + *src = s + nms; + return (nchr); + } else if (nb == 0) { + *src = NULL; + return (nchr); + } + s += nb; + nms -= nb; + nchr++; + dst++; + } + *src = s; + return (nchr); +} diff --git a/src/lib/libc/locale/mbsrtowcs.c b/src/lib/libc/locale/mbsrtowcs.c new file mode 100644 index 0000000..12feaab --- /dev/null +++ b/src/lib/libc/locale/mbsrtowcs.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/mbsrtowcs.c,v 1.6 2004/07/21 10:54:57 tjr Exp $"); + +#include +#include +#include +#include +#include "mblocal.h" + +size_t +mbsrtowcs(wchar_t * __restrict dst, const char ** __restrict src, size_t len, + mbstate_t * __restrict ps) +{ + static mbstate_t mbs; + + if (ps == NULL) + ps = &mbs; + return (__mbsnrtowcs(dst, src, SIZE_T_MAX, len, ps)); +} diff --git a/src/lib/libc/locale/mbstowcs.c b/src/lib/libc/locale/mbstowcs.c new file mode 100644 index 0000000..ab2e849 --- /dev/null +++ b/src/lib/libc/locale/mbstowcs.c @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/mbstowcs.c,v 1.11 2004/07/21 10:54:57 tjr Exp $"); + +#include +#include +#include +#include "mblocal.h" + +size_t +mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n) +{ + static const mbstate_t initial; + mbstate_t mbs; + + mbs = initial; + return (__mbsnrtowcs(pwcs, &s, SIZE_T_MAX, n, &mbs)); +} diff --git a/src/lib/libc/locale/mbtowc.c b/src/lib/libc/locale/mbtowc.c new file mode 100644 index 0000000..5e3a368 --- /dev/null +++ b/src/lib/libc/locale/mbtowc.c @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/mbtowc.c,v 1.11 2004/07/29 06:18:40 tjr Exp $"); + +#include +#include +#include "mblocal.h" + +int +mbtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n) +{ + static const mbstate_t initial; + static mbstate_t mbs; + size_t rval; + + if (s == NULL) { + /* No support for state dependent encodings. */ + mbs = initial; + return (0); + } + rval = __mbrtowc(pwc, s, n, &mbs); + if (rval == (size_t)-1 || rval == (size_t)-2) + return (-1); + return ((int)rval); +} diff --git a/src/lib/libc/locale/mskanji.c b/src/lib/libc/locale/mskanji.c new file mode 100644 index 0000000..9735d3a --- /dev/null +++ b/src/lib/libc/locale/mskanji.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. + * + * ja_JP.SJIS locale table for BSD4.4/rune + * version 1.0 + * (C) Sin'ichiro MIYATANI / Phase One, Inc + * May 12, 1995 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Phase One, Inc. + * 4. The name of Phase One, Inc. may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)mskanji.c 1.0 (Phase One) 5/5/95"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/mskanji.c,v 1.17 2005/02/27 15:11:09 phantom Exp $"); + +#include +#include +#include +#include +#include +#include +#include "mblocal.h" + +static size_t _MSKanji_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _MSKanji_mbsinit(const mbstate_t *); +static size_t _MSKanji_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); + +typedef struct { + wchar_t ch; +} _MSKanjiState; + +int +_MSKanji_init(_RuneLocale *rl) +{ + + __mbrtowc = _MSKanji_mbrtowc; + __wcrtomb = _MSKanji_wcrtomb; + __mbsinit = _MSKanji_mbsinit; + _CurrentRuneLocale = rl; + __mb_cur_max = 2; + return (0); +} + +static int +_MSKanji_mbsinit(const mbstate_t *ps) +{ + + return (ps == NULL || ((const _MSKanjiState *)ps)->ch == 0); +} + +static size_t +_MSKanji_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps) +{ + _MSKanjiState *ms; + wchar_t wc; + + ms = (_MSKanjiState *)ps; + + if ((ms->ch & ~0xFF) != 0) { + /* Bad conversion state. */ + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + + if (ms->ch != 0) { + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (ms->ch << 8) | (*s & 0xFF); + if (pwc != NULL) + *pwc = wc; + ms->ch = 0; + return (1); + } + wc = *s++ & 0xff; + if ((wc > 0x80 && wc < 0xa0) || (wc >= 0xe0 && wc < 0xfd)) { + if (n < 2) { + /* Incomplete multibyte sequence */ + ms->ch = wc; + return ((size_t)-2); + } + if (*s == '\0') { + errno = EILSEQ; + return ((size_t)-1); + } + wc = (wc << 8) | (*s++ & 0xff); + if (pwc != NULL) + *pwc = wc; + return (2); + } else { + if (pwc != NULL) + *pwc = wc; + return (wc == L'\0' ? 0 : 1); + } +} + +static size_t +_MSKanji_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) +{ + _MSKanjiState *ms; + int len, i; + + ms = (_MSKanjiState *)ps; + + if (ms->ch != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + len = (wc > 0x100) ? 2 : 1; + for (i = len; i-- > 0; ) + *s++ = wc >> (i << 3); + return (len); +} diff --git a/src/lib/libc/locale/nextwctype.c b/src/lib/libc/locale/nextwctype.c new file mode 100644 index 0000000..89c63df --- /dev/null +++ b/src/lib/libc/locale/nextwctype.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/nextwctype.c,v 1.1 2004/07/08 06:43:37 tjr Exp $"); + +#include +#include +#include + +wint_t +nextwctype(wint_t wc, wctype_t wct) +{ + size_t lim; + _RuneRange *rr = &_CurrentRuneLocale->__runetype_ext; + _RuneEntry *base, *re; + int noinc; + + noinc = 0; + if (wc < _CACHED_RUNES) { + wc++; + while (wc < _CACHED_RUNES) { + if (_CurrentRuneLocale->__runetype[wc] & wct) + return (wc); + wc++; + } + wc--; + } + if (rr->__ranges != NULL && wc < rr->__ranges[0].__min) { + wc = rr->__ranges[0].__min; + noinc = 1; + } + + /* Binary search -- see bsearch.c for explanation. */ + base = rr->__ranges; + for (lim = rr->__nranges; lim != 0; lim >>= 1) { + re = base + (lim >> 1); + if (re->__min <= wc && wc <= re->__max) + goto found; + else if (wc > re->__max) { + base = re + 1; + lim--; + } + } + return (-1); +found: + if (!noinc) + wc++; + if (re->__min <= wc && wc <= re->__max) { + if (re->__types != NULL) { + for (; wc <= re->__max; wc++) + if (re->__types[wc - re->__min] & wct) + return (wc); + } else if (re->__map & wct) + return (wc); + } + while (++re < rr->__ranges + rr->__nranges) { + wc = re->__min; + if (re->__types != NULL) { + for (; wc <= re->__max; wc++) + if (re->__types[wc - re->__min] & wct) + return (wc); + } else if (re->__map & wct) + return (wc); + } + return (-1); +} diff --git a/src/lib/libc/locale/nl_langinfo.c b/src/lib/libc/locale/nl_langinfo.c new file mode 100644 index 0000000..22d27a3 --- /dev/null +++ b/src/lib/libc/locale/nl_langinfo.c @@ -0,0 +1,175 @@ +/*- + * Copyright (c) 2001, 2003 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/nl_langinfo.c,v 1.17 2003/06/26 10:46:16 phantom Exp $"); + +#include +#include +#include +#include +#include + +#include "lnumeric.h" +#include "lmessages.h" +#include "lmonetary.h" +#include "../stdtime/timelocal.h" + +#define _REL(BASE) ((int)item-BASE) + +char * +nl_langinfo(nl_item item) +{ + char *ret, *s, *cs; + static char *csym = NULL; + + switch (item) { + case CODESET: + ret = ""; + if ((s = setlocale(LC_CTYPE, NULL)) != NULL) { + if ((cs = strchr(s, '.')) != NULL) + ret = cs + 1; + else if (strcmp(s, "C") == 0 || + strcmp(s, "POSIX") == 0) + ret = "US-ASCII"; + } + break; + case D_T_FMT: + ret = (char *) __get_current_time_locale()->c_fmt; + break; + case D_FMT: + ret = (char *) __get_current_time_locale()->x_fmt; + break; + case T_FMT: + ret = (char *) __get_current_time_locale()->X_fmt; + break; + case T_FMT_AMPM: + ret = (char *) __get_current_time_locale()->ampm_fmt; + break; + case AM_STR: + ret = (char *) __get_current_time_locale()->am; + break; + case PM_STR: + ret = (char *) __get_current_time_locale()->pm; + break; + case DAY_1: case DAY_2: case DAY_3: + case DAY_4: case DAY_5: case DAY_6: case DAY_7: + ret = (char*) __get_current_time_locale()->weekday[_REL(DAY_1)]; + break; + case ABDAY_1: case ABDAY_2: case ABDAY_3: + case ABDAY_4: case ABDAY_5: case ABDAY_6: case ABDAY_7: + ret = (char*) __get_current_time_locale()->wday[_REL(ABDAY_1)]; + break; + case MON_1: case MON_2: case MON_3: case MON_4: + case MON_5: case MON_6: case MON_7: case MON_8: + case MON_9: case MON_10: case MON_11: case MON_12: + ret = (char*) __get_current_time_locale()->month[_REL(MON_1)]; + break; + case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4: + case ABMON_5: case ABMON_6: case ABMON_7: case ABMON_8: + case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12: + ret = (char*) __get_current_time_locale()->mon[_REL(ABMON_1)]; + break; + case ERA: + /* XXX: need to be implemented */ + ret = ""; + break; + case ERA_D_FMT: + /* XXX: need to be implemented */ + ret = ""; + break; + case ERA_D_T_FMT: + /* XXX: need to be implemented */ + ret = ""; + break; + case ERA_T_FMT: + /* XXX: need to be implemented */ + ret = ""; + break; + case ALT_DIGITS: + /* XXX: need to be implemented */ + ret = ""; + break; + case RADIXCHAR: + ret = (char*) __get_current_numeric_locale()->decimal_point; + break; + case THOUSEP: + ret = (char*) __get_current_numeric_locale()->thousands_sep; + break; + case YESEXPR: + ret = (char*) __get_current_messages_locale()->yesexpr; + break; + case NOEXPR: + ret = (char*) __get_current_messages_locale()->noexpr; + break; + /* + * YESSTR and NOSTR items marked with LEGACY are available, but not + * recomended by SUSv2 to be used in portable applications since + * they're subject to remove in future specification editions. + */ + case YESSTR: /* LEGACY */ + ret = (char*) __get_current_messages_locale()->yesstr; + break; + case NOSTR: /* LEGACY */ + ret = (char*) __get_current_messages_locale()->nostr; + break; + /* + * SUSv2 special formatted currency string + */ + case CRNCYSTR: + ret = ""; + cs = (char*) __get_current_monetary_locale()->currency_symbol; + if (*cs != '\0') { + char pos = localeconv()->p_cs_precedes; + + if (pos == localeconv()->n_cs_precedes) { + char psn = '\0'; + + if (pos == CHAR_MAX) { + if (strcmp(cs, __get_current_monetary_locale()->mon_decimal_point) == 0) + psn = '.'; + } else + psn = pos ? '-' : '+'; + if (psn != '\0') { + int clen = strlen(cs); + + if ((csym = reallocf(csym, clen + 2)) != NULL) { + *csym = psn; + strcpy(csym + 1, cs); + ret = csym; + } + } + } + } + break; + case D_MD_ORDER: /* FreeBSD local extension */ + ret = (char *) __get_current_time_locale()->md_order; + break; + default: + ret = ""; + } + return (ret); +} diff --git a/src/lib/libc/locale/nomacros.c b/src/lib/libc/locale/nomacros.c new file mode 100644 index 0000000..eea37d0 --- /dev/null +++ b/src/lib/libc/locale/nomacros.c @@ -0,0 +1,12 @@ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/nomacros.c,v 1.5 2002/03/22 21:52:18 obrien Exp $"); + +/* + * Tell to generate extern versions of all its inline + * functions. The extern versions get called if the system doesn't + * support inlines or the user defines _DONT_USE_CTYPE_INLINE_ + * before including . + */ +#define _EXTERNALIZE_CTYPE_INLINES_ + +#include diff --git a/src/lib/libc/locale/none.c b/src/lib/libc/locale/none.c new file mode 100644 index 0000000..6381019 --- /dev/null +++ b/src/lib/libc/locale/none.c @@ -0,0 +1,193 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)none.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/none.c,v 1.13 2005/02/27 15:11:09 phantom Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mblocal.h" + +static size_t _none_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _none_mbsinit(const mbstate_t *); +static size_t _none_mbsnrtowcs(wchar_t * __restrict dst, + const char ** __restrict src, size_t nms, size_t len, + mbstate_t * __restrict ps __unused); +static size_t _none_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); +static size_t _none_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict); + +int +_none_init(_RuneLocale *rl) +{ + + __mbrtowc = _none_mbrtowc; + __mbsinit = _none_mbsinit; + __mbsnrtowcs = _none_mbsnrtowcs; + __wcrtomb = _none_wcrtomb; + __wcsnrtombs = _none_wcsnrtombs; + _CurrentRuneLocale = rl; + __mb_cur_max = 1; + return(0); +} + +static int +_none_mbsinit(const mbstate_t *ps __unused) +{ + + /* + * Encoding is not state dependent - we are always in the + * initial state. + */ + return (1); +} + +static size_t +_none_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps __unused) +{ + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (0); + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + if (pwc != NULL) + *pwc = (unsigned char)*s; + return (*s == '\0' ? 0 : 1); +} + +static size_t +_none_wcrtomb(char * __restrict s, wchar_t wc, + mbstate_t * __restrict ps __unused) +{ + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + if (wc < 0 || wc > UCHAR_MAX) { + errno = EILSEQ; + return ((size_t)-1); + } + *s = (unsigned char)wc; + return (1); +} + +static size_t +_none_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, + size_t nms, size_t len, mbstate_t * __restrict ps __unused) +{ + const char *s; + size_t nchr; + + if (dst == NULL) { + s = memchr(*src, '\0', nms); + return (s != NULL ? s - *src : nms); + } + + s = *src; + nchr = 0; + while (len-- > 0 && nms-- > 0) { + if ((*dst++ = (unsigned char)*s++) == L'\0') { + *src = NULL; + return (nchr); + } + nchr++; + } + *src = s; + return (nchr); +} + +static size_t +_none_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, + size_t nwc, size_t len, mbstate_t * __restrict ps __unused) +{ + const wchar_t *s; + size_t nchr; + + if (dst == NULL) { + for (s = *src; nwc > 0 && *s != L'\0'; s++, nwc--) { + if (*s < 0 || *s > UCHAR_MAX) { + errno = EILSEQ; + return ((size_t)-1); + } + } + return (s - *src); + } + + s = *src; + nchr = 0; + while (len-- > 0 && nwc-- > 0) { + if (*s < 0 || *s > UCHAR_MAX) { + errno = EILSEQ; + return ((size_t)-1); + } + if ((*dst++ = *s++) == '\0') { + *src = NULL; + return (nchr); + } + nchr++; + } + *src = s; + return (nchr); +} + +/* setup defaults */ + +int __mb_cur_max = 1; +size_t (*__mbrtowc)(wchar_t * __restrict, const char * __restrict, size_t, + mbstate_t * __restrict) = _none_mbrtowc; +int (*__mbsinit)(const mbstate_t *) = _none_mbsinit; +size_t (*__mbsnrtowcs)(wchar_t * __restrict, const char ** __restrict, + size_t, size_t, mbstate_t * __restrict) = _none_mbsnrtowcs; +size_t (*__wcrtomb)(char * __restrict, wchar_t, mbstate_t * __restrict) = + _none_wcrtomb; +size_t (*__wcsnrtombs)(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict) = _none_wcsnrtombs; + diff --git a/src/lib/libc/locale/rpmatch.c b/src/lib/libc/locale/rpmatch.c new file mode 100644 index 0000000..370f23d --- /dev/null +++ b/src/lib/libc/locale/rpmatch.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2004-2005 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/rpmatch.c,v 1.1 2005/01/09 03:55:13 tjr Exp $"); + +#include +#include +#include + +int +rpmatch(const char *response) +{ + regex_t yes, no; + int ret; + + if (regcomp(&yes, nl_langinfo(YESEXPR), REG_EXTENDED|REG_NOSUB) != 0) + return (-1); + if (regcomp(&no, nl_langinfo(NOEXPR), REG_EXTENDED|REG_NOSUB) != 0) { + regfree(&yes); + return (-1); + } + if (regexec(&yes, response, 0, NULL, 0) == 0) + ret = 1; + else if (regexec(&no, response, 0, NULL, 0) == 0) + ret = 0; + else + ret = -1; + regfree(&yes); + regfree(&no); + return (ret); +} diff --git a/src/lib/libc/locale/rune.c b/src/lib/libc/locale/rune.c new file mode 100644 index 0000000..bcb70f9 --- /dev/null +++ b/src/lib/libc/locale/rune.c @@ -0,0 +1,290 @@ +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/rune.c,v 1.14 2005/05/16 09:32:41 ru Exp $"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "runefile.h" + +_RuneLocale *_Read_RuneMagi(FILE *); + +_RuneLocale * +_Read_RuneMagi(FILE *fp) +{ + char *fdata, *data; + void *lastp; + _FileRuneLocale *frl; + _RuneLocale *rl; + _FileRuneEntry *frr; + _RuneEntry *rr; + struct stat sb; + int x, saverr; + void *variable; + _FileRuneEntry *runetype_ext_ranges; + _FileRuneEntry *maplower_ext_ranges; + _FileRuneEntry *mapupper_ext_ranges; + int runetype_ext_len = 0; + + if (_fstat(fileno(fp), &sb) < 0) + return (NULL); + + if ((size_t)sb.st_size < sizeof(_FileRuneLocale)) { + errno = EFTYPE; + return (NULL); + } + + if ((fdata = malloc(sb.st_size)) == NULL) + return (NULL); + + errno = 0; + rewind(fp); /* Someone might have read the magic number once already */ + if (errno) { + saverr = errno; + free(fdata); + errno = saverr; + return (NULL); + } + + if (fread(fdata, sb.st_size, 1, fp) != 1) { + saverr = errno; + free(fdata); + errno = saverr; + return (NULL); + } + + frl = (_FileRuneLocale *)fdata; + lastp = fdata + sb.st_size; + + variable = frl + 1; + + if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof(frl->magic))) { + free(fdata); + errno = EFTYPE; + return (NULL); + } + + frl->variable_len = ntohl(frl->variable_len); + frl->runetype_ext_nranges = ntohl(frl->runetype_ext_nranges); + frl->maplower_ext_nranges = ntohl(frl->maplower_ext_nranges); + frl->mapupper_ext_nranges = ntohl(frl->mapupper_ext_nranges); + + for (x = 0; x < _CACHED_RUNES; ++x) { + frl->runetype[x] = ntohl(frl->runetype[x]); + frl->maplower[x] = ntohl(frl->maplower[x]); + frl->mapupper[x] = ntohl(frl->mapupper[x]); + } + + runetype_ext_ranges = (_FileRuneEntry *)variable; + variable = runetype_ext_ranges + frl->runetype_ext_nranges; + if (variable > lastp) { + free(fdata); + errno = EFTYPE; + return (NULL); + } + + maplower_ext_ranges = (_FileRuneEntry *)variable; + variable = maplower_ext_ranges + frl->maplower_ext_nranges; + if (variable > lastp) { + free(fdata); + errno = EFTYPE; + return (NULL); + } + + mapupper_ext_ranges = (_FileRuneEntry *)variable; + variable = mapupper_ext_ranges + frl->mapupper_ext_nranges; + if (variable > lastp) { + free(fdata); + errno = EFTYPE; + return (NULL); + } + + frr = runetype_ext_ranges; + for (x = 0; x < frl->runetype_ext_nranges; ++x) { + uint32_t *types; + + frr[x].min = ntohl(frr[x].min); + frr[x].max = ntohl(frr[x].max); + frr[x].map = ntohl(frr[x].map); + if (frr[x].map == 0) { + int len = frr[x].max - frr[x].min + 1; + types = variable; + variable = types + len; + runetype_ext_len += len; + if (variable > lastp) { + free(fdata); + errno = EFTYPE; + return (NULL); + } + while (len-- > 0) + types[len] = ntohl(types[len]); + } + } + + frr = maplower_ext_ranges; + for (x = 0; x < frl->maplower_ext_nranges; ++x) { + frr[x].min = ntohl(frr[x].min); + frr[x].max = ntohl(frr[x].max); + frr[x].map = ntohl(frr[x].map); + } + + frr = mapupper_ext_ranges; + for (x = 0; x < frl->mapupper_ext_nranges; ++x) { + frr[x].min = ntohl(frr[x].min); + frr[x].max = ntohl(frr[x].max); + frr[x].map = ntohl(frr[x].map); + } + if ((char *)variable + frl->variable_len > (char *)lastp) { + free(fdata); + errno = EFTYPE; + return (NULL); + } + + /* + * Convert from disk format to host format. + */ + data = malloc(sizeof(_RuneLocale) + + (frl->runetype_ext_nranges + frl->maplower_ext_nranges + + frl->mapupper_ext_nranges) * sizeof(_RuneEntry) + + runetype_ext_len * sizeof(*rr->__types) + + frl->variable_len); + if (data == NULL) { + saverr = errno; + free(fdata); + errno = saverr; + return (NULL); + } + + rl = (_RuneLocale *)data; + rl->__variable = rl + 1; + + memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic)); + memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding)); + rl->__invalid_rune = 0; + + rl->__variable_len = frl->variable_len; + rl->__runetype_ext.__nranges = frl->runetype_ext_nranges; + rl->__maplower_ext.__nranges = frl->maplower_ext_nranges; + rl->__mapupper_ext.__nranges = frl->mapupper_ext_nranges; + + for (x = 0; x < _CACHED_RUNES; ++x) { + rl->__runetype[x] = frl->runetype[x]; + rl->__maplower[x] = frl->maplower[x]; + rl->__mapupper[x] = frl->mapupper[x]; + } + + rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable; + rl->__variable = rl->__runetype_ext.__ranges + + rl->__runetype_ext.__nranges; + + rl->__maplower_ext.__ranges = (_RuneEntry *)rl->__variable; + rl->__variable = rl->__maplower_ext.__ranges + + rl->__maplower_ext.__nranges; + + rl->__mapupper_ext.__ranges = (_RuneEntry *)rl->__variable; + rl->__variable = rl->__mapupper_ext.__ranges + + rl->__mapupper_ext.__nranges; + + variable = mapupper_ext_ranges + frl->mapupper_ext_nranges; + frr = runetype_ext_ranges; + rr = rl->__runetype_ext.__ranges; + for (x = 0; x < rl->__runetype_ext.__nranges; ++x) { + uint32_t *types; + + rr[x].__min = frr[x].min; + rr[x].__max = frr[x].max; + rr[x].__map = frr[x].map; + if (rr[x].__map == 0) { + int len = rr[x].__max - rr[x].__min + 1; + types = variable; + variable = types + len; + rr[x].__types = rl->__variable; + rl->__variable = rr[x].__types + len; + while (len-- > 0) + rr[x].__types[len] = types[len]; + } else + rr[x].__types = NULL; + } + + frr = maplower_ext_ranges; + rr = rl->__maplower_ext.__ranges; + for (x = 0; x < rl->__maplower_ext.__nranges; ++x) { + rr[x].__min = frr[x].min; + rr[x].__max = frr[x].max; + rr[x].__map = frr[x].map; + } + + frr = mapupper_ext_ranges; + rr = rl->__mapupper_ext.__ranges; + for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) { + rr[x].__min = frr[x].min; + rr[x].__max = frr[x].max; + rr[x].__map = frr[x].map; + } + + memcpy(rl->__variable, variable, rl->__variable_len); + free(fdata); + + /* + * Go out and zero pointers that should be zero. + */ + if (!rl->__variable_len) + rl->__variable = NULL; + + if (!rl->__runetype_ext.__nranges) + rl->__runetype_ext.__ranges = NULL; + + if (!rl->__maplower_ext.__nranges) + rl->__maplower_ext.__ranges = NULL; + + if (!rl->__mapupper_ext.__nranges) + rl->__mapupper_ext.__ranges = NULL; + + return (rl); +} diff --git a/src/lib/libc/locale/runefile.h b/src/lib/libc/locale/runefile.h new file mode 100644 index 0000000..cacc66f --- /dev/null +++ b/src/lib/libc/locale/runefile.h @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2005 Ruslan Ermilov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/locale/runefile.h,v 1.1 2005/05/16 09:32:41 ru Exp $ + */ + +#ifndef _RUNEFILE_H_ +#define _RUNEFILE_H_ + +#include + +#ifndef _CACHED_RUNES +#define _CACHED_RUNES (1 << 8) +#endif + +typedef struct { + int32_t min; + int32_t max; + int32_t map; +} _FileRuneEntry; + +typedef struct { + char magic[8]; + char encoding[32]; + + uint32_t runetype[_CACHED_RUNES]; + int32_t maplower[_CACHED_RUNES]; + int32_t mapupper[_CACHED_RUNES]; + + int32_t runetype_ext_nranges; + int32_t maplower_ext_nranges; + int32_t mapupper_ext_nranges; + + int32_t variable_len; +} _FileRuneLocale; + +#define _FILE_RUNE_MAGIC_1 "RuneMag1" + +#endif /* !_RUNEFILE_H_ */ diff --git a/src/lib/libc/locale/runetype.c b/src/lib/libc/locale/runetype.c new file mode 100644 index 0000000..d62ed9b --- /dev/null +++ b/src/lib/libc/locale/runetype.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/runetype.c,v 1.12 2005/02/27 14:54:23 phantom Exp $"); + +#include +#include + +unsigned long +___runetype(__ct_rune_t c) +{ + size_t lim; + _RuneRange *rr = &_CurrentRuneLocale->__runetype_ext; + _RuneEntry *base, *re; + + if (c < 0 || c == EOF) + return(0L); + + /* Binary search -- see bsearch.c for explanation. */ + base = rr->__ranges; + for (lim = rr->__nranges; lim != 0; lim >>= 1) { + re = base + (lim >> 1); + if (re->__min <= c && c <= re->__max) { + if (re->__types) + return(re->__types[c - re->__min]); + else + return(re->__map); + } else if (c > re->__max) { + base = re + 1; + lim--; + } + } + + return(0L); +} diff --git a/src/lib/libc/locale/setlocale.c b/src/lib/libc/locale/setlocale.c new file mode 100644 index 0000000..e42f53a --- /dev/null +++ b/src/lib/libc/locale/setlocale.c @@ -0,0 +1,336 @@ +/* + * Copyright (c) 1996 - 2002 FreeBSD Project + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)setlocale.c 8.1 (Berkeley) 7/4/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/setlocale.c,v 1.50 2004/01/31 19:15:32 ache Exp $"); + +#include +#include +#include +#include +#include +#include /* for _PATH_LOCALE */ +#include +#include +#include +#include "collate.h" +#include "lmonetary.h" /* for __monetary_load_locale() */ +#include "lnumeric.h" /* for __numeric_load_locale() */ +#include "lmessages.h" /* for __messages_load_locale() */ +#include "setlocale.h" +#include "ldpart.h" +#include "../stdtime/timelocal.h" /* for __time_load_locale() */ + +/* + * Category names for getenv() + */ +static char *categories[_LC_LAST] = { + "LC_ALL", + "LC_COLLATE", + "LC_CTYPE", + "LC_MONETARY", + "LC_NUMERIC", + "LC_TIME", + "LC_MESSAGES", +}; + +/* + * Current locales for each category + */ +static char current_categories[_LC_LAST][ENCODING_LEN + 1] = { + "C", + "C", + "C", + "C", + "C", + "C", + "C", +}; + +/* + * Path to locale storage directory + */ +char *_PathLocale; + +/* + * The locales we are going to try and load + */ +static char new_categories[_LC_LAST][ENCODING_LEN + 1]; +static char saved_categories[_LC_LAST][ENCODING_LEN + 1]; + +static char current_locale_string[_LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1)]; + +static char *currentlocale(void); +static char *loadlocale(int); +static const char *__get_locale_env(int); + +char * +setlocale(category, locale) + int category; + const char *locale; +{ + int i, j, len, saverr; + const char *env, *r; + + if (category < LC_ALL || category >= _LC_LAST) { + errno = EINVAL; + return (NULL); + } + + if (locale == NULL) + return (category != LC_ALL ? + current_categories[category] : currentlocale()); + + /* + * Default to the current locale for everything. + */ + for (i = 1; i < _LC_LAST; ++i) + (void)strcpy(new_categories[i], current_categories[i]); + + /* + * Now go fill up new_categories from the locale argument + */ + if (!*locale) { + if (category == LC_ALL) { + for (i = 1; i < _LC_LAST; ++i) { + env = __get_locale_env(i); + if (strlen(env) > ENCODING_LEN) { + errno = EINVAL; + return (NULL); + } + (void)strcpy(new_categories[i], env); + } + } else { + env = __get_locale_env(category); + if (strlen(env) > ENCODING_LEN) { + errno = EINVAL; + return (NULL); + } + (void)strcpy(new_categories[category], env); + } + } else if (category != LC_ALL) { + if (strlen(locale) > ENCODING_LEN) { + errno = EINVAL; + return (NULL); + } + (void)strcpy(new_categories[category], locale); + } else { + if ((r = strchr(locale, '/')) == NULL) { + if (strlen(locale) > ENCODING_LEN) { + errno = EINVAL; + return (NULL); + } + for (i = 1; i < _LC_LAST; ++i) + (void)strcpy(new_categories[i], locale); + } else { + for (i = 1; r[1] == '/'; ++r) + ; + if (!r[1]) { + errno = EINVAL; + return (NULL); /* Hmm, just slashes... */ + } + do { + if (i == _LC_LAST) + break; /* Too many slashes... */ + if ((len = r - locale) > ENCODING_LEN) { + errno = EINVAL; + return (NULL); + } + (void)strlcpy(new_categories[i], locale, + len + 1); + i++; + while (*r == '/') + r++; + locale = r; + while (*r && *r != '/') + r++; + } while (*locale); + while (i < _LC_LAST) { + (void)strcpy(new_categories[i], + new_categories[i-1]); + i++; + } + } + } + + if (category != LC_ALL) + return (loadlocale(category)); + + for (i = 1; i < _LC_LAST; ++i) { + (void)strcpy(saved_categories[i], current_categories[i]); + if (loadlocale(i) == NULL) { + saverr = errno; + for (j = 1; j < i; j++) { + (void)strcpy(new_categories[j], + saved_categories[j]); + if (loadlocale(j) == NULL) { + (void)strcpy(new_categories[j], "C"); + (void)loadlocale(j); + } + } + errno = saverr; + return (NULL); + } + } + return (currentlocale()); +} + +static char * +currentlocale() +{ + int i; + + (void)strcpy(current_locale_string, current_categories[1]); + + for (i = 2; i < _LC_LAST; ++i) + if (strcmp(current_categories[1], current_categories[i])) { + for (i = 2; i < _LC_LAST; ++i) { + (void)strcat(current_locale_string, "/"); + (void)strcat(current_locale_string, + current_categories[i]); + } + break; + } + return (current_locale_string); +} + +static char * +loadlocale(category) + int category; +{ + char *new = new_categories[category]; + char *old = current_categories[category]; + int (*func)(const char *); + int saved_errno; + + if ((new[0] == '.' && + (new[1] == '\0' || (new[1] == '.' && new[2] == '\0'))) || + strchr(new, '/') != NULL) { + errno = EINVAL; + return (NULL); + } + + saved_errno = errno; + errno = __detect_path_locale(); + if (errno != 0) + return (NULL); + errno = saved_errno; + + switch (category) { + case LC_CTYPE: + func = __wrap_setrunelocale; + break; + case LC_COLLATE: + func = __collate_load_tables; + break; + case LC_TIME: + func = __time_load_locale; + break; + case LC_NUMERIC: + func = __numeric_load_locale; + break; + case LC_MONETARY: + func = __monetary_load_locale; + break; + case LC_MESSAGES: + func = __messages_load_locale; + break; + default: + errno = EINVAL; + return (NULL); + } + + if (strcmp(new, old) == 0) + return (old); + + if (func(new) != _LDP_ERROR) { + (void)strcpy(old, new); + return (old); + } + + return (NULL); +} + +static const char * +__get_locale_env(category) + int category; +{ + const char *env; + + /* 1. check LC_ALL. */ + env = getenv(categories[0]); + + /* 2. check LC_* */ + if (env == NULL || !*env) + env = getenv(categories[category]); + + /* 3. check LANG */ + if (env == NULL || !*env) + env = getenv("LANG"); + + /* 4. if none is set, fall to "C" */ + if (env == NULL || !*env) + env = "C"; + + return (env); +} + +/* + * Detect locale storage location and store its value to _PathLocale variable + */ +int +__detect_path_locale(void) +{ + if (_PathLocale == NULL) { + char *p = getenv("PATH_LOCALE"); + + if (p != NULL && !issetugid()) { + if (strlen(p) + 1/*"/"*/ + ENCODING_LEN + + 1/*"/"*/ + CATEGORY_LEN >= PATH_MAX) + return (ENAMETOOLONG); + _PathLocale = strdup(p); + if (_PathLocale == NULL) + return (errno == 0 ? ENOMEM : errno); + } else + _PathLocale = _PATH_LOCALE; + } + return (0); +} + diff --git a/src/lib/libc/locale/setlocale.h b/src/lib/libc/locale/setlocale.h new file mode 100644 index 0000000..82462ee --- /dev/null +++ b/src/lib/libc/locale/setlocale.h @@ -0,0 +1,40 @@ +/*- + * Copyright (C) 1997 by Andrey A. Chernov, Moscow, Russia. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/locale/setlocale.h,v 1.6 2003/07/06 02:03:37 ache Exp $ + */ + +#ifndef _SETLOCALE_H_ +#define _SETLOCALE_H_ + +#define ENCODING_LEN 31 +#define CATEGORY_LEN 11 + +extern char *_PathLocale; + +int __detect_path_locale(void); +int __wrap_setrunelocale(const char *); + +#endif /* !_SETLOCALE_H_ */ diff --git a/src/lib/libc/locale/setrunelocale.c b/src/lib/libc/locale/setrunelocale.c new file mode 100644 index 0000000..fd71947 --- /dev/null +++ b/src/lib/libc/locale/setrunelocale.c @@ -0,0 +1,177 @@ +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/setrunelocale.c,v 1.45 2005/02/27 15:11:09 phantom Exp $"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ldpart.h" +#include "mblocal.h" +#include "setlocale.h" + +extern _RuneLocale *_Read_RuneMagi(FILE *); + +static int __setrunelocale(const char *); + +static int +__setrunelocale(const char *encoding) +{ + FILE *fp; + char name[PATH_MAX]; + _RuneLocale *rl; + int saverr, ret; + static char ctype_encoding[ENCODING_LEN + 1]; + static _RuneLocale *CachedRuneLocale; + static int Cached__mb_cur_max; + static size_t (*Cached__mbrtowc)(wchar_t * __restrict, + const char * __restrict, size_t, mbstate_t * __restrict); + static size_t (*Cached__wcrtomb)(char * __restrict, wchar_t, + mbstate_t * __restrict); + static int (*Cached__mbsinit)(const mbstate_t *); + static size_t (*Cached__mbsnrtowcs)(wchar_t * __restrict, + const char ** __restrict, size_t, size_t, mbstate_t * __restrict); + static size_t (*Cached__wcsnrtombs)(char * __restrict, + const wchar_t ** __restrict, size_t, size_t, + mbstate_t * __restrict); + + /* + * The "C" and "POSIX" locale are always here. + */ + if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { + _none_init(&_DefaultRuneLocale); + return (0); + } + + /* + * If the locale name is the same as our cache, use the cache. + */ + if (CachedRuneLocale != NULL && + strcmp(encoding, ctype_encoding) == 0) { + _CurrentRuneLocale = CachedRuneLocale; + __mb_cur_max = Cached__mb_cur_max; + __mbrtowc = Cached__mbrtowc; + __mbsinit = Cached__mbsinit; + __mbsnrtowcs = Cached__mbsnrtowcs; + __wcrtomb = Cached__wcrtomb; + __wcsnrtombs = Cached__wcsnrtombs; + return (0); + } + + /* + * Slurp the locale file into the cache. + */ + + /* Range checking not needed, encoding length already checked before */ + (void) strcpy(name, _PathLocale); + (void) strcat(name, "/"); + (void) strcat(name, encoding); + (void) strcat(name, "/LC_CTYPE"); + + if ((fp = fopen(name, "r")) == NULL) + return (errno == 0 ? ENOENT : errno); + + if ((rl = _Read_RuneMagi(fp)) == NULL) { + saverr = (errno == 0 ? EFTYPE : errno); + (void)fclose(fp); + return (saverr); + } + (void)fclose(fp); + + __mbrtowc = NULL; + __mbsinit = NULL; + __mbsnrtowcs = __mbsnrtowcs_std; + __wcrtomb = NULL; + __wcsnrtombs = __wcsnrtombs_std; + rl->__sputrune = NULL; + rl->__sgetrune = NULL; + if (strcmp(rl->__encoding, "NONE") == 0) + ret = _none_init(rl); + else if (strcmp(rl->__encoding, "UTF-8") == 0) + ret = _UTF8_init(rl); + else if (strcmp(rl->__encoding, "EUC") == 0) + ret = _EUC_init(rl); + else if (strcmp(rl->__encoding, "GB18030") == 0) + ret = _GB18030_init(rl); + else if (strcmp(rl->__encoding, "GB2312") == 0) + ret = _GB2312_init(rl); + else if (strcmp(rl->__encoding, "GBK") == 0) + ret = _GBK_init(rl); + else if (strcmp(rl->__encoding, "BIG5") == 0) + ret = _BIG5_init(rl); + else if (strcmp(rl->__encoding, "MSKanji") == 0) + ret = _MSKanji_init(rl); + else + ret = EFTYPE; + if (ret == 0) { + if (CachedRuneLocale != NULL) { + /* See euc.c */ + if (strcmp(CachedRuneLocale->__encoding, "EUC") == 0) + free(CachedRuneLocale->__variable); + free(CachedRuneLocale); + } + CachedRuneLocale = _CurrentRuneLocale; + Cached__mb_cur_max = __mb_cur_max; + Cached__mbrtowc = __mbrtowc; + Cached__mbsinit = __mbsinit; + Cached__mbsnrtowcs = __mbsnrtowcs; + Cached__wcrtomb = __wcrtomb; + Cached__wcsnrtombs = __wcsnrtombs; + (void)strcpy(ctype_encoding, encoding); + } else + free(rl); + + return (ret); +} + +int +__wrap_setrunelocale(const char *locale) +{ + int ret = __setrunelocale(locale); + + if (ret != 0) { + errno = ret; + return (_LDP_ERROR); + } + return (_LDP_LOADED); +} + diff --git a/src/lib/libc/locale/table.c b/src/lib/libc/locale/table.c new file mode 100644 index 0000000..b393d30 --- /dev/null +++ b/src/lib/libc/locale/table.c @@ -0,0 +1,253 @@ +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)table.c 8.1 (Berkeley) 6/27/93"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/table.c,v 1.27 2005/02/27 15:11:09 phantom Exp $"); + +#include +#include +#include +#include "mblocal.h" + +_RuneLocale _DefaultRuneLocale = { + _RUNE_MAGIC_1, + "NONE", + NULL, + NULL, + 0xFFFD, + + { /*00*/ _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + /*08*/ _CTYPE_C, + _CTYPE_C|_CTYPE_S|_CTYPE_B, + _CTYPE_C|_CTYPE_S, + _CTYPE_C|_CTYPE_S, + _CTYPE_C|_CTYPE_S, + _CTYPE_C|_CTYPE_S, + _CTYPE_C, + _CTYPE_C, + /*10*/ _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + /*18*/ _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + _CTYPE_C, + /*20*/ _CTYPE_S|_CTYPE_B|_CTYPE_R, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + /*28*/ _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + /*30*/ _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|0, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|1, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|2, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|3, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|4, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|5, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|6, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|7, + /*38*/ _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|8, + _CTYPE_D|_CTYPE_R|_CTYPE_G|_CTYPE_X|9, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + /*40*/ _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|10, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|11, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|12, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|13, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|14, + _CTYPE_U|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|15, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*48*/ _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*50*/ _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*58*/ _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_U|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + /*60*/ _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|10, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|11, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|12, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|13, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|14, + _CTYPE_L|_CTYPE_X|_CTYPE_R|_CTYPE_G|_CTYPE_A|15, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*68*/ _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*70*/ _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + /*78*/ _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_L|_CTYPE_R|_CTYPE_G|_CTYPE_A, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_P|_CTYPE_R|_CTYPE_G, + _CTYPE_C, + }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + }, +}; + +_RuneLocale *_CurrentRuneLocale = &_DefaultRuneLocale; + diff --git a/src/lib/libc/locale/tolower.c b/src/lib/libc/locale/tolower.c new file mode 100644 index 0000000..24694e7 --- /dev/null +++ b/src/lib/libc/locale/tolower.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/tolower.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); + +#include +#include + +__ct_rune_t +___tolower(c) + __ct_rune_t c; +{ + size_t lim; + _RuneRange *rr = &_CurrentRuneLocale->__maplower_ext; + _RuneEntry *base, *re; + + if (c < 0 || c == EOF) + return(c); + + /* Binary search -- see bsearch.c for explanation. */ + base = rr->__ranges; + for (lim = rr->__nranges; lim != 0; lim >>= 1) { + re = base + (lim >> 1); + if (re->__min <= c && c <= re->__max) + return (re->__map + c - re->__min); + else if (c > re->__max) { + base = re + 1; + lim--; + } + } + + return(c); +} diff --git a/src/lib/libc/locale/toupper.c b/src/lib/libc/locale/toupper.c new file mode 100644 index 0000000..bb7f36a --- /dev/null +++ b/src/lib/libc/locale/toupper.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/toupper.c,v 1.11 2004/07/29 06:16:19 tjr Exp $"); + +#include +#include + +__ct_rune_t +___toupper(c) + __ct_rune_t c; +{ + size_t lim; + _RuneRange *rr = &_CurrentRuneLocale->__mapupper_ext; + _RuneEntry *base, *re; + + if (c < 0 || c == EOF) + return(c); + + /* Binary search -- see bsearch.c for explanation. */ + base = rr->__ranges; + for (lim = rr->__nranges; lim != 0; lim >>= 1) { + re = base + (lim >> 1); + if (re->__min <= c && c <= re->__max) + return (re->__map + c - re->__min); + else if (c > re->__max) { + base = re + 1; + lim--; + } + } + + return(c); +} diff --git a/src/lib/libc/locale/utf8.c b/src/lib/libc/locale/utf8.c new file mode 100644 index 0000000..08b8c2d --- /dev/null +++ b/src/lib/libc/locale/utf8.c @@ -0,0 +1,421 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/utf8.c,v 1.13.2.1 2006/05/17 13:26:01 trhodes Exp $"); + +#include +#include +#include +#include +#include +#include +#include "mblocal.h" + +static size_t _UTF8_mbrtowc(wchar_t * __restrict, const char * __restrict, + size_t, mbstate_t * __restrict); +static int _UTF8_mbsinit(const mbstate_t *); +static size_t _UTF8_mbsnrtowcs(wchar_t * __restrict, + const char ** __restrict, size_t, size_t, + mbstate_t * __restrict); +static size_t _UTF8_wcrtomb(char * __restrict, wchar_t, + mbstate_t * __restrict); +static size_t _UTF8_wcsnrtombs(char * __restrict, const wchar_t ** __restrict, + size_t, size_t, mbstate_t * __restrict); + +typedef struct { + wchar_t ch; + int want; + wchar_t lbound; +} _UTF8State; + +int +_UTF8_init(_RuneLocale *rl) +{ + + __mbrtowc = _UTF8_mbrtowc; + __wcrtomb = _UTF8_wcrtomb; + __mbsinit = _UTF8_mbsinit; + __mbsnrtowcs = _UTF8_mbsnrtowcs; + __wcsnrtombs = _UTF8_wcsnrtombs; + _CurrentRuneLocale = rl; + __mb_cur_max = 6; + + return (0); +} + +static int +_UTF8_mbsinit(const mbstate_t *ps) +{ + + return (ps == NULL || ((const _UTF8State *)ps)->want == 0); +} + +static size_t +_UTF8_mbrtowc(wchar_t * __restrict pwc, const char * __restrict s, size_t n, + mbstate_t * __restrict ps) +{ + _UTF8State *us; + int ch, i, mask, want; + wchar_t lbound, wch; + + us = (_UTF8State *)ps; + + if (us->want < 0 || us->want > 6) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) { + s = ""; + n = 1; + pwc = NULL; + } + + if (n == 0) + /* Incomplete multibyte sequence */ + return ((size_t)-2); + + if (us->want == 0 && ((ch = (unsigned char)*s) & ~0x7f) == 0) { + /* Fast path for plain ASCII characters. */ + if (pwc != NULL) + *pwc = ch; + return (ch != '\0' ? 1 : 0); + } + + if (us->want == 0) { + /* + * Determine the number of octets that make up this character + * from the first octet, and a mask that extracts the + * interesting bits of the first octet. We already know + * the character is at least two bytes long. + * + * We also specify a lower bound for the character code to + * detect redundant, non-"shortest form" encodings. For + * example, the sequence C0 80 is _not_ a legal representation + * of the null character. This enforces a 1-to-1 mapping + * between character codes and their multibyte representations. + */ + ch = (unsigned char)*s; + if ((ch & 0x80) == 0) { + mask = 0x7f; + want = 1; + lbound = 0; + } else if ((ch & 0xe0) == 0xc0) { + mask = 0x1f; + want = 2; + lbound = 0x80; + } else if ((ch & 0xf0) == 0xe0) { + mask = 0x0f; + want = 3; + lbound = 0x800; + } else if ((ch & 0xf8) == 0xf0) { + mask = 0x07; + want = 4; + lbound = 0x10000; + } else if ((ch & 0xfc) == 0xf8) { + mask = 0x03; + want = 5; + lbound = 0x200000; + } else if ((ch & 0xfe) == 0xfc) { + mask = 0x01; + want = 6; + lbound = 0x4000000; + } else { + /* + * Malformed input; input is not UTF-8. + */ + errno = EILSEQ; + return ((size_t)-1); + } + } else { + want = us->want; + lbound = us->lbound; + } + + /* + * Decode the octet sequence representing the character in chunks + * of 6 bits, most significant first. + */ + if (us->want == 0) + wch = (unsigned char)*s++ & mask; + else + wch = us->ch; + for (i = (us->want == 0) ? 1 : 0; i < MIN(want, n); i++) { + if ((*s & 0xc0) != 0x80) { + /* + * Malformed input; bad characters in the middle + * of a character. + */ + errno = EILSEQ; + return ((size_t)-1); + } + wch <<= 6; + wch |= *s++ & 0x3f; + } + if (i < want) { + /* Incomplete multibyte sequence. */ + us->want = want - i; + us->lbound = lbound; + us->ch = wch; + return ((size_t)-2); + } + if (wch < lbound) { + /* + * Malformed input; redundant encoding. + */ + errno = EILSEQ; + return ((size_t)-1); + } + if (pwc != NULL) + *pwc = wch; + us->want = 0; + return (wch == L'\0' ? 0 : want); +} + +static size_t +_UTF8_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, + size_t nms, size_t len, mbstate_t * __restrict ps) +{ + _UTF8State *us; + const char *s; + size_t nchr; + wchar_t wc; + size_t nb; + + us = (_UTF8State *)ps; + + s = *src; + nchr = 0; + + if (dst == NULL) { + /* + * The fast path in the loop below is not safe if an ASCII + * character appears as anything but the first byte of a + * multibyte sequence. Check now to avoid doing it in the loop. + */ + if (nms > 0 && us->want > 0 && (signed char)*s > 0) { + errno = EILSEQ; + return ((size_t)-1); + } + for (;;) { + if (nms > 0 && (signed char)*s > 0) + /* + * Fast path for plain ASCII characters + * excluding NUL. + */ + nb = 1; + else if ((nb = _UTF8_mbrtowc(&wc, s, nms, ps)) == + (size_t)-1) + /* Invalid sequence - mbrtowc() sets errno. */ + return ((size_t)-1); + else if (nb == 0 || nb == (size_t)-2) + return (nchr); + s += nb; + nms -= nb; + nchr++; + } + /*NOTREACHED*/ + } + + /* + * The fast path in the loop below is not safe if an ASCII + * character appears as anything but the first byte of a + * multibyte sequence. Check now to avoid doing it in the loop. + */ + if (nms > 0 && len > 0 && us->want > 0 && (signed char)*s > 0) { + errno = EILSEQ; + return ((size_t)-1); + } + while (len-- > 0) { + if (nms > 0 && (signed char)*s > 0) { + /* + * Fast path for plain ASCII characters + * excluding NUL. + */ + *dst = (wchar_t)*s; + nb = 1; + } else if ((nb = _UTF8_mbrtowc(dst, s, nms, ps)) == + (size_t)-1) { + *src = s; + return ((size_t)-1); + } else if (nb == (size_t)-2) { + *src = s + nms; + return (nchr); + } else if (nb == 0) { + *src = NULL; + return (nchr); + } + s += nb; + nms -= nb; + nchr++; + dst++; + } + *src = s; + return (nchr); +} + +static size_t +_UTF8_wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) +{ + _UTF8State *us; + unsigned char lead; + int i, len; + + us = (_UTF8State *)ps; + + if (us->want != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + if (s == NULL) + /* Reset to initial shift state (no-op) */ + return (1); + + if ((wc & ~0x7f) == 0) { + /* Fast path for plain ASCII characters. */ + *s = (char)wc; + return (1); + } + + /* + * Determine the number of octets needed to represent this character. + * We always output the shortest sequence possible. Also specify the + * first few bits of the first octet, which contains the information + * about the sequence length. + */ + if ((wc & ~0x7f) == 0) { + lead = 0; + len = 1; + } else if ((wc & ~0x7ff) == 0) { + lead = 0xc0; + len = 2; + } else if ((wc & ~0xffff) == 0) { + lead = 0xe0; + len = 3; + } else if ((wc & ~0x1fffff) == 0) { + lead = 0xf0; + len = 4; + } else if ((wc & ~0x3ffffff) == 0) { + lead = 0xf8; + len = 5; + } else if ((wc & ~0x7fffffff) == 0) { + lead = 0xfc; + len = 6; + } else { + errno = EILSEQ; + return ((size_t)-1); + } + + /* + * Output the octets representing the character in chunks + * of 6 bits, least significant last. The first octet is + * a special case because it contains the sequence length + * information. + */ + for (i = len - 1; i > 0; i--) { + s[i] = (wc & 0x3f) | 0x80; + wc >>= 6; + } + *s = (wc & 0xff) | lead; + + return (len); +} + +static size_t +_UTF8_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, + size_t nwc, size_t len, mbstate_t * __restrict ps) +{ + _UTF8State *us; + char buf[MB_LEN_MAX]; + const wchar_t *s; + size_t nbytes; + size_t nb; + + us = (_UTF8State *)ps; + + if (us->want != 0) { + errno = EINVAL; + return ((size_t)-1); + } + + s = *src; + nbytes = 0; + + if (dst == NULL) { + while (nwc-- > 0) { + if (0 <= *s && *s < 0x80) + /* Fast path for plain ASCII characters. */ + nb = 1; + else if ((nb = _UTF8_wcrtomb(buf, *s, ps)) == + (size_t)-1) + /* Invalid character - wcrtomb() sets errno. */ + return ((size_t)-1); + if (*s == L'\0') + return (nbytes + nb - 1); + s++; + nbytes += nb; + } + return (nbytes); + } + + while (len > 0 && nwc-- > 0) { + if (0 <= *s && *s < 0x80) { + /* Fast path for plain ASCII characters. */ + nb = 1; + *dst = *s; + } else if (len > (size_t)MB_CUR_MAX) { + /* Enough space to translate in-place. */ + if ((nb = _UTF8_wcrtomb(dst, *s, ps)) == (size_t)-1) { + *src = s; + return ((size_t)-1); + } + } else { + /* + * May not be enough space; use temp. buffer. + */ + if ((nb = _UTF8_wcrtomb(buf, *s, ps)) == (size_t)-1) { + *src = s; + return ((size_t)-1); + } + if (nb > (int)len) + /* MB sequence for character won't fit. */ + break; + memcpy(dst, buf, nb); + } + if (*s == L'\0') { + *src = NULL; + return (nbytes + nb - 1); + } + s++; + dst += nb; + len -= nb; + nbytes += nb; + } + *src = s; + return (nbytes); +} diff --git a/src/lib/libc/locale/wcrtomb.c b/src/lib/libc/locale/wcrtomb.c new file mode 100644 index 0000000..4d7b115 --- /dev/null +++ b/src/lib/libc/locale/wcrtomb.c @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wcrtomb.c,v 1.8 2004/05/12 14:09:04 tjr Exp $"); + +#include +#include "mblocal.h" + +size_t +wcrtomb(char * __restrict s, wchar_t wc, mbstate_t * __restrict ps) +{ + static mbstate_t mbs; + + if (ps == NULL) + ps = &mbs; + return (__wcrtomb(s, wc, ps)); +} diff --git a/src/lib/libc/locale/wcsftime.c b/src/lib/libc/locale/wcsftime.c new file mode 100644 index 0000000..2598043 --- /dev/null +++ b/src/lib/libc/locale/wcsftime.c @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wcsftime.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); + +#include +#include +#include +#include +#include + +/* + * Convert date and time to a wide-character string. + * + * This is the wide-character counterpart of strftime(). So that we do not + * have to duplicate the code of strftime(), we convert the format string to + * multibyte, call strftime(), then convert the result back into wide + * characters. + * + * This technique loses in the presence of stateful multibyte encoding if any + * of the conversions in the format string change conversion state. When + * stateful encoding is implemented, we will need to reset the state between + * format specifications in the format string. + */ +size_t +wcsftime(wchar_t * __restrict wcs, size_t maxsize, + const wchar_t * __restrict format, const struct tm * __restrict timeptr) +{ + static const mbstate_t initial; + mbstate_t mbs; + char *dst, *dstp, *sformat; + size_t n, sflen; + int sverrno; + + sformat = dst = NULL; + + /* + * Convert the supplied format string to a multibyte representation + * for strftime(), which only handles single-byte characters. + */ + mbs = initial; + sflen = wcsrtombs(NULL, &format, 0, &mbs); + if (sflen == (size_t)-1) + goto error; + if ((sformat = malloc(sflen + 1)) == NULL) + goto error; + mbs = initial; + wcsrtombs(sformat, &format, sflen + 1, &mbs); + + /* + * Allocate memory for longest multibyte sequence that will fit + * into the caller's buffer and call strftime() to fill it. + * Then, copy and convert the result back into wide characters in + * the caller's buffer. + */ + if (SIZE_T_MAX / MB_CUR_MAX <= maxsize) { + /* maxsize is prepostorously large - avoid int. overflow. */ + errno = EINVAL; + goto error; + } + if ((dst = malloc(maxsize * MB_CUR_MAX)) == NULL) + goto error; + if (strftime(dst, maxsize, sformat, timeptr) == 0) + goto error; + dstp = dst; + mbs = initial; + n = mbsrtowcs(wcs, (const char **)&dstp, maxsize, &mbs); + if (n == (size_t)-2 || n == (size_t)-1 || dstp != NULL) + goto error; + + free(sformat); + free(dst); + return (n); + +error: + sverrno = errno; + free(sformat); + free(dst); + errno = sverrno; + return (0); +} diff --git a/src/lib/libc/locale/wcsnrtombs.c b/src/lib/libc/locale/wcsnrtombs.c new file mode 100644 index 0000000..89cd9b7 --- /dev/null +++ b/src/lib/libc/locale/wcsnrtombs.c @@ -0,0 +1,111 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wcsnrtombs.c,v 1.3 2005/02/12 08:45:12 stefanf Exp $"); + +#include +#include +#include +#include +#include "mblocal.h" + +size_t +wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t nwc, + size_t len, mbstate_t * __restrict ps) +{ + static mbstate_t mbs; + + if (ps == NULL) + ps = &mbs; + return (__wcsnrtombs(dst, src, nwc, len, ps)); +} + +size_t +__wcsnrtombs_std(char * __restrict dst, const wchar_t ** __restrict src, + size_t nwc, size_t len, mbstate_t * __restrict ps) +{ + mbstate_t mbsbak; + char buf[MB_LEN_MAX]; + const wchar_t *s; + size_t nbytes; + size_t nb; + + s = *src; + nbytes = 0; + + if (dst == NULL) { + while (nwc-- > 0) { + if ((nb = __wcrtomb(buf, *s, ps)) == (size_t)-1) + /* Invalid character - wcrtomb() sets errno. */ + return ((size_t)-1); + else if (*s == L'\0') + return (nbytes + nb - 1); + s++; + nbytes += nb; + } + return (nbytes); + } + + while (len > 0 && nwc-- > 0) { + if (len > (size_t)MB_CUR_MAX) { + /* Enough space to translate in-place. */ + if ((nb = __wcrtomb(dst, *s, ps)) == (size_t)-1) { + *src = s; + return ((size_t)-1); + } + } else { + /* + * May not be enough space; use temp. buffer. + * + * We need to save a copy of the conversion state + * here so we can restore it if the multibyte + * character is too long for the buffer. + */ + mbsbak = *ps; + if ((nb = __wcrtomb(buf, *s, ps)) == (size_t)-1) { + *src = s; + return ((size_t)-1); + } + if (nb > (int)len) { + /* MB sequence for character won't fit. */ + *ps = mbsbak; + break; + } + memcpy(dst, buf, nb); + } + if (*s == L'\0') { + *src = NULL; + return (nbytes + nb - 1); + } + s++; + dst += nb; + len -= nb; + nbytes += nb; + } + *src = s; + return (nbytes); +} diff --git a/src/lib/libc/locale/wcsrtombs.c b/src/lib/libc/locale/wcsrtombs.c new file mode 100644 index 0000000..61e5432 --- /dev/null +++ b/src/lib/libc/locale/wcsrtombs.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wcsrtombs.c,v 1.6 2004/07/21 10:54:57 tjr Exp $"); + +#include +#include +#include +#include +#include "mblocal.h" + +size_t +wcsrtombs(char * __restrict dst, const wchar_t ** __restrict src, size_t len, + mbstate_t * __restrict ps) +{ + static mbstate_t mbs; + + if (ps == NULL) + ps = &mbs; + return (__wcsnrtombs(dst, src, SIZE_T_MAX, len, ps)); +} diff --git a/src/lib/libc/locale/wcstod.c b/src/lib/libc/locale/wcstod.c new file mode 100644 index 0000000..da90f16 --- /dev/null +++ b/src/lib/libc/locale/wcstod.c @@ -0,0 +1,94 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstod.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); + +#include +#include +#include + +/* + * Convert a string to a double-precision number. + * + * This is the wide-character counterpart of strtod(). So that we do not + * have to duplicate the code of strtod() here, we convert the supplied + * wide character string to multibyte and call strtod() on the result. + * This assumes that the multibyte encoding is compatible with ASCII + * for at least the digits, radix character and letters. + */ +double +wcstod(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + static const mbstate_t initial; + mbstate_t mbs; + double val; + char *buf, *end; + const wchar_t *wcp; + size_t len; + + while (iswspace(*nptr)) + nptr++; + + /* + * Convert the supplied numeric wide char. string to multibyte. + * + * We could attempt to find the end of the numeric portion of the + * wide char. string to avoid converting unneeded characters but + * choose not to bother; optimising the uncommon case where + * the input string contains a lot of text after the number + * duplicates a lot of strtod()'s functionality and slows down the + * most common cases. + */ + wcp = nptr; + mbs = initial; + if ((len = wcsrtombs(NULL, &wcp, 0, &mbs)) == (size_t)-1) { + if (endptr != NULL) + *endptr = (wchar_t *)nptr; + return (0.0); + } + if ((buf = malloc(len + 1)) == NULL) + return (0.0); + mbs = initial; + wcsrtombs(buf, &wcp, len + 1, &mbs); + + /* Let strtod() do most of the work for us. */ + val = strtod(buf, &end); + + /* + * We only know where the number ended in the _multibyte_ + * representation of the string. If the caller wants to know + * where it ended, count multibyte characters to find the + * corresponding position in the wide char string. + */ + if (endptr != NULL) + /* XXX Assume each wide char is one byte. */ + *endptr = (wchar_t *)nptr + (end - buf); + + free(buf); + + return (val); +} diff --git a/src/lib/libc/locale/wcstof.c b/src/lib/libc/locale/wcstof.c new file mode 100644 index 0000000..a68b382 --- /dev/null +++ b/src/lib/libc/locale/wcstof.c @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2002, 2003 Tim J. Robbins + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstof.c,v 1.3 2004/04/07 09:47:56 tjr Exp $"); + +#include +#include +#include + +/* + * See wcstod() for comments as to the logic used. + */ +float +wcstof(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + static const mbstate_t initial; + mbstate_t mbs; + float val; + char *buf, *end; + const wchar_t *wcp; + size_t len; + + while (iswspace(*nptr)) + nptr++; + + wcp = nptr; + mbs = initial; + if ((len = wcsrtombs(NULL, &wcp, 0, &mbs)) == (size_t)-1) { + if (endptr != NULL) + *endptr = (wchar_t *)nptr; + return (0.0); + } + if ((buf = malloc(len + 1)) == NULL) + return (0.0); + mbs = initial; + wcsrtombs(buf, &wcp, len + 1, &mbs); + + val = strtof(buf, &end); + + if (endptr != NULL) + *endptr = (wchar_t *)nptr + (end - buf); + + free(buf); + + return (val); +} diff --git a/src/lib/libc/locale/wcstoimax.c b/src/lib/libc/locale/wcstoimax.c new file mode 100644 index 0000000..09e7817 --- /dev/null +++ b/src/lib/libc/locale/wcstoimax.c @@ -0,0 +1,128 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "from @(#)strtol.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +__FBSDID("FreeBSD: src/lib/libc/stdlib/strtoimax.c,v 1.8 2002/09/06 11:23:59 tjr Exp "); +#endif +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoimax.c,v 1.2 2003/01/01 18:48:43 schweikh Exp $"); + +#include +#include +#include +#include +#include + +/* + * Convert a wide character string to an intmax_t integer. + */ +intmax_t +wcstoimax(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base) +{ + const wchar_t *s; + uintmax_t acc; + wchar_t c; + uintmax_t cutoff; + int neg, any, cutlim; + + /* + * See strtoimax for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace(c)); + if (c == L'-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == L'+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = neg ? (uintmax_t)-(INTMAX_MIN + INTMAX_MAX) + INTMAX_MAX + : INTMAX_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { +#ifdef notyet + if (iswdigit(c)) + c = digittoint(c); + else +#endif + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= L'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? INTMAX_MIN : INTMAX_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (wchar_t *)(any ? s - 1 : nptr); + return (acc); +} diff --git a/src/lib/libc/locale/wcstol.c b/src/lib/libc/locale/wcstol.c new file mode 100644 index 0000000..ae51c2e --- /dev/null +++ b/src/lib/libc/locale/wcstol.c @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstol.c,v 1.1 2002/09/08 13:27:26 tjr Exp $"); + +#include +#include +#include +#include +#include + +/* + * Convert a string to a long integer. + */ +long +wcstol(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) +{ + const wchar_t *s; + unsigned long acc; + wchar_t c; + unsigned long cutoff; + int neg, any, cutlim; + + /* + * See strtol for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace(c)); + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == L'+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX + : LONG_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { +#ifdef notyet + if (iswdigit(c)) + c = digittoint(c); + else +#endif + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LONG_MIN : LONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (wchar_t *)(any ? s - 1 : nptr); + return (acc); +} diff --git a/src/lib/libc/locale/wcstold.c b/src/lib/libc/locale/wcstold.c new file mode 100644 index 0000000..c50ffbd --- /dev/null +++ b/src/lib/libc/locale/wcstold.c @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2002, 2003 Tim J. Robbins + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstold.c,v 1.4 2004/04/07 09:47:56 tjr Exp $"); + +#include +#include +#include + +/* + * See wcstod() for comments as to the logic used. + */ +long double +wcstold(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr) +{ + static const mbstate_t initial; + mbstate_t mbs; + long double val; + char *buf, *end; + const wchar_t *wcp; + size_t len; + + while (iswspace(*nptr)) + nptr++; + + wcp = nptr; + mbs = initial; + if ((len = wcsrtombs(NULL, &wcp, 0, &mbs)) == (size_t)-1) { + if (endptr != NULL) + *endptr = (wchar_t *)nptr; + return (0.0); + } + if ((buf = malloc(len + 1)) == NULL) + return (0.0); + mbs = initial; + wcsrtombs(buf, &wcp, len + 1, &mbs); + + val = strtold(buf, &end); + + if (endptr != NULL) + *endptr = (wchar_t *)nptr + (end - buf); + + free(buf); + + return (val); +} diff --git a/src/lib/libc/locale/wcstoll.c b/src/lib/libc/locale/wcstoll.c new file mode 100644 index 0000000..a48056c --- /dev/null +++ b/src/lib/libc/locale/wcstoll.c @@ -0,0 +1,127 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +__FBSDID("FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.19 2002/09/06 11:23:59 tjr Exp "); +#endif +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoll.c,v 1.1 2002/09/22 08:06:45 tjr Exp $"); + +#include +#include +#include +#include +#include + +/* + * Convert a wide character string to a long long integer. + */ +long long +wcstoll(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) +{ + const wchar_t *s; + unsigned long long acc; + wchar_t c; + unsigned long long cutoff; + int neg, any, cutlim; + + /* + * See strtoll for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace(c)); + if (c == L'-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == L'+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX + : LLONG_MAX; + cutlim = cutoff % base; + cutoff /= base; + for ( ; ; c = *s++) { +#ifdef notyet + if (iswdigit(c)) + c = digittoint(c); + else +#endif + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = neg ? LLONG_MIN : LLONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (wchar_t *)(any ? s - 1 : nptr); + return (acc); +} diff --git a/src/lib/libc/locale/wcstombs.c b/src/lib/libc/locale/wcstombs.c new file mode 100644 index 0000000..b798c9e --- /dev/null +++ b/src/lib/libc/locale/wcstombs.c @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstombs.c,v 1.10 2004/07/21 10:54:57 tjr Exp $"); + +#include +#include +#include +#include "mblocal.h" + +size_t +wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n) +{ + static const mbstate_t initial; + mbstate_t mbs; + + mbs = initial; + return (__wcsnrtombs(s, &pwcs, SIZE_T_MAX, n, &mbs)); +} diff --git a/src/lib/libc/locale/wcstoul.c b/src/lib/libc/locale/wcstoul.c new file mode 100644 index 0000000..f3b8b49 --- /dev/null +++ b/src/lib/libc/locale/wcstoul.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoul.c,v 1.1 2002/09/08 13:27:26 tjr Exp $"); + +#include +#include +#include +#include +#include + +/* + * Convert a wide character string to an unsigned long integer. + */ +unsigned long +wcstoul(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, int base) +{ + const wchar_t *s; + unsigned long acc; + wchar_t c; + unsigned long cutoff; + int neg, any, cutlim; + + /* + * See strtol for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace(c)); + if (c == L'-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == L'+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = ULONG_MAX / base; + cutlim = ULONG_MAX % base; + for ( ; ; c = *s++) { +#ifdef notyet + if (iswdigit(c)) + c = digittoint(c); + else +#endif + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (wchar_t *)(any ? s - 1 : nptr); + return (acc); +} diff --git a/src/lib/libc/locale/wcstoull.c b/src/lib/libc/locale/wcstoull.c new file mode 100644 index 0000000..fd9558b --- /dev/null +++ b/src/lib/libc/locale/wcstoull.c @@ -0,0 +1,126 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +__FBSDID("FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.18 2002/09/06 11:23:59 tjr Exp "); +#endif +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoull.c,v 1.1 2002/09/22 08:06:45 tjr Exp $"); + +#include +#include +#include +#include +#include + +/* + * Convert a wide character string to an unsigned long long integer. + */ +unsigned long long +wcstoull(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base) +{ + const wchar_t *s; + unsigned long long acc; + wchar_t c; + unsigned long long cutoff; + int neg, any, cutlim; + + /* + * See strtoull for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace(c)); + if (c == L'-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == L'+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = ULLONG_MAX / base; + cutlim = ULLONG_MAX % base; + for ( ; ; c = *s++) { +#ifdef notyet + if (iswdigit(c)) + c = digittoint(c); + else +#endif + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = ULLONG_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (wchar_t *)(any ? s - 1 : nptr); + return (acc); +} diff --git a/src/lib/libc/locale/wcstoumax.c b/src/lib/libc/locale/wcstoumax.c new file mode 100644 index 0000000..01e25d5 --- /dev/null +++ b/src/lib/libc/locale/wcstoumax.c @@ -0,0 +1,126 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "from @(#)strtoul.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ +__FBSDID("FreeBSD: src/lib/libc/stdlib/strtoumax.c,v 1.8 2002/09/06 11:23:59 tjr Exp "); +#endif +__FBSDID("$FreeBSD: src/lib/libc/locale/wcstoumax.c,v 1.1 2002/09/22 08:06:45 tjr Exp $"); + +#include +#include +#include +#include +#include + +/* + * Convert a wide character string to a uintmax_t integer. + */ +uintmax_t +wcstoumax(const wchar_t * __restrict nptr, wchar_t ** __restrict endptr, + int base) +{ + const wchar_t *s; + uintmax_t acc; + wchar_t c; + uintmax_t cutoff; + int neg, any, cutlim; + + /* + * See strtoimax for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (iswspace(c)); + if (c == L'-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == L'+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'0' ? 8 : 10; + acc = any = 0; + if (base < 2 || base > 36) + goto noconv; + + cutoff = UINTMAX_MAX / base; + cutlim = UINTMAX_MAX % base; + for ( ; ; c = *s++) { +#ifdef notyet + if (iswdigit(c)) + c = digittoint(c); + else +#endif + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'a' - 10; + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + any = -1; + else { + any = 1; + acc *= base; + acc += c; + } + } + if (any < 0) { + acc = UINTMAX_MAX; + errno = ERANGE; + } else if (!any) { +noconv: + errno = EINVAL; + } else if (neg) + acc = -acc; + if (endptr != NULL) + *endptr = (wchar_t *)(any ? s - 1 : nptr); + return (acc); +} diff --git a/src/lib/libc/locale/wctob.c b/src/lib/libc/locale/wctob.c new file mode 100644 index 0000000..a8f0056 --- /dev/null +++ b/src/lib/libc/locale/wctob.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wctob.c,v 1.4 2004/05/12 14:26:54 tjr Exp $"); + +#include +#include +#include +#include "mblocal.h" + +int +wctob(wint_t c) +{ + static const mbstate_t initial; + mbstate_t mbs = initial; + char buf[MB_LEN_MAX]; + + if (c == WEOF || __wcrtomb(buf, c, &mbs) != 1) + return (EOF); + return ((unsigned char)*buf); +} diff --git a/src/lib/libc/locale/wctomb.c b/src/lib/libc/locale/wctomb.c new file mode 100644 index 0000000..701b3ca --- /dev/null +++ b/src/lib/libc/locale/wctomb.c @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2002-2004 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wctomb.c,v 1.8 2004/07/29 06:18:40 tjr Exp $"); + +#include +#include +#include "mblocal.h" + +int +wctomb(char *s, wchar_t wchar) +{ + static const mbstate_t initial; + static mbstate_t mbs; + size_t rval; + + if (s == NULL) { + /* No support for state dependent encodings. */ + mbs = initial; + return (0); + } + if ((rval = __wcrtomb(s, wchar, &mbs)) == (size_t)-1) + return (-1); + return ((int)rval); +} diff --git a/src/lib/libc/locale/wctrans.c b/src/lib/libc/locale/wctrans.c new file mode 100644 index 0000000..a86e5c7 --- /dev/null +++ b/src/lib/libc/locale/wctrans.c @@ -0,0 +1,80 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wctrans.c,v 1.3 2003/11/01 08:20:58 tjr Exp $"); + +#include +#include +#include + +enum { + _WCT_ERROR = 0, + _WCT_TOLOWER = 1, + _WCT_TOUPPER = 2 +}; + +wint_t +towctrans(wint_t wc, wctrans_t desc) +{ + + switch (desc) { + case _WCT_TOLOWER: + wc = towlower(wc); + break; + case _WCT_TOUPPER: + wc = towupper(wc); + break; + case _WCT_ERROR: + default: + errno = EINVAL; + break; + } + + return (wc); +} + +wctrans_t +wctrans(const char *charclass) +{ + struct { + const char *name; + wctrans_t trans; + } ccls[] = { + { "tolower", _WCT_TOLOWER }, + { "toupper", _WCT_TOUPPER }, + { NULL, _WCT_ERROR }, /* Default */ + }; + int i; + + i = 0; + while (ccls[i].name != NULL && strcmp(ccls[i].name, charclass) != 0) + i++; + + if (ccls[i].trans == _WCT_ERROR) + errno = EINVAL; + return (ccls[i].trans); +} diff --git a/src/lib/libc/locale/wctype.c b/src/lib/libc/locale/wctype.c new file mode 100644 index 0000000..a0e21bc --- /dev/null +++ b/src/lib/libc/locale/wctype.c @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 2002 Tim J. Robbins. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wctype.c,v 1.3 2004/03/27 08:59:21 tjr Exp $"); + +#include +#include +#include + +#undef iswctype +int +iswctype(wint_t wc, wctype_t charclass) +{ + + return (__istype(wc, charclass)); +} + +wctype_t +wctype(const char *property) +{ + struct { + const char *name; + wctype_t mask; + } props[] = { + { "alnum", _CTYPE_A|_CTYPE_D }, + { "alpha", _CTYPE_A }, + { "blank", _CTYPE_B }, + { "cntrl", _CTYPE_C }, + { "digit", _CTYPE_D }, + { "graph", _CTYPE_G }, + { "lower", _CTYPE_L }, + { "print", _CTYPE_R }, + { "punct", _CTYPE_P }, + { "space", _CTYPE_S }, + { "upper", _CTYPE_U }, + { "xdigit", _CTYPE_X }, + { "ideogram", _CTYPE_I }, /* BSD extension */ + { "special", _CTYPE_T }, /* BSD extension */ + { "phonogram", _CTYPE_Q }, /* BSD extension */ + { "rune", 0xFFFFFF00L }, /* BSD extension */ + { NULL, 0UL }, /* Default */ + }; + int i; + + i = 0; + while (props[i].name != NULL && strcmp(props[i].name, property) != 0) + i++; + + return (props[i].mask); +} diff --git a/src/lib/libc/locale/wcwidth.c b/src/lib/libc/locale/wcwidth.c new file mode 100644 index 0000000..288a60d --- /dev/null +++ b/src/lib/libc/locale/wcwidth.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * This code is derived from software contributed to Berkeley by + * Paul Borman at Krystal Technologies. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD: src/lib/libc/locale/wcwidth.c,v 1.7 2004/08/12 12:19:11 tjr Exp $"); + +#include + +#undef wcwidth + +int +wcwidth(wchar_t wc) +{ + + return (__wcwidth(wc)); +}