root/maint/gnulib/lib/unicase/u-ct-casefold.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. FUNC

   1 /* Casefolding mapping for Unicode substrings (locale dependent).
   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 UNIT *
  27 FUNC (const UNIT *s, size_t n,
     /* [previous][next][first][last][top][bottom][index][help] */
  28       casing_prefix_context_t prefix_context,
  29       casing_suffix_context_t suffix_context,
  30       const char *iso639_language,
  31       uninorm_t nf,
  32       UNIT *resultbuf, size_t *lengthp)
  33 {
  34   /* Implement the three definitions of caseless matching, as described in
  35      Unicode 5.0, section "Default caseless matching":
  36        - If no normalization is requested, simply apply the casefolding.
  37            X -> toCasefold(X).
  38        - If canonical normalization is requested, apply it, and apply an NFD
  39          before.
  40            X -> NFD(toCasefold(NFD(X))).
  41        - If compatibility normalization is requested, apply it twice, apply
  42          the normalization after each, and apply an NFD before:
  43            X -> NFKD(toCasefold(NFKD(toCasefold(NFD(X))))).  */
  44   if (nf == NULL)
  45     /* X -> toCasefold(X) */
  46     return U_CASEMAP (s, n, prefix_context, suffix_context, iso639_language,
  47                       uc_tocasefold, offsetof (struct special_casing_rule, casefold[0]),
  48                       NULL,
  49                       resultbuf, lengthp);
  50   else
  51     {
  52       uninorm_t nfd = uninorm_decomposing_form (nf);
  53       /* X -> nf(toCasefold(NFD(X))) or
  54          X -> nf(toCasefold(nfd(toCasefold(NFD(X)))))  */
  55       int repeat = (uninorm_is_compat_decomposing (nf) ? 2 : 1);
  56       UNIT tmpbuf1[2048 / sizeof (UNIT)];
  57       UNIT tmpbuf2[2048 / sizeof (UNIT)];
  58       UNIT *tmp1;
  59       size_t tmp1_length;
  60       UNIT *tmp2;
  61       size_t tmp2_length;
  62 
  63       tmp1_length = sizeof (tmpbuf1) / sizeof (UNIT);
  64       tmp1 = U_NORMALIZE (UNINORM_NFD, s, n, tmpbuf1, &tmp1_length);
  65       if (tmp1 == NULL)
  66         /* errno is set here.  */
  67         return NULL;
  68 
  69       do
  70         {
  71           tmp2_length = sizeof (tmpbuf2) / sizeof (UNIT);
  72           tmp2 = U_CASEMAP (tmp1, tmp1_length,
  73                             prefix_context, suffix_context, iso639_language,
  74                             uc_tocasefold, offsetof (struct special_casing_rule, casefold[0]),
  75                             NULL,
  76                             tmpbuf2, &tmp2_length);
  77           if (tmp2 == NULL)
  78             {
  79               int saved_errno = errno;
  80               if (tmp1 != tmpbuf1)
  81                 free (tmp1);
  82               errno = saved_errno;
  83               return NULL;
  84             }
  85 
  86           if (tmp1 != tmpbuf1)
  87             free (tmp1);
  88 
  89           if (repeat > 1)
  90             {
  91               tmp1_length = sizeof (tmpbuf1) / sizeof (UNIT);
  92               tmp1 = U_NORMALIZE (nfd, tmp2, tmp2_length,
  93                                   tmpbuf1, &tmp1_length);
  94             }
  95           else
  96             /* Last run through this loop.  */
  97             tmp1 = U_NORMALIZE (nf, tmp2, tmp2_length,
  98                                 resultbuf, lengthp);
  99           if (tmp1 == NULL)
 100             {
 101               int saved_errno = errno;
 102               if (tmp2 != tmpbuf2)
 103                 free (tmp2);
 104               errno = saved_errno;
 105               return NULL;
 106             }
 107 
 108           if (tmp2 != tmpbuf2)
 109             free (tmp2);
 110         }
 111       while (--repeat > 0);
 112 
 113       return tmp1;
 114     }
 115 }

/* [previous][next][first][last][top][bottom][index][help] */