1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22: #include <dlfcn.h>
23: #include <stdint.h>
24: #include <assert.h>
25: #include <stdlib.h>
26:
27: #define NELEMS(arr) (sizeof (arr) / sizeof (arr[0]))
28:
29:
30: #define CHARSET_NAME "CP1258//"
31: #define FROM_LOOP from_cp1258
32: #define TO_LOOP to_cp1258
33: #define DEFINE_INIT 1
34: #define DEFINE_FINI 1
35: #define FROM_LOOP_MIN_NEEDED_FROM 1
36: #define FROM_LOOP_MAX_NEEDED_FROM 1
37: #define FROM_LOOP_MIN_NEEDED_TO 4
38: #define FROM_LOOP_MAX_NEEDED_TO 4
39: #define TO_LOOP_MIN_NEEDED_FROM 4
40: #define TO_LOOP_MAX_NEEDED_FROM 4
41: #define TO_LOOP_MIN_NEEDED_TO 1
42: #define TO_LOOP_MAX_NEEDED_TO 2
43: #define PREPARE_LOOP \
44: int saved_state; \
45: int *statep = &data->__statep->__count;
46: #define EXTRA_LOOP_ARGS , statep
47:
48:
49:
50:
51: #define SAVE_RESET_STATE(Save) \
52: if (Save) \
53: saved_state = *statep; \
54: else \
55: *statep = saved_state
56:
57:
58:
59:
60:
61:
62:
63:
64:
65: #define EMIT_SHIFT_TO_INIT \
66: if (data->__statep->__count != 0) \
67: { \
68: if (FROM_DIRECTION) \
69: { \
70: if (__builtin_expect (outbuf + 4 <= outend, 1)) \
71: { \
72: \
73: *((uint32_t *) outbuf) = data->__statep->__count >> 3; \
74: outbuf += sizeof (uint32_t); \
75: data->__statep->__count = 0; \
76: } \
77: else \
78: \
79: status = __GCONV_FULL_OUTPUT; \
80: } \
81: else \
82: \
83: data->__statep->__count = 0; \
84: }
85:
86:
87:
88:
89: static const uint16_t to_ucs4[128] =
90: {
91:
92: 0x20AC, 0, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
93: 0x02C6, 0x2030, 0, 0x2039, 0x0152, 0, 0, 0,
94:
95: 0, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
96: 0x02DC, 0x2122, 0, 0x203A, 0x0153, 0, 0, 0x0178,
97:
98: 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
99: 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
100:
101: 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
102: 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
103:
104: 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
105: 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
106:
107: 0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
108: 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
109:
110: 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
111: 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
112:
113: 0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
114: 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF,
115: };
116:
117:
118:
119:
120:
121: static const struct
122: {
123: uint16_t base;
124: uint16_t composed;
125: } comp_table_data[] =
126: {
127: #define COMP_TABLE_IDX_0300 0
128: #define COMP_TABLE_LEN_0300 31
129: { 0x0041, 0x00C0 },
130: { 0x0045, 0x00C8 },
131: { 0x0049, 0x00CC },
132: { 0x004E, 0x01F8 },
133: { 0x004F, 0x00D2 },
134: { 0x0055, 0x00D9 },
135: { 0x0057, 0x1E80 },
136: { 0x0059, 0x1EF2 },
137: { 0x0061, 0x00E0 },
138: { 0x0065, 0x00E8 },
139: { 0x0069, 0x00EC },
140: { 0x006E, 0x01F9 },
141: { 0x006F, 0x00F2 },
142: { 0x0075, 0x00F9 },
143: { 0x0077, 0x1E81 },
144: { 0x0079, 0x1EF3 },
145: { 0x00A8, 0x1FED },
146: { 0x00C2, 0x1EA6 },
147: { 0x00CA, 0x1EC0 },
148: { 0x00D4, 0x1ED2 },
149: { 0x00DC, 0x01DB },
150: { 0x00E2, 0x1EA7 },
151: { 0x00EA, 0x1EC1 },
152: { 0x00F4, 0x1ED3 },
153: { 0x00FC, 0x01DC },
154: { 0x0102, 0x1EB0 },
155: { 0x0103, 0x1EB1 },
156:
157:
158:
159:
160: { 0x01A0, 0x1EDC },
161: { 0x01A1, 0x1EDD },
162: { 0x01AF, 0x1EEA },
163: { 0x01B0, 0x1EEB },
164: #define COMP_TABLE_IDX_0301 (COMP_TABLE_IDX_0300 + COMP_TABLE_LEN_0300)
165: #define COMP_TABLE_LEN_0301 60
166: { 0x0041, 0x00C1 },
167: { 0x0043, 0x0106 },
168: { 0x0045, 0x00C9 },
169: { 0x0047, 0x01F4 },
170: { 0x0049, 0x00CD },
171: { 0x004B, 0x1E30 },
172: { 0x004C, 0x0139 },
173: { 0x004D, 0x1E3E },
174: { 0x004E, 0x0143 },
175: { 0x004F, 0x00D3 },
176: { 0x0050, 0x1E54 },
177: { 0x0052, 0x0154 },
178: { 0x0053, 0x015A },
179: { 0x0055, 0x00DA },
180: { 0x0057, 0x1E82 },
181: { 0x0059, 0x00DD },
182: { 0x005A, 0x0179 },
183: { 0x0061, 0x00E1 },
184: { 0x0063, 0x0107 },
185: { 0x0065, 0x00E9 },
186: { 0x0067, 0x01F5 },
187: { 0x0069, 0x00ED },
188: { 0x006B, 0x1E31 },
189: { 0x006C, 0x013A },
190: { 0x006D, 0x1E3F },
191: { 0x006E, 0x0144 },
192: { 0x006F, 0x00F3 },
193: { 0x0070, 0x1E55 },
194: { 0x0072, 0x0155 },
195: { 0x0073, 0x015B },
196: { 0x0075, 0x00FA },
197: { 0x0077, 0x1E83 },
198: { 0x0079, 0x00FD },
199: { 0x007A, 0x017A },
200: { 0x00A5, 0x0385 },
201: { 0x00A8, 0x1FEE },
202: { 0x00C2, 0x1EA4 },
203: { 0x00C5, 0x01FA },
204: { 0x00C6, 0x01FC },
205: { 0x00C7, 0x1E08 },
206: { 0x00CA, 0x1EBE },
207: { 0x00CF, 0x1E2E },
208: { 0x00D4, 0x1ED0 },
209:
210: { 0x00D8, 0x01FE },
211: { 0x00DC, 0x01D7 },
212: { 0x00E2, 0x1EA5 },
213: { 0x00E5, 0x01FB },
214: { 0x00E6, 0x01FD },
215: { 0x00E7, 0x1E09 },
216: { 0x00EA, 0x1EBF },
217: { 0x00EF, 0x1E2F },
218: { 0x00F4, 0x1ED1 },
219:
220: { 0x00F8, 0x01FF },
221: { 0x00FC, 0x01D8 },
222: { 0x0102, 0x1EAE },
223: { 0x0103, 0x1EAF },
224:
225:
226:
227:
228:
229:
230: { 0x01A0, 0x1EDA },
231: { 0x01A1, 0x1EDB },
232: { 0x01AF, 0x1EE8 },
233: { 0x01B0, 0x1EE9 },
234: #define COMP_TABLE_IDX_0303 (COMP_TABLE_IDX_0301 + COMP_TABLE_LEN_0301)
235: #define COMP_TABLE_LEN_0303 34
236: { 0x0041, 0x00C3 },
237: { 0x0045, 0x1EBC },
238: { 0x0049, 0x0128 },
239: { 0x004E, 0x00D1 },
240: { 0x004F, 0x00D5 },
241: { 0x0055, 0x0168 },
242: { 0x0056, 0x1E7C },
243: { 0x0059, 0x1EF8 },
244: { 0x0061, 0x00E3 },
245: { 0x0065, 0x1EBD },
246: { 0x0069, 0x0129 },
247: { 0x006E, 0x00F1 },
248: { 0x006F, 0x00F5 },
249: { 0x0075, 0x0169 },
250: { 0x0076, 0x1E7D },
251: { 0x0079, 0x1EF9 },
252: { 0x00C2, 0x1EAA },
253: { 0x00CA, 0x1EC4 },
254: { 0x00D3, 0x1E4C },
255: { 0x00D4, 0x1ED6 },
256: { 0x00D6, 0x1E4E },
257: { 0x00DA, 0x1E78 },
258: { 0x00E2, 0x1EAB },
259: { 0x00EA, 0x1EC5 },
260: { 0x00F3, 0x1E4D },
261: { 0x00F4, 0x1ED7 },
262: { 0x00F6, 0x1E4F },
263: { 0x00FA, 0x1E79 },
264: { 0x0102, 0x1EB4 },
265: { 0x0103, 0x1EB5 },
266: { 0x01A0, 0x1EE0 },
267: { 0x01A1, 0x1EE1 },
268: { 0x01AF, 0x1EEE },
269: { 0x01B0, 0x1EEF },
270: #define COMP_TABLE_IDX_0309 (COMP_TABLE_IDX_0303 + COMP_TABLE_LEN_0303)
271: #define COMP_TABLE_LEN_0309 24
272: { 0x0041, 0x1EA2 },
273: { 0x0045, 0x1EBA },
274: { 0x0049, 0x1EC8 },
275: { 0x004F, 0x1ECE },
276: { 0x0055, 0x1EE6 },
277: { 0x0059, 0x1EF6 },
278: { 0x0061, 0x1EA3 },
279: { 0x0065, 0x1EBB },
280: { 0x0069, 0x1EC9 },
281: { 0x006F, 0x1ECF },
282: { 0x0075, 0x1EE7 },
283: { 0x0079, 0x1EF7 },
284: { 0x00C2, 0x1EA8 },
285: { 0x00CA, 0x1EC2 },
286: { 0x00D4, 0x1ED4 },
287: { 0x00E2, 0x1EA9 },
288: { 0x00EA, 0x1EC3 },
289: { 0x00F4, 0x1ED5 },
290: { 0x0102, 0x1EB2 },
291: { 0x0103, 0x1EB3 },
292: { 0x01A0, 0x1EDE },
293: { 0x01A1, 0x1EDF },
294: { 0x01AF, 0x1EEC },
295: { 0x01B0, 0x1EED },
296: #define COMP_TABLE_IDX_0323 (COMP_TABLE_IDX_0309 + COMP_TABLE_LEN_0309)
297: #define COMP_TABLE_LEN_0323 50
298: { 0x0041, 0x1EA0 },
299: { 0x0042, 0x1E04 },
300: { 0x0044, 0x1E0C },
301: { 0x0045, 0x1EB8 },
302: { 0x0048, 0x1E24 },
303: { 0x0049, 0x1ECA },
304: { 0x004B, 0x1E32 },
305: { 0x004C, 0x1E36 },
306: { 0x004D, 0x1E42 },
307: { 0x004E, 0x1E46 },
308: { 0x004F, 0x1ECC },
309: { 0x0052, 0x1E5A },
310: { 0x0053, 0x1E62 },
311: { 0x0054, 0x1E6C },
312: { 0x0055, 0x1EE4 },
313: { 0x0056, 0x1E7E },
314: { 0x0057, 0x1E88 },
315: { 0x0059, 0x1EF4 },
316: { 0x005A, 0x1E92 },
317: { 0x0061, 0x1EA1 },
318: { 0x0062, 0x1E05 },
319: { 0x0064, 0x1E0D },
320: { 0x0065, 0x1EB9 },
321: { 0x0068, 0x1E25 },
322: { 0x0069, 0x1ECB },
323: { 0x006B, 0x1E33 },
324: { 0x006C, 0x1E37 },
325: { 0x006D, 0x1E43 },
326: { 0x006E, 0x1E47 },
327: { 0x006F, 0x1ECD },
328: { 0x0072, 0x1E5B },
329: { 0x0073, 0x1E63 },
330: { 0x0074, 0x1E6D },
331: { 0x0075, 0x1EE5 },
332: { 0x0076, 0x1E7F },
333: { 0x0077, 0x1E89 },
334: { 0x0079, 0x1EF5 },
335: { 0x007A, 0x1E93 },
336: { 0x00C2, 0x1EAC },
337: { 0x00CA, 0x1EC6 },
338: { 0x00D4, 0x1ED8 },
339: { 0x00E2, 0x1EAD },
340: { 0x00EA, 0x1EC7 },
341: { 0x00F4, 0x1ED9 },
342: { 0x0102, 0x1EB6 },
343: { 0x0103, 0x1EB7 },
344: { 0x01A0, 0x1EE2 },
345: { 0x01A1, 0x1EE3 },
346: { 0x01AF, 0x1EF0 },
347: { 0x01B0, 0x1EF1 },
348: #define COMP_TABLE_IDX_END (COMP_TABLE_IDX_0323 + COMP_TABLE_LEN_0323)
349: };
350:
351: typedef int verify1[(NELEMS (comp_table_data) == COMP_TABLE_IDX_END) - 1];
352:
353: static const struct
354: {
355: unsigned int idx;
356: unsigned int len;
357: } comp_table[5] =
358: {
359: { COMP_TABLE_IDX_0300, COMP_TABLE_LEN_0300 },
360: { COMP_TABLE_IDX_0301, COMP_TABLE_LEN_0301 },
361: { COMP_TABLE_IDX_0303, COMP_TABLE_LEN_0303 },
362: { COMP_TABLE_IDX_0309, COMP_TABLE_LEN_0309 },
363: { COMP_TABLE_IDX_0323, COMP_TABLE_LEN_0323 }
364: };
365:
366: #define MIN_NEEDED_INPUT FROM_LOOP_MIN_NEEDED_FROM
367: #define MAX_NEEDED_INPUT FROM_LOOP_MAX_NEEDED_FROM
368: #define MIN_NEEDED_OUTPUT FROM_LOOP_MIN_NEEDED_TO
369: #define MAX_NEEDED_OUTPUT FROM_LOOP_MAX_NEEDED_TO
370: #define LOOPFCT FROM_LOOP
371: #define BODY \
372: { \
373: uint32_t ch = *inptr; \
374: uint32_t last_ch; \
375: int must_buffer_ch; \
376: \
377: if (ch >= 0x80) \
378: { \
379: ch = to_ucs4[ch - 0x80]; \
380: if (__builtin_expect (ch == L'\0', 0)) \
381: { \
382: \
383: STANDARD_FROM_LOOP_ERR_HANDLER (1); \
384: } \
385: } \
386: \
387: \
388: last_ch = *statep >> 3; \
389: \
390: \
391: must_buffer_ch = (ch >= 0x0041 && ch <= 0x01b0); \
392: \
393: if (last_ch) \
394: { \
395: if (ch >= 0x0300 && ch < 0x0340) \
396: { \
397: \
398: unsigned int i, i1, i2; \
399: \
400: switch (ch) \
401: { \
402: case 0x0300: \
403: i = 0; \
404: break; \
405: case 0x0301: \
406: i = 1; \
407: break; \
408: case 0x0303: \
409: i = 2; \
410: break; \
411: case 0x0309: \
412: i = 3; \
413: break; \
414: case 0x0323: \
415: i = 4; \
416: break; \
417: default: \
418: abort (); \
419: } \
420: \
421: i1 = comp_table[i].idx; \
422: i2 = i1 + comp_table[i].len - 1; \
423: \
424: if (last_ch >= comp_table_data[i1].base \
425: && last_ch <= comp_table_data[i2].base) \
426: { \
427: for (;;) \
428: { \
429: i = (i1 + i2) >> 1; \
430: if (last_ch == comp_table_data[i].base) \
431: break; \
432: if (last_ch < comp_table_data[i].base) \
433: { \
434: if (i1 == i) \
435: goto not_combining; \
436: i2 = i; \
437: } \
438: else \
439: { \
440: if (i1 != i) \
441: i1 = i; \
442: else \
443: { \
444: i = i2; \
445: if (last_ch == comp_table_data[i].base) \
446: break; \
447: goto not_combining; \
448: } \
449: } \
450: } \
451: last_ch = comp_table_data[i].composed; \
452: \
453: put32 (outptr, last_ch); \
454: outptr += 4; \
455: *statep = 0; \
456: ++inptr; \
457: continue; \
458: } \
459: } \
460: \
461: not_combining: \
462: \
463: put32 (outptr, last_ch); \
464: outptr += 4; \
465: *statep = 0; \
466: \
467:
468: \
469: if (!must_buffer_ch && __builtin_expect (outptr + 4 > outend, 0)) \
470: continue; \
471: } \
472: \
473: if (must_buffer_ch) \
474: *statep = ch << 3; \
475: else \
476: { \
477: put32 (outptr, ch); \
478: outptr += 4; \
479: } \
480: ++inptr; \
481: }
482: #define LOOP_NEED_FLAGS
483: #define EXTRA_LOOP_DECLS , int *statep
484: #define ONEBYTE_BODY \
485: { \
486: uint32_t ch; \
487: \
488: if (c < 0x80) \
489: ch = c; \
490: else \
491: { \
492: ch = to_ucs4[c - 0x80]; \
493: if (ch == L'\0') \
494: return WEOF; \
495: } \
496: if (ch >= 0x0041 && ch <= 0x01b0) \
497: return WEOF; \
498: return ch; \
499: }
500: #include <iconv/loop.c>
501:
502:
503:
504:
505: static const unsigned char from_ucs4[] =
506: {
507: #define FROM_IDX_00 0
508: 0xc4, 0xc5, 0xc6, 0xc7,
509: 0xc8, 0xc9, 0xca, 0xcb, 0x00, 0xcd, 0xce, 0xcf,
510: 0x00, 0xd1, 0x00, 0xd3, 0xd4, 0x00, 0xd6, 0xd7,
511: 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf,
512: 0xe0, 0xe1, 0xe2, 0x00, 0xe4, 0xe5, 0xe6, 0xe7,
513: 0xe8, 0xe9, 0xea, 0xeb, 0x00, 0xed, 0xee, 0xef,
514: 0x00, 0xf1, 0x00, 0xf3, 0xf4, 0x00, 0xf6, 0xf7,
515: 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0xff,
516: 0x00, 0x00, 0xc3, 0xe3, 0x00, 0x00, 0x00, 0x00,
517: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518: 0xd0, 0xf0,
519: #define FROM_IDX_01 (FROM_IDX_00 + 78)
520: 0x8c, 0x9c, 0x00, 0x00, 0x00, 0x00,
521: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
522: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
523: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
524: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,