1/* Locale dependent transformation for comparison of Unicode strings. 2 Copyright (C) 2009-2010 Free Software Foundation, Inc. 3 Written by Bruno Haible <bruno@clisp.org>, 2009. 4 5 This program is free software: you can redistribute it and/or modify it 6 under the terms of the GNU Lesser General Public License as published 7 by the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18char * 19FUNC (const UNIT *s, size_t n, uninorm_t nf, 20 char *resultbuf, size_t *lengthp) 21{ 22 UNIT normsbuf[2048 / sizeof (UNIT)]; 23 UNIT *norms; 24 size_t norms_length; 25 char convsbuf[2048]; 26 char *convs; 27 size_t convs_length; 28 char *result; 29 30 /* Normalize the Unicode string. */ 31 norms_length = sizeof (normsbuf) / sizeof (UNIT); 32 norms = U_NORMALIZE (nf, s, n, normsbuf, &norms_length); 33 if (norms == NULL) 34 /* errno is set here. */ 35 return NULL; 36 37 /* Convert it to locale encoding. */ 38 convs_length = sizeof (convsbuf) - 1; 39 convs = U_CONV_TO_ENCODING (locale_charset (), 40 iconveh_error, 41 norms, norms_length, 42 NULL, 43 convsbuf, &convs_length); 44 if (convs == NULL) 45 { 46 if (norms != normsbuf) 47 { 48 int saved_errno = errno; 49 free (norms); 50 errno = saved_errno; 51 } 52 return NULL; 53 } 54 55 if (norms != normsbuf) 56 free (norms); 57 58 /* Ensure one more byte is available. */ 59 if (convs != convsbuf) 60 { 61 char *memory = (char *) realloc (convs, convs_length + 1); 62 if (memory == NULL) 63 { 64 free (convs); 65 errno = ENOMEM; 66 return NULL; 67 } 68 convs = memory; 69 } 70 71 /* Apply locale dependent transformations for comparison. */ 72 result = memxfrm (convs, convs_length, resultbuf, lengthp); 73 if (result == NULL) 74 { 75 if (convs != convsbuf) 76 { 77 int saved_errno = errno; 78 free (convs); 79 errno = saved_errno; 80 } 81 return NULL; 82 } 83 84 if (convs != convsbuf) 85 free (convs); 86 return result; 87} 88