about summary refs log tree commit diff
path: root/tr2cyr.c
blob: 8244664d2f441932a90434f0fe5be36a8687bd8e (plain)
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <wchar.h>

/*
 * a = а
 * b = б
 * v = в
 * g = г
 * d = д
 * e = е
 * yo = ё
 * yz = ж
 * z = з
 * i = и
 * j = й
 * k = к
 * l = л
 * m = м
 * n = н
 * o = о
 * p = п
 * r = р
 * s = с
 * t = т
 * u = у
 * f = ф
 * h = х
 * c = ц
 * yc = ч
 * ys = ш
 * yg = щ
 * y" = ъ
 * yi = ы
 * y' = ь
 * ye = э
 * yu = ю
 * ya = я
 */

typedef int Translator_Writer(wchar_t ch, void *arg);

int Translator_convert(FILE *file, Translator_Writer *writer, void *arg)
{
    wint_t ch;
    while ((ch = getwchar()) != WEOF)
    {
        wchar_t towrite;
#define CASE(x, y) case x: towrite = y; break
        switch (ch)
        {
        CASE(L'a', L'а');
        CASE(L'b', L'б');
        CASE(L'v', L'в');
        CASE(L'g', L'г');
        CASE(L'd', L'д');
        CASE(L'e', L'е');
        CASE(L'z', L'з');
        CASE(L'i', L'и');
        CASE(L'j', L'й');
        CASE(L'k', L'к');
        CASE(L'l', L'л');
        CASE(L'm', L'м');
        CASE(L'n', L'н');
        CASE(L'o', L'о');
        CASE(L'p', L'п');
        CASE(L'r', L'р');
        CASE(L's', L'с');
        CASE(L't', L'т');
        CASE(L'u', L'у');
        CASE(L'f', L'ф');
        CASE(L'h', L'х');
        CASE(L'c', L'ц');
        case 'y':
        {
            if ((ch = getwchar()) == WEOF)
                return errno ? -1 : 0;

            switch(ch)
            {
            CASE(L'o', L'ё');
            CASE(L'z', L'ж');
            CASE(L'c', L'ч');
            CASE(L's', L'ш');
            CASE(L'g', L'щ');
            CASE(L'"', L'ъ');
            CASE(L'i', L'ы');
            CASE(L'\'', L'ь');
            CASE(L'e', L'э');
            CASE(L'u', L'ю');
            CASE(L'a', L'я');
            default:
            {
                int ret = writer(L'y', arg);
                if (ret)
                    return ret;

                towrite = ch;
            } break;
            }
        } break;
        default:
            towrite = ch;
        }
#undef CASE

        int ret = writer(towrite, arg);
        if (ret)
            return ret;
    }
    return errno ? -1 : 0;
}

static int writer(wchar_t ch, void *arg)
{
    (void)arg;
    return putwchar(ch) == WEOF ? -1 : 0;
}

int main(int argc, char **argv)
{
    setlocale(LC_CTYPE, "");
    Translator_convert(stdin, &writer, 0);
}