LCOV - code coverage report
Current view: top level - py - unicode.c (source / functions) Hit Total Coverage
Test: unix_coverage_v1.24.0-73-g2e796d6c3.info Lines: 66 66 100.0 %
Date: 2024-11-30 10:29:47 Functions: 16 16 100.0 %
Branches: 62 68 91.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * This file is part of the MicroPython project, http://micropython.org/
       3                 :            :  *
       4                 :            :  * The MIT License (MIT)
       5                 :            :  *
       6                 :            :  * Copyright (c) 2013, 2014 Damien P. George
       7                 :            :  *
       8                 :            :  * Permission is hereby granted, free of charge, to any person obtaining a copy
       9                 :            :  * of this software and associated documentation files (the "Software"), to deal
      10                 :            :  * in the Software without restriction, including without limitation the rights
      11                 :            :  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      12                 :            :  * copies of the Software, and to permit persons to whom the Software is
      13                 :            :  * furnished to do so, subject to the following conditions:
      14                 :            :  *
      15                 :            :  * The above copyright notice and this permission notice shall be included in
      16                 :            :  * all copies or substantial portions of the Software.
      17                 :            :  *
      18                 :            :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      19                 :            :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      20                 :            :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      21                 :            :  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      22                 :            :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      23                 :            :  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      24                 :            :  * THE SOFTWARE.
      25                 :            :  */
      26                 :            : 
      27                 :            : #include <stdint.h>
      28                 :            : 
      29                 :            : #include "py/unicode.h"
      30                 :            : 
      31                 :            : // attribute flags
      32                 :            : #define FL_PRINT (0x01)
      33                 :            : #define FL_SPACE (0x02)
      34                 :            : #define FL_DIGIT (0x04)
      35                 :            : #define FL_ALPHA (0x08)
      36                 :            : #define FL_UPPER (0x10)
      37                 :            : #define FL_LOWER (0x20)
      38                 :            : #define FL_XDIGIT (0x40)
      39                 :            : 
      40                 :            : // shorthand character attributes
      41                 :            : #define AT_PR (FL_PRINT)
      42                 :            : #define AT_SP (FL_SPACE | FL_PRINT)
      43                 :            : #define AT_DI (FL_DIGIT | FL_PRINT | FL_XDIGIT)
      44                 :            : #define AT_AL (FL_ALPHA | FL_PRINT)
      45                 :            : #define AT_UP (FL_UPPER | FL_ALPHA | FL_PRINT)
      46                 :            : #define AT_LO (FL_LOWER | FL_ALPHA | FL_PRINT)
      47                 :            : #define AT_UX (FL_UPPER | FL_ALPHA | FL_PRINT | FL_XDIGIT)
      48                 :            : #define AT_LX (FL_LOWER | FL_ALPHA | FL_PRINT | FL_XDIGIT)
      49                 :            : 
      50                 :            : // table of attributes for ascii characters
      51                 :            : static const uint8_t attr[] = {
      52                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
      53                 :            :     0, AT_SP, AT_SP, AT_SP, AT_SP, AT_SP, 0, 0,
      54                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
      55                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
      56                 :            :     AT_SP, AT_PR, AT_PR, AT_PR, AT_PR, AT_PR, AT_PR, AT_PR,
      57                 :            :     AT_PR, AT_PR, AT_PR, AT_PR, AT_PR, AT_PR, AT_PR, AT_PR,
      58                 :            :     AT_DI, AT_DI, AT_DI, AT_DI, AT_DI, AT_DI, AT_DI, AT_DI,
      59                 :            :     AT_DI, AT_DI, AT_PR, AT_PR, AT_PR, AT_PR, AT_PR, AT_PR,
      60                 :            :     AT_PR, AT_UX, AT_UX, AT_UX, AT_UX, AT_UX, AT_UX, AT_UP,
      61                 :            :     AT_UP, AT_UP, AT_UP, AT_UP, AT_UP, AT_UP, AT_UP, AT_UP,
      62                 :            :     AT_UP, AT_UP, AT_UP, AT_UP, AT_UP, AT_UP, AT_UP, AT_UP,
      63                 :            :     AT_UP, AT_UP, AT_UP, AT_PR, AT_PR, AT_PR, AT_PR, AT_PR,
      64                 :            :     AT_PR, AT_LX, AT_LX, AT_LX, AT_LX, AT_LX, AT_LX, AT_LO,
      65                 :            :     AT_LO, AT_LO, AT_LO, AT_LO, AT_LO, AT_LO, AT_LO, AT_LO,
      66                 :            :     AT_LO, AT_LO, AT_LO, AT_LO, AT_LO, AT_LO, AT_LO, AT_LO,
      67                 :            :     AT_LO, AT_LO, AT_LO, AT_PR, AT_PR, AT_PR, AT_PR, 0
      68                 :            : };
      69                 :            : 
      70                 :            : #if MICROPY_PY_BUILTINS_STR_UNICODE
      71                 :            : 
      72                 :      42220 : unichar utf8_get_char(const byte *s) {
      73                 :      42220 :     unichar ord = *s++;
      74         [ +  + ]:      42220 :     if (!UTF8_IS_NONASCII(ord)) {
      75                 :            :         return ord;
      76                 :            :     }
      77                 :         36 :     ord &= 0x7F;
      78         [ +  + ]:         94 :     for (unichar mask = 0x40; ord & mask; mask >>= 1) {
      79                 :         58 :         ord &= ~mask;
      80                 :            :     }
      81         [ +  + ]:         94 :     while (UTF8_IS_CONT(*s)) {
      82                 :         58 :         ord = (ord << 6) | (*s++ & 0x3F);
      83                 :            :     }
      84                 :            :     return ord;
      85                 :            : }
      86                 :            : 
      87                 :      23230 : const byte *utf8_next_char(const byte *s) {
      88                 :      23230 :     ++s;
      89         [ +  + ]:      23252 :     while (UTF8_IS_CONT(*s)) {
      90                 :         22 :         ++s;
      91                 :            :     }
      92                 :      23230 :     return s;
      93                 :            : }
      94                 :            : 
      95                 :        498 : mp_uint_t utf8_ptr_to_index(const byte *s, const byte *ptr) {
      96                 :        498 :     mp_uint_t i = 0;
      97         [ +  + ]:       2088 :     while (ptr > s) {
      98         [ +  + ]:       1590 :         if (!UTF8_IS_CONT(*--ptr)) {
      99                 :       1552 :             i++;
     100                 :            :         }
     101                 :            :     }
     102                 :            : 
     103                 :        498 :     return i;
     104                 :            : }
     105                 :            : 
     106                 :      25350 : size_t utf8_charlen(const byte *str, size_t len) {
     107                 :      25350 :     size_t charlen = 0;
     108         [ +  + ]:    2251390 :     for (const byte *top = str + len; str < top; ++str) {
     109         [ +  + ]:    2226040 :         if (!UTF8_IS_CONT(*str)) {
     110                 :    2224978 :             ++charlen;
     111                 :            :         }
     112                 :            :     }
     113                 :      25350 :     return charlen;
     114                 :            : }
     115                 :            : 
     116                 :            : #endif
     117                 :            : 
     118                 :            : // Be aware: These unichar_is* functions are actually ASCII-only!
     119                 :    1107186 : bool unichar_isspace(unichar c) {
     120   [ +  +  +  + ]:    1107186 :     return c < 128 && (attr[c] & FL_SPACE) != 0;
     121                 :            : }
     122                 :            : 
     123                 :    1366861 : bool unichar_isalpha(unichar c) {
     124   [ +  +  +  + ]:    1366861 :     return c < 128 && (attr[c] & FL_ALPHA) != 0;
     125                 :            : }
     126                 :            : 
     127                 :            : /* unused
     128                 :            : bool unichar_isprint(unichar c) {
     129                 :            :     return c < 128 && (attr[c] & FL_PRINT) != 0;
     130                 :            : }
     131                 :            : */
     132                 :            : 
     133                 :     548197 : bool unichar_isdigit(unichar c) {
     134   [ +  +  +  + ]:     548197 :     return c < 128 && (attr[c] & FL_DIGIT) != 0;
     135                 :            : }
     136                 :            : 
     137                 :      13910 : bool unichar_isxdigit(unichar c) {
     138   [ +  -  +  + ]:      13910 :     return c < 128 && (attr[c] & FL_XDIGIT) != 0;
     139                 :            : }
     140                 :            : 
     141                 :         40 : bool unichar_isident(unichar c) {
     142   [ +  -  +  +  :         40 :     return c < 128 && ((attr[c] & (FL_ALPHA | FL_DIGIT)) != 0 || c == '_');
                   +  - ]
     143                 :            : }
     144                 :            : 
     145                 :        106 : bool unichar_isalnum(unichar c) {
     146   [ +  -  +  + ]:        106 :     return c < 128 && ((attr[c] & (FL_ALPHA | FL_DIGIT)) != 0);
     147                 :            : }
     148                 :            : 
     149                 :        178 : bool unichar_isupper(unichar c) {
     150   [ +  -  +  + ]:        178 :     return c < 128 && (attr[c] & FL_UPPER) != 0;
     151                 :            : }
     152                 :            : 
     153                 :        296 : bool unichar_islower(unichar c) {
     154   [ +  -  +  + ]:        296 :     return c < 128 && (attr[c] & FL_LOWER) != 0;
     155                 :            : }
     156                 :            : 
     157                 :         78 : unichar unichar_tolower(unichar c) {
     158         [ +  + ]:         78 :     if (unichar_isupper(c)) {
     159                 :         38 :         return c + 0x20;
     160                 :            :     }
     161                 :            :     return c;
     162                 :            : }
     163                 :            : 
     164                 :        156 : unichar unichar_toupper(unichar c) {
     165         [ +  + ]:        156 :     if (unichar_islower(c)) {
     166                 :         80 :         return c - 0x20;
     167                 :            :     }
     168                 :            :     return c;
     169                 :            : }
     170                 :            : 
     171                 :      13864 : mp_uint_t unichar_xdigit_value(unichar c) {
     172                 :            :     // c is assumed to be hex digit
     173                 :      13864 :     mp_uint_t n = c - '0';
     174         [ +  + ]:      13864 :     if (n > 9) {
     175                 :       4448 :         n &= ~('a' - 'A');
     176                 :       4448 :         n -= ('A' - ('9' + 1));
     177                 :            :     }
     178                 :      13864 :     return n;
     179                 :            : }
     180                 :            : 
     181                 :            : #if MICROPY_PY_BUILTINS_STR_UNICODE
     182                 :            : 
     183                 :      10226 : bool utf8_check(const byte *p, size_t len) {
     184                 :      10226 :     uint8_t need = 0;
     185                 :      10226 :     const byte *end = p + len;
     186         [ +  + ]:     288468 :     for (; p < end; p++) {
     187                 :     278252 :         byte c = *p;
     188         [ +  + ]:     278252 :         if (need) {
     189         [ +  + ]:       1494 :             if (UTF8_IS_CONT(c)) {
     190                 :       1490 :                 need--;
     191                 :            :             } else {
     192                 :            :                 // mismatch
     193                 :            :                 return 0;
     194                 :            :             }
     195                 :            :         } else {
     196         [ +  + ]:     276758 :             if (c >= 0xc0) {
     197         [ +  + ]:       1066 :                 if (c >= 0xf8) {
     198                 :            :                     // mismatch
     199                 :            :                     return 0;
     200                 :            :                 }
     201                 :       1062 :                 need = (0xe5 >> ((c >> 3) & 0x6)) & 3;
     202         [ +  + ]:     275692 :             } else if (c >= 0x80) {
     203                 :            :                 // mismatch
     204                 :            :                 return 0;
     205                 :            :             }
     206                 :            :         }
     207                 :            :     }
     208                 :      10216 :     return need == 0; // no pending fragments allowed
     209                 :            : }
     210                 :            : 
     211                 :            : #endif

Generated by: LCOV version 1.15-5-g462f71d