Print this page
3154 Nonconforming tolower and toupper with UTF-8 locales

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/localedef/ctype.c
          +++ new/usr/src/cmd/localedef/ctype.c
↓ open down ↓ 203 lines elided ↑ open up ↑
 204  204  
 205  205  void
 206  206  dump_ctype(void)
 207  207  {
 208  208          FILE            *f;
 209  209          _FileRuneLocale rl;
 210  210          ctype_node_t    *ctn, *last_ct, *last_lo, *last_up;
 211  211          _FileRuneEntry  *ct = NULL;
 212  212          _FileRuneEntry  *lo = NULL;
 213  213          _FileRuneEntry  *up = NULL;
      214 +        wchar_t         wc;
 214  215  
 215  216          (void) memset(&rl, 0, sizeof (rl));
 216  217          last_ct = NULL;
 217  218          last_lo = NULL;
 218  219          last_up = NULL;
 219  220  
 220  221          if ((f = open_category()) == NULL)
 221  222                  return;
 222  223  
 223  224          (void) memcpy(rl.magic, _FILE_RUNE_MAGIC_1, 8);
 224  225          (void) strncpy(rl.encoding, get_wide_encoding(), sizeof (rl.encoding));
 225  226  
 226      -        for (ctn = avl_first(&ctypes); ctn; ctn = AVL_NEXT(&ctypes, ctn)) {
      227 +        /*
      228 +         * Preinit the identity map.
      229 +         */
      230 +        for (wc = 0; (unsigned)wc < _CACHED_RUNES; wc++) {
      231 +                rl.maplower[wc] = wc;
      232 +                rl.mapupper[wc] = wc;
      233 +        }
 227  234  
 228      -                wchar_t wc = ctn->wc;
      235 +        for (ctn = avl_first(&ctypes); ctn; ctn = AVL_NEXT(&ctypes, ctn)) {
 229  236                  int conflict = 0;
 230  237  
      238 +                wc = ctn->wc;
      239 +
 231  240                  /*
 232  241                   * POSIX requires certain portable characters have
 233  242                   * certain types.  Add them if they are missing.
 234  243                   */
 235  244                  if ((wc >= 1) && (wc <= 127)) {
 236  245                          if ((wc >= 'A') && (wc <= 'Z'))
 237  246                                  ctn->ctype |= _ISUPPER;
 238  247                          if ((wc >= 'a') && (wc <= 'z'))
 239  248                                  ctn->ctype |= _ISLOWER;
 240  249                          if ((wc >= '0') && (wc <= '9'))
↓ open down ↓ 57 lines elided ↑ open up ↑
 298  307                          warn("conflicting classes for character 0x%x (%x)",
 299  308                              wc, ctn->ctype);
 300  309                  }
 301  310                  /*
 302  311                   * Handle the lower 256 characters using the simple
 303  312                   * optimization.  Note that if we have not defined the
 304  313                   * upper/lower case, then we identity map it.
 305  314                   */
 306  315                  if ((unsigned)wc < _CACHED_RUNES) {
 307  316                          rl.runetype[wc] = ctn->ctype;
 308      -                        rl.maplower[wc] = ctn->tolower ? ctn->tolower : wc;
 309      -                        rl.mapupper[wc] = ctn->toupper ? ctn->toupper : wc;
      317 +                        if (ctn->tolower)
      318 +                                rl.maplower[wc] = ctn->tolower;
      319 +                        if (ctn->toupper)
      320 +                                rl.mapupper[wc] = ctn->toupper;
 310  321                          continue;
 311  322                  }
 312  323  
 313  324                  if ((last_ct != NULL) && (last_ct->ctype == ctn->ctype)) {
 314  325                          ct[rl.runetype_ext_nranges-1].max = wc;
 315  326                          last_ct = ctn;
 316  327                  } else {
 317  328                          rl.runetype_ext_nranges++;
 318  329                          ct = realloc(ct,
 319  330                              sizeof (*ct) * rl.runetype_ext_nranges);
↓ open down ↓ 47 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX