]> git.lyx.org Git - lyx.git/blob - 3rdparty/libiconv/1.15/lib/iso2022_jp.h
Implement auto-nesting.
[lyx.git] / 3rdparty / libiconv / 1.15 / lib / iso2022_jp.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
22  */
23
24 /* Specification: RFC 1468 */
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
35 static int
36 iso2022_jp_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, size_t n)
37 {
38   state_t state = conv->istate;
39   int count = 0;
40   unsigned char c;
41   for (;;) {
42     c = *s;
43     if (c == ESC) {
44       if (n < count+3)
45         goto none;
46       if (s[1] == '(') {
47         if (s[2] == 'B') {
48           state = STATE_ASCII;
49           s += 3; count += 3;
50           if (n < count+1)
51             goto none;
52           continue;
53         }
54         if (s[2] == 'J') {
55           state = STATE_JISX0201ROMAN;
56           s += 3; count += 3;
57           if (n < count+1)
58             goto none;
59           continue;
60         }
61         goto ilseq;
62       }
63       if (s[1] == '$') {
64         if (s[2] == '@' || s[2] == 'B') {
65           /* We don't distinguish JIS X 0208-1978 and JIS X 0208-1983. */
66           state = STATE_JISX0208;
67           s += 3; count += 3;
68           if (n < count+1)
69             goto none;
70           continue;
71         }
72         goto ilseq;
73       }
74       goto ilseq;
75     }
76     break;
77   }
78   switch (state) {
79     case STATE_ASCII:
80       if (c < 0x80) {
81         int ret = ascii_mbtowc(conv,pwc,s,1);
82         if (ret == RET_ILSEQ)
83           goto ilseq;
84         if (ret != 1) abort();
85         conv->istate = state;
86         return count+1;
87       } else
88         goto ilseq;
89     case STATE_JISX0201ROMAN:
90       if (c < 0x80) {
91         int ret = jisx0201_mbtowc(conv,pwc,s,1);
92         if (ret == RET_ILSEQ)
93           goto ilseq;
94         if (ret != 1) abort();
95         conv->istate = state;
96         return count+1;
97       } else
98         goto ilseq;
99     case STATE_JISX0208:
100       if (n < count+2)
101         goto none;
102       if (s[0] < 0x80 && s[1] < 0x80) {
103         int ret = jisx0208_mbtowc(conv,pwc,s,2);
104         if (ret == RET_ILSEQ)
105           goto ilseq;
106         if (ret != 2) abort();
107         conv->istate = state;
108         return count+2;
109       } else
110         goto ilseq;
111     default: abort();
112   }
113
114 none:
115   conv->istate = state;
116   return RET_TOOFEW(count);
117
118 ilseq:
119   conv->istate = state;
120   return RET_SHIFT_ILSEQ(count);
121 }
122
123 static int
124 iso2022_jp_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, size_t n)
125 {
126   state_t state = conv->ostate;
127   unsigned char buf[2];
128   int ret;
129
130   /* Try ASCII. */
131   ret = ascii_wctomb(conv,buf,wc,1);
132   if (ret != RET_ILUNI) {
133     if (ret != 1) abort();
134     if (buf[0] < 0x80) {
135       int count = (state == STATE_ASCII ? 1 : 4);
136       if (n < count)
137         return RET_TOOSMALL;
138       if (state != STATE_ASCII) {
139         r[0] = ESC;
140         r[1] = '(';
141         r[2] = 'B';
142         r += 3;
143         state = STATE_ASCII;
144       }
145       r[0] = buf[0];
146       conv->ostate = state;
147       return count;
148     }
149   }
150
151   /* Try JIS X 0201-1976 Roman. */
152   ret = jisx0201_wctomb(conv,buf,wc,1);
153   if (ret != RET_ILUNI) {
154     if (ret != 1) abort();
155     if (buf[0] < 0x80) {
156       int count = (state == STATE_JISX0201ROMAN ? 1 : 4);
157       if (n < count)
158         return RET_TOOSMALL;
159       if (state != STATE_JISX0201ROMAN) {
160         r[0] = ESC;
161         r[1] = '(';
162         r[2] = 'J';
163         r += 3;
164         state = STATE_JISX0201ROMAN;
165       }
166       r[0] = buf[0];
167       conv->ostate = state;
168       return count;
169     }
170   }
171
172   /* Try JIS X 0208-1990 in place of JIS X 0208-1978 and JIS X 0208-1983. */
173   ret = jisx0208_wctomb(conv,buf,wc,2);
174   if (ret != RET_ILUNI) {
175     if (ret != 2) abort();
176     if (buf[0] < 0x80 && buf[1] < 0x80) {
177       int count = (state == STATE_JISX0208 ? 2 : 5);
178       if (n < count)
179         return RET_TOOSMALL;
180       if (state != STATE_JISX0208) {
181         r[0] = ESC;
182         r[1] = '$';
183         r[2] = 'B';
184         r += 3;
185         state = STATE_JISX0208;
186       }
187       r[0] = buf[0];
188       r[1] = buf[1];
189       conv->ostate = state;
190       return count;
191     }
192   }
193
194   return RET_ILUNI;
195 }
196
197 static int
198 iso2022_jp_reset (conv_t conv, unsigned char *r, size_t n)
199 {
200   state_t state = conv->ostate;
201   if (state != STATE_ASCII) {
202     if (n < 3)
203       return RET_TOOSMALL;
204     r[0] = ESC;
205     r[1] = '(';
206     r[2] = 'B';
207     /* conv->ostate = 0; will be done by the caller */
208     return 3;
209   } else
210     return 0;
211 }
212
213 #undef STATE_JISX0208
214 #undef STATE_JISX0201ROMAN
215 #undef STATE_ASCII