Coverage Report

Created: 2026-02-26 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/w3m/libwc/hkscs.c
Line
Count
Source
1
2
#include "wc.h"
3
#include "big5.h"
4
#include "hkscs.h"
5
#include "search.h"
6
#include "wtf.h"
7
#ifdef USE_UNICODE
8
#include "ucs.h"
9
#endif
10
11
#define C0 WC_HKSCS_MAP_C0
12
#define GL WC_HKSCS_MAP_GL
13
853k
#define C1 WC_HKSCS_MAP_C1
14
939k
#define LB WC_HKSCS_MAP_LB
15
410k
#define UB WC_HKSCS_MAP_UB
16
939k
#define UH WC_HKSCS_MAP_UH
17
18
wc_uint8 WC_HKSCS_MAP[ 0x100 ] = {
19
    C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0,
20
    C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0, C0,
21
    GL, GL, GL, GL, GL, GL, GL, GL, GL, GL, GL, GL, GL, GL, GL, GL,
22
    GL, GL, GL, GL, GL, GL, GL, GL, GL, GL, GL, GL, GL, GL, GL, GL,
23
    LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB,
24
    LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB,
25
    LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB,
26
    LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, LB, C0,
27
28
    C1, C1, C1, C1, C1, C1, C1, C1, UH, UH, UH, UH, UH, UH, UH, UH,
29
    UH, UH, UH, UH, UH, UH, UH, UH, UH, UH, UH, UH, UH, UH, UH, UH,
30
    UH, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB,
31
    UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB,
32
    UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB,
33
    UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB,
34
    UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB,
35
    UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, UB, C1,
36
};
37
38
wc_wchar_t
39
wc_hkscs_to_cs128w(wc_wchar_t cc)
40
84.0k
{
41
84.0k
    cc.code = WC_HKSCS_N(cc.code);
42
84.0k
    if (cc.code < 0x4000)
43
72.5k
  cc.ccs = WC_CCS_HKSCS_1;
44
11.4k
    else {
45
11.4k
  cc.ccs = WC_CCS_HKSCS_2;
46
11.4k
  cc.code -= 0x4000;
47
11.4k
    }
48
84.0k
    cc.code = WC_N_CS128W(cc.code);
49
84.0k
    return cc;
50
84.0k
}
51
52
wc_wchar_t
53
wc_cs128w_to_hkscs(wc_wchar_t cc)
54
84.0k
{
55
84.0k
    cc.code = WC_CS128W_N(cc.code);
56
84.0k
    if (cc.ccs == WC_CCS_HKSCS_2)
57
11.4k
  cc.code += 0x4000;
58
84.0k
    cc.ccs = WC_CCS_HKSCS;
59
84.0k
    cc.code = WC_N_HKSCS(cc.code);
60
84.0k
    return cc;
61
84.0k
}
62
63
wc_uint32
64
wc_hkscs_to_N(wc_uint32 c)
65
29.9k
{
66
29.9k
    if (c < 0xA140)  /* 0x8840 - 0xA0FE */
67
24.9k
  return WC_HKSCS_N(c);
68
          /* 0xFA40 - 0xFEFE */
69
5.01k
    return WC_HKSCS_N(c) - 0x59 * 0x9D;
70
29.9k
}
71
72
Str
73
wc_conv_from_hkscs(Str is, wc_ces ces)
74
178
{
75
178
    Str os;
76
178
    wc_uchar *sp = (wc_uchar *)is->ptr;
77
178
    wc_uchar *ep = sp + is->length;
78
178
    wc_uchar *p;
79
178
    int state = WC_HKSCS_NOSTATE;
80
178
    wc_uint32 hkscs;
81
82
33.2k
    for (p = sp; p < ep && *p < 0x80; p++) 
83
33.1k
  ;
84
178
    if (p == ep)
85
28
  return is;
86
150
    os = Strnew_size(is->length);
87
150
    if (p > sp)
88
21
  Strcat_charp_n(os, (char *)is->ptr, (int)(p - sp));
89
90
4.53M
    for (; p < ep; p++) {
91
4.53M
  switch (state) {
92
3.59M
  case WC_HKSCS_NOSTATE:
93
3.59M
      switch (WC_HKSCS_MAP[*p]) {
94
410k
      case UB:
95
939k
      case UH:
96
939k
    state = WC_HKSCS_MBYTE1;
97
939k
    break;
98
853k
      case C1:
99
853k
    wtf_push_unknown(os, p, 1);
100
853k
    break;
101
1.79M
      default:
102
1.79M
    Strcat_char(os, (char)*p);
103
1.79M
    break;
104
3.59M
      }
105
3.59M
      break;
106
3.59M
  case WC_HKSCS_MBYTE1:
107
939k
      if (WC_HKSCS_MAP[*p] & LB) {
108
358k
    hkscs = ((wc_uint32)*(p-1) << 8) | *p;
109
358k
    if (*(p-1) >= 0xA1 && *(p-1) <= 0xF9)
110
312k
        wtf_push(os, WC_CCS_BIG5, hkscs);
111
45.8k
    else
112
45.8k
        wtf_push(os, WC_CCS_HKSCS, hkscs);
113
358k
      } else
114
581k
    wtf_push_unknown(os, p-1, 2);
115
939k
      state = WC_HKSCS_NOSTATE;
116
939k
      break;
117
4.53M
  }
118
4.53M
    }
119
150
    switch (state) {
120
23
    case WC_HKSCS_MBYTE1:
121
23
  wtf_push_unknown(os, p-1, 1);
122
23
  break;
123
150
    }
124
150
    return os;
125
150
}
126
127
void
128
wc_push_to_hkscs(Str os, wc_wchar_t cc, wc_status *st)
129
9.51M
{
130
16.3M
  while (1) {
131
16.3M
    switch (cc.ccs) {
132
1.26M
    case WC_CCS_US_ASCII:
133
1.26M
  Strcat_char(os, (char)cc.code);
134
1.26M
  return;
135
3.25M
    case WC_CCS_BIG5_1:
136
4.17M
    case WC_CCS_BIG5_2:
137
4.17M
  cc = wc_cs94w_to_big5(cc);
138
4.26M
    case WC_CCS_BIG5:
139
4.26M
  Strcat_char(os, (char)(cc.code >> 8));
140
4.26M
  Strcat_char(os, (char)(cc.code & 0xff));
141
4.26M
  return;
142
35.4k
    case WC_CCS_HKSCS_1:
143
38.1k
    case WC_CCS_HKSCS_2:
144
38.1k
  cc = wc_cs128w_to_hkscs(cc);
145
45.3k
    case WC_CCS_HKSCS:
146
45.3k
  Strcat_char(os, (char)(cc.code >> 8));
147
45.3k
  Strcat_char(os, (char)(cc.code & 0xff));
148
45.3k
  return;
149
1.04M
    case WC_CCS_UNKNOWN_W:
150
1.04M
  if (!WcOption.no_replace)
151
1.04M
      Strcat_charp(os, WC_REPLACE_W);
152
1.04M
  return;
153
2.89M
    case WC_CCS_UNKNOWN:
154
2.89M
  if (!WcOption.no_replace)
155
2.89M
      Strcat_charp(os, WC_REPLACE);
156
2.89M
  return;
157
6.80M
    default:
158
6.80M
#ifdef USE_UNICODE
159
6.80M
  if (WcOption.ucs_conv)
160
6.80M
      cc = wc_any_to_any_ces(cc, st);
161
0
  else
162
0
#endif
163
0
      cc.ccs = WC_CCS_IS_WIDE(cc.ccs) ? WC_CCS_UNKNOWN_W : WC_CCS_UNKNOWN;
164
6.80M
  continue;
165
16.3M
    }
166
16.3M
  }
167
9.51M
}
168
169
Str
170
wc_char_conv_from_hkscs(wc_uchar c, wc_status *st)
171
0
{
172
0
    static Str os;
173
0
    static wc_uchar hkscsu;
174
0
    wc_uint32 hkscs;
175
176
0
    if (st->state == -1) {
177
0
  st->state = WC_HKSCS_NOSTATE;
178
0
  os = Strnew_size(8);
179
0
    }
180
181
0
    switch (st->state) {
182
0
    case WC_HKSCS_NOSTATE:
183
0
  switch (WC_HKSCS_MAP[c]) {
184
0
  case UB:
185
0
  case UH:
186
0
      hkscsu = c;
187
0
      st->state = WC_HKSCS_MBYTE1;
188
0
      return NULL;
189
0
  case C1:
190
0
      break;
191
0
  default:
192
0
      Strcat_char(os, (char)c);
193
0
      break;
194
0
  }
195
0
  break;
196
0
    case WC_HKSCS_MBYTE1:
197
0
  if (WC_HKSCS_MAP[c] & LB) {
198
0
      hkscs = ((wc_uint32)hkscsu << 8) | c;
199
0
      if (hkscsu >= 0xA1 && hkscsu <= 0xF9 && c >= 0xA1)
200
0
    wtf_push(os, WC_CCS_BIG5, hkscs);
201
0
      else
202
0
    wtf_push(os, WC_CCS_HKSCS, hkscs);
203
0
  }
204
0
  break;
205
0
    }
206
0
    st->state = -1;
207
0
    return os;
208
0
}