#include #include typedef unsigned char uchar; typedef uchar *str; typedef enum { xli, alt, koi } coding; static uchar sh2xli [0x40][5] = { // lowercase "a", "b", "v", "g", "d", "e", "zh","z", "i", "j", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", "h", "c", "ch", "sh","shch", "''", "y", "'", "e'", "ju", "ja", // uppercase "A", "B", "V", "G", "D", "E", "Zh","Z", "I", "J", "K", "L", "M", "N", "O", "P", "R", "S", "T", "U", "F", "H", "C", "Ch", "Sh","Shch", "''", "Y", "'", "E'", "Ju", "Ja" }; static uchar sh2alt [0x40] = { // lowercase 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, // uppercase 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F }; static uchar sh2koi [0x40] = { // lowercase 0301, 0302, 0327, 0307, 0304, 0305, 0326, 0332, 0311, 0312, 0313, 0314, 0315, 0316, 0317, 0320, 0322, 0323, 0324, 0325, 0306, 0310, 0303, 0336, 0333, 0335, 0337, 0331, 0330, 0334, 0300, 0321, // uppercase; 0341, 0342, 0367, 0347, 0344, 0345, 0366, 0372, 0351, 0352, 0353, 0354, 0355, 0356, 0357, 0360, 0362, 0363, 0364, 0365, 0346, 0350, 0343, 0376, 0373, 0375, 0377, 0371, 0370, 0374, 0340, 0361 }; /* Needs fixing, as it's extremely inefficient */ int koi2sh( uchar c) { int i; for( i=0; i < 0x40; i++) if (sh2koi[i] == c) return i; return -1; } int alt2sh( uchar c) { int sh = -1; if ( c >= 0x80 && c < 0xA0) sh = c - 0x80 + 0x20; else if ( c>= 0xA0 && c < 0xB0) sh = c - 0xA0; else if ( c>= 0xE0 && c < 0xF0) sh = c - 0xE0 + 0x10; return sh; } static int char2sh[ 0x100 ]; /* Fills the table char2sh */ void make_table( coding source ) { int c; for( c = 0; c < 0x100; c ++) { if ( source == alt ) char2sh[ c ] = alt2sh( c ); else if (source == koi) char2sh[ c ] = koi2sh( c ); } } void Decode(FILE *f, FILE *g, coding target) { int c, sh; while( c = getc(f) , c != EOF ) { sh = char2sh[ c ]; if ( sh== -1) putc( c, g) ; else { if (target == xli) fprintf( g, "%s", sh2xli[sh]); else if (target == koi) putc( sh2koi[sh], g); else if (target == alt) putc( sh2alt[sh], g); } } } static str progname; void usage() { printf("\nUsage: %s input-file output-file", progname); printf("\nFormat:"); printf("\n a : Alt ASCII; k : KOI-8; x : transliteration"); printf("\n"); exit(1); } coding get_format( str s) { if (s[1]) usage(); else if (s[0] == 'a') return alt; else if (s[0] == 'k') return koi; else if (s[0] == 'x') return xli; else usage(); return xli; /* Just to prevent warning */ } int main(int argc, str argv[]) { FILE *f, *g; coding source=koi, target=alt; progname = argv[0]; if (argc < 3 || argc> 5) usage(); source = get_format( argv[1]); target = get_format( argv[2]); if (source == xli) { fprintf(stderr, "\nCan't convert FROM transliterated format!\n"); exit(1); } if (argc > 3) { f = fopen( argv[3], "rt"); if (!f) { printf("\nCan't read from `%s'", argv[3] ); exit(1); } } else f = stdin; if (argc> 4) { g = fopen( argv[4], "wt"); if (!g) { printf("\nCan't write to `%s'", argv[4] ); exit(1); } } else g = stdout; make_table( source ); Decode(f,g, target); fclose(f); fclose(g); return 0; }