LCOV - code coverage report
Current view: | top level - Modules/cjkcodecs - _codecs_iso2022.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 1 | 485 | 0.2 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 1 | 40 | 2.5 %
|  |  | Branches: | 0 | 673 | 0.0 %

               Branch data     Line data    Source code
           1                 :            : /*
           2                 :            :  * _codecs_iso2022.c: Codecs collection for ISO-2022 encodings.
           3                 :            :  *
           4                 :            :  * Written by Hye-Shik Chang <perky@FreeBSD.org>
           5                 :            :  */
           6                 :            :
           7                 :            : #define USING_IMPORTED_MAPS
           8                 :            : #define USING_BINARY_PAIR_SEARCH
           9                 :            : #define EXTERN_JISX0213_PAIR
          10                 :            : #define EMULATE_JISX0213_2000_ENCODE_INVALID MAP_UNMAPPABLE
          11                 :            : #define EMULATE_JISX0213_2000_DECODE_INVALID MAP_UNMAPPABLE
          12                 :            :
          13                 :            : #include "cjkcodecs.h"
          14                 :            : #include "alg_jisx0201.h"
          15                 :            : #include "emu_jisx0213_2000.h"
          16                 :            : #include "mappings_jisx0213_pair.h"
          17                 :            :
          18                 :            : /* STATE
          19                 :            :
          20                 :            :    state->c[0-3]
          21                 :            :
          22                 :            :     00000000
          23                 :            :     ||^^^^^|
          24                 :            :     |+-----+----  G0-3 Character Set
          25                 :            :     +-----------  Is G0-3 double byte?
          26                 :            :
          27                 :            :    state->c[4]
          28                 :            :
          29                 :            :     00000000
          30                 :            :           ||
          31                 :            :           |+----  Locked-Shift?
          32                 :            :           +-----  ESC Throughout
          33                 :            : */
          34                 :            :
          35                 :            : #define ESC                     0x1B
          36                 :            : #define SO                      0x0E
          37                 :            : #define SI                      0x0F
          38                 :            : #define LF                      0x0A
          39                 :            :
          40                 :            : #define MAX_ESCSEQLEN           16
          41                 :            :
          42                 :            : #define CHARSET_ISO8859_1       'A'
          43                 :            : #define CHARSET_ASCII           'B'
          44                 :            : #define CHARSET_ISO8859_7       'F'
          45                 :            : #define CHARSET_JISX0201_K      'I'
          46                 :            : #define CHARSET_JISX0201_R      'J'
          47                 :            :
          48                 :            : #define CHARSET_GB2312          ('A'|CHARSET_DBCS)
          49                 :            : #define CHARSET_JISX0208        ('B'|CHARSET_DBCS)
          50                 :            : #define CHARSET_KSX1001         ('C'|CHARSET_DBCS)
          51                 :            : #define CHARSET_JISX0212        ('D'|CHARSET_DBCS)
          52                 :            : #define CHARSET_GB2312_8565     ('E'|CHARSET_DBCS)
          53                 :            : #define CHARSET_CNS11643_1      ('G'|CHARSET_DBCS)
          54                 :            : #define CHARSET_CNS11643_2      ('H'|CHARSET_DBCS)
          55                 :            : #define CHARSET_JISX0213_2000_1 ('O'|CHARSET_DBCS)
          56                 :            : #define CHARSET_JISX0213_2      ('P'|CHARSET_DBCS)
          57                 :            : #define CHARSET_JISX0213_2004_1 ('Q'|CHARSET_DBCS)
          58                 :            : #define CHARSET_JISX0208_O      ('@'|CHARSET_DBCS)
          59                 :            :
          60                 :            : #define CHARSET_DBCS            0x80
          61                 :            : #define ESCMARK(mark)           ((mark) & 0x7f)
          62                 :            :
          63                 :            : #define IS_ESCEND(c)    (((c) >= 'A' && (c) <= 'Z') || (c) == '@')
          64                 :            : #define IS_ISO2022ESC(c2) \
          65                 :            :         ((c2) == '(' || (c2) == ')' || (c2) == '$' || \
          66                 :            :          (c2) == '.' || (c2) == '&')
          67                 :            :     /* this is not a complete list of ISO-2022 escape sequence headers.
          68                 :            :      * but, it's enough to implement CJK instances of iso-2022. */
          69                 :            :
          70                 :            : #define MAP_UNMAPPABLE          0xFFFF
          71                 :            : #define MAP_MULTIPLE_AVAIL      0xFFFE /* for JIS X 0213 */
          72                 :            :
          73                 :            : #define F_SHIFTED               0x01
          74                 :            : #define F_ESCTHROUGHOUT         0x02
          75                 :            :
          76                 :            : #define STATE_SETG(dn, v)       do { ((state)->c[dn]) = (v); } while (0)
          77                 :            : #define STATE_GETG(dn)          ((state)->c[dn])
          78                 :            :
          79                 :            : #define STATE_G0                STATE_GETG(0)
          80                 :            : #define STATE_G1                STATE_GETG(1)
          81                 :            : #define STATE_G2                STATE_GETG(2)
          82                 :            : #define STATE_G3                STATE_GETG(3)
          83                 :            : #define STATE_SETG0(v)          STATE_SETG(0, v)
          84                 :            : #define STATE_SETG1(v)          STATE_SETG(1, v)
          85                 :            : #define STATE_SETG2(v)          STATE_SETG(2, v)
          86                 :            : #define STATE_SETG3(v)          STATE_SETG(3, v)
          87                 :            :
          88                 :            : #define STATE_SETFLAG(f)        do { ((state)->c[4]) |= (f); } while (0)
          89                 :            : #define STATE_GETFLAG(f)        ((state)->c[4] & (f))
          90                 :            : #define STATE_CLEARFLAG(f)      do { ((state)->c[4]) &= ~(f); } while (0)
          91                 :            : #define STATE_CLEARFLAGS()      do { ((state)->c[4]) = 0; } while (0)
          92                 :            :
          93                 :            : #define ISO2022_CONFIG          ((const struct iso2022_config *)config)
          94                 :            : #define CONFIG_ISSET(flag)      (ISO2022_CONFIG->flags & (flag))
          95                 :            : #define CONFIG_DESIGNATIONS     (ISO2022_CONFIG->designations)
          96                 :            :
          97                 :            : /* iso2022_config.flags */
          98                 :            : #define NO_SHIFT                0x01
          99                 :            : #define USE_G2                  0x02
         100                 :            : #define USE_JISX0208_EXT        0x04
         101                 :            :
         102                 :            : /*-*- internal data structures -*-*/
         103                 :            :
         104                 :            : typedef int (*iso2022_init_func)(void);
         105                 :            : typedef Py_UCS4 (*iso2022_decode_func)(const unsigned char *data);
         106                 :            : typedef DBCHAR (*iso2022_encode_func)(const Py_UCS4 *data, Py_ssize_t *length);
         107                 :            :
         108                 :            : struct iso2022_designation {
         109                 :            :     unsigned char mark;
         110                 :            :     unsigned char plane;
         111                 :            :     unsigned char width;
         112                 :            :     iso2022_init_func initializer;
         113                 :            :     iso2022_decode_func decoder;
         114                 :            :     iso2022_encode_func encoder;
         115                 :            : };
         116                 :            :
         117                 :            : struct iso2022_config {
         118                 :            :     int flags;
         119                 :            :     const struct iso2022_designation *designations; /* non-ascii desigs */
         120                 :            : };
         121                 :            :
         122                 :            : /*-*- iso-2022 codec implementation -*-*/
         123                 :            :
         124                 :          0 : CODEC_INIT(iso2022)
         125                 :            : {
         126                 :            :     const struct iso2022_designation *desig;
         127         [ #  # ]:          0 :     for (desig = CONFIG_DESIGNATIONS; desig->mark; desig++)
         128   [ #  #  #  # ]:          0 :         if (desig->initializer != NULL && desig->initializer() != 0)
         129                 :          0 :             return -1;
         130                 :          0 :     return 0;
         131                 :            : }
         132                 :            :
         133                 :          0 : ENCODER_INIT(iso2022)
         134                 :            : {
         135                 :          0 :     STATE_CLEARFLAGS();
         136                 :          0 :     STATE_SETG0(CHARSET_ASCII);
         137                 :          0 :     STATE_SETG1(CHARSET_ASCII);
         138                 :          0 :     return 0;
         139                 :            : }
         140                 :            :
         141                 :          0 : ENCODER_RESET(iso2022)
         142                 :            : {
         143         [ #  # ]:          0 :     if (STATE_GETFLAG(F_SHIFTED)) {
         144         [ #  # ]:          0 :         WRITEBYTE1(SI);
         145                 :          0 :         NEXT_OUT(1);
         146                 :          0 :         STATE_CLEARFLAG(F_SHIFTED);
         147                 :            :     }
         148         [ #  # ]:          0 :     if (STATE_G0 != CHARSET_ASCII) {
         149         [ #  # ]:          0 :         WRITEBYTE3(ESC, '(', 'B');
         150                 :          0 :         NEXT_OUT(3);
         151                 :          0 :         STATE_SETG0(CHARSET_ASCII);
         152                 :            :     }
         153                 :          0 :     return 0;
         154                 :            : }
         155                 :            :
         156                 :          0 : ENCODER(iso2022)
         157                 :            : {
         158         [ #  # ]:          0 :     while (*inpos < inlen) {
         159                 :            :         const struct iso2022_designation *dsg;
         160                 :            :         DBCHAR encoded;
         161                 :          0 :         Py_UCS4 c = INCHAR1;
         162                 :            :         Py_ssize_t insize;
         163                 :            :
         164         [ #  # ]:          0 :         if (c < 0x80) {
         165         [ #  # ]:          0 :             if (STATE_G0 != CHARSET_ASCII) {
         166         [ #  # ]:          0 :                 WRITEBYTE3(ESC, '(', 'B');
         167                 :          0 :                 STATE_SETG0(CHARSET_ASCII);
         168                 :          0 :                 NEXT_OUT(3);
         169                 :            :             }
         170         [ #  # ]:          0 :             if (STATE_GETFLAG(F_SHIFTED)) {
         171         [ #  # ]:          0 :                 WRITEBYTE1(SI);
         172                 :          0 :                 STATE_CLEARFLAG(F_SHIFTED);
         173                 :          0 :                 NEXT_OUT(1);
         174                 :            :             }
         175         [ #  # ]:          0 :             WRITEBYTE1((unsigned char)c);
         176                 :          0 :             NEXT(1, 1);
         177                 :          0 :             continue;
         178                 :            :         }
         179                 :            :
         180                 :          0 :         insize = 1;
         181                 :            :
         182                 :          0 :         encoded = MAP_UNMAPPABLE;
         183         [ #  # ]:          0 :         for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) {
         184                 :          0 :             Py_ssize_t length = 1;
         185                 :          0 :             encoded = dsg->encoder(&c, &length);
         186         [ #  # ]:          0 :             if (encoded == MAP_MULTIPLE_AVAIL) {
         187                 :            :                 /* this implementation won't work for pair
         188                 :            :                  * of non-bmp characters. */
         189         [ #  # ]:          0 :                 if (inlen - *inpos < 2) {
         190         [ #  # ]:          0 :                     if (!(flags & MBENC_FLUSH))
         191                 :          0 :                         return MBERR_TOOFEW;
         192                 :          0 :                     length = -1;
         193                 :            :                 }
         194                 :            :                 else
         195                 :          0 :                     length = 2;
         196                 :          0 :                 encoded = dsg->encoder(&c, &length);
         197         [ #  # ]:          0 :                 if (encoded != MAP_UNMAPPABLE) {
         198                 :          0 :                     insize = length;
         199                 :          0 :                     break;
         200                 :            :                 }
         201                 :            :             }
         202         [ #  # ]:          0 :             else if (encoded != MAP_UNMAPPABLE)
         203                 :          0 :                 break;
         204                 :            :         }
         205                 :            :
         206         [ #  # ]:          0 :         if (!dsg->mark)
         207                 :          0 :             return 1;
         208                 :            :         assert(dsg->width == 1 || dsg->width == 2);
         209                 :            :
         210      [ #  #  # ]:          0 :         switch (dsg->plane) {
         211                 :          0 :         case 0: /* G0 */
         212         [ #  # ]:          0 :             if (STATE_GETFLAG(F_SHIFTED)) {
         213         [ #  # ]:          0 :                 WRITEBYTE1(SI);
         214                 :          0 :                 STATE_CLEARFLAG(F_SHIFTED);
         215                 :          0 :                 NEXT_OUT(1);
         216                 :            :             }
         217         [ #  # ]:          0 :             if (STATE_G0 != dsg->mark) {
         218         [ #  # ]:          0 :                 if (dsg->width == 1) {
         219         [ #  # ]:          0 :                     WRITEBYTE3(ESC, '(', ESCMARK(dsg->mark));
         220                 :          0 :                     STATE_SETG0(dsg->mark);
         221                 :          0 :                     NEXT_OUT(3);
         222                 :            :                 }
         223         [ #  # ]:          0 :                 else if (dsg->mark == CHARSET_JISX0208) {
         224         [ #  # ]:          0 :                     WRITEBYTE3(ESC, '$', ESCMARK(dsg->mark));
         225                 :          0 :                     STATE_SETG0(dsg->mark);
         226                 :          0 :                     NEXT_OUT(3);
         227                 :            :                 }
         228                 :            :                 else {
         229         [ #  # ]:          0 :                     WRITEBYTE4(ESC, '$', '(',
         230                 :            :                         ESCMARK(dsg->mark));
         231                 :          0 :                     STATE_SETG0(dsg->mark);
         232                 :          0 :                     NEXT_OUT(4);
         233                 :            :                 }
         234                 :            :             }
         235                 :          0 :             break;
         236                 :          0 :         case 1: /* G1 */
         237         [ #  # ]:          0 :             if (STATE_G1 != dsg->mark) {
         238         [ #  # ]:          0 :                 if (dsg->width == 1) {
         239         [ #  # ]:          0 :                     WRITEBYTE3(ESC, ')', ESCMARK(dsg->mark));
         240                 :          0 :                     STATE_SETG1(dsg->mark);
         241                 :          0 :                     NEXT_OUT(3);
         242                 :            :                 }
         243                 :            :                 else {
         244         [ #  # ]:          0 :                     WRITEBYTE4(ESC, '$', ')', ESCMARK(dsg->mark));
         245                 :          0 :                     STATE_SETG1(dsg->mark);
         246                 :          0 :                     NEXT_OUT(4);
         247                 :            :                 }
         248                 :            :             }
         249         [ #  # ]:          0 :             if (!STATE_GETFLAG(F_SHIFTED)) {
         250         [ #  # ]:          0 :                 WRITEBYTE1(SO);
         251                 :          0 :                 STATE_SETFLAG(F_SHIFTED);
         252                 :          0 :                 NEXT_OUT(1);
         253                 :            :             }
         254                 :          0 :             break;
         255                 :          0 :         default: /* G2 and G3 is not supported: no encoding in
         256                 :            :                   * CJKCodecs are using them yet */
         257                 :          0 :             return MBERR_INTERNAL;
         258                 :            :         }
         259                 :            :
         260         [ #  # ]:          0 :         if (dsg->width == 1) {
         261         [ #  # ]:          0 :             WRITEBYTE1((unsigned char)encoded);
         262                 :          0 :             NEXT_OUT(1);
         263                 :            :         }
         264                 :            :         else {
         265         [ #  # ]:          0 :             WRITEBYTE2(encoded >> 8, encoded & 0xff);
         266                 :          0 :             NEXT_OUT(2);
         267                 :            :         }
         268                 :          0 :         NEXT_INCHAR(insize);
         269                 :            :     }
         270                 :            :
         271                 :          0 :     return 0;
         272                 :            : }
         273                 :            :
         274                 :          0 : DECODER_INIT(iso2022)
         275                 :            : {
         276                 :          0 :     STATE_CLEARFLAGS();
         277                 :          0 :     STATE_SETG0(CHARSET_ASCII);
         278                 :          0 :     STATE_SETG1(CHARSET_ASCII);
         279                 :          0 :     STATE_SETG2(CHARSET_ASCII);
         280                 :          0 :     return 0;
         281                 :            : }
         282                 :            :
         283                 :          0 : DECODER_RESET(iso2022)
         284                 :            : {
         285                 :          0 :     STATE_SETG0(CHARSET_ASCII);
         286                 :          0 :     STATE_CLEARFLAG(F_SHIFTED);
         287                 :          0 :     return 0;
         288                 :            : }
         289                 :            :
         290                 :            : static Py_ssize_t
         291                 :          0 : iso2022processesc(const void *config, MultibyteCodec_State *state,
         292                 :            :                   const unsigned char **inbuf, Py_ssize_t *inleft)
         293                 :            : {
         294                 :            :     unsigned char charset, designation;
         295                 :          0 :     Py_ssize_t i, esclen = 0;
         296                 :            :
         297         [ #  # ]:          0 :     for (i = 1;i < MAX_ESCSEQLEN;i++) {
         298         [ #  # ]:          0 :         if (i >= *inleft)
         299                 :          0 :             return MBERR_TOOFEW;
         300   [ #  #  #  #  :          0 :         if (IS_ESCEND((*inbuf)[i])) {
                       #  # ]
         301                 :          0 :             esclen = i + 1;
         302                 :          0 :             break;
         303                 :            :         }
         304   [ #  #  #  # ]:          0 :         else if (CONFIG_ISSET(USE_JISX0208_EXT) && i+1 < *inleft &&
         305   [ #  #  #  # ]:          0 :                  (*inbuf)[i] == '&' && (*inbuf)[i+1] == '@') {
         306                 :          0 :             i += 2;
         307                 :            :         }
         308                 :            :     }
         309                 :            :
         310   [ #  #  #  #  :          0 :     switch (esclen) {
                          # ]
         311                 :          0 :     case 0:
         312                 :          0 :         return 1; /* unterminated escape sequence */
         313                 :          0 :     case 3:
         314         [ #  # ]:          0 :         if (INBYTE2 == '$') {
         315                 :          0 :             charset = INBYTE3 | CHARSET_DBCS;
         316                 :          0 :             designation = 0;
         317                 :            :         }
         318                 :            :         else {
         319                 :          0 :             charset = INBYTE3;
         320         [ #  # ]:          0 :             if (INBYTE2 == '(')
         321                 :          0 :                 designation = 0;
         322         [ #  # ]:          0 :             else if (INBYTE2 == ')')
         323                 :          0 :                 designation = 1;
         324   [ #  #  #  # ]:          0 :             else if (CONFIG_ISSET(USE_G2) && INBYTE2 == '.')
         325                 :          0 :                 designation = 2;
         326                 :            :             else
         327                 :          0 :                 return 3;
         328                 :            :         }
         329                 :          0 :         break;
         330                 :          0 :     case 4:
         331         [ #  # ]:          0 :         if (INBYTE2 != '$')
         332                 :          0 :             return 4;
         333                 :            :
         334                 :          0 :         charset = INBYTE4 | CHARSET_DBCS;
         335         [ #  # ]:          0 :         if (INBYTE3 == '(')
         336                 :          0 :             designation = 0;
         337         [ #  # ]:          0 :         else if (INBYTE3 == ')')
         338                 :          0 :             designation = 1;
         339                 :            :         else
         340                 :          0 :             return 4;
         341                 :          0 :         break;
         342                 :          0 :     case 6: /* designation with prefix */
         343         [ #  # ]:          0 :         if (CONFIG_ISSET(USE_JISX0208_EXT) &&
         344   [ #  #  #  # ]:          0 :             (*inbuf)[3] == ESC && (*inbuf)[4] == '$' &&
         345         [ #  # ]:          0 :             (*inbuf)[5] == 'B') {
         346                 :          0 :             charset = 'B' | CHARSET_DBCS;
         347                 :          0 :             designation = 0;
         348                 :            :         }
         349                 :            :         else
         350                 :          0 :             return 6;
         351                 :          0 :         break;
         352                 :          0 :     default:
         353                 :          0 :         return esclen;
         354                 :            :     }
         355                 :            :
         356                 :            :     /* raise error when the charset is not designated for this encoding */
         357         [ #  # ]:          0 :     if (charset != CHARSET_ASCII) {
         358                 :            :         const struct iso2022_designation *dsg;
         359                 :            :
         360         [ #  # ]:          0 :         for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) {
         361         [ #  # ]:          0 :             if (dsg->mark == charset)
         362                 :          0 :                 break;
         363                 :            :         }
         364         [ #  # ]:          0 :         if (!dsg->mark)
         365                 :          0 :             return esclen;
         366                 :            :     }
         367                 :            :
         368                 :          0 :     STATE_SETG(designation, charset);
         369                 :          0 :     *inleft -= esclen;
         370                 :          0 :     (*inbuf) += esclen;
         371                 :          0 :     return 0;
         372                 :            : }
         373                 :            :
         374                 :            : #define ISO8859_7_DECODE(c, writer)                                \
         375                 :            :     if ((c) < 0xa0) {                                              \
         376                 :            :         OUTCHAR(c);                                                \
         377                 :            :     } else if ((c) < 0xc0 && (0x288f3bc9L & (1L << ((c)-0xa0)))) { \
         378                 :            :         OUTCHAR(c);                                                \
         379                 :            :     } else if ((c) >= 0xb4 && (c) <= 0xfe && ((c) >= 0xd4 ||       \
         380                 :            :              (0xbffffd77L & (1L << ((c)-0xb4))))) {                \
         381                 :            :         OUTCHAR(0x02d0 + (c));                                     \
         382                 :            :     } else if ((c) == 0xa1) {                                      \
         383                 :            :         OUTCHAR(0x2018);                                           \
         384                 :            :     } else if ((c) == 0xa2) {                                      \
         385                 :            :         OUTCHAR(0x2019);                                           \
         386                 :            :     } else if ((c) == 0xaf) {                                      \
         387                 :            :         OUTCHAR(0x2015);                                           \
         388                 :            :     }
         389                 :            :
         390                 :            : static Py_ssize_t
         391                 :          0 : iso2022processg2(const void *config, MultibyteCodec_State *state,
         392                 :            :                  const unsigned char **inbuf, Py_ssize_t *inleft,
         393                 :            :                  _PyUnicodeWriter *writer)
         394                 :            : {
         395                 :            :     /* not written to use encoder, decoder functions because only few
         396                 :            :      * encodings use G2 designations in CJKCodecs */
         397         [ #  # ]:          0 :     if (STATE_G2 == CHARSET_ISO8859_1) {
         398         [ #  # ]:          0 :         if (INBYTE3 < 0x80)
         399         [ #  # ]:          0 :             OUTCHAR(INBYTE3 + 0x80);
         400                 :            :         else
         401                 :          0 :             return 3;
         402                 :            :     }
         403         [ #  # ]:          0 :     else if (STATE_G2 == CHARSET_ISO8859_7) {
         404   [ #  #  #  #  :          0 :         ISO8859_7_DECODE(INBYTE3 ^ 0x80, writer)
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
                    #  #  # ]
         405                 :            :         else
         406                 :          0 :             return 3;
         407                 :            :     }
         408         [ #  # ]:          0 :     else if (STATE_G2 == CHARSET_ASCII) {
         409         [ #  # ]:          0 :         if (INBYTE3 & 0x80)
         410                 :          0 :             return 3;
         411                 :            :         else
         412         [ #  # ]:          0 :             OUTCHAR(INBYTE3);
         413                 :            :     }
         414                 :            :     else
         415                 :          0 :         return MBERR_INTERNAL;
         416                 :            :
         417                 :          0 :     (*inbuf) += 3;
         418                 :          0 :     *inleft -= 3;
         419                 :          0 :     return 0;
         420                 :            : }
         421                 :            :
         422                 :          0 : DECODER(iso2022)
         423                 :            : {
         424                 :          0 :     const struct iso2022_designation *dsgcache = NULL;
         425                 :            :
         426         [ #  # ]:          0 :     while (inleft > 0) {
         427                 :          0 :         unsigned char c = INBYTE1;
         428                 :            :         Py_ssize_t err;
         429                 :            :
         430         [ #  # ]:          0 :         if (STATE_GETFLAG(F_ESCTHROUGHOUT)) {
         431                 :            :             /* ESC throughout mode:
         432                 :            :              * for non-iso2022 escape sequences */
         433         [ #  # ]:          0 :             OUTCHAR(c); /* assume as ISO-8859-1 */
         434                 :          0 :             NEXT_IN(1);
         435   [ #  #  #  #  :          0 :             if (IS_ESCEND(c)) {
                       #  # ]
         436                 :          0 :                 STATE_CLEARFLAG(F_ESCTHROUGHOUT);
         437                 :            :             }
         438                 :          0 :             continue;
         439                 :            :         }
         440                 :            :
         441   [ #  #  #  #  :          0 :         switch (c) {
                          # ]
         442                 :          0 :         case ESC:
         443         [ #  # ]:          0 :             REQUIRE_INBUF(2);
         444   [ #  #  #  #  :          0 :             if (IS_ISO2022ESC(INBYTE2)) {
              #  #  #  #  #
                          # ]
         445                 :          0 :                 err = iso2022processesc(config, state,
         446                 :            :                                         inbuf, &inleft);
         447         [ #  # ]:          0 :                 if (err != 0)
         448                 :          0 :                     return err;
         449                 :            :             }
         450   [ #  #  #  # ]:          0 :             else if (CONFIG_ISSET(USE_G2) && INBYTE2 == 'N') {/* SS2 */
         451         [ #  # ]:          0 :                 REQUIRE_INBUF(3);
         452                 :          0 :                 err = iso2022processg2(config, state,
         453                 :            :                                        inbuf, &inleft, writer);
         454         [ #  # ]:          0 :                 if (err != 0)
         455                 :          0 :                     return err;
         456                 :            :             }
         457                 :            :             else {
         458         [ #  # ]:          0 :                 OUTCHAR(ESC);
         459                 :          0 :                 STATE_SETFLAG(F_ESCTHROUGHOUT);
         460                 :          0 :                 NEXT_IN(1);
         461                 :            :             }
         462                 :          0 :             break;
         463                 :          0 :         case SI:
         464         [ #  # ]:          0 :             if (CONFIG_ISSET(NO_SHIFT))
         465                 :          0 :                 goto bypass;
         466                 :          0 :             STATE_CLEARFLAG(F_SHIFTED);
         467                 :          0 :             NEXT_IN(1);
         468                 :          0 :             break;
         469                 :          0 :         case SO:
         470         [ #  # ]:          0 :             if (CONFIG_ISSET(NO_SHIFT))
         471                 :          0 :                 goto bypass;
         472                 :          0 :             STATE_SETFLAG(F_SHIFTED);
         473                 :          0 :             NEXT_IN(1);
         474                 :          0 :             break;
         475                 :          0 :         case LF:
         476                 :          0 :             STATE_CLEARFLAG(F_SHIFTED);
         477         [ #  # ]:          0 :             OUTCHAR(LF);
         478                 :          0 :             NEXT_IN(1);
         479                 :          0 :             break;
         480                 :          0 :         default:
         481         [ #  # ]:          0 :             if (c < 0x20) /* C0 */
         482                 :          0 :                 goto bypass;
         483         [ #  # ]:          0 :             else if (c >= 0x80)
         484                 :          0 :                 return 1;
         485                 :            :             else {
         486                 :            :                 const struct iso2022_designation *dsg;
         487                 :            :                 unsigned char charset;
         488                 :            :                 Py_UCS4 decoded;
         489                 :            :
         490         [ #  # ]:          0 :                 if (STATE_GETFLAG(F_SHIFTED))
         491                 :          0 :                     charset = STATE_G1;
         492                 :            :                 else
         493                 :          0 :                     charset = STATE_G0;
         494                 :            :
         495         [ #  # ]:          0 :                 if (charset == CHARSET_ASCII) {
         496                 :          0 : bypass:
         497         [ #  # ]:          0 :                     OUTCHAR(c);
         498                 :          0 :                     NEXT_IN(1);
         499                 :          0 :                     break;
         500                 :            :                 }
         501                 :            :
         502         [ #  # ]:          0 :                 if (dsgcache != NULL &&
         503         [ #  # ]:          0 :                     dsgcache->mark == charset)
         504                 :          0 :                         dsg = dsgcache;
         505                 :            :                 else {
         506                 :          0 :                     for (dsg = CONFIG_DESIGNATIONS;
         507         [ #  # ]:          0 :                          dsg->mark != charset
         508                 :            : #ifdef Py_DEBUG
         509                 :            :                             && dsg->mark != '\0'
         510                 :            : #endif
         511                 :          0 :                          ; dsg++)
         512                 :            :                     {
         513                 :            :                         /* noop */
         514                 :            :                     }
         515                 :            :                     assert(dsg->mark != '\0');
         516                 :          0 :                     dsgcache = dsg;
         517                 :            :                 }
         518                 :            :
         519         [ #  # ]:          0 :                 REQUIRE_INBUF(dsg->width);
         520                 :          0 :                 decoded = dsg->decoder(*inbuf);
         521         [ #  # ]:          0 :                 if (decoded == MAP_UNMAPPABLE)
         522                 :          0 :                     return dsg->width;
         523                 :            :
         524         [ #  # ]:          0 :                 if (decoded < 0x10000) {
         525         [ #  # ]:          0 :                     OUTCHAR(decoded);
         526                 :            :                 }
         527         [ #  # ]:          0 :                 else if (decoded < 0x30000) {
         528         [ #  # ]:          0 :                     OUTCHAR(decoded);
         529                 :            :                 }
         530                 :            :                 else { /* JIS X 0213 pairs */
         531   [ #  #  #  #  :          0 :                     OUTCHAR2(decoded >> 16, decoded & 0xffff);
                       #  # ]
         532                 :            :                 }
         533                 :          0 :                 NEXT_IN(dsg->width);
         534                 :            :             }
         535                 :          0 :             break;
         536                 :            :         }
         537                 :            :     }
         538                 :          0 :     return 0;
         539                 :            : }
         540                 :            :
         541                 :            : /*-*- mapping table holders -*-*/
         542                 :            :
         543                 :            : #define ENCMAP(enc) static const encode_map *enc##_encmap = NULL;
         544                 :            : #define DECMAP(enc) static const decode_map *enc##_decmap = NULL;
         545                 :            :
         546                 :            : /* kr */
         547                 :            : ENCMAP(cp949)
         548                 :            : DECMAP(ksx1001)
         549                 :            :
         550                 :            : /* jp */
         551                 :            : ENCMAP(jisxcommon)
         552                 :            : DECMAP(jisx0208)
         553                 :            : DECMAP(jisx0212)
         554                 :            : ENCMAP(jisx0213_bmp)
         555                 :            : DECMAP(jisx0213_1_bmp)
         556                 :            : DECMAP(jisx0213_2_bmp)
         557                 :            : ENCMAP(jisx0213_emp)
         558                 :            : DECMAP(jisx0213_1_emp)
         559                 :            : DECMAP(jisx0213_2_emp)
         560                 :            :
         561                 :            : /* cn */
         562                 :            : ENCMAP(gbcommon)
         563                 :            : DECMAP(gb2312)
         564                 :            :
         565                 :            : /* tw */
         566                 :            :
         567                 :            : /*-*- mapping access functions -*-*/
         568                 :            :
         569                 :            : static int
         570                 :          0 : ksx1001_init(void)
         571                 :            : {
         572                 :            :     static int initialized = 0;
         573                 :            :
         574   [ #  #  #  # ]:          0 :     if (!initialized && (
         575         [ #  # ]:          0 :                     IMPORT_MAP(kr, cp949, &cp949_encmap, NULL) ||
         576                 :          0 :                     IMPORT_MAP(kr, ksx1001, NULL, &ksx1001_decmap)))
         577                 :          0 :         return -1;
         578                 :          0 :     initialized = 1;
         579                 :          0 :     return 0;
         580                 :            : }
         581                 :            :
         582                 :            : static Py_UCS4
         583                 :          0 : ksx1001_decoder(const unsigned char *data)
         584                 :            : {
         585                 :            :     Py_UCS4 u;
         586   [ #  #  #  #  :          0 :     if (TRYMAP_DEC(ksx1001, u, data[0], data[1]))
                 #  #  #  # ]
         587                 :          0 :         return u;
         588                 :            :     else
         589                 :          0 :         return MAP_UNMAPPABLE;
         590                 :            : }
         591                 :            :
         592                 :            : static DBCHAR
         593                 :          0 : ksx1001_encoder(const Py_UCS4 *data, Py_ssize_t *length)
         594                 :            : {
         595                 :            :     DBCHAR coded;
         596                 :            :     assert(*length == 1);
         597         [ #  # ]:          0 :     if (*data < 0x10000) {
         598   [ #  #  #  #  :          0 :         if (TRYMAP_ENC(cp949, coded, *data)) {
                 #  #  #  # ]
         599         [ #  # ]:          0 :             if (!(coded & 0x8000))
         600                 :          0 :                 return coded;
         601                 :            :         }
         602                 :            :     }
         603                 :          0 :     return MAP_UNMAPPABLE;
         604                 :            : }
         605                 :            :
         606                 :            : static int
         607                 :          0 : jisx0208_init(void)
         608                 :            : {
         609                 :            :     static int initialized = 0;
         610                 :            :
         611   [ #  #  #  # ]:          0 :     if (!initialized && (
         612         [ #  # ]:          0 :                     IMPORT_MAP(jp, jisxcommon, &jisxcommon_encmap, NULL) ||
         613                 :          0 :                     IMPORT_MAP(jp, jisx0208, NULL, &jisx0208_decmap)))
         614                 :          0 :         return -1;
         615                 :          0 :     initialized = 1;
         616                 :          0 :     return 0;
         617                 :            : }
         618                 :            :
         619                 :            : static Py_UCS4
         620                 :          0 : jisx0208_decoder(const unsigned char *data)
         621                 :            : {
         622                 :            :     Py_UCS4 u;
         623   [ #  #  #  # ]:          0 :     if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */
         624                 :          0 :         return 0xff3c;
         625   [ #  #  #  #  :          0 :     else if (TRYMAP_DEC(jisx0208, u, data[0], data[1]))
                 #  #  #  # ]
         626                 :          0 :         return u;
         627                 :            :     else
         628                 :          0 :         return MAP_UNMAPPABLE;
         629                 :            : }
         630                 :            :
         631                 :            : static DBCHAR
         632                 :          0 : jisx0208_encoder(const Py_UCS4 *data, Py_ssize_t *length)
         633                 :            : {
         634                 :            :     DBCHAR coded;
         635                 :            :     assert(*length == 1);
         636         [ #  # ]:          0 :     if (*data < 0x10000) {
         637         [ #  # ]:          0 :         if (*data == 0xff3c) /* F/W REVERSE SOLIDUS */
         638                 :          0 :             return 0x2140;
         639   [ #  #  #  #  :          0 :         else if (TRYMAP_ENC(jisxcommon, coded, *data)) {
                 #  #  #  # ]
         640         [ #  # ]:          0 :             if (!(coded & 0x8000))
         641                 :          0 :                 return coded;
         642                 :            :         }
         643                 :            :     }
         644                 :          0 :     return MAP_UNMAPPABLE;
         645                 :            : }
         646                 :            :
         647                 :            : static int
         648                 :          0 : jisx0212_init(void)
         649                 :            : {
         650                 :            :     static int initialized = 0;
         651                 :            :
         652   [ #  #  #  # ]:          0 :     if (!initialized && (
         653         [ #  # ]:          0 :                     IMPORT_MAP(jp, jisxcommon, &jisxcommon_encmap, NULL) ||
         654                 :          0 :                     IMPORT_MAP(jp, jisx0212, NULL, &jisx0212_decmap)))
         655                 :          0 :         return -1;
         656                 :          0 :     initialized = 1;
         657                 :          0 :     return 0;
         658                 :            : }
         659                 :            :
         660                 :            : static Py_UCS4
         661                 :          0 : jisx0212_decoder(const unsigned char *data)
         662                 :            : {
         663                 :            :     Py_UCS4 u;
         664   [ #  #  #  #  :          0 :     if (TRYMAP_DEC(jisx0212, u, data[0], data[1]))
                 #  #  #  # ]
         665                 :          0 :         return u;
         666                 :            :     else
         667                 :          0 :         return MAP_UNMAPPABLE;
         668                 :            : }
         669                 :            :
         670                 :            : static DBCHAR
         671                 :          0 : jisx0212_encoder(const Py_UCS4 *data, Py_ssize_t *length)
         672                 :            : {
         673                 :            :     DBCHAR coded;
         674                 :            :     assert(*length == 1);
         675         [ #  # ]:          0 :     if (*data < 0x10000) {
         676   [ #  #  #  #  :          0 :         if (TRYMAP_ENC(jisxcommon, coded, *data)) {
                 #  #  #  # ]
         677         [ #  # ]:          0 :             if (coded & 0x8000)
         678                 :          0 :                 return coded & 0x7fff;
         679                 :            :         }
         680                 :            :     }
         681                 :          0 :     return MAP_UNMAPPABLE;
         682                 :            : }
         683                 :            :
         684                 :            : static int
         685                 :          0 : jisx0213_init(void)
         686                 :            : {
         687                 :            :     static int initialized = 0;
         688                 :            :
         689   [ #  #  #  # ]:          0 :     if (!initialized && (
         690         [ #  # ]:          0 :                     jisx0208_init() ||
         691                 :          0 :                     IMPORT_MAP(jp, jisx0213_bmp,
         692         [ #  # ]:          0 :                                &jisx0213_bmp_encmap, NULL) ||
         693                 :          0 :                     IMPORT_MAP(jp, jisx0213_1_bmp,
         694         [ #  # ]:          0 :                                NULL, &jisx0213_1_bmp_decmap) ||
         695                 :          0 :                     IMPORT_MAP(jp, jisx0213_2_bmp,
         696         [ #  # ]:          0 :                                NULL, &jisx0213_2_bmp_decmap) ||
         697                 :          0 :                     IMPORT_MAP(jp, jisx0213_emp,
         698         [ #  # ]:          0 :                                &jisx0213_emp_encmap, NULL) ||
         699                 :          0 :                     IMPORT_MAP(jp, jisx0213_1_emp,
         700         [ #  # ]:          0 :                                NULL, &jisx0213_1_emp_decmap) ||
         701                 :          0 :                     IMPORT_MAP(jp, jisx0213_2_emp,
         702         [ #  # ]:          0 :                                NULL, &jisx0213_2_emp_decmap) ||
         703                 :          0 :                     IMPORT_MAP(jp, jisx0213_pair, &jisx0213_pair_encmap,
         704                 :            :                                &jisx0213_pair_decmap)))
         705                 :          0 :         return -1;
         706                 :          0 :     initialized = 1;
         707                 :          0 :     return 0;
         708                 :            : }
         709                 :            :
         710                 :            : #define config ((void *)2000)
         711                 :            : static Py_UCS4
         712                 :          0 : jisx0213_2000_1_decoder(const unsigned char *data)
         713                 :            : {
         714                 :            :     Py_UCS4 u;
         715   [ #  #  #  #  :          0 :     EMULATE_JISX0213_2000_DECODE_PLANE1(u, data[0], data[1])
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
                          # ]
         716   [ #  #  #  # ]:          0 :     else if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */
         717                 :          0 :         return 0xff3c;
         718   [ #  #  #  #  :          0 :     else if (TRYMAP_DEC(jisx0208, u, data[0], data[1]))
                 #  #  #  # ]
         719                 :            :         ;
         720   [ #  #  #  #  :          0 :     else if (TRYMAP_DEC(jisx0213_1_bmp, u, data[0], data[1]))
                 #  #  #  # ]
         721                 :            :         ;
         722   [ #  #  #  #  :          0 :     else if (TRYMAP_DEC(jisx0213_1_emp, u, data[0], data[1]))
                 #  #  #  # ]
         723                 :          0 :         u |= 0x20000;
         724   [ #  #  #  #  :          0 :     else if (TRYMAP_DEC(jisx0213_pair, u, data[0], data[1]))
                 #  #  #  # ]
         725                 :            :         ;
         726                 :            :     else
         727                 :          0 :         return MAP_UNMAPPABLE;
         728                 :          0 :     return u;
         729                 :            : }
         730                 :            :
         731                 :            : static Py_UCS4
         732                 :          0 : jisx0213_2000_2_decoder(const unsigned char *data)
         733                 :            : {
         734                 :            :     Py_UCS4 u;
         735   [ #  #  #  # ]:          0 :     EMULATE_JISX0213_2000_DECODE_PLANE2_CHAR(u, data[0], data[1])
         736   [ #  #  #  #  :          0 :     if (TRYMAP_DEC(jisx0213_2_bmp, u, data[0], data[1]))
                 #  #  #  # ]
         737                 :            :         ;
         738   [ #  #  #  #  :          0 :     else if (TRYMAP_DEC(jisx0213_2_emp, u, data[0], data[1]))
                 #  #  #  # ]
         739                 :          0 :         u |= 0x20000;
         740                 :            :     else
         741                 :          0 :         return MAP_UNMAPPABLE;
         742                 :          0 :     return u;
         743                 :            : }
         744                 :            : #undef config
         745                 :            :
         746                 :            : static Py_UCS4
         747                 :          0 : jisx0213_2004_1_decoder(const unsigned char *data)
         748                 :            : {
         749                 :            :     Py_UCS4 u;
         750   [ #  #  #  # ]:          0 :     if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */
         751                 :          0 :         return 0xff3c;
         752   [ #  #  #  #  :          0 :     else if (TRYMAP_DEC(jisx0208, u, data[0], data[1]))
                 #  #  #  # ]
         753                 :            :         ;
         754   [ #  #  #  #  :          0 :     else if (TRYMAP_DEC(jisx0213_1_bmp, u, data[0], data[1]))
                 #  #  #  # ]
         755                 :            :         ;
         756   [ #  #  #  #  :          0 :     else if (TRYMAP_DEC(jisx0213_1_emp, u, data[0], data[1]))
                 #  #  #  # ]
         757                 :          0 :         u |= 0x20000;
         758   [ #  #  #  #  :          0 :     else if (TRYMAP_DEC(jisx0213_pair, u, data[0], data[1]))
                 #  #  #  # ]
         759                 :            :         ;
         760                 :            :     else
         761                 :          0 :         return MAP_UNMAPPABLE;
         762                 :          0 :     return u;
         763                 :            : }
         764                 :            :
         765                 :            : static Py_UCS4
         766                 :          0 : jisx0213_2004_2_decoder(const unsigned char *data)
         767                 :            : {
         768                 :            :     Py_UCS4 u;
         769   [ #  #  #  #  :          0 :     if (TRYMAP_DEC(jisx0213_2_bmp, u, data[0], data[1]))
                 #  #  #  # ]
         770                 :            :         ;
         771   [ #  #  #  #  :          0 :     else if (TRYMAP_DEC(jisx0213_2_emp, u, data[0], data[1]))
                 #  #  #  # ]
         772                 :          0 :         u |= 0x20000;
         773                 :            :     else
         774                 :          0 :         return MAP_UNMAPPABLE;
         775                 :          0 :     return u;
         776                 :            : }
         777                 :            :
         778                 :            : static DBCHAR
         779                 :          0 : jisx0213_encoder(const Py_UCS4 *data, Py_ssize_t *length, void *config)
         780                 :            : {
         781                 :            :     DBCHAR coded;
         782                 :            :
         783   [ #  #  #  # ]:          0 :     switch (*length) {
         784                 :          0 :     case 1: /* first character */
         785         [ #  # ]:          0 :         if (*data >= 0x10000) {
         786         [ #  # ]:          0 :             if ((*data) >> 16 == 0x20000 >> 16) {
         787   [ #  #  #  # ]:          0 :                 EMULATE_JISX0213_2000_ENCODE_EMP(coded, *data)
         788   [ #  #  #  #  :          0 :                 else if (TRYMAP_ENC(jisx0213_emp, coded, (*data) & 0xffff))
                 #  #  #  # ]
         789                 :          0 :                     return coded;
         790                 :            :             }
         791                 :          0 :             return MAP_UNMAPPABLE;
         792                 :            :         }
         793                 :            :
         794   [ #  #  #  #  :          0 :         EMULATE_JISX0213_2000_ENCODE_BMP(coded, *data)
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
              #  #  #  #  #
                       #  # ]
         795   [ #  #  #  #  :          0 :         else if (TRYMAP_ENC(jisx0213_bmp, coded, *data)) {
                 #  #  #  # ]
         796         [ #  # ]:          0 :             if (coded == MULTIC)
         797                 :          0 :                 return MAP_MULTIPLE_AVAIL;
         798                 :            :         }
         799   [ #  #  #  #  :          0 :         else if (TRYMAP_ENC(jisxcommon, coded, *data)) {
                 #  #  #  # ]
         800         [ #  # ]:          0 :             if (coded & 0x8000)
         801                 :          0 :                 return MAP_UNMAPPABLE;
         802                 :            :         }
         803                 :            :         else
         804                 :          0 :             return MAP_UNMAPPABLE;
         805                 :          0 :         return coded;
         806                 :            :
         807                 :          0 :     case 2: /* second character of unicode pair */
         808                 :          0 :         coded = find_pairencmap((ucs2_t)data[0], (ucs2_t)data[1],
         809                 :            :                                 jisx0213_pair_encmap, JISX0213_ENCPAIRS);
         810         [ #  # ]:          0 :         if (coded != DBCINV)
         811                 :          0 :             return coded;
         812                 :            :         /* fall through */
         813                 :            :
         814                 :            :     case -1: /* flush unterminated */
         815                 :          0 :         *length = 1;
         816                 :          0 :         coded = find_pairencmap((ucs2_t)data[0], 0,
         817                 :            :                                 jisx0213_pair_encmap, JISX0213_ENCPAIRS);
         818         [ #  # ]:          0 :         if (coded == DBCINV)
         819                 :          0 :             return MAP_UNMAPPABLE;
         820                 :            :         else
         821                 :          0 :             return coded;
         822                 :            :         break;
         823                 :            :
         824                 :          0 :     default:
         825                 :          0 :         return MAP_UNMAPPABLE;
         826                 :            :     }
         827                 :            : }
         828                 :            :
         829                 :            : static DBCHAR
         830                 :          0 : jisx0213_2000_1_encoder(const Py_UCS4 *data, Py_ssize_t *length)
         831                 :            : {
         832                 :          0 :     DBCHAR coded = jisx0213_encoder(data, length, (void *)2000);
         833   [ #  #  #  # ]:          0 :     if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL)
         834                 :          0 :         return coded;
         835         [ #  # ]:          0 :     else if (coded & 0x8000)
         836                 :          0 :         return MAP_UNMAPPABLE;
         837                 :            :     else
         838                 :          0 :         return coded;
         839                 :            : }
         840                 :            :
         841                 :            : static DBCHAR
         842                 :          0 : jisx0213_2000_1_encoder_paironly(const Py_UCS4 *data, Py_ssize_t *length)
         843                 :            : {
         844                 :            :     DBCHAR coded;
         845                 :          0 :     Py_ssize_t ilength = *length;
         846                 :            :
         847                 :          0 :     coded = jisx0213_encoder(data, length, (void *)2000);
         848      [ #  #  # ]:          0 :     switch (ilength) {
         849                 :          0 :     case 1:
         850         [ #  # ]:          0 :         if (coded == MAP_MULTIPLE_AVAIL)
         851                 :          0 :             return MAP_MULTIPLE_AVAIL;
         852                 :            :         else
         853                 :          0 :             return MAP_UNMAPPABLE;
         854                 :          0 :     case 2:
         855         [ #  # ]:          0 :         if (*length != 2)
         856                 :          0 :             return MAP_UNMAPPABLE;
         857                 :            :         else
         858                 :          0 :             return coded;
         859                 :          0 :     default:
         860                 :          0 :         return MAP_UNMAPPABLE;
         861                 :            :     }
         862                 :            : }
         863                 :            :
         864                 :            : static DBCHAR
         865                 :          0 : jisx0213_2000_2_encoder(const Py_UCS4 *data, Py_ssize_t *length)
         866                 :            : {
         867                 :          0 :     DBCHAR coded = jisx0213_encoder(data, length, (void *)2000);
         868   [ #  #  #  # ]:          0 :     if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL)
         869                 :          0 :         return coded;
         870         [ #  # ]:          0 :     else if (coded & 0x8000)
         871                 :          0 :         return coded & 0x7fff;
         872                 :            :     else
         873                 :          0 :         return MAP_UNMAPPABLE;
         874                 :            : }
         875                 :            :
         876                 :            : static DBCHAR
         877                 :          0 : jisx0213_2004_1_encoder(const Py_UCS4 *data, Py_ssize_t *length)
         878                 :            : {
         879                 :          0 :     DBCHAR coded = jisx0213_encoder(data, length, NULL);
         880   [ #  #  #  # ]:          0 :     if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL)
         881                 :          0 :         return coded;
         882         [ #  # ]:          0 :     else if (coded & 0x8000)
         883                 :          0 :         return MAP_UNMAPPABLE;
         884                 :            :     else
         885                 :          0 :         return coded;
         886                 :            : }
         887                 :            :
         888                 :            : static DBCHAR
         889                 :          0 : jisx0213_2004_1_encoder_paironly(const Py_UCS4 *data, Py_ssize_t *length)
         890                 :            : {
         891                 :            :     DBCHAR coded;
         892                 :          0 :     Py_ssize_t ilength = *length;
         893                 :            :
         894                 :          0 :     coded = jisx0213_encoder(data, length, NULL);
         895      [ #  #  # ]:          0 :     switch (ilength) {
         896                 :          0 :     case 1:
         897         [ #  # ]:          0 :         if (coded == MAP_MULTIPLE_AVAIL)
         898                 :          0 :             return MAP_MULTIPLE_AVAIL;
         899                 :            :         else
         900                 :          0 :             return MAP_UNMAPPABLE;
         901                 :          0 :     case 2:
         902         [ #  # ]:          0 :         if (*length != 2)
         903                 :          0 :             return MAP_UNMAPPABLE;
         904                 :            :         else
         905                 :          0 :             return coded;
         906                 :          0 :     default:
         907                 :          0 :         return MAP_UNMAPPABLE;
         908                 :            :     }
         909                 :            : }
         910                 :            :
         911                 :            : static DBCHAR
         912                 :          0 : jisx0213_2004_2_encoder(const Py_UCS4 *data, Py_ssize_t *length)
         913                 :            : {
         914                 :          0 :     DBCHAR coded = jisx0213_encoder(data, length, NULL);
         915   [ #  #  #  # ]:          0 :     if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL)
         916                 :          0 :         return coded;
         917         [ #  # ]:          0 :     else if (coded & 0x8000)
         918                 :          0 :         return coded & 0x7fff;
         919                 :            :     else
         920                 :          0 :         return MAP_UNMAPPABLE;
         921                 :            : }
         922                 :            :
         923                 :            : static Py_UCS4
         924                 :          0 : jisx0201_r_decoder(const unsigned char *data)
         925                 :            : {
         926                 :            :     Py_UCS4 u;
         927   [ #  #  #  #  :          0 :     JISX0201_R_DECODE_CHAR(*data, u)
              #  #  #  #  #
                          # ]
         928                 :            :     else
         929                 :          0 :         return MAP_UNMAPPABLE;
         930                 :          0 :     return u;
         931                 :            : }
         932                 :            :
         933                 :            : static DBCHAR
         934                 :          0 : jisx0201_r_encoder(const Py_UCS4 *data, Py_ssize_t *length)
         935                 :            : {
         936                 :            :     DBCHAR coded;
         937   [ #  #  #  #  :          0 :     JISX0201_R_ENCODE(*data, coded)
              #  #  #  #  #
                          # ]
         938                 :            :     else
         939                 :          0 :         return MAP_UNMAPPABLE;
         940                 :          0 :     return coded;
         941                 :            : }
         942                 :            :
         943                 :            : static Py_UCS4
         944                 :          0 : jisx0201_k_decoder(const unsigned char *data)
         945                 :            : {
         946                 :            :     Py_UCS4 u;
         947   [ #  #  #  # ]:          0 :     JISX0201_K_DECODE_CHAR(*data ^ 0x80, u)
         948                 :            :     else
         949                 :          0 :         return MAP_UNMAPPABLE;
         950                 :          0 :     return u;
         951                 :            : }
         952                 :            :
         953                 :            : static DBCHAR
         954                 :          0 : jisx0201_k_encoder(const Py_UCS4 *data, Py_ssize_t *length)
         955                 :            : {
         956                 :            :     DBCHAR coded;
         957   [ #  #  #  # ]:          0 :     JISX0201_K_ENCODE(*data, coded)
         958                 :            :     else
         959                 :          0 :         return MAP_UNMAPPABLE;
         960                 :          0 :     return coded - 0x80;
         961                 :            : }
         962                 :            :
         963                 :            : static int
         964                 :          0 : gb2312_init(void)
         965                 :            : {
         966                 :            :     static int initialized = 0;
         967                 :            :
         968   [ #  #  #  # ]:          0 :     if (!initialized && (
         969         [ #  # ]:          0 :                     IMPORT_MAP(cn, gbcommon, &gbcommon_encmap, NULL) ||
         970                 :          0 :                     IMPORT_MAP(cn, gb2312, NULL, &gb2312_decmap)))
         971                 :          0 :         return -1;
         972                 :          0 :     initialized = 1;
         973                 :          0 :     return 0;
         974                 :            : }
         975                 :            :
         976                 :            : static Py_UCS4
         977                 :          0 : gb2312_decoder(const unsigned char *data)
         978                 :            : {
         979                 :            :     Py_UCS4 u;
         980   [ #  #  #  #  :          0 :     if (TRYMAP_DEC(gb2312, u, data[0], data[1]))
                 #  #  #  # ]
         981                 :          0 :         return u;
         982                 :            :     else
         983                 :          0 :         return MAP_UNMAPPABLE;
         984                 :            : }
         985                 :            :
         986                 :            : static DBCHAR
         987                 :          0 : gb2312_encoder(const Py_UCS4 *data, Py_ssize_t *length)
         988                 :            : {
         989                 :            :     DBCHAR coded;
         990                 :            :     assert(*length == 1);
         991         [ #  # ]:          0 :     if (*data < 0x10000) {
         992   [ #  #  #  #  :          0 :         if (TRYMAP_ENC(gbcommon, coded, *data)) {
                 #  #  #  # ]
         993         [ #  # ]:          0 :             if (!(coded & 0x8000))
         994                 :          0 :                 return coded;
         995                 :            :         }
         996                 :            :     }
         997                 :          0 :     return MAP_UNMAPPABLE;
         998                 :            : }
         999                 :            :
        1000                 :            :
        1001                 :            : static Py_UCS4
        1002                 :          0 : dummy_decoder(const unsigned char *data)
        1003                 :            : {
        1004                 :          0 :     return MAP_UNMAPPABLE;
        1005                 :            : }
        1006                 :            :
        1007                 :            : static DBCHAR
        1008                 :          0 : dummy_encoder(const Py_UCS4 *data, Py_ssize_t *length)
        1009                 :            : {
        1010                 :          0 :     return MAP_UNMAPPABLE;
        1011                 :            : }
        1012                 :            :
        1013                 :            : /*-*- registry tables -*-*/
        1014                 :            :
        1015                 :            : #define REGISTRY_KSX1001_G0     { CHARSET_KSX1001, 0, 2,                \
        1016                 :            :                   ksx1001_init,                                         \
        1017                 :            :                   ksx1001_decoder, ksx1001_encoder }
        1018                 :            : #define REGISTRY_KSX1001_G1     { CHARSET_KSX1001, 1, 2,                \
        1019                 :            :                   ksx1001_init,                                         \
        1020                 :            :                   ksx1001_decoder, ksx1001_encoder }
        1021                 :            : #define REGISTRY_JISX0201_R     { CHARSET_JISX0201_R, 0, 1,             \
        1022                 :            :                   NULL,                                                 \
        1023                 :            :                   jisx0201_r_decoder, jisx0201_r_encoder }
        1024                 :            : #define REGISTRY_JISX0201_K     { CHARSET_JISX0201_K, 0, 1,             \
        1025                 :            :                   NULL,                                                 \
        1026                 :            :                   jisx0201_k_decoder, jisx0201_k_encoder }
        1027                 :            : #define REGISTRY_JISX0208       { CHARSET_JISX0208, 0, 2,               \
        1028                 :            :                   jisx0208_init,                                        \
        1029                 :            :                   jisx0208_decoder, jisx0208_encoder }
        1030                 :            : #define REGISTRY_JISX0208_O     { CHARSET_JISX0208_O, 0, 2,             \
        1031                 :            :                   jisx0208_init,                                        \
        1032                 :            :                   jisx0208_decoder, jisx0208_encoder }
        1033                 :            : #define REGISTRY_JISX0212       { CHARSET_JISX0212, 0, 2,               \
        1034                 :            :                   jisx0212_init,                                        \
        1035                 :            :                   jisx0212_decoder, jisx0212_encoder }
        1036                 :            : #define REGISTRY_JISX0213_2000_1 { CHARSET_JISX0213_2000_1, 0, 2,       \
        1037                 :            :                   jisx0213_init,                                        \
        1038                 :            :                   jisx0213_2000_1_decoder,                              \
        1039                 :            :                   jisx0213_2000_1_encoder }
        1040                 :            : #define REGISTRY_JISX0213_2000_1_PAIRONLY { CHARSET_JISX0213_2000_1, 0, 2, \
        1041                 :            :                   jisx0213_init,                                        \
        1042                 :            :                   jisx0213_2000_1_decoder,                              \
        1043                 :            :                   jisx0213_2000_1_encoder_paironly }
        1044                 :            : #define REGISTRY_JISX0213_2000_2 { CHARSET_JISX0213_2, 0, 2,            \
        1045                 :            :                   jisx0213_init,                                        \
        1046                 :            :                   jisx0213_2000_2_decoder,                              \
        1047                 :            :                   jisx0213_2000_2_encoder }
        1048                 :            : #define REGISTRY_JISX0213_2004_1 { CHARSET_JISX0213_2004_1, 0, 2,       \
        1049                 :            :                   jisx0213_init,                                        \
        1050                 :            :                   jisx0213_2004_1_decoder,                              \
        1051                 :            :                   jisx0213_2004_1_encoder }
        1052                 :            : #define REGISTRY_JISX0213_2004_1_PAIRONLY { CHARSET_JISX0213_2004_1, 0, 2, \
        1053                 :            :                   jisx0213_init,                                        \
        1054                 :            :                   jisx0213_2004_1_decoder,                              \
        1055                 :            :                   jisx0213_2004_1_encoder_paironly }
        1056                 :            : #define REGISTRY_JISX0213_2004_2 { CHARSET_JISX0213_2, 0, 2,            \
        1057                 :            :                   jisx0213_init,                                        \
        1058                 :            :                   jisx0213_2004_2_decoder,                              \
        1059                 :            :                   jisx0213_2004_2_encoder }
        1060                 :            : #define REGISTRY_GB2312         { CHARSET_GB2312, 0, 2,                 \
        1061                 :            :                   gb2312_init,                                          \
        1062                 :            :                   gb2312_decoder, gb2312_encoder }
        1063                 :            : #define REGISTRY_CNS11643_1     { CHARSET_CNS11643_1, 1, 2,             \
        1064                 :            :                   cns11643_init,                                        \
        1065                 :            :                   cns11643_1_decoder, cns11643_1_encoder }
        1066                 :            : #define REGISTRY_CNS11643_2     { CHARSET_CNS11643_2, 2, 2,             \
        1067                 :            :                   cns11643_init,                                        \
        1068                 :            :                   cns11643_2_decoder, cns11643_2_encoder }
        1069                 :            : #define REGISTRY_ISO8859_1      { CHARSET_ISO8859_1, 2, 1,              \
        1070                 :            :                   NULL, dummy_decoder, dummy_encoder }
        1071                 :            : #define REGISTRY_ISO8859_7      { CHARSET_ISO8859_7, 2, 1,              \
        1072                 :            :                   NULL, dummy_decoder, dummy_encoder }
        1073                 :            : #define REGISTRY_SENTINEL       { 0, }
        1074                 :            : #define CONFIGDEF(var, attrs)                                           \
        1075                 :            :     static const struct iso2022_config iso2022_##var##_config = {       \
        1076                 :            :         attrs, iso2022_##var##_designations                             \
        1077                 :            :     };
        1078                 :            :
        1079                 :            : static const struct iso2022_designation iso2022_kr_designations[] = {
        1080                 :            :     REGISTRY_KSX1001_G1, REGISTRY_SENTINEL
        1081                 :            : };
        1082                 :            : CONFIGDEF(kr, 0)
        1083                 :            :
        1084                 :            : static const struct iso2022_designation iso2022_jp_designations[] = {
        1085                 :            :     REGISTRY_JISX0208, REGISTRY_JISX0201_R, REGISTRY_JISX0208_O,
        1086                 :            :     REGISTRY_SENTINEL
        1087                 :            : };
        1088                 :            : CONFIGDEF(jp, NO_SHIFT | USE_JISX0208_EXT)
        1089                 :            :
        1090                 :            : static const struct iso2022_designation iso2022_jp_1_designations[] = {
        1091                 :            :     REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_JISX0201_R,
        1092                 :            :     REGISTRY_JISX0208_O, REGISTRY_SENTINEL
        1093                 :            : };
        1094                 :            : CONFIGDEF(jp_1, NO_SHIFT | USE_JISX0208_EXT)
        1095                 :            :
        1096                 :            : static const struct iso2022_designation iso2022_jp_2_designations[] = {
        1097                 :            :     REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_KSX1001_G0,
        1098                 :            :     REGISTRY_GB2312, REGISTRY_JISX0201_R, REGISTRY_JISX0208_O,
        1099                 :            :     REGISTRY_ISO8859_1, REGISTRY_ISO8859_7, REGISTRY_SENTINEL
        1100                 :            : };
        1101                 :            : CONFIGDEF(jp_2, NO_SHIFT | USE_G2 | USE_JISX0208_EXT)
        1102                 :            :
        1103                 :            : static const struct iso2022_designation iso2022_jp_2004_designations[] = {
        1104                 :            :     REGISTRY_JISX0213_2004_1_PAIRONLY, REGISTRY_JISX0208,
        1105                 :            :     REGISTRY_JISX0213_2004_1, REGISTRY_JISX0213_2004_2, REGISTRY_SENTINEL
        1106                 :            : };
        1107                 :            : CONFIGDEF(jp_2004, NO_SHIFT | USE_JISX0208_EXT)
        1108                 :            :
        1109                 :            : static const struct iso2022_designation iso2022_jp_3_designations[] = {
        1110                 :            :     REGISTRY_JISX0213_2000_1_PAIRONLY, REGISTRY_JISX0208,
        1111                 :            :     REGISTRY_JISX0213_2000_1, REGISTRY_JISX0213_2000_2, REGISTRY_SENTINEL
        1112                 :            : };
        1113                 :            : CONFIGDEF(jp_3, NO_SHIFT | USE_JISX0208_EXT)
        1114                 :            :
        1115                 :            : static const struct iso2022_designation iso2022_jp_ext_designations[] = {
        1116                 :            :     REGISTRY_JISX0208, REGISTRY_JISX0212, REGISTRY_JISX0201_R,
        1117                 :            :     REGISTRY_JISX0201_K, REGISTRY_JISX0208_O, REGISTRY_SENTINEL
        1118                 :            : };
        1119                 :            : CONFIGDEF(jp_ext, NO_SHIFT | USE_JISX0208_EXT)
        1120                 :            :
        1121                 :            :
        1122                 :            : BEGIN_MAPPINGS_LIST
        1123                 :            :   /* no mapping table here */
        1124                 :            : END_MAPPINGS_LIST
        1125                 :            :
        1126                 :            : #define ISO2022_CODEC(variation) {              \
        1127                 :            :     "iso2022_" #variation,                      \
        1128                 :            :     &iso2022_##variation##_config,              \
        1129                 :            :     iso2022_codec_init,                         \
        1130                 :            :     _STATEFUL_METHODS(iso2022)                  \
        1131                 :            : },
        1132                 :            :
        1133                 :            : BEGIN_CODECS_LIST
        1134                 :            :   ISO2022_CODEC(kr)
        1135                 :            :   ISO2022_CODEC(jp)
        1136                 :            :   ISO2022_CODEC(jp_1)
        1137                 :            :   ISO2022_CODEC(jp_2)
        1138                 :            :   ISO2022_CODEC(jp_2004)
        1139                 :            :   ISO2022_CODEC(jp_3)
        1140                 :            :   ISO2022_CODEC(jp_ext)
        1141                 :            : END_CODECS_LIST
        1142                 :            :
        1143                 :          1 : I_AM_A_MODULE_FOR(iso2022)

Generated by: LCOV version 1.14