diff options
Diffstat (limited to 'lib/mbrtowc-impl-utf8.h')
| -rw-r--r-- | lib/mbrtowc-impl-utf8.h | 138 | 
1 files changed, 138 insertions, 0 deletions
diff --git a/lib/mbrtowc-impl-utf8.h b/lib/mbrtowc-impl-utf8.h new file mode 100644 index 00000000..8e5ac14e --- /dev/null +++ b/lib/mbrtowc-impl-utf8.h @@ -0,0 +1,138 @@ +/* Convert multibyte character to wide character. +   Copyright (C) 1999-2002, 2005-2022 Free Software Foundation, Inc. + +   This file is free software: you can redistribute it and/or modify +   it under the terms of the GNU Lesser General Public License as +   published by the Free Software Foundation; either version 2.1 of the +   License, or (at your option) any later version. + +   This file is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +   GNU Lesser General Public License for more details. + +   You should have received a copy of the GNU Lesser General Public License +   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */ + +/* Written by Bruno Haible <bruno@clisp.org>, 2008.  */ + +/* This file contains the part of the body of the mbrtowc and mbrtoc32 functions +   that handles the special case of the UTF-8 encoding.  */ + +        /* Cf. unistr/u8-mbtouc.c.  */ +        unsigned char c = (unsigned char) p[0]; + +        if (c < 0x80) +          { +            if (pwc != NULL) +              *pwc = c; +            res = (c == 0 ? 0 : 1); +            goto success; +          } +        if (c >= 0xc2) +          { +            if (c < 0xe0) +              { +                if (m == 1) +                  goto incomplete; +                else /* m >= 2 */ +                  { +                    unsigned char c2 = (unsigned char) p[1]; + +                    if ((c2 ^ 0x80) < 0x40) +                      { +                        if (pwc != NULL) +                          *pwc = ((unsigned int) (c & 0x1f) << 6) +                                 | (unsigned int) (c2 ^ 0x80); +                        res = 2; +                        goto success; +                      } +                  } +              } +            else if (c < 0xf0) +              { +                if (m == 1) +                  goto incomplete; +                else +                  { +                    unsigned char c2 = (unsigned char) p[1]; + +                    if ((c2 ^ 0x80) < 0x40 +                        && (c >= 0xe1 || c2 >= 0xa0) +                        && (c != 0xed || c2 < 0xa0)) +                      { +                        if (m == 2) +                          goto incomplete; +                        else /* m >= 3 */ +                          { +                            unsigned char c3 = (unsigned char) p[2]; + +                            if ((c3 ^ 0x80) < 0x40) +                              { +                                unsigned int wc = +                                  (((unsigned int) (c & 0x0f) << 12) +                                   | ((unsigned int) (c2 ^ 0x80) << 6) +                                   | (unsigned int) (c3 ^ 0x80)); + +                                if (FITS_IN_CHAR_TYPE (wc)) +                                  { +                                    if (pwc != NULL) +                                      *pwc = wc; +                                    res = 3; +                                    goto success; +                                  } +                              } +                          } +                      } +                  } +              } +            else if (c <= 0xf4) +              { +                if (m == 1) +                  goto incomplete; +                else +                  { +                    unsigned char c2 = (unsigned char) p[1]; + +                    if ((c2 ^ 0x80) < 0x40 +                        && (c >= 0xf1 || c2 >= 0x90) +                        && (c < 0xf4 || (/* c == 0xf4 && */ c2 < 0x90))) +                      { +                        if (m == 2) +                          goto incomplete; +                        else +                          { +                            unsigned char c3 = (unsigned char) p[2]; + +                            if ((c3 ^ 0x80) < 0x40) +                              { +                                if (m == 3) +                                  goto incomplete; +                                else /* m >= 4 */ +                                  { +                                    unsigned char c4 = (unsigned char) p[3]; + +                                    if ((c4 ^ 0x80) < 0x40) +                                      { +                                        unsigned int wc = +                                          (((unsigned int) (c & 0x07) << 18) +                                           | ((unsigned int) (c2 ^ 0x80) << 12) +                                           | ((unsigned int) (c3 ^ 0x80) << 6) +                                           | (unsigned int) (c4 ^ 0x80)); + +                                        if (FITS_IN_CHAR_TYPE (wc)) +                                          { +                                            if (pwc != NULL) +                                              *pwc = wc; +                                            res = 4; +                                            goto success; +                                          } +                                      } +                                  } +                              } +                          } +                      } +                  } +              } +          } +        goto invalid;  | 
