1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
#include <errno.h>
#include <wchar.h>
#include <wctype.h>
#include "tr2cyr.h"
int tr2cyr(tr2cyr_reader *reader, void *readerarg, tr2cyr_writer *writer, void *writerarg)
{
size_t i = 0;
int lowercase;
wint_t ch;
while ((ch = reader(i++, readerarg)) != WEOF)
{
lowercase = towlower(ch) == ch;
wchar_t towrite;
#define CASE(option, lower, upper) case option: towrite = lowercase ? lower : upper; break
switch (towlower(ch))
{
CASE(L'a', L'а', L'А');
CASE(L'b', L'б', L'Б');
CASE(L'v', L'в', L'В');
CASE(L'g', L'г', L'Г');
CASE(L'd', L'д', L'Д');
CASE(L'e', L'е', L'Е');
CASE(L'z', L'з', L'З');
CASE(L'i', L'и', L'И');
CASE(L'j', L'й', L'Й');
CASE(L'k', L'к', L'К');
CASE(L'l', L'л', L'Л');
CASE(L'm', L'м', L'М');
CASE(L'n', L'н', L'Н');
CASE(L'o', L'о', L'О');
CASE(L'p', L'п', L'П');
CASE(L'r', L'р', L'Р');
CASE(L's', L'с', L'С');
CASE(L't', L'т', L'Т');
CASE(L'u', L'у', L'У');
CASE(L'f', L'ф', L'Ф');
CASE(L'h', L'х', L'Х');
CASE(L'c', L'ц', L'Ц');
case 'y':
{
if ((ch = reader(i++, readerarg)) == WEOF)
{
writer(lowercase ? L'y' : L'Y', writerarg);
return errno ? -1 : 0;
}
switch(towlower(ch))
{
CASE(L'o', L'ё', L'Ё');
CASE(L'z', L'ж', L'Ж');
CASE(L'c', L'ч', L'Ч');
CASE(L's', L'ш', L'Ш');
CASE(L'g', L'щ', L'Щ');
CASE(L'"', L'ъ', L'Ъ');
CASE(L'i', L'ы', L'Ы');
CASE(L'\'', L'ь', L'Ь');
CASE(L'e', L'э', L'Э');
CASE(L'u', L'ю', L'Ю');
CASE(L'a', L'я', L'Я');
default:
{
int ret = writer(lowercase ? L'y' : L'Y', writerarg);
if (ret)
return ret;
towrite = ch;
} break;
}
} break;
default:
towrite = ch;
}
#undef CASE
int ret = writer(towrite, writerarg);
if (ret)
return ret;
}
return errno ? -1 : 0;
}
|