1 /* Case and normalization insensitive comparison of Unicode strings. 2 Copyright (C) 2009-2021 Free Software Foundation, Inc. 3 Written by Bruno Haible <bruno@clisp.org>, 2009. 4 5 This file is free software. 6 It is dual-licensed under "the GNU LGPLv3+ or the GNU GPLv2+". 7 You can redistribute it and/or modify it under either 8 - the terms of the GNU Lesser General Public License as published 9 by the Free Software Foundation; either version 3, or (at your 10 option) any later version, or 11 - the terms of the GNU General Public License as published by the 12 Free Software Foundation; either version 2, or (at your option) 13 any later version, or 14 - the same dual license "the GNU LGPLv3+ or the GNU GPLv2+". 15 16 This file is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 Lesser General Public License and the GNU General Public License 20 for more details. 21 22 You should have received a copy of the GNU Lesser General Public 23 License and of the GNU General Public License along with this 24 program. If not, see <https://www.gnu.org/licenses/>. */ 25 26 int 27 FUNC (const SRC_UNIT *s1, size_t n1, const SRC_UNIT *s2, size_t n2, /* */ 28 const char *iso639_language, uninorm_t nf, int *resultp) 29 { 30 UNIT buf1[2048 / sizeof (UNIT)]; 31 UNIT buf2[2048 / sizeof (UNIT)]; 32 UNIT *norms1; 33 size_t norms1_length; 34 UNIT *norms2; 35 size_t norms2_length; 36 int cmp; 37 38 /* Optimization: There is no need to do canonical composition of each string. 39 Decomposition is enough. */ 40 if (nf != NULL) 41 nf = uninorm_decomposing_form (nf); 42 43 /* Case-fold and normalize S1. */ 44 norms1_length = sizeof (buf1) / sizeof (UNIT); 45 norms1 = U_CASEFOLD (s1, n1, iso639_language, nf, buf1, &norms1_length); 46 if (norms1 == NULL) 47 /* errno is set here. */ 48 return -1; 49 50 /* Case-fold and normalize S2. */ 51 norms2_length = sizeof (buf2) / sizeof (UNIT); 52 norms2 = U_CASEFOLD (s2, n2, iso639_language, nf, buf2, &norms2_length); 53 if (norms2 == NULL) 54 { 55 if (norms1 != buf1) 56 { 57 int saved_errno = errno; 58 free (norms1); 59 errno = saved_errno; 60 } 61 return -1; 62 } 63 64 /* Compare the normalized strings. */ 65 cmp = U_CMP2 (norms1, norms1_length, norms2, norms2_length); 66 if (cmp > 0) 67 cmp = 1; 68 else if (cmp < 0) 69 cmp = -1; 70 71 if (norms2 != buf2) 72 free (norms2); 73 if (norms1 != buf1) 74 free (norms1); 75 *resultp = cmp; 76 return 0; 77 }