]> git.lyx.org Git - lyx.git/blob - 3rdparty/libiconv/1.15/lib/iso2022_jp1.h
Implement auto-nesting.
[lyx.git] / 3rdparty / libiconv / 1.15 / lib / iso2022_jp1.h
1 /*
2  * Copyright (C) 1999-2001, 2008, 2016 Free Software Foundation, Inc.
3  * This file is part of the GNU LIBICONV Library.
4  *
5  * The GNU LIBICONV Library is free software; you can redistribute it
6  * and/or modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * The GNU LIBICONV Library is distributed in the hope that it will be
11  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with the GNU LIBICONV Library; see the file COPYING.LIB.
17  * If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 /*
21  * ISO-2022-JP-1
22  */
23
24 /* Specification: RFC 2237 */
25
26 #define ESC 0x1b
27
28 /*
29  * The state can be one of the following values.
30  */
31 #define STATE_ASCII          0
32 #define STATE_JISX0201ROMAN  1
33 #define STATE_JISX0208       2
34 #define STATE_JISX0212       3
35
36 static int
37 iso2022_jp1_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
38 {
39   state_t state = conv->istate;
40   int count = 0;
41   unsigned char c;
42   for (;;) {
43     c = *s;
44     if (c == ESC) {
45       if (n < count+3)
46         goto none;
47       if (s[1] == '(') {
48         if (s[2] == 'B') {
49           state = STATE_ASCII;
50           s += 3; count += 3;
51           if (n < count+1)
52             goto none;
53           continue;
54         }
55         if (s[2] == 'J') {
56           state = STATE_JISX0201ROMAN;
57           s += 3; count += 3;
58           if (n < count+1)
59             goto none;
60           continue;
61         }
62         goto ilseq;
63       }
64       if (s[1] == '$') {
65         if (s[2] == '@' || s[2] == 'B') {
66           /* We don't distinguish JIS X 0208-1978 and JIS X 0208-1983. */
67           state = STATE_JISX0208;
68           s += 3; count += 3;
69           if (n < count+1)
70             goto none;
71           continue;
72         }
73         if (s[2] == '(') {
74           if (n < count+4)
75             goto none;
76           if (s[3] == 'D') {
77             state = STATE_JISX0212;
78             s += 4; count += 4;
79             if (n < count+1)
80               goto none;
81             continue;
82           }
83         }
84         goto ilseq;
85       }
86       goto ilseq;
87     }
88     break;
89   }
90   switch (state) {
91     case STATE_ASCII:
92       if (c < 0x80) {
93         int ret = ascii_mbtowc(conv,pwc,s,1);
94         if (ret == RET_ILSEQ)
95           goto ilseq;
96         if (ret != 1) abort();
97         conv->istate = state;
98         return count+1;
99       } else
100         goto ilseq;
101     case STATE_JISX0201ROMAN:
102       if (c < 0x80) {
103         int ret = jisx0201_mbtowc(conv,pwc,s,1);
104         if (ret == RET_ILSEQ)
105           goto ilseq;
106         if (ret != 1) abort();
107         conv->istate = state;
108         return count+1;
109       } else
110         goto ilseq;
111     case STATE_JISX0208:
112       if (n < count+2)
113         goto none;
114       if (s[0] < 0x80 && s[1] < 0x80) {
115         int ret = jisx0208_mbtowc(conv,pwc,s,2);
116         if (ret == RET_ILSEQ)
117           goto ilseq;
118         if (ret != 2) abort();
119         conv->istate = state;
120         return count+2;
121       } else
122         goto ilseq;
123     case STATE_JISX0212:
124       if (n < count+2)
125         goto none;
126       if (s[0] < 0x80 && s[1] < 0x80) {
127         int ret = jisx0212_mbtowc(conv,pwc,s,2);
128         if (ret == RET_ILSEQ)
129           goto ilseq;
130         if (ret != 2) abort();
131         conv->istate = state;
132         return count+2;
133       } else
134         goto ilseq;
135     default: abort();
136   }
137
138 none:
139   conv->istate = state;
140   return RET_TOOFEW(count);
141
142 ilseq:
143   conv->istate = state;
144   return RET_SHIFT_ILSEQ(count);
145 }
146
147 static int
148 iso2022_jp1_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, size_t n)
149 {
150   state_t state = conv->ostate;
151   unsigned char buf[2];
152   int ret;
153
154   /* Try ASCII. */
155   ret = ascii_wctomb(conv,buf,wc,1);
156   if (ret != RET_ILUNI) {
157     if (ret != 1) abort();
158     if (buf[0] < 0x80) {
159       int count = (state == STATE_ASCII ? 1 : 4);
160       if (n < count)
161         return RET_TOOSMALL;
162       if (state != STATE_ASCII) {
163         r[0] = ESC;
164         r[1] = '(';
165         r[2] = 'B';
166         r += 3;
167         state = STATE_ASCII;
168       }
169       r[0] = buf[0];
170       conv->ostate = state;
171       return count;
172     }
173   }
174
175   /* Try JIS X 0201-1976 Roman. */
176   ret = jisx0201_wctomb(conv,buf,wc,1);
177   if (ret != RET_ILUNI) {
178     if (ret != 1) abort();
179     if (buf[0] < 0x80) {
180       int count = (state == STATE_JISX0201ROMAN ? 1 : 4);
181       if (n < count)
182         return RET_TOOSMALL;
183       if (state != STATE_JISX0201ROMAN) {
184         r[0] = ESC;
185         r[1] = '(';
186         r[2] = 'J';
187         r += 3;
188         state = STATE_JISX0201ROMAN;
189       }
190       r[0] = buf[0];
191       conv->ostate = state;
192       return count;
193     }
194   }
195
196   /* Try JIS X 0208-1990 in place of JIS X 0208-1978 and JIS X 0208-1983. */
197   ret = jisx0208_wctomb(conv,buf,wc,2);
198   if (ret != RET_ILUNI) {
199     if (ret != 2) abort();
200     if (buf[0] < 0x80 && buf[1] < 0x80) {
201       int count = (state == STATE_JISX0208 ? 2 : 5);
202       if (n < count)
203         return RET_TOOSMALL;
204       if (state != STATE_JISX0208) {
205         r[0] = ESC;
206         r[1] = '$';
207         r[2] = 'B';
208         r += 3;
209         state = STATE_JISX0208;
210       }
211       r[0] = buf[0];
212       r[1] = buf[1];
213       conv->ostate = state;
214       return count;
215     }
216   }
217
218   /* Try JIS X 0212-1990. */
219   ret = jisx0212_wctomb(conv,buf,wc,2);
220   if (ret != RET_ILUNI) {
221     if (ret != 2) abort();
222     if (buf[0] < 0x80 && buf[1] < 0x80) {
223       int count = (state == STATE_JISX0212 ? 2 : 6);
224       if (n < count)
225         return RET_TOOSMALL;
226       if (state != STATE_JISX0212) {
227         r[0] = ESC;
228         r[1] = '$';
229         r[2] = '(';
230         r[3] = 'D';
231         r += 4;
232         state = STATE_JISX0212;
233       }
234       r[0] = buf[0];
235       r[1] = buf[1];
236       conv->ostate = state;
237       return count;
238     }
239   }
240
241   return RET_ILUNI;
242 }
243
244 static int
245 iso2022_jp1_reset (conv_t conv, unsigned char *r, size_t n)
246 {
247   state_t state = conv->ostate;
248   if (state != STATE_ASCII) {
249     if (n < 3)
250       return RET_TOOSMALL;
251     r[0] = ESC;
252     r[1] = '(';
253     r[2] = 'B';
254     /* conv->ostate = 0; will be done by the caller */
255     return 3;
256   } else
257     return 0;
258 }
259
260 #undef STATE_JISX0212
261 #undef STATE_JISX0208
262 #undef STATE_JISX0201ROMAN
263 #undef STATE_ASCII