diff options
Diffstat (limited to 'usr/src/lib')
73 files changed, 1087 insertions, 786 deletions
diff --git a/usr/src/lib/libc/Makefile b/usr/src/lib/libc/Makefile index 08d61a5f76..a6415ea2a1 100644 --- a/usr/src/lib/libc/Makefile +++ b/usr/src/lib/libc/Makefile @@ -127,7 +127,11 @@ $(ROOTVARIANTDIR64)/$(VAR1_DYNLIB64) := FILEMODE= 755 .KEEP_STATE: -all: lib32 $(BUILD64) .WAIT lib64 .WAIT etc +all: lib32 $(BUILD64) .WAIT lib64 .WAIT etc THIRDPARTYLICENSE + +THIRDPARTYLICENSE: extract-copyright + $(RM) $@ + ./extract-copyright . > $@ etc: $($(MACH)_ETC) diff --git a/usr/src/lib/libc/THIRDPARTYLICENSE.descrip b/usr/src/lib/libc/THIRDPARTYLICENSE.descrip new file mode 100644 index 0000000000..65b3b05edd --- /dev/null +++ b/usr/src/lib/libc/THIRDPARTYLICENSE.descrip @@ -0,0 +1 @@ +PORTIONS OF LIBC diff --git a/usr/src/lib/libc/extract-copyright.pl b/usr/src/lib/libc/extract-copyright.pl new file mode 100644 index 0000000000..2172216ae7 --- /dev/null +++ b/usr/src/lib/libc/extract-copyright.pl @@ -0,0 +1,121 @@ +#! /usr/perl5/bin/perl +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy is of the CDDL is also available via the Internet +# at http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2010 Nexenta Systems, Inc. All rights reserved. +# + +# +# This extracts all the BSD copyrights (excluding the CDDL licenses) +# for use in a THIRDPARTYLICENSE file. It tries hard to avoid duplicates. +# + +use strict; +use warnings; +use File::Find; + +my %LICENSE = (); + +sub dofile +{ + my $file = shift; + my $comment = 0; + my @license = (); + my @block = ();; + my $copyr = 0; + open(FILE, $file); + while (<FILE>) { + if (/^\/\*$/) { + $comment = 1; + $copyr = 0; + @block = (); + next; + } + if (!$comment) { + next; + } + # + # We don't want to know about CDDL files. They don't + # require an explicit THIRDPARTYLICENSE file. + # + if (/CDDL/) { + #print "$file is CDDL.\n"; + close(FILE); + return; + } + if (/Copyright/) { + $copyr = 1; + } + if (!/^ \*\//) { + push(@block, $_); + next; + } + # + # We have reached the end of the comment now. + # + $comment = 0; + + # Check to see if we saw a copyright. + if (!$copyr) { + next; + } + my $line; + foreach $line (@block) { + chomp $line; + $line =~ s/^ \* //; + $line =~ s/^ \*//; + $line =~ s/^ \*$//; + push(@license, $line); + } + } + + if ($#license > 0) { + my $lic = join "\n", @license; + push (@{$LICENSE{$lic}}, $file); + } + + close(FILE); +} + +my @FILES; + +sub wanted { + my $path = $File::Find::name; + + if (!-f $path) { + if ($path =~ /\.[chs]$/) { + push(@FILES, $path); + } + } + +} +foreach $a (@ARGV) { + if (-d $a) { + find(\&wanted, $a); + } elsif (-f $a) { + push(@FILES, $a); + } +} + +foreach $a (@FILES) { + dofile($a); +} + +foreach my $lic (keys %LICENSE) { + my @files = @{$LICENSE{$lic}}; + print "\nThe following files from the C library:\n"; + foreach my $f (@files) { + print(" $f\n"); + } + print "are provided under the following terms:\n\n"; + print "$lic\n"; +} diff --git a/usr/src/lib/libc/port/i18n/isdigit.c b/usr/src/lib/libc/port/i18n/isdigit.c index ca82bdb1d4..0629a0b411 100644 --- a/usr/src/lib/libc/port/i18n/isdigit.c +++ b/usr/src/lib/libc/port/i18n/isdigit.c @@ -1,27 +1,16 @@ /* - * CDDL HEADER START + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms version + * 1.0 of the CDDL. * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END + * A full copy of the text of the CDDL should have accompanied this + * source. A copy is of the CDDL is also available via the Internet + * at http://www.illumos.org/license/CDDL. */ /* * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. */ /* diff --git a/usr/src/lib/libc/port/locale/_ctype.h b/usr/src/lib/libc/port/locale/_ctype.h index ebf966c608..34c3a49435 100644 --- a/usr/src/lib/libc/port/locale/_ctype.h +++ b/usr/src/lib/libc/port/locale/_ctype.h @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. @@ -35,11 +36,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #ifndef __CTYPE_H_ #define __CTYPE_H_ diff --git a/usr/src/lib/libc/port/locale/ascii.c b/usr/src/lib/libc/port/locale/ascii.c index 3209956d22..74c76ddd73 100644 --- a/usr/src/lib/libc/port/locale/ascii.c +++ b/usr/src/lib/libc/port/locale/ascii.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. @@ -31,11 +32,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <sys/types.h> #include <errno.h> diff --git a/usr/src/lib/libc/port/locale/big5.c b/usr/src/lib/libc/port/locale/big5.c index ffc662e2a0..f13df7a6f2 100644 --- a/usr/src/lib/libc/port/locale/big5.c +++ b/usr/src/lib/libc/port/locale/big5.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. @@ -14,10 +15,6 @@ * 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. @@ -35,11 +32,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <sys/types.h> #include <errno.h> diff --git a/usr/src/lib/libc/port/locale/btowc.c b/usr/src/lib/libc/port/locale/btowc.c index 56d2536968..d835f8da77 100644 --- a/usr/src/lib/libc/port/locale/btowc.c +++ b/usr/src/lib/libc/port/locale/btowc.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002, 2003 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <stdio.h> #include <wchar.h> diff --git a/usr/src/lib/libc/port/locale/collate.c b/usr/src/lib/libc/port/locale/collate.c index d3354e858f..5ce0b847e5 100644 --- a/usr/src/lib/libc/port/locale/collate.c +++ b/usr/src/lib/libc/port/locale/collate.c @@ -1,4 +1,5 @@ /* + * Copright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> * at Electronni Visti IA, Kiev, Ukraine. * All rights reserved. @@ -25,52 +26,61 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - */ - #include "lint.h" #include "file64.h" #include <stdio.h> #include <stdlib.h> +#include <stddef.h> #include <string.h> +#include <wchar.h> #include <errno.h> #include <unistd.h> -#include <sysexits.h> -#include <netinet/in.h> +#include <ctype.h> +#include <unistd.h> +#include <fcntl.h> +#include <assert.h> +#include <sys/stat.h> +#include <sys/mman.h> #include "collate.h" #include "setlocale.h" #include "ldpart.h" -int __collate_load_error = 1; -int __collate_substitute_nontrivial; +static collate_subst_t *subst_table[COLL_WEIGHTS_MAX]; +static collate_char_pri_t *char_pri_table; +static collate_large_pri_t *large_pri_table; +static collate_chain_pri_t *chain_pri_table; +static char *cache = NULL; +static size_t cachesz; +static char collate_encoding[ENCODING_LEN + 1]; + +/* Exposed externally to other parts of libc. */ +collate_info_t *_collate_info; +int _collate_load_error = 1; -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; int -__collate_load_tables(const char *encoding) +_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]; + int i, chains, z; + char buf[PATH_MAX]; + char *TMP; + char *map; + collate_info_t *info; + struct stat sbuf; + int fd; /* 'encoding' must be already checked. */ if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { - __collate_load_error = 1; + _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; + if (cache && (strncmp(encoding, collate_encoding, ENCODING_LEN) == 0)) { + _collate_load_error = 0; return (_LDP_CACHE); } @@ -81,171 +91,533 @@ __collate_load_tables(const char *encoding) (void) snprintf(buf, sizeof (buf), "%s/%s/LC_COLLATE/LCL_DATA", _PathLocale, encoding); - if ((fp = fopen(buf, "r")) == NULL) + if ((fd = open(buf, O_RDONLY)) < 0) return (_LDP_ERROR); - - if (fread(strbuf, sizeof (strbuf), 1, fp) != 1) { - saverr = errno; - (void) fclose(fp); - errno = saverr; + if (fstat(fd, &sbuf) < 0) { + (void) close(fd); 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); + if (sbuf.st_size < (COLLATE_STR_LEN + sizeof (info))) { + (void) close(fd); errno = EINVAL; 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 = EINVAL; - return (_LDP_ERROR); - } - } else - chains = TABLE_SIZE; + map = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + (void) close(fd); + if ((TMP = map) == NULL) { + return (_LDP_ERROR); + } - if ((TMP_substitute_table = - malloc(sizeof (__collate_substitute_table))) == NULL) { - saverr = errno; - (void) fclose(fp); - errno = saverr; + if (strncmp(TMP, COLLATE_VERSION, COLLATE_STR_LEN) != 0) { + (void) munmap(map, sbuf.st_size); + errno = EINVAL; 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; + TMP += COLLATE_STR_LEN; + + info = (void *)TMP; + TMP += sizeof (*info); + + if ((info->directive_count < 1) || + (info->directive_count >= COLL_WEIGHTS_MAX) || + ((chains = info->chain_count) < 0)) { + (void) munmap(map, sbuf.st_size); + errno = EINVAL; 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; + + i = (sizeof (collate_char_pri_t) * (UCHAR_MAX + 1)) + + (sizeof (collate_chain_pri_t) * chains) + + (sizeof (collate_large_pri_t) * info->large_pri_count); + for (z = 0; z < (info->directive_count); z++) { + i += sizeof (collate_subst_t) * info->subst_count[z]; + } + if (i != (sbuf.st_size - (TMP - map))) { + (void) munmap(map, sbuf.st_size); + errno = EINVAL; 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); \ - } \ -} + char_pri_table = (void *)TMP; + TMP += sizeof (collate_char_pri_t) * (UCHAR_MAX + 1); - 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; + for (z = 0; z < info->directive_count; z++) { + if (info->subst_count[z] > 0) { + subst_table[z] = (void *)TMP; + TMP += info->subst_count[z] * sizeof (collate_subst_t); + } else { + subst_table[z] = NULL; } } - __collate_load_error = 0; + + if (chains > 0) { + chain_pri_table = (void *)TMP; + TMP += chains * sizeof (collate_chain_pri_t); + } else + chain_pri_table = NULL; + if (info->large_pri_count > 0) + large_pri_table = (void *)TMP; + else + large_pri_table = NULL; + + (void) strlcpy(collate_encoding, encoding, ENCODING_LEN); + _collate_info = info; + + if (cache) + (void) munmap(cache, cachesz); + + cache = map; + cachesz = sbuf.st_size; + _collate_load_error = 0; return (_LDP_LOADED); } -char * -__collate_substitute(const char *str) +/* + * Note: for performance reasons, we have expanded bsearch here. This avoids + * function call overhead with each comparison. + */ + +static int32_t * +substsearch(const wchar_t key, int pass) { - int dest_len, len, nlen; - int delta; - char *dest_str = NULL; - uchar_t *s = (uchar_t *)str; + int low; + int high; + int next, compar; + collate_subst_t *p; + collate_subst_t *tab; + int n = _collate_info->subst_count[pass]; - if (s == NULL || *s == '\0') { - return (strdup("")); + if (n == 0) + return (NULL); + + tab = subst_table[pass]; + low = 0; + high = n - 1; + while (low <= high) { + next = (low + high) / 2; + p = tab + next; + compar = key - p->key; + if (compar == 0) + return (p->pri); + if (compar > 0) + low = next + 1; + else + high = next - 1; } + return (NULL); +} - delta = strlen(str); - delta += delta / 8; - dest_str = malloc(dest_len = delta); - if (dest_str == NULL) +static collate_chain_pri_t * +chainsearch(const wchar_t *key, int *len) +{ + int low; + int high; + int next, compar, l; + collate_chain_pri_t *p; + collate_chain_pri_t *tab; + + if (_collate_info->chain_count == 0) return (NULL); - len = 0; - while (*s) { - nlen = len + strlen(__collate_substitute_table[*s]); - if (dest_len <= nlen) { - char *new_str; - new_str = realloc(dest_str, dest_len = nlen + delta); - if (new_str == NULL) { - free(dest_str); - return (NULL); + + low = 0; + high = _collate_info->chain_count - 1; + tab = chain_pri_table; + + while (low <= high) { + next = (low + high) / 2; + p = tab + next; + compar = *key - *p->str; + if (compar == 0) { + l = wcsnlen(p->str, COLLATE_STR_LEN); + compar = wcsncmp(key, p->str, l); + if (compar == 0) { + *len = l; + return (p); } - dest_str = new_str; } - (void) strcpy(dest_str + len, - (char *)__collate_substitute_table[*s++]); - len = nlen; + if (compar > 0) + low = next + 1; + else + high = next - 1; } - return (dest_str); + return (NULL); +} + +static collate_large_pri_t * +largesearch(const wchar_t key) +{ + int low = 0; + int high = _collate_info->large_pri_count - 1; + int next, compar; + collate_large_pri_t *p; + collate_large_pri_t *tab = large_pri_table; + + if (_collate_info->large_pri_count == 0) + return (NULL); + + while (low <= high) { + next = (low + high) / 2; + p = tab + next; + compar = key - p->val; + if (compar == 0) + return (p); + if (compar > 0) + low = next + 1; + else + high = next - 1; + } + return (NULL); } void -__collate_lookup(const char *t, int *len, int *prim, int *sec) +_collate_lookup(const wchar_t *t, int *len, int *pri, int which, + int **state) { - struct __collate_st_chain_pri *p2; + collate_chain_pri_t *p2; + collate_large_pri_t *match; + int p, l; + int *sptr; + /* + * If we have remaining substitution data from a previous + * call, consume it first. + */ + if ((sptr = *state) != NULL) { + *pri = *sptr; + sptr++; + *state = *sptr ? sptr : NULL; + *len = 0; + return; + } + + /* No active substitutions */ *len = 1; - *prim = *sec = 0; - for (p2 = __collate_chain_pri_table; p2->str[0] != '\0'; p2++) { - if (*t == p2->str[0] && - strncmp(t, (char *)p2->str, strlen((char *)p2->str)) == 0) { - *len = strlen((char *)p2->str); - *prim = p2->prim; - *sec = p2->sec; - return; + + /* + * Check for composites such as dipthongs that collate as a + * single element (aka chains or collating-elements). + */ + if (((p2 = chainsearch(t, &l)) != NULL) && + ((p = p2->pri[which]) >= 0)) { + + *len = l; + *pri = p; + + } else if (*t <= UCHAR_MAX) { + + /* + * Character is a small (8-bit) character. + * We just look these up directly for speed. + */ + *pri = char_pri_table[*t].pri[which]; + + } else if ((_collate_info->large_pri_count > 0) && + ((match = largesearch(*t)) != NULL)) { + + /* + * Character was found in the extended table. + */ + *pri = match->pri.pri[which]; + + } else { + /* + * Character lacks a specific definition. + */ + if (_collate_info->directive[which] & DIRECTIVE_UNDEFINED) { + /* Mask off sign bit to prevent ordering confusion. */ + *pri = (*t & COLLATE_MAX_PRIORITY); + } else { + *pri = _collate_info->undef_pri[which]; } + /* No substitutions for undefined characters! */ + return; } - *prim = __collate_char_pri_table[(uchar_t)*t].prim; - *sec = __collate_char_pri_table[(uchar_t)*t].sec; + + /* + * Try substituting (expanding) the character. We are + * currently doing this *after* the chain compression. I + * think it should not matter, but this way might be slightly + * faster. + * + * We do this after the priority search, as this will help us + * to identify a single key value. In order for this to work, + * its important that the priority assigned to a given element + * to be substituted be unique for that level. The localedef + * code ensures this for us. + */ + if ((*pri & COLLATE_SUBST_PRIORITY) && + (sptr = substsearch(*pri, which)) != NULL) { + if ((*pri = *sptr) != 0) { + sptr++; + *state = *sptr ? sptr : NULL; + } + } + +} + +/* + * This is the meaty part of wcsxfrm & strxfrm. Note that it does + * NOT NULL terminate. That is left to the caller. + */ +size_t +_collate_wxfrm(const wchar_t *src, wchar_t *xf, size_t room) +{ + int pri; + int len; + const wchar_t *t; + wchar_t *tr = NULL; + int direc; + int pass; + int32_t *state; + size_t want = 0; + size_t need = 0; + + assert(src); + + for (pass = 0; pass <= _collate_info->directive_count; pass++) { + + state = NULL; + + if (pass != 0) { + /* insert level separator from the previous pass */ + if (room) { + *xf++ = 1; + room--; + } + want++; + } + + /* special pass for undefined */ + if (pass == _collate_info->directive_count) { + direc = DIRECTIVE_FORWARD | DIRECTIVE_UNDEFINED; + } else { + direc = _collate_info->directive[pass]; + } + + t = src; + + if (direc & DIRECTIVE_BACKWARD) { + wchar_t *bp, *fp, c; + if (tr) + free(tr); + if ((tr = wcsdup(t)) == NULL) { + errno = ENOMEM; + goto fail; + } + bp = tr; + fp = tr + wcslen(tr) - 1; + while (bp < fp) { + c = *bp; + *bp++ = *fp; + *fp-- = c; + } + t = (const wchar_t *)tr; + } + + if (direc & DIRECTIVE_POSITION) { + while (*t || state) { + _collate_lookup(t, &len, &pri, pass, &state); + t += len; + if (pri <= 0) { + if (pri < 0) { + errno = EINVAL; + goto fail; + } + pri = COLLATE_MAX_PRIORITY; + } + if (room) { + *xf++ = pri; + room--; + } + want++; + need = want; + } + } else { + while (*t || state) { + _collate_lookup(t, &len, &pri, pass, &state); + t += len; + if (pri <= 0) { + if (pri < 0) { + errno = EINVAL; + goto fail; + } + continue; + } + if (room) { + *xf++ = pri; + room--; + } + want++; + need = want; + } + } + } + +end: + if (tr) + free(tr); + return (need); + +fail: + if (tr) + free(tr); + return ((size_t)(-1)); +} + +/* + * In the non-POSIX case, we transform each character into a string of + * characters representing the character's priority. Since char is usually + * signed, we are limited by 7 bits per byte. To avoid zero, we need to add + * XFRM_OFFSET, so we can't use a full 7 bits. For simplicity, we choose 6 + * bits per byte. + * + * It turns out that we sometimes have real priorities that are + * 31-bits wide. (But: be careful using priorities where the high + * order bit is set -- i.e. the priority is negative. The sort order + * may be surprising!) + * + * TODO: This would be a good area to optimize somewhat. It turns out + * that real prioririties *except for the last UNDEFINED pass* are generally + * very small. We need the localedef code to precalculate the max + * priority for us, and ideally also give us a mask, and then we could + * severely limit what we expand to. + */ +#define XFRM_BYTES 6 +#define XFRM_OFFSET ('0') /* make all printable characters */ +#define XFRM_SHIFT 6 +#define XFRM_MASK ((1 << XFRM_SHIFT) - 1) +#define XFRM_SEP ('.') /* chosen to be less than XFRM_OFFSET */ + +static void +xfrm(unsigned char *p, int pri) +{ + int i; + for (i = 0; i < XFRM_BYTES; i++) { + p[i] = (pri & XFRM_MASK) + XFRM_OFFSET; + pri >>= XFRM_SHIFT; + } +} + +size_t +_collate_sxfrm(const wchar_t *src, char *xf, size_t room) +{ + int pri; + int len; + const wchar_t *t; + wchar_t *tr = NULL; + int direc; + int pass; + int32_t *state; + size_t want = 0; + size_t need = 0; + int b; + uint8_t buf[XFRM_BYTES]; + + assert(src); + + for (pass = 0; pass <= _collate_info->directive_count; pass++) { + + state = NULL; + + if (pass != 0) { + /* insert level separator from the previous pass */ + if (room) { + *xf++ = XFRM_SEP; + room--; + } + want++; + } + + /* special pass for undefined */ + if (pass == _collate_info->directive_count) { + direc = DIRECTIVE_FORWARD | DIRECTIVE_UNDEFINED; + } else { + direc = _collate_info->directive[pass]; + } + + t = src; + + if (direc & DIRECTIVE_BACKWARD) { + wchar_t *bp, *fp, c; + if (tr) + free(tr); + if ((tr = wcsdup(t)) == NULL) { + errno = ENOMEM; + goto fail; + } + bp = tr; + fp = tr + wcslen(tr) - 1; + while (bp < fp) { + c = *bp; + *bp++ = *fp; + *fp-- = c; + } + t = (const wchar_t *)tr; + } + + if (direc & DIRECTIVE_POSITION) { + while (*t || state) { + + _collate_lookup(t, &len, &pri, pass, &state); + t += len; + if (pri <= 0) { + if (pri < 0) { + errno = EINVAL; + goto fail; + } + pri = COLLATE_MAX_PRIORITY; + } + + if (room) { + b = XFRM_BYTES; + xfrm(buf, pri); + + while (b) { + b--; + if (room) + *xf++ = buf[b]; + room--; + } + } + want += XFRM_BYTES; + need = want; + } + } else { + while (*t || state) { + _collate_lookup(t, &len, &pri, pass, &state); + t += len; + if (pri <= 0) { + if (pri < 0) { + errno = EINVAL; + goto fail; + } + continue; + } + if (room) { + b = XFRM_BYTES; + xfrm(buf, pri); + + while (b) { + b--; + if (room) + *xf++ = buf[b]; + room--; + } + } + want += XFRM_BYTES; + need = want; + } + } + } + +end: + if (tr) + free(tr); + return (need); + +fail: + if (tr) + free(tr); + return ((size_t)(-1)); } diff --git a/usr/src/lib/libc/port/locale/collate.h b/usr/src/lib/libc/port/locale/collate.h index 149ba6866a..02bf4be6f3 100644 --- a/usr/src/lib/libc/port/locale/collate.h +++ b/usr/src/lib/libc/port/locale/collate.h @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systmes, Inc. All rights reserved. * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> * at Electronni Visti IA, Kiev, Ukraine. * All rights reserved. @@ -31,31 +32,73 @@ #include <sys/types.h> #include <limits.h> -#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 { - 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 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; - -char *__collate_substitute(const char *); -int __collate_load_tables(const char *); -void __collate_lookup(const char *, int *, int *, int *); -int __collate_range_cmp(int, int); +#define COLLATE_STR_LEN 24 /* should be 64-bit multiple */ +#define COLLATE_VERSION "I1.0\n" + +#define COLLATE_MAX_PRIORITY (0x7fffffff) /* max signed value */ +#define COLLATE_SUBST_PRIORITY (0x40000000) /* bit indicates subst table */ + +#define DIRECTIVE_UNDEF 0x00 +#define DIRECTIVE_FORWARD 0x01 +#define DIRECTIVE_BACKWARD 0x02 +#define DIRECTIVE_POSITION 0x04 +#define DIRECTIVE_UNDEFINED 0x08 /* special last weight for UNDEFINED */ + +#define DIRECTIVE_DIRECTION_MASK (DIRECTIVE_FORWARD | DIRECTIVE_BACKWARD) + +/* + * The collate file format is as follows: + * + * char version[COLLATE_STR_LEN]; // must be COLLATE_VERSION + * collate_info_t info; // see below, includes padding + * collate_char_pri_t char_data[256]; // 8 bit char values + * collate_subst_t subst[*]; // 0 or more substitutions + * collate_chain_pri_t chains[*]; // 0 or more chains + * collate_large_pri_t large[*]; // extended char priorities + * + * Note that all structures must be 32-bit aligned, as each structure + * contains 32-bit member fields. The entire file is mmap'd, so its + * critical that alignment be observed. It is not generally safe to + * use any 64-bit values in the structures. + */ + +typedef struct collate_info { + uint8_t directive_count; + uint8_t directive[COLL_WEIGHTS_MAX]; + int32_t flags; + int32_t chain_count; + int32_t large_pri_count; + int32_t subst_count[COLL_WEIGHTS_MAX]; + int32_t undef_pri[COLL_WEIGHTS_MAX]; +} collate_info_t; + +typedef struct collate_char_pri { + int32_t pri[COLL_WEIGHTS_MAX]; +} collate_char_pri_t; + +typedef struct collate_chain_pri { + wchar_t str[COLLATE_STR_LEN]; + int32_t pri[COLL_WEIGHTS_MAX]; +} collate_chain_pri_t; + +typedef struct collate_large_pri { + int32_t val; + collate_char_pri_t pri; +} collate_large_pri_t; + +typedef struct collate_subst { + int32_t key; + int32_t pri[COLLATE_STR_LEN]; +} collate_subst_t; + +int _collate_load_tables(const char *); +void _collate_lookup(const wchar_t *, int *, int *, int, int **); +size_t _collate_wxfrm(const wchar_t *, wchar_t *, size_t); +size_t _collate_sxfrm(const wchar_t *, char *, size_t); +int _collate_range_cmp(wchar_t, wchar_t); + +extern int _collate_load_error; +extern int _collate_substitute_nontrivial; +extern collate_info_t *_collate_info; #endif /* !_COLLATE_H_ */ diff --git a/usr/src/lib/libc/port/locale/collcmp.c b/usr/src/lib/libc/port/locale/collcmp.c index b73d24dd11..1b075f3c5f 100644 --- a/usr/src/lib/libc/port/locale/collcmp.c +++ b/usr/src/lib/libc/port/locale/collcmp.c @@ -26,6 +26,7 @@ #include "lint.h" #include <string.h> +#include <wchar.h> #include "collate.h" /* @@ -33,11 +34,11 @@ */ int -__collate_range_cmp(int c1, int c2) +_collate_range_cmp(wchar_t c1, wchar_t c2) { - static char s1[2], s2[2]; + static wchar_t s1[2], s2[2]; s1[0] = c1; s2[0] = c2; - return (strcoll(s1, s2)); + return (wcscoll(s1, s2)); } diff --git a/usr/src/lib/libc/port/locale/engine.c b/usr/src/lib/libc/port/locale/engine.c index 6fcf81ad15..80f2fc89dc 100644 --- a/usr/src/lib/libc/port/locale/engine.c +++ b/usr/src/lib/libc/port/locale/engine.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1992, 1993, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -32,11 +33,6 @@ */ /* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* * The matching engine and friends. This file is #included by regexec.c * after suitable #defines of a variety of macros used herein, so that * different state representations can be used without duplicating masses diff --git a/usr/src/lib/libc/port/locale/euc.c b/usr/src/lib/libc/port/locale/euc.c index 28883e53df..b6d349182f 100644 --- a/usr/src/lib/libc/port/locale/euc.c +++ b/usr/src/lib/libc/port/locale/euc.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. @@ -14,10 +15,6 @@ * 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. @@ -35,11 +32,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <errno.h> #include <limits.h> diff --git a/usr/src/lib/libc/port/locale/fgetwc.c b/usr/src/lib/libc/port/locale/fgetwc.c index f3d0fd8728..6f86247132 100644 --- a/usr/src/lib/libc/port/locale/fgetwc.c +++ b/usr/src/lib/libc/port/locale/fgetwc.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -23,10 +24,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ #include "lint.h" #include "mse_int.h" diff --git a/usr/src/lib/libc/port/locale/fgetws.c b/usr/src/lib/libc/port/locale/fgetws.c index bba61bbd83..e209023141 100644 --- a/usr/src/lib/libc/port/locale/fgetws.c +++ b/usr/src/lib/libc/port/locale/fgetws.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -23,10 +24,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ #include "lint.h" #include "mse_int.h" diff --git a/usr/src/lib/libc/port/locale/fnmatch.c b/usr/src/lib/libc/port/locale/fnmatch.c index 24cc3f7b4e..c218812bf2 100644 --- a/usr/src/lib/libc/port/locale/fnmatch.c +++ b/usr/src/lib/libc/port/locale/fnmatch.c @@ -277,10 +277,10 @@ rangematch(pattern, test, flags, newp, patmbs) if (flags & FNM_IGNORECASE) c2 = towlower(c2); - if (__collate_load_error ? + if (_collate_load_error ? c <= test && test <= c2 : - __collate_range_cmp(c, test) <= 0 && - __collate_range_cmp(test, c2) <= 0) + _collate_range_cmp(c, test) <= 0 && + _collate_range_cmp(test, c2) <= 0) ok = 1; } else if (c == test) ok = 1; diff --git a/usr/src/lib/libc/port/locale/fwide.c b/usr/src/lib/libc/port/locale/fwide.c index 6e326cff17..9de0ac46b5 100644 --- a/usr/src/lib/libc/port/locale/fwide.c +++ b/usr/src/lib/libc/port/locale/fwide.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include "mse_int.h" #include "file64.h" diff --git a/usr/src/lib/libc/port/locale/gb18030.c b/usr/src/lib/libc/port/locale/gb18030.c index 9c96fd4e06..eab6e332c2 100644 --- a/usr/src/lib/libc/port/locale/gb18030.c +++ b/usr/src/lib/libc/port/locale/gb18030.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins * All rights reserved. * @@ -25,11 +26,6 @@ */ /* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* * PRC National Standard GB 18030-2000 encoding of Chinese text. * * See gb18030(5) for details. diff --git a/usr/src/lib/libc/port/locale/gb2312.c b/usr/src/lib/libc/port/locale/gb2312.c index 3c0633f630..4658fe3944 100644 --- a/usr/src/lib/libc/port/locale/gb2312.c +++ b/usr/src/lib/libc/port/locale/gb2312.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2004 Tim J. Robbins. All rights reserved. * Copyright (c) 2003 David Xu <davidxu@freebsd.org> * All rights reserved. @@ -25,11 +26,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <sys/types.h> #include <errno.h> diff --git a/usr/src/lib/libc/port/locale/gbk.c b/usr/src/lib/libc/port/locale/gbk.c index 020263670b..1d02c189a1 100644 --- a/usr/src/lib/libc/port/locale/gbk.c +++ b/usr/src/lib/libc/port/locale/gbk.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. @@ -31,11 +32,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <sys/types.h> #include <errno.h> diff --git a/usr/src/lib/libc/port/locale/getdate.c b/usr/src/lib/libc/port/locale/getdate.c index a2bb0685bf..325d4237d4 100644 --- a/usr/src/lib/libc/port/locale/getdate.c +++ b/usr/src/lib/libc/port/locale/getdate.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2009 The NetBSD Foundation, Inc. * All rights reserved. * @@ -27,11 +28,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include "file64.h" #include <sys/types.h> diff --git a/usr/src/lib/libc/port/locale/iswctype.c b/usr/src/lib/libc/port/locale/iswctype.c index e6b1140562..c387a0cdae 100644 --- a/usr/src/lib/libc/port/locale/iswctype.c +++ b/usr/src/lib/libc/port/locale/iswctype.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. @@ -35,11 +36,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <wctype.h> #include "runefile.h" @@ -47,7 +43,7 @@ #include "_ctype.h" /* - * We removed: iswascii, iswrune, iswhexnumber, and iswnumber, as + * We removed: iswascii, iswhexnumber, and iswnumber, as * these are not present on Solaris. Note that the standard requires * iswascii to be a macro, so it is defined in our headers. * diff --git a/usr/src/lib/libc/port/locale/ldpart.c b/usr/src/lib/libc/port/locale/ldpart.c index eb350948c1..6ae51a9423 100644 --- a/usr/src/lib/libc/port/locale/ldpart.c +++ b/usr/src/lib/libc/port/locale/ldpart.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org> * All rights reserved. * @@ -24,10 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - */ - #include "lint.h" #include "file64.h" #include <sys/types.h> diff --git a/usr/src/lib/libc/port/locale/lmessages.c b/usr/src/lib/libc/port/locale/lmessages.c index 75076b1d01..1cb83e0ac8 100644 --- a/usr/src/lib/libc/port/locale/lmessages.c +++ b/usr/src/lib/libc/port/locale/lmessages.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org> * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <stddef.h> #include "ldpart.h" diff --git a/usr/src/lib/libc/port/locale/lmonetary.c b/usr/src/lib/libc/port/locale/lmonetary.c index ff04b5637c..051a6b4d6c 100644 --- a/usr/src/lib/libc/port/locale/lmonetary.c +++ b/usr/src/lib/libc/port/locale/lmonetary.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org> * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <limits.h> #include <stddef.h> diff --git a/usr/src/lib/libc/port/locale/lnumeric.c b/usr/src/lib/libc/port/locale/lnumeric.c index c125ebcc5d..4fd70f1fe7 100644 --- a/usr/src/lib/libc/port/locale/lnumeric.c +++ b/usr/src/lib/libc/port/locale/lnumeric.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org> * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <limits.h> #include "ldpart.h" diff --git a/usr/src/lib/libc/port/locale/localeconv.c b/usr/src/lib/libc/port/locale/localeconv.c index c99f1ee088..f2ad7f5559 100644 --- a/usr/src/lib/libc/port/locale/localeconv.c +++ b/usr/src/lib/libc/port/locale/localeconv.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org> * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. @@ -28,11 +29,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #ifndef _LCONV_C99 #define _LCONV_C99 /* so we get all the extensions */ #endif diff --git a/usr/src/lib/libc/port/locale/mbftowc.c b/usr/src/lib/libc/port/locale/mbftowc.c index ed6514c406..feef82f097 100644 --- a/usr/src/lib/libc/port/locale/mbftowc.c +++ b/usr/src/lib/libc/port/locale/mbftowc.c @@ -1,27 +1,16 @@ /* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - * - * 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 file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms version + * 1.0 of the CDDL. * - * 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. + * A full copy of the text of the CDDL should have accompanied this + * source. A copy is of the CDDL is also available via the Internet + * at http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. */ #include "lint.h" diff --git a/usr/src/lib/libc/port/locale/mblen.c b/usr/src/lib/libc/port/locale/mblen.c index 5ab2608236..454aeead6c 100644 --- a/usr/src/lib/libc/port/locale/mblen.c +++ b/usr/src/lib/libc/port/locale/mblen.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <stdlib.h> #include <wchar.h> diff --git a/usr/src/lib/libc/port/locale/mblocal.h b/usr/src/lib/libc/port/locale/mblocal.h index f2b44a6675..0d609f9b77 100644 --- a/usr/src/lib/libc/port/locale/mblocal.h +++ b/usr/src/lib/libc/port/locale/mblocal.h @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #ifndef _MBLOCAL_H_ #define _MBLOCAL_H_ diff --git a/usr/src/lib/libc/port/locale/mbrlen.c b/usr/src/lib/libc/port/locale/mbrlen.c index 6a65ce40b2..d01ac90b60 100644 --- a/usr/src/lib/libc/port/locale/mbrlen.c +++ b/usr/src/lib/libc/port/locale/mbrlen.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <wchar.h> #include "mblocal.h" diff --git a/usr/src/lib/libc/port/locale/mbrtowc.c b/usr/src/lib/libc/port/locale/mbrtowc.c index 165f30efc2..2d155d2bca 100644 --- a/usr/src/lib/libc/port/locale/mbrtowc.c +++ b/usr/src/lib/libc/port/locale/mbrtowc.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <wchar.h> #include "mblocal.h" diff --git a/usr/src/lib/libc/port/locale/mbsinit.c b/usr/src/lib/libc/port/locale/mbsinit.c index d514d0ee51..036f704260 100644 --- a/usr/src/lib/libc/port/locale/mbsinit.c +++ b/usr/src/lib/libc/port/locale/mbsinit.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <wchar.h> #include "mblocal.h" diff --git a/usr/src/lib/libc/port/locale/mbsnrtowcs.c b/usr/src/lib/libc/port/locale/mbsnrtowcs.c index 7ca21ac915..3ed93cfeb5 100644 --- a/usr/src/lib/libc/port/locale/mbsnrtowcs.c +++ b/usr/src/lib/libc/port/locale/mbsnrtowcs.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <errno.h> #include <limits.h> diff --git a/usr/src/lib/libc/port/locale/mbsrtowcs.c b/usr/src/lib/libc/port/locale/mbsrtowcs.c index b1eff34f6a..592a0e3c83 100644 --- a/usr/src/lib/libc/port/locale/mbsrtowcs.c +++ b/usr/src/lib/libc/port/locale/mbsrtowcs.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <errno.h> #include <limits.h> diff --git a/usr/src/lib/libc/port/locale/mbstowcs.c b/usr/src/lib/libc/port/locale/mbstowcs.c index 29fbac2ce0..343564ec93 100644 --- a/usr/src/lib/libc/port/locale/mbstowcs.c +++ b/usr/src/lib/libc/port/locale/mbstowcs.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <limits.h> #include <stdlib.h> diff --git a/usr/src/lib/libc/port/locale/mbtowc.c b/usr/src/lib/libc/port/locale/mbtowc.c index c87a181b45..66718fa90a 100644 --- a/usr/src/lib/libc/port/locale/mbtowc.c +++ b/usr/src/lib/libc/port/locale/mbtowc.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <stdlib.h> #include <wchar.h> diff --git a/usr/src/lib/libc/port/locale/mskanji.c b/usr/src/lib/libc/port/locale/mskanji.c index d9cc0eb6a8..1b6c2d0584 100644 --- a/usr/src/lib/libc/port/locale/mskanji.c +++ b/usr/src/lib/libc/port/locale/mskanji.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. * * ja_JP.SJIS locale table for BSD4.4/rune @@ -33,11 +34,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <sys/types.h> #include <errno.h> diff --git a/usr/src/lib/libc/port/locale/nl_langinfo.c b/usr/src/lib/libc/port/locale/nl_langinfo.c index 2c296b45e5..840f45ef45 100644 --- a/usr/src/lib/libc/port/locale/nl_langinfo.c +++ b/usr/src/lib/libc/port/locale/nl_langinfo.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2001, 2003 Alexey Zelkin <phantom@FreeBSD.org> * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <langinfo.h> #include <limits.h> diff --git a/usr/src/lib/libc/port/locale/none.c b/usr/src/lib/libc/port/locale/none.c index 802a056929..14b6d71abb 100644 --- a/usr/src/lib/libc/port/locale/none.c +++ b/usr/src/lib/libc/port/locale/none.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. @@ -31,11 +32,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <errno.h> #include <limits.h> diff --git a/usr/src/lib/libc/port/locale/regcomp.c b/usr/src/lib/libc/port/locale/regcomp.c index 0424234d39..b43fbfd599 100644 --- a/usr/src/lib/libc/port/locale/regcomp.c +++ b/usr/src/lib/libc/port/locale/regcomp.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1992, 1993, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -31,11 +32,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include "file64.h" #include <sys/types.h> @@ -760,18 +756,16 @@ p_b_term(struct parse *p, cset *cs) if (start == finish) CHadd(p, cs, start); else { - if (__collate_load_error) { + if (_collate_load_error) { (void) REQUIRE((uch)start <= (uch)finish, REG_ERANGE); CHaddrange(p, cs, start, finish); } else { - (void) REQUIRE(__collate_range_cmp(start, + (void) REQUIRE(_collate_range_cmp(start, finish) <= 0, REG_ERANGE); for (i = 0; i <= UCHAR_MAX; i++) { - if (__collate_range_cmp(start, i) <= - 0 && - __collate_range_cmp(i, finish) <= - 0) + if (_collate_range_cmp(start, i) <= 0 && + _collate_range_cmp(i, finish) <= 0) CHadd(p, cs, i); } } diff --git a/usr/src/lib/libc/port/locale/regerror.c b/usr/src/lib/libc/port/locale/regerror.c index 2a81ed67f1..eb5178d1e5 100644 --- a/usr/src/lib/libc/port/locale/regerror.c +++ b/usr/src/lib/libc/port/locale/regerror.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1992, 1993, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -31,11 +32,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include "file64.h" #include <sys/types.h> diff --git a/usr/src/lib/libc/port/locale/regexec.c b/usr/src/lib/libc/port/locale/regexec.c index f824fa2af4..b6b9b6f56c 100644 --- a/usr/src/lib/libc/port/locale/regexec.c +++ b/usr/src/lib/libc/port/locale/regexec.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1992, 1993, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -32,11 +33,6 @@ */ /* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* * the outer shell of regexec() * * This file includes engine.c three times, after muchos fiddling with the diff --git a/usr/src/lib/libc/port/locale/regfree.c b/usr/src/lib/libc/port/locale/regfree.c index e35784214a..43c7e13958 100644 --- a/usr/src/lib/libc/port/locale/regfree.c +++ b/usr/src/lib/libc/port/locale/regfree.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1992, 1993, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -31,11 +32,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include "file64.h" #include <sys/types.h> diff --git a/usr/src/lib/libc/port/locale/rune.c b/usr/src/lib/libc/port/locale/rune.c index 787a4a663b..545682691e 100644 --- a/usr/src/lib/libc/port/locale/rune.c +++ b/usr/src/lib/libc/port/locale/rune.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * @@ -30,11 +31,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include "file64.h" #include <errno.h> @@ -43,7 +39,6 @@ #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> -#include <netinet/in.h> #include "runetype.h" #include "runefile.h" @@ -105,17 +100,6 @@ _Read_RuneMagi(FILE *fp) 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) { @@ -144,9 +128,6 @@ _Read_RuneMagi(FILE *fp) 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; @@ -157,24 +138,9 @@ _Read_RuneMagi(FILE *fp) errno = EINVAL; 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 = EINVAL; diff --git a/usr/src/lib/libc/port/locale/runetype.c b/usr/src/lib/libc/port/locale/runetype.c index f79c73f4a7..3a978fe038 100644 --- a/usr/src/lib/libc/port/locale/runetype.c +++ b/usr/src/lib/libc/port/locale/runetype.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * @@ -30,11 +31,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <ctype.h> #include <stdio.h> diff --git a/usr/src/lib/libc/port/locale/runetype.h b/usr/src/lib/libc/port/locale/runetype.h index d638a06fcb..9d5648496c 100644 --- a/usr/src/lib/libc/port/locale/runetype.h +++ b/usr/src/lib/libc/port/locale/runetype.h @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * @@ -58,11 +59,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #ifndef _RUNETYPE_H_ #define _RUNETYPE_H_ diff --git a/usr/src/lib/libc/port/locale/setlocale.c b/usr/src/lib/libc/port/locale/setlocale.c index b726084d6d..8cf7f88f98 100644 --- a/usr/src/lib/libc/port/locale/setlocale.c +++ b/usr/src/lib/libc/port/locale/setlocale.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1996 - 2002 FreeBSD Project * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. @@ -31,10 +32,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - */ - #include "lint.h" #include <sys/types.h> #include <sys/stat.h> @@ -59,7 +56,7 @@ * Category names for getenv() Note that this was modified * for Solaris. See <iso/locale_iso.h>. */ -#define NUM_CATS 7 +#define NUM_CATS 7 static char *categories[7] = { "LC_CTYPE", "LC_NUMERIC", @@ -278,7 +275,7 @@ loadlocale(int category) func = __wrap_setrunelocale; break; case LC_COLLATE: - func = __collate_load_tables; + func = _collate_load_tables; break; case LC_TIME: func = __time_load_locale; diff --git a/usr/src/lib/libc/port/locale/setrunelocale.c b/usr/src/lib/libc/port/locale/setrunelocale.c index e08bb38da8..64842514ed 100644 --- a/usr/src/lib/libc/port/locale/setrunelocale.c +++ b/usr/src/lib/libc/port/locale/setrunelocale.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * @@ -30,10 +31,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - */ - #include "lint.h" #include "file64.h" #include <errno.h> diff --git a/usr/src/lib/libc/port/locale/strcoll.c b/usr/src/lib/libc/port/locale/strcoll.c index 1888063512..be20f23e0b 100644 --- a/usr/src/lib/libc/port/locale/strcoll.c +++ b/usr/src/lib/libc/port/locale/strcoll.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> * at Electronni Visti IA, Kiev, Ukraine. * All rights reserved. @@ -25,77 +26,80 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" +#include "file64.h" +#include <alloca.h> #include <stdlib.h> #include <string.h> #include <errno.h> +#include <wchar.h> #include "collate.h" +#define ALLOCA_LIMIT 16 + +/* + * In order to properly handle multibyte locales, its easiet to just + * convert to wide characters and then use wcscoll. However if an + * error occurs, we gracefully fall back to simple strcmp. Caller + * should check errno. + */ int -strcoll(const char *s, const char *s2) +strcoll(const char *s1, const char *s2) { - int len, len2, prim, prim2, sec, sec2, ret, ret2; - const char *t, *t2; - char *tt, *tt2; + int ret; + wchar_t *t1 = NULL, *t2 = NULL; + wchar_t *w1 = NULL, *w2 = NULL; + size_t sz1, sz2; + + if (_collate_load_error) + goto error; - if (__collate_load_error) - return (strcmp(s, s2)); + sz1 = strlen(s1) + 1; + sz2 = strlen(s2) + 1; - len = len2 = 1; - ret = ret2 = 0; - if (__collate_substitute_nontrivial) { - t = tt = __collate_substitute(s); - t2 = tt2 = __collate_substitute(s2); - if ((tt == NULL) || (tt2 == NULL)) { - errno = ENOMEM; - if (tt) - free(tt); - if (tt2) - free(tt2); - /* - * All we can do here is set errno, the application - * is obliged to check it. - */ - return (strcmp(s, s2)); - } + /* + * Simple assumption: conversion to wide format is strictly + * reducing, i.e. a single byte (or multibyte character) + * cannot result in multiple wide characters. + * + * We gain a bit of performance by giving preference to alloca + * for small string allocations. + */ + if (sz1 > ALLOCA_LIMIT) { + if ((t1 = malloc(sz1 * sizeof (wchar_t))) == NULL) + goto error; + w1 = t1; } else { - tt = tt2 = NULL; - t = s; - t2 = s2; + if ((w1 = alloca(sz1 * sizeof (wchar_t))) == NULL) + goto error; } - while (*t && *t2) { - prim = prim2 = 0; - while (*t && !prim) { - __collate_lookup(t, &len, &prim, &sec); - t += len; - } - while (*t2 && !prim2) { - __collate_lookup(t2, &len2, &prim2, &sec2); - t2 += len2; - } - if (!prim || !prim2) - break; - if (prim != prim2) { - ret = prim - prim2; - goto end; - } - if (!ret2) - ret2 = sec - sec2; + if (sz2 > ALLOCA_LIMIT) { + if ((t2 = malloc(sz2 * sizeof (wchar_t))) == NULL) + goto error; + w2 = t2; + } else { + if ((w2 = alloca(sz2 * sizeof (wchar_t))) == NULL) + goto error; } - if (!*t && *t2) - ret = -(int)((uchar_t)*t2); - else if (*t && !*t2) - ret = (uchar_t)*t; - else if (!*t && !*t2) - ret = ret2; -end: - free(tt); - free(tt2); + + if ((mbstowcs(w1, s1, sz1)) == (size_t)-1) + goto error; + + if ((mbstowcs(w2, s2, sz2)) == (size_t)-1) + goto error; + + ret = wcscoll(w1, w2); + if (t1) + free(t1); + if (t2) + free(t2); return (ret); + +error: + if (t1) + free(t1); + if (t2) + free(t2); + return (strcmp(s1, s2)); } diff --git a/usr/src/lib/libc/port/locale/strfmon.c b/usr/src/lib/libc/port/locale/strfmon.c index d49d2ba3a1..18ba631ddc 100644 --- a/usr/src/lib/libc/port/locale/strfmon.c +++ b/usr/src/lib/libc/port/locale/strfmon.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org> * All rights reserved. * @@ -25,11 +26,6 @@ * */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #ifndef _LCONV_C99 #define _LCONV_C99 #endif diff --git a/usr/src/lib/libc/port/locale/strftime.c b/usr/src/lib/libc/port/locale/strftime.c index 9e7e30f17c..328d07f25c 100644 --- a/usr/src/lib/libc/port/locale/strftime.c +++ b/usr/src/lib/libc/port/locale/strftime.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * @@ -15,11 +16,6 @@ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include "tzfile.h" #include <fcntl.h> diff --git a/usr/src/lib/libc/port/locale/strptime.c b/usr/src/lib/libc/port/locale/strptime.c index 5b59acaab1..4e8c5d56d1 100644 --- a/usr/src/lib/libc/port/locale/strptime.c +++ b/usr/src/lib/libc/port/locale/strptime.c @@ -20,6 +20,7 @@ * Powerdog Industries, Inc. */ /* + * Copyright 2010, Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1994 Powerdog Industries. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,11 +51,6 @@ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -/* - * Copyright 2010, Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ #include "lint.h" #include <time.h> #include <ctype.h> diff --git a/usr/src/lib/libc/port/locale/strxfrm.c b/usr/src/lib/libc/port/locale/strxfrm.c index 2166d18dc9..08366cef69 100644 --- a/usr/src/lib/libc/port/locale/strxfrm.c +++ b/usr/src/lib/libc/port/locale/strxfrm.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> * at Electronni Visti IA, Kiev, Ukraine. * All rights reserved. @@ -25,58 +26,62 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <stdlib.h> #include <string.h> #include <errno.h> +#include <wchar.h> +#include <assert.h> #include "collate.h" size_t -strxfrm(char *_RESTRICT_KYWD dest, const char *_RESTRICT_KYWD src, size_t len) +strxfrm(char *_RESTRICT_KYWD xf, const char *_RESTRICT_KYWD src, size_t dlen) { - int prim, sec, l; size_t slen; - char *s, *ss; + size_t xlen; + wchar_t *wcs = NULL; if (!*src) { - if (len > 0) - *dest = '\0'; + if (dlen > 0) + *xf = '\0'; return (0); } - if (__collate_load_error) - return (strlcpy(dest, src, len)); + /* + * The conversion from multibyte to wide character strings is + * strictly reducing (one byte of an mbs cannot expand to more + * than one wide character.) + */ + slen = strlen(src); - slen = 0; - prim = sec = 0; - ss = s = __collate_substitute(src); - if (s == NULL) { - /* Best effort, caller must check errno per spec. */ - errno = ENOMEM; - return (strlcpy(dest, src, len)); - } - while (*s) { - while (*s && !prim) { - __collate_lookup(s, &l, &prim, &sec); - s += l; - } - if (prim) { - if (len > 1) { - *dest++ = (char)prim; - len--; - } - slen++; - prim = 0; - } + if (_collate_load_error) + goto error; + + if ((wcs = malloc((slen + 1) * sizeof (wchar_t))) == NULL) + goto error; + + if (mbstowcs(wcs, src, slen + 1) == (size_t)-1) + goto error; + + if ((xlen = _collate_sxfrm(wcs, xf, dlen)) == (size_t)-1) + goto error; + + if (wcs) + free(wcs); + + if (dlen > xlen) { + xf[xlen] = 0; + } else if (dlen) { + xf[dlen-1] = 0; } - free(ss); - if (len > 0) - *dest = '\0'; + + return (xlen); + +error: + /* errno should be set to ENOMEM if malloc failed */ + if (wcs) + free(wcs); + (void) strlcpy(xf, src, dlen); return (slen); } diff --git a/usr/src/lib/libc/port/locale/table.c b/usr/src/lib/libc/port/locale/table.c index c3b39c9589..c48c51062b 100644 --- a/usr/src/lib/libc/port/locale/table.c +++ b/usr/src/lib/libc/port/locale/table.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * @@ -30,11 +31,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <ctype.h> #include <wchar.h> diff --git a/usr/src/lib/libc/port/locale/timelocal.c b/usr/src/lib/libc/port/locale/timelocal.c index 58dfbe24c7..98af393f48 100644 --- a/usr/src/lib/libc/port/locale/timelocal.c +++ b/usr/src/lib/libc/port/locale/timelocal.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org> * Copyright (c) 1997 FreeBSD Inc. * All rights reserved. @@ -25,11 +26,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <stddef.h> #include "ldpart.h" diff --git a/usr/src/lib/libc/port/locale/timelocal.h b/usr/src/lib/libc/port/locale/timelocal.h index d3629ae3b5..e0c89945a1 100644 --- a/usr/src/lib/libc/port/locale/timelocal.h +++ b/usr/src/lib/libc/port/locale/timelocal.h @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1997-2002 FreeBSD Project. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #ifndef _TIMELOCAL_H_ #define _TIMELOCAL_H_ diff --git a/usr/src/lib/libc/port/locale/tolower.c b/usr/src/lib/libc/port/locale/tolower.c index 1f83c0e900..6e9e10c01e 100644 --- a/usr/src/lib/libc/port/locale/tolower.c +++ b/usr/src/lib/libc/port/locale/tolower.c @@ -1,27 +1,16 @@ /* - * CDDL HEADER START + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms version + * 1.0 of the CDDL. * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END + * A full copy of the text of the CDDL should have accompanied this + * source. A copy is of the CDDL is also available via the Internet + * at http://www.illumos.org/license/CDDL. */ /* * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. */ #include "lint.h" #include <ctype.h> diff --git a/usr/src/lib/libc/port/locale/towlower.c b/usr/src/lib/libc/port/locale/towlower.c index 74d408cfc4..13a20100d9 100644 --- a/usr/src/lib/libc/port/locale/towlower.c +++ b/usr/src/lib/libc/port/locale/towlower.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. @@ -35,11 +36,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <wctype.h> #include <stdio.h> diff --git a/usr/src/lib/libc/port/locale/utf8.c b/usr/src/lib/libc/port/locale/utf8.c index d6d74738c8..c2ac1f99c8 100644 --- a/usr/src/lib/libc/port/locale/utf8.c +++ b/usr/src/lib/libc/port/locale/utf8.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins * All rights reserved. * @@ -23,10 +24,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ #include "lint.h" #include <errno.h> diff --git a/usr/src/lib/libc/port/locale/utils.h b/usr/src/lib/libc/port/locale/utils.h index aec21991ab..3ed1484391 100644 --- a/usr/src/lib/libc/port/locale/utils.h +++ b/usr/src/lib/libc/port/locale/utils.h @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1992, 1993, 1994 Henry Spencer. * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -31,11 +32,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - /* utility definitions */ #define DUPMAX _POSIX2_RE_DUP_MAX /* xxx is this right? */ #define INFINITY (DUPMAX + 1) diff --git a/usr/src/lib/libc/port/locale/wcrtomb.c b/usr/src/lib/libc/port/locale/wcrtomb.c index 2648b25ae1..a3fa0d3d4a 100644 --- a/usr/src/lib/libc/port/locale/wcrtomb.c +++ b/usr/src/lib/libc/port/locale/wcrtomb.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <wchar.h> #include "mblocal.h" diff --git a/usr/src/lib/libc/port/locale/wcscoll.c b/usr/src/lib/libc/port/locale/wcscoll.c index 0837f1c867..ac4218c356 100644 --- a/usr/src/lib/libc/port/locale/wcscoll.c +++ b/usr/src/lib/libc/port/locale/wcscoll.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * @@ -24,78 +25,164 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <errno.h> #include <stdlib.h> #include <string.h> #include <wchar.h> +#include <assert.h> #include "collate.h" -static char *__mbsdup(const wchar_t *); - -/* - * Placeholder implementation of wcscoll(). Attempts to use the single-byte - * collation ordering where possible, and falls back on wcscmp() in locales - * with extended character sets. - */ int wcscoll(const wchar_t *ws1, const wchar_t *ws2) { - char *mbs1, *mbs2; - int diff, sverrno; + int len1, len2, pri1, pri2, ret; + wchar_t *tr1 = NULL, *tr2 = NULL; + int direc, pass; - if (__collate_load_error || MB_CUR_MAX > 1) - /* - * Locale has no special collating order, could not be - * loaded, or has an extended character set; do a fast binary - * comparison. - */ - return (wcscmp(ws1, ws2)); + collate_info_t *info = _collate_info; - if ((mbs1 = __mbsdup(ws1)) == NULL || (mbs2 = __mbsdup(ws2)) == NULL) { + if (_collate_load_error) /* - * Out of memory or illegal wide chars; fall back to wcscmp() - * but leave errno indicating the error. Callers that don't - * check for error will get a reasonable but often slightly - * incorrect result. + * Locale has no special collating order or could not be + * loaded, do a fast binary comparison. */ - sverrno = errno; - free(mbs1); - errno = sverrno; return (wcscmp(ws1, ws2)); - } - diff = strcoll(mbs1, mbs2); - sverrno = errno; - free(mbs1); - free(mbs2); - errno = sverrno; + ret = 0; - return (diff); -} + /* + * Once upon a time we had code to try to optimize this, but + * it turns out that you really can't make many assumptions + * safely. You absolutely have to run this pass by pass, + * because some passes will be ignored for a given character, + * while others will not. Simpler locales will benefit from + * having fewer passes, and most comparisions should resolve + * during the primary pass anyway. + * + * Note that we do one final extra pass at the end to pick + * up UNDEFINED elements. There is special handling for them. + */ + for (pass = 0; pass <= info->directive_count; pass++) { -static char * -__mbsdup(const wchar_t *ws) -{ - static const mbstate_t initial = { 0 }; - mbstate_t st; - const wchar_t *wcp; - size_t len; - char *mbs; + int32_t *st1 = NULL; + int32_t *st2 = NULL; + const wchar_t *w1 = ws1; + const wchar_t *w2 = ws2; + + /* special pass for UNDEFINED */ + if (pass == info->directive_count) { + direc = DIRECTIVE_FORWARD | DIRECTIVE_UNDEFINED; + } else { + direc = info->directive[pass]; + } + + if (direc & DIRECTIVE_BACKWARD) { + wchar_t *bp, *fp, c; + if ((tr1 = wcsdup(w1)) == NULL) + goto fail; + bp = tr1; + fp = tr1 + wcslen(tr1) - 1; + while (bp < fp) { + c = *bp; + *bp++ = *fp; + *fp-- = c; + } + if ((tr2 = wcsdup(w2)) == NULL) + goto fail; + bp = tr2; + fp = tr2 + wcslen(tr2) - 1; + while (bp < fp) { + c = *bp; + *bp++ = *fp; + *fp-- = c; + } + w1 = tr1; + w2 = tr2; + } + + if (direc & DIRECTIVE_POSITION) { + while ((*w1 || st1) && (*w2 || st2)) { + pri1 = pri2 = 0; + _collate_lookup(w1, &len1, &pri1, pass, &st1); + if (pri1 <= 0) { + if (pri1 < 0) { + errno = EINVAL; + goto fail; + } + pri1 = COLLATE_MAX_PRIORITY; + } + _collate_lookup(w2, &len2, &pri2, pass, &st2); + if (pri2 <= 0) { + if (pri2 < 0) { + errno = EINVAL; + goto fail; + } + pri2 = COLLATE_MAX_PRIORITY; + } + if (pri1 != pri2) { + ret = pri1 - pri2; + goto end; + } + w1 += len1; + w2 += len2; + } + } else { + while ((*w1 || st1) && (*w2 || st2)) { + pri1 = pri2 = 0; + while (*w1) { + _collate_lookup(w1, &len1, + &pri1, pass, &st1); + if (pri1 > 0) + break; + if (pri1 < 0) { + errno = EINVAL; + goto fail; + } + w1 += len1; + } + while (*w2) { + _collate_lookup(w2, &len2, + &pri2, pass, &st2); + if (pri2 > 0) + break; + if (pri2 < 0) { + errno = EINVAL; + goto fail; + } + w2 += len2; + } + if (!pri1 || !pri2) + break; + if (pri1 != pri2) { + ret = pri1 - pri2; + goto end; + } + w1 += len1; + w2 += len2; + } + } + if (!*w1) { + if (*w2) { + ret = -(int)*w2; + goto end; + } + } else { + ret = *w1; + goto end; + } + } + ret = 0; + +end: + if (tr1) + free(tr1); + if (tr2) + free(tr2); - wcp = ws; - st = initial; - if ((len = wcsrtombs(NULL, &wcp, 0, &st)) == (size_t)-1) - return (NULL); - if ((mbs = malloc(len + 1)) == NULL) - return (NULL); - st = initial; - (void) wcsrtombs(mbs, &ws, len + 1, &st); + return (ret); - return (mbs); +fail: + ret = wcscmp(ws1, ws2); + goto end; } diff --git a/usr/src/lib/libc/port/locale/wcsftime.c b/usr/src/lib/libc/port/locale/wcsftime.c index 80afc62a7a..da8353a0aa 100644 --- a/usr/src/lib/libc/port/locale/wcsftime.c +++ b/usr/src/lib/libc/port/locale/wcsftime.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002 Tim J. Robbins * All rights reserved. * @@ -23,10 +24,6 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ #include "lint.h" #include "mse_int.h" @@ -127,12 +124,16 @@ wcsftime(wchar_t *wcs, size_t maxsize, const char *format, { int len; wchar_t *wfmt; + size_t rv; /* Convert the format (mb string) to wide char array */ len = strlen(format) + 1; - wfmt = alloca(sizeof (wchar_t) * len); + wfmt = malloc(sizeof (wchar_t) * len); if (mbstowcs(wfmt, format, len) == (size_t)-1) { + free(wfmt); return (0); } - return (__wcsftime_xpg5(wcs, maxsize, wfmt, timeptr)); + rv = __wcsftime_xpg5(wcs, maxsize, wfmt, timeptr); + free(wfmt); + return (rv); } diff --git a/usr/src/lib/libc/port/locale/wcsnrtombs.c b/usr/src/lib/libc/port/locale/wcsnrtombs.c index d053419341..ecf7b641c4 100644 --- a/usr/src/lib/libc/port/locale/wcsnrtombs.c +++ b/usr/src/lib/libc/port/locale/wcsnrtombs.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <limits.h> #include <stdlib.h> diff --git a/usr/src/lib/libc/port/locale/wcsrtombs.c b/usr/src/lib/libc/port/locale/wcsrtombs.c index 60c9132dd9..8250e6302e 100644 --- a/usr/src/lib/libc/port/locale/wcsrtombs.c +++ b/usr/src/lib/libc/port/locale/wcsrtombs.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <limits.h> #include <stdlib.h> diff --git a/usr/src/lib/libc/port/locale/wcstombs.c b/usr/src/lib/libc/port/locale/wcstombs.c index 4155d93cc4..28f31799d2 100644 --- a/usr/src/lib/libc/port/locale/wcstombs.c +++ b/usr/src/lib/libc/port/locale/wcstombs.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * diff --git a/usr/src/lib/libc/port/locale/wcswidth.c b/usr/src/lib/libc/port/locale/wcswidth.c index 1988460a5a..e6d98488d1 100644 --- a/usr/src/lib/libc/port/locale/wcswidth.c +++ b/usr/src/lib/libc/port/locale/wcswidth.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. @@ -35,11 +36,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <wchar.h> diff --git a/usr/src/lib/libc/port/locale/wcsxfrm.c b/usr/src/lib/libc/port/locale/wcsxfrm.c index 5d98aa3441..f095c6c56b 100644 --- a/usr/src/lib/libc/port/locale/wcsxfrm.c +++ b/usr/src/lib/libc/port/locale/wcsxfrm.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> * at Electronni Visti IA, Kiev, Ukraine. * All rights reserved. @@ -25,30 +26,20 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <stdlib.h> #include <string.h> #include <wchar.h> +#include <assert.h> #include "collate.h" -static char *__mbsdup(const wchar_t *); +#define WCS_XFRM_OFFSET 1 -/* - * Placeholder wcsxfrm() implementation. See wcscoll.c for a description of - * the logic used. - */ size_t wcsxfrm(wchar_t *_RESTRICT_KYWD dest, const wchar_t *_RESTRICT_KYWD src, size_t len) { - int prim, sec, l; size_t slen; - char *mbsrc, *s, *ss; if (*src == L'\0') { if (len != 0) @@ -56,62 +47,27 @@ wcsxfrm(wchar_t *_RESTRICT_KYWD dest, return (0); } - if (__collate_load_error || MB_CUR_MAX > 1) { - slen = wcslen(src); - if (len > 0) { - if (slen < len) - (void) wcscpy(dest, src); - else { - (void) wcsncpy(dest, src, len - 1); - dest[len - 1] = L'\0'; - } - } - return (slen); + if ((_collate_load_error) || + ((slen = _collate_wxfrm(src, dest, len)) == (size_t)-1)) { + goto error; } - mbsrc = __mbsdup(src); - slen = 0; - prim = sec = 0; - ss = s = __collate_substitute(mbsrc); - while (*s != '\0') { - while (*s != '\0' && prim == 0) { - __collate_lookup(s, &l, &prim, &sec); - s += l; - } - if (prim != 0) { - if (len > 1) { - *dest++ = (wchar_t)prim; - len--; - } - slen++; - prim = 0; - } + /* Add null termination at the correct location. */ + if (len > slen) { + dest[slen] = 0; + } else if (len) { + dest[len-1] = 0; } - free(ss); - free(mbsrc); - if (len != 0) - *dest = L'\0'; return (slen); -} - -static char * -__mbsdup(const wchar_t *ws) -{ - static const mbstate_t initial = { 0 }; - mbstate_t st; - const wchar_t *wcp; - size_t len; - char *mbs; - wcp = ws; - st = initial; - if ((len = wcsrtombs(NULL, &wcp, 0, &st)) == (size_t)-1) - return (NULL); - if ((mbs = malloc(len + 1)) == NULL) - return (NULL); - st = initial; - (void) wcsrtombs(mbs, &ws, len + 1, &st); - - return (mbs); +error: + slen = wcslen(src); + if (slen < len) + (void) wcscpy(dest, src); + else { + (void) wcsncpy(dest, src, len - 1); + dest[len - 1] = L'\0'; + } + return (slen); } diff --git a/usr/src/lib/libc/port/locale/wctob.c b/usr/src/lib/libc/port/locale/wctob.c index 5f3ec17790..c44c10fbb7 100644 --- a/usr/src/lib/libc/port/locale/wctob.c +++ b/usr/src/lib/libc/port/locale/wctob.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <limits.h> #include <stdio.h> diff --git a/usr/src/lib/libc/port/locale/wctomb.c b/usr/src/lib/libc/port/locale/wctomb.c index 4760b51dde..2c6bd77a61 100644 --- a/usr/src/lib/libc/port/locale/wctomb.c +++ b/usr/src/lib/libc/port/locale/wctomb.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002-2004 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <stdlib.h> #include <wchar.h> diff --git a/usr/src/lib/libc/port/locale/wctrans.c b/usr/src/lib/libc/port/locale/wctrans.c index 276704a9a0..c7f6fb597f 100644 --- a/usr/src/lib/libc/port/locale/wctrans.c +++ b/usr/src/lib/libc/port/locale/wctrans.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <errno.h> #include <string.h> diff --git a/usr/src/lib/libc/port/locale/wctype.c b/usr/src/lib/libc/port/locale/wctype.c index 0147f56a16..62a37ad794 100644 --- a/usr/src/lib/libc/port/locale/wctype.c +++ b/usr/src/lib/libc/port/locale/wctype.c @@ -1,4 +1,5 @@ /* + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2002 Tim J. Robbins. * All rights reserved. * @@ -24,11 +25,6 @@ * SUCH DAMAGE. */ -/* - * Copyright 2010 Nexenta Systems, Inc. All rights reserved. - * Use is subject to license terms. - */ - #include "lint.h" #include <ctype.h> #include <string.h> |
