/* Russian encodings with care to letter YO from www.rusf.ru/books/yo */ /* Written in 2002--2004 by D.V.Khmelev */ /* !!!!!!!!!!!! BEFORE COMPILATION !!!!!!!!!!!!!!!!!!!!!!!!!!! */ /* Please #define D_ALT for messages in cp866 */ /* Please #define D_WIN for messages in cp12151 */ /* Please #define D_KOI for messages in koi8-r */ /* You can also pass their definitions through compiler command line */ /* gcc -DD_KOI xcode.c -o xcode #GNU C compiler */ /* bcc.exe -DD_ALT xcode.c #Borland C compiler */ // чЩИПДОБС ЛПДЙТПЧЛБ РП ХНПМЮБОЙА // Output encoding by default #define __ENCLINE__ __LINE__ //#define D_ALT //#define D_WIN //#define D_KOI //#define D_ISO //#define D_MAC #ifdef D_ALT # define OUTPUT_ENC 0 // МЙВП "БМШФЕТОБФЙЧОБС" (Ф.Е. ДПУПЧУЛБС) //either cp866 #elif defined(D_WIN) # define OUTPUT_ENC 1 // win=cp1251 #elif defined(D_KOI) # define OUTPUT_ENC 2 // МЙВП "KOI". // or koi8 #elif defined(D_ISO) # define OUTPUT_ENC 3 // iso #elif defined(D_MAC) # define OUTPUT_ENC 4 // mac #else # error Please #define default output encoding D_ALT D_WIN D_KOI D_ISO D_MAC #endif #if defined(__MSDOS__) || defined(_WIN32) || defined(WIN32)|| defined(__WIN32__) || defined(__TURBOC__) #define STDOUT_PROBLEM_DOS 1 #endif #if defined(__MINGW__) #define STDOUT_PROBLEM_MINGW 2 #endif // Change Log: // $Log: xcode.c,v $ // Revision 4.1 2004/02/04 05:32:13 mamont // дПВБЧМЕО РЕТЕЛМАЮБФЕМШ -c, РПЪЧПМСАЭЙК // ПРТЕДЕМСФШ ЛПДЙТПЧЛХ ЖБКМБ Й ЧЩДБЧБФШ ЕЈ // ОБ ЬЛТБО. рПМОБС УРТБЧЛБ РП -H УПДЕТЦЙФ // ЙОУФТХЛГЙЙ РП РТЙНЕОЕОЙА ЬФПК ОПЧПК // ЧПЪНПЦОПУФЙ. рТЙ ЛПТТЕЛФОПН // ЙУРПМШЪПЧБОЙЙ РЕТЕЛМАЮБФЕМС -c РТПЗТБННБ // ЧЩИПДЙФ У ЛПДПН ПЫЙВЛЙ // 6 --- ERROR_INFORM_ENCODING. // // Revision 4.0 2003/12/20 23:11:12 mamont // дПВБЧМЕО ЛМАЮ -d ДМС ПРТЕДЕМЕОЙС // ДЧПКОПК РЕТЕЛПДЙТПЧЛЙ. уНЕОБ ОПНЕТБ // ЧЕТУЙЙ ОБ 4.0 // // Revision 3.7 2003/10/05 18:35:21 mamont // йУРТБЧМЕО ЗМАЛ, ЧПЪОЙЛБЧЫЙК РТЙ ЧЩЪПЧЕ // xcode in out // У ПФУХФУФЧХАЭЙН ЖБКМПН out (ЧЩДБЧБМБУШ // ПЫЙВЛБ). // // Revision 3.6 2003/10/05 00:15:24 mamont // ъБТБВПФБМ РТПЪТБЮОП ВЙОБТОЩК УФБОДБТФОЩК // ЧЧПД/ЧЩЧПД РПД дпу-ПЛОПН. чЕТУЙА mingw // ОЕ РТПЧЕТСМ, ОП, РП ЙДЕЕ ФПЦЕ ДПМЦОБ ТБВПФБФШ. // // Revision 3.5 2003/10/04 23:26:25 mamont // фЕРЕТШ stdout ХУФБОБЧМЙЧБЕФУС Ч ВЙОБТОЩК // ТЕЦЙН Ч DOS/WIN ПЛТХЦЕОЙЙ. йОБЮЕ // ДПВБЧМСМУС ЛПД \x0D Ч ЛПОГЕ ЛБЦДПК // УФТПЛЙ (\x0D\x0A). // // Revision 3.4 2003/10/04 23:02:54 mamont // йУРТБЧМЕОБ ПЫЙВЛБ Ч ЧЩДБЮЕ ДЙБЗОПУФЙЛЙ // Ч РТЕДЩДХЭЕК ЧЕТУЙЙ. // // дПВБЧМЕОЩ ДПРПМОЙФЕМШОЩЕ ЛПДЩ ЧЩИПДБ // (УН. xcode -H, ТБЪДЕМ лпдщ чщипдб) // // дПВБЧМЕО РЕТЕЛМАЮБФЕМШ --, РП ЛПФПТПНХ // РТЕТЩЧБЕФУС ТБЪВПТ ЛПНБОДОПК УФТПЛЙ. // // дПВБЧМЕОП УППВЭЕОЙЕ ПВ ПЫЙВЛЕ Ч БТЗХНЕОФБИ // РТПЗТБННЩ, ЕЦЕМЙ ФБЛБС РТПУИПДЙФ. // // Revision 3.3 2003/09/27 18:37:05 mamont // РЕТЕЖПТНБФЙТПЧБМ ЛПННЕОФБТЙЙ // // Revision 3.2 2003/09/27 18:35:43 mamont // уПЧУЕН ЪБВЩМ: ФЕРЕТШ РТПЗТБННБ ЧЩИПДЙФ // У ОЕОХМЕЧЩН ЛПДПН РТЙ ЛБЛПК-МЙВП ПЫЙВЛЕ. // уБНЙ ПЫЙВЛЙ НПЦОП РПУНПФТЕФШ Ч ФЕЛУФЕ: // E_OK Й Ф.Д. // // Revision 3.1 2003/09/27 18:28:26 mamont // фЕРЕТШ ПРГЙЙ ЧЙДБ /h ДПРХУФЙНЩ ФПМШЛП РТЙ // ЧЩИПДОПК ЛПДЙТПЧЛЕ D_ALT // // рП ПРГЙЙ "--" УЛБОЙТПЧБОЙЕ БТЗХНЕОФПЧ // ПУФБОБЧМЙЧБЕФУС. уМЕДХАЭЙЕ БТЗХНЕОФЩ // ТБУУНБФТЙЧБАФУС ЛБЛ ЙНЕОБ ЖБКМПЧ. // // Revision 3.0 2003/04/03 20:00:35 mamont // уНЕОБ ЧЕТУЙЙ ОБ 3.0 // ЛПНБОДБ: ci -f3.0 xcode.c // // Revision 2.10 2003/04/03 19:47:12 mamont // рПРТБЧМЕОБ ПЫЙВЛБ Ч ЛПДЙТПЧЛЕ "mac", ОБ ЛПФПТХА // МАВЕЪОП ХЛБЪБМ уЕТЗЕК уЛПФОЙЛПЧ (ОЕЧЕТОЩК ЛПД // ВХЛЧЩ ``С''). йУРПМШЪХЕНБС ВЙВМЙПФЕЛБ // РЕТЕУФБОПЧПЮОПК РЕТЕЛПДЙТПЧЛЙ У // http://www.rusf.ru/books/yo/encoding.html РПМХЮЙМБ // ОБЪЧБОЙЕ SRECODE.C Й СЧОП ЧЩДЕМЕОБ Ч ФЕЛУФЕ // РТПЗТБННЩ ЛПННЕОФБТЙСНЙ. // // Revision 2.9 2003/03/31 15:46:49 mamont // фЕЛУФ РТЙЧЕДЈО Л УФБОДБТФХ C99 (РП НПДХМА РТЕДХРТЕЦДЕОЙК П ЛПОЧЕТФБГЙЙ // НЕЦДХ ЪОБЛПЧЩНЙ/ВЕЪЪОБЛПЧЩНЙ ВХЛЧБНЙ). вПТПФШУС У ЬФЙН НПЦОП СЧОЩН // ЪБДБОЙЕН РТЕПВТБЪПЧБОЙС ХЛБЪБФЕМЕК, ОП ОЕ ОХЦОП Ч УЙМХ ХУМПЦОЕОЙС // ЛПДБ. // // Revision 2.8 2003/03/26 02:17:16 mamont // рПРТБЧМЕОП РТЕДХРТЕЦДЕОЙЕ "suspicious pointer conversion" // // Revision 2.7 2003/03/26 02:14:13 mamont // дПВБЧМЕОП ДЕЛПДЙТПЧБОЙЕ html-хОЙЛПДЕООЩИ ФЕЛУФПЧ // (ЧТПДЕ Дима) // // Revision 2.6 2003/03/10 17:36:26 mamont // йОЖПТНБГЙС П ТЕЦЙНЕ silent ДПВБЧМЕОБС Ч УРТБЧЛХ // // Revision 2.5 2003/03/10 17:30:05 mamont // дПВБЧМЕО ТЕЦЙН silent РП ПРГЙЙ -s // // Revision 2.4 2003/03/09 01:42:47 mamont // йУРТБЧМЕОП ОЕРТБЧЙМШОПЕ РПЧЕДЕОЙЕ РТЙ ПДОПН ЙНЕОЙ ЖБКМБ // // Revision 2.3 2003/03/08 19:57:28 mamont // фЕРЕТШ РТПЗТБННБ ЛПНРЙМЙТХЕФУС bc 3.1 ВЕЪ РТЕДХРТЕЦДЕОЙК Й ПЫЙВПЛ. // // Revision 2.2 2003/03/08 19:33:27 mamont // тЕЦЙН ФТХВЩ ФЕРЕТШ РП ХНПМЮБОЙА ФПМШЛП Ч дПУЕ/чЙОДБИ. (дПУ/Win // ПРТЕДЕМСЕФУС РП РЕТЕЛМАЮБФЕМА D_ALT) // // Revision 2.1 2003/03/08 19:25:05 mamont // *** empty log message *** // // Revision 2.0 2003/03/08 19:23:31 mamont // уНЕОБ ОПНЕТБ ЧЕТУЙЙ ОБ 2.0 // // Revision 1.14 2003/03/08 19:13:24 mamont // ъОБЮЙФЕМШОЩЕ ХМХЮЫЕОЙС РП УТБЧОЕОЙА У РТЕДЩДХЭЕК ЧЕТУЙЕК. фЕРЕТШ // ЙНЕЕФУС ПРГЙС У ФТХВПК -p, Б РПД дПУПЧУЛПК ЛПОУПМША РП ХНПМЮБОЙА // РТПЗТБННБ ЧЩЧПДЙФ ЛТБФЛХА РПНПЭШ. // // еУМЙ ЧИПДОБС ЛПДЙТПЧЛБ ХЦЕ ХЛБЪБОБ, ФП РТПЗТБННБ ОЕ ПРТЕДЕМСЕФ ЕЈ // БЧФПНБФЙЮЕУЛЙ, Б УТБЪХ РТПЙЪЧПДЙФ РЕТЕЛПДЙТПЧЛХ. еДЙОУФЧЕООЩК ФПОЛЙК // НПНЕОФ: ЛПЗДБ ОБДП РЕТЕЛПДЙТПЧБФШ ЖБКМ ОБ НЕУФЕ. ч ЬФПН УМХЮБЕ // ЙУРПМШЪХЕФУС ЧТЕНЕООЩК ЖБКМ ОБ ДЙУЛЕ, ЛБЛ Й ЧУЕЗДБ. // // Revision 1.13 2003/03/08 16:24:13 mamont // дПВБЧЙМ Revision // // Revision 1.12 2003/03/08 16:17:35 mamont // оБЮБФ МПЗ ЙЪНЕОЕОЙК // #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <assert.h> #include <sys/stat.h> #ifdef STDOUT_PROBLEM_DOS #include <fcntl.h> #include <io.h> #endif//STDOUT_PROBLEM_DOS #define XCODE "xcode" #define REVISION "$Revision: 4.1 $" static char * VERSIONR=REVISION; static char VERSION[100];//=VERSIONR+11 #define SELF_URL_BASE "http://www.rusf.ru/books/yo" #define SELF_URL SELF_URL_BASE "/src/xcode.c" /* Library SRECODE.C (Shuffle RECODE) ver. 1.0 * бЧФПТ ЛПДБ: д.ч.иНЕМЈЧ, нБТФ 2002--БРТЕМШ 2003 * рПДТПВОПУФЙ: http://www.rusf.ru/books/yo * рПДРТПЗТБННЩ ОБ СЪЩЛЕ уЙ, ПВЕУРЕЮЙЧБАЭЙЕ * РЕТЕУФБОПЧПЮОХА РЕТЕЛПДЙТПЧЛХ 14 ЛПДЙТПЧПЛ * ТХУУЛЙИ ВХЛЧ ДТХЗ Ч ДТХЗБ. * Functions for Perl, providing exchange * transformation of 14 russian encodings to * each other. * уМЕДХАЭЙК ЛПД СЧМСЕФУС і-ware, йНЕООП, ЕЗП НПЦОП * УЧПВПДОП ТБУРТПУФТБОСФШ НПДЙЖЙГЙТПЧБФШ, Й ДБЦЕ * ДЙЪБУУЕНВМЙТПЧБФШ ЛБЛ Ч ДЧПЙЮОПН ЧЙДЕ, ФБЛ Й Ч * ЙУИПДОПН ФЕЛУФЕ. пДОБЛП, ЙУРПМШЪХС ЬФПФ ЛПД, ЧЩ * ДПМЦОЩ ЙУРПМШЪПЧБФШ ВХЛЧХ і ЧП ЧУЕИ ФЕЛУФБИ, * ЛПФПТЩЕ ОБВЙТБЕФЕ ОБ ЛПНРШАФЕТБИ: ОБЮЙОБС У * ЬМЕЛФТПООЩИ РЙУЕН Й ЪБЛБОЮЙЧБС ЛТХРОПК * РТПЪБЙЮЕУЛПК ЖПТНПК. * бЧФПТ ЧПЪДЕТЦЙЧБЕФУС ПФ ЧУСЮЕУЛЙИ ЗБТБОФЙК * ОБДЈЦОПУФЙ ЛПДБ Й УОЙНБЕФ У УЕВС ПФЧЕФУФЧЕООПУФШ * ЪБ ЧПЪНПЦОХА РПФЕТА ДБООЩИ РТЙ ЕЗП * ЙУРПМШЪПЧБОЙЙ. фЕН ОЕ НЕОЕЕ, БЧФПТ РПУФБТБМУС * УДЕМБФШ ЧУЈ ЧПЪНПЦОПЕ, ЮФПВЩ РПФЕТЙ ДБООЩИ НПЦОП * ВЩМП ЙЪВЕЦБФШ. * Written by D.V. Khmelev, March 2002 -- April 2003 * More information at http://www.rusf.ru/books/yo * The following code is YO-ware. YO-ware means that * you can freely copy, modify and disassemble it in * binary and/or source text. However, if you use * this program code, you should use Russian letter * YO in all texts in Russian you type in computer * from e-mails to novels. * The author disclaims any responsibility for code * safety and holds no responsibility for the loss of * data, resulting the the use of the following * code. However, the author tried to do his best to * avoid loss of data. */ typedef enum { CP866=0, CP1251, KOI8_R, ISO8859_5, MAC, OSN, MOSHKOV, SORT, ALT_FIDO, KOI7, DKOI, CP500, EBCDIC, ASCII, TOTAL_ENCODING_NUMBER} encoding_t; char * encoding_name[]={ "cp866", /* CP866 */ "cp1251", /* CP1251 */ "koi8-r", /* KOI8_R */ "iso8859-5", /* ISO8859_5 */ "mac", /* MAC */ "osn", /* OSN */ "moshkov", /* MOSHKOV */ "sort", /* SORT */ "alt-fido", /* ALT_FIDO */ "koi7", /* KOI7 */ "dkoi", /* DKOI */ "cp500", /* CP500 */ "ebcdic", /* EBCDIC */ "ascii", /* ASCII */ }; unsigned char * encoding_alphabet[]={ /* CP866 */ (unsigned char*) "\240\241\242\243\244\245\361\246\247\250" "\251\252\253\254\255\256\257\340\341\342" "\343\344\345\346\347\350\351\352\353\354" "\355\356\357" "\200\201\202\203\204\205\360\206\207\210" "\211\212\213\214\215\216\217\220\221\222" "\223\224\225\226\227\230\231\232\233\234" "\235\236\237", /* CP1251 */ (unsigned char*) "\340\341\342\343\344\345\270\346\347\350" "\351\352\353\354\355\356\357\360\361\362" "\363\364\365\366\367\370\371\372\373\374" "\375\376\377" "\300\301\302\303\304\305\250\306\307\310" "\311\312\313\314\315\316\317\320\321\322" "\323\324\325\326\327\330\331\332\333\334" "\335\336\337", /* KOI8_R */ (unsigned char*) "\301\302\327\307\304\305\243\326\332\311" "\312\313\314\315\316\317\320\322\323\324" "\325\306\310\303\336\333\335\337\331\330" "\334\300\321" "\341\342\367\347\344\345\263\366\372\351" "\352\353\354\355\356\357\360\362\363\364" "\365\346\350\343\376\373\375\377\371\370" "\374\340\361", /* ISO8859_5 */ (unsigned char*) "\320\321\322\323\324\325\361\326\327\330" "\331\332\333\334\335\336\337\340\341\342" "\343\344\345\346\347\350\351\352\353\354" "\355\356\357" "\260\261\262\263\264\265\241\266\267\270" "\271\272\273\274\275\276\277\300\301\302" "\303\304\305\306\307\310\311\312\313\314" "\315\316\317", /* MAC */ (unsigned char*) "\340\341\342\343\344\345\336\346\347\350" "\351\352\353\354\355\356\357\360\361\362" "\363\364\365\366\367\370\371\372\373\374" "\375\376\337" "\200\201\202\203\204\205\335\206\207\210" "\211\212\213\214\215\216\217\220\221\222" "\223\224\225\226\227\230\231\232\233\234" "\235\236\237", /* OSN */ (unsigned char*) "\320\321\322\323\324\325\361\326\327\330" "\331\332\333\334\335\336\337\340\341\342" "\343\344\345\346\347\350\351\352\353\354" "\355\356\357" "\260\261\262\263\264\265\360\266\267\270" "\271\272\273\274\275\276\277\300\301\302" "\303\304\305\306\307\310\311\312\313\314" "\315\316\317", /* MOSHKOV */ (unsigned char*) "\341\342\367\347\344\345\243\366\372\351" "\352\353\354\355\356\357\360\362\363\364" "\365\346\350\343\376\373\375\256\371\370" "\374\340\361" "\301\302\327\307\304\305\263\326\332\311" "\312\313\314\315\316\317\320\322\323\324" "\325\306\310\303\336\333\335\254\331\330" "\334\300\321", /* SORT */ (unsigned char*) "\241\242\243\244\245\246\247\250\251\252" "\253\254\255\256\257\260\261\262\263\264" "\265\266\267\270\271\272\273\274\275\276" "\277\300\301" "\200\201\202\203\204\205\206\207\210\211" "\212\213\214\215\216\217\220\221\222\223" "\224\225\226\227\230\231\232\233\234\235" "\236\237\240", /* ALT_FIDO */ (unsigned char*) "\240\241\242\243\244\245\361\246\247\250" "\251\252\253\254\255\256\257\160\341\342" "\343\344\345\346\347\350\351\352\353\354" "\355\356\357" "\200\201\202\203\204\205\360\206\207\210" "\211\212\213\214\110\216\217\220\221\222" "\223\224\225\226\227\230\231\232\233\234" "\235\236\237", /* KOI7 */ (unsigned char*) "\101\102\127\107\104\105\43\126\132\111" "\112\113\114\115\116\117\120\122\123\124" "\125\106\110\103\136\133\135\137\131\130" "\134\100\121" "\141\142\167\147\144\145\44\166\172\151" "\152\153\154\155\156\157\160\162\163\164" "\165\146\150\143\176\173\175\42\171\170" "\174\140\161", /* DKOI */ (unsigned char*) "\167\170\257\215\212\213\131\256\262\217" "\220\232\233\234\235\236\237\252\253\254" "\255\214\216\200\266\263\265\267\261\260" "\264\166\240" "\271\272\355\277\274\275\102\354\372\313" "\314\315\316\317\332\333\334\336\337\352" "\353\276\312\273\376\373\375\165\357\356" "\374\270\335", /* CP500 */ (unsigned char*) "\254\151\355\356\353\357\111\354\277\200" "\375\376\373\374\255\256\131\104\105\102" "\106\103\107\234\110\124\121\122\123\130" "\125\126\127" "\220\217\352\372\276\240\252\266\263\235" "\332\233\213\267\270\271\253\144\145\142" "\146\143\147\236\150\164\161\162\163\170" "\165\166\167", /* EBCDIC */ (unsigned char*) "\237\240\252\253\254\255\335\256\257\260" "\261\262\263\264\265\266\267\270\271\272" "\273\274\275\276\277\312\313\314\315\316" "\317\332\333" "\130\131\142\143\144\145\102\146\147\150" "\151\160\161\162\163\164\165\166\167\170" "\200\212\213\214\215\216\217\220\232\233" "\234\235\236", /* ASCII */ (unsigned char*) "\141\142\167\147\144\145\136\166\172\151" "\152\153\154\155\156\157\160\162\163\164" "\165\146\150\143\75\133\135\43\171\170" "\134\140\161" "\101\102\127\107\104\105\46\126\132\111" "\112\113\114\115\116\117\120\122\123\124" "\125\106\110\103\53\173\175\44\131\130" "\174\176\121", }; int *full_encoding_list(encoding_t encoding, int table[]){ int i,j; static int exists[256]; for(i=0;i<256;i++) exists[i]=0; for(i=0;i<66;i++) { table[i]=encoding_alphabet[encoding][i]; exists[table[i]]=1; } for(j=66,i=0;i<256;i++){ if(exists[i]) continue; table[j++]=i; } return table; } int *fill_recode_table(int table[], encoding_t from, encoding_t to){ static int full_enc_from[256]; static int full_enc_to[256]; int i; full_encoding_list(from,full_enc_from); full_encoding_list(to,full_enc_to); for(i=0;i<256;i++) table[full_enc_from[i]]=full_enc_to[i]; return table; } unsigned char *srecode(unsigned char *s, encoding_t from, encoding_t to){ static int prev_from=-1, prev_to=-1; static int recode_table[256]; int i; if((from!=prev_from)||(to!=prev_to)){ prev_from=from; prev_to=to; fill_recode_table(recode_table,from,to); } for(i=0;s[i];i++) s[i]=recode_table[s[i]]; return s; } unsigned char *srecode2(unsigned char *s, unsigned char *t, encoding_t from, encoding_t to){ static int prev_from=-1, prev_to=-1; static int recode_table[256]; int i; if((from!=prev_from)||(to!=prev_to)){ prev_from=from; prev_to=to; fill_recode_table(recode_table,from,to); } for(i=0;t[i];i++) s[i]=recode_table[t[i]]; s[i]=0; return s; } /* ЛПОЕГ ЛПДБ ВЙВМЙПФЕЛЙ SRECODE.C * * end of the code of the library SRECODE.C */ /*************************************************/ /**** ERROR_LIST ********/ /*************************************************/ // чОЙНБОЙЕ!!! рТПЗТБННБ ЧПЪЧТБЭБЕФ 0 ФПЗДБ Й ФПМШЛП ФПЗДБ, ЛПЗДБ // ХУРЕЫОП РЕТЕЛПДЙТПЧБМБ ЖБКМ (Ф.Е. УДЕМБМБ ФП, ДМС ЮЕЗП // РТЕДОБЪОБЮЕОБ). чЩДБЮБ ЧЕТУЙЙ, ЙМЙ УРТБЧЛЙ ТБУУНБФТЙЧБАФУС ЛБЛ // ПЫЙВЛЙ: ФБЛПЗП РТЙ ЙУРПМШЪПЧБОЙЙ Ч РБЛЕФОПН ТЕЦЙНЕ РТПЙУИПДЙФШ ОЕ // ДПМЦОП. // уРЙУПЛ ЧЧЕДЈО РП РТПУШВЕ чМБДЙУМБЧБ оПУПЧБ (nvv@mail^primorye^ru) enum{ ERROR_OK=0, ERROR_VERSION, ERROR_HELP, ERROR_DESCRIPTION, ERROR_NO_ARGUMENT, ERROR_WRONG_ARGUMENT, ERROR_INFORM_ENCODING, ERROR_SERIOUS=16, ERROR_INTERNAL=ERROR_SERIOUS, ERROR_MALLOC, ERROR_STAT_FILE, ERROR_EMPTY_FILE, ERROR_OPEN_FILE_READ, ERROR_OPEN_FILE_WRITE, ERROR_OPEN_FILE_TMP, ERROR_WRITE_FILE, }; #define NUMCOD 5 char encLetter[]={'a','w','k','i','m'}; int enc=OUTPUT_ENC; int program_output_encoding=OUTPUT_ENC; int Russian=1; unsigned char *alphabet= "БВЧЗДЕЈЦЪЙКЛМНОПРТУФХЖИГЮЫЭЯЩШЬАСбвчздеіцъйклмнопртуфхжигюыэящшьас"; int self_encoding=2; // РП ХНПМЮБОЙА --- УПВУФЧЕООБС ЛПДЙТПЧЛБ ЕУФШ koi void determine_self_encoding(char *selfname){ for(self_encoding=0; self_encoding<TOTAL_ENCODING_NUMBER; self_encoding++) if(strcmp(alphabet,encoding_alphabet[self_encoding])==0) return; Russian=0; self_encoding=2; fprintf(stderr, "WARNING: This version of %s has passed incorrect change of \n" "WARNING: russian letters encoding!!!\n" "WARNING: Download correct version from " SELF_URL "\n", selfname); } static char temps[1500]; char *_rec(char *s){ return srecode2(temps,s,self_encoding,program_output_encoding); } char *msgs_eng[]={ /* msg_descr */ "(Based on a program written originally by Andrey V. Lukyanov, May 14, 1997,\n" "and updated later by Cyril Rotmistrovsky and Igor V. Krassikov)\n" "\n" "DESCRIPTION\n" "\n" "This program tries to determine input document encoding\n" "and to convert it into a desired one.\n" "The important feature of this program is ONE-TO-ONE conversion,\n" "which prevents you from damaging your file. If conversion is\n" "incorrect or if you even converted a binary file, you can always\n" "RESTORE source file by backward conversion (if you did not use\n" "options -l, -q or -t)\n" "\n" "LICENSE\n" "\n" "This program is YO-ware. YO-ware means that you can freely copy,\n" "modify and disassemble in binary and/or source text.\n" "However, if you use this program, you should use Russian letter YO\n" "in all texts in Russian you type in computer from e-mails\n" "to novels.\n" "\n" "EXIT CODES\n" "\n" "The program terminates with 0 exit code only in the case it actually\n" "did, what it is supposed to do: recoded the file. In all other cases\n" "the exit code is non-zero.\n" "In particular help output returns non-zero code ERROR_HELP.\n" "Mistakes, related to interaction with operating system has code >=16.\n" "In future versions other exit codes might be added, but current shall\n" "not be changed." "\n" " THE TABLE OF EXIT CODES:\n" , /* msg_encodings */ "OTHER SWITCHES\n" "\n" "Switch -- stops parsing command line arguments and further parameters\n" "are considered as filenames (this way you can work with files, whose\n" "name begins with dash sign - ;).\n" "\n" "Switch -У changes xcode to the state of informing about encoding\n" "of the input. The program prints to output file the following string\n" " encoding: name_of_input_file\n" "If standard input was used, then the name of input file is <<stdin>>.\n" "Combination with -d leads to printing 3 encodings: \n" " from->to, result: ЙНС_ЧИПДОПЗП_ЖБКМБ\n" "where 'from->to' is the recommended transform to get the file suggestively\n" "in encoding 'result'.\n" "Using -c automatically implies -s, i.e. the information on encodings\n" "is not duplicated to standard errors stream.\n" "In order to view encodings of html-files in current directory\n" "under bash in GNU type in the following one-comman-line script:\n" " for f in *.html; do xcode -c $f; done\n" "To carry out the similar action in file manager Far under Win32 (and in\n" "all other childs of Commander Norton), select files, press Ctrl-G, and\n" "type in command\n" " xcode -c !.!\n" "\n" "The following switches could be used for input " "and output encoding. \nHowever, " "automatic recognition is supported for first 5 encodings only.\n" "More information can be found at \n" " " SELF_URL_BASE "/xcode.html\n", /* msg_version */ "Program "XCODE" version %s written by D.V.Khmelev\n" "(see http://www.rusf.ru/books/yo/xcode.html for details)\n" "\n" "The author disclaims any responsibility for program\n" "safety and holds no responsibility for the loss of\n" "data, resulting the the use of the program.\n" "However, the author tried to do his best to\n" "avoid loss of data.\n", /* msg_help */ "Usage: " XCODE" -E -[hH?] -[wkaim1234567890] +[wkaim1234567890] [-q] " "[in [out]]\n" "-E -h in English (don't forget to add -h or -H switch!)\n" "-v print version information\n" "-H manual, list of 14 encodings supported, and view YO-ware license\n" "-d double recoding (try if simple '"XCODE"' failed)\n" "-q quoted-printable decoding (useful for decoding MIME-files)\n" "-l decode html Unicoded text (like Дима)\n" "-c determine encoding and print it to the output (see details by -H)\n" "-t do unix2dos transformation (convert LF to CR/LF) in DOS/Win only\n" "-p pipe mode (applies to DOS/Win environment only)\n" "-s silent mode (no information on encodings displayed)\n" "If input/output files are not specified, the standard input/output is used.\n", /* msg_out */ "-%c to set %-10s output", /* msg_forc */ "+%c to force %-10s input\n", /* msg_defl */ " (default)\n", /* msg_info */ "-%d to set %-10s output +%d to set %-10s input\n", /* msg_err_temp_file */ "Unable to create temporary file. No free space on disk?\n", /* msg_guessinp */ "Guessed input encoding: %s\n", /* msg_forceinp */ "Forced input encoding: %s\n", /* msg_outpenc */ "Output encoding: %s\n", /* msg_double_recode */ "Double recode: %s->%s, %s->%s\n", /* msg_erropenfile */ "Unable to open output file %s\n", /* msg_err_in_file */ "Unable to open input file %s\n", /* msg_cant_write_temp_file */ "Can't write to temporary file. Disk full?\n", /* msg_pipe */ "To use pipe mode run the program with option -p\n", /* msg_tryhelp */ "Try `xcode -e -h' for more information.\n", /* msg_uni_qp */ "You can not use -q and -l switches simultaneously.\n" "Try pipe 'xcode -l|xcode -q' to get desired result.\n", /* msg_conflict_force_inform */ "You can not use -c and any of -l, +[awikm] or +1, +2, ...\n" "switches simultaneously.\n", /* msg_wrong_argument */ "*** ERROR IN A PROGRAM ARGUMENT ***\n", }; char *msgs_rus[]={ /* msg_descr */ "(пУОПЧБОП ОБ РТПЗТБННЕ, ЛПФПТХА ОБРЙУБМ бОДТЕК ч. мХЛШСОПЧ 14.05.1997,\n" "Й ЛПФПТХА РПФПН РТБЧЙМЙ лЙТЙММ тПФНЙУФТПЧУЛЙК Й йЗПТШ ч. лТБУЙЛПЧ)\n" "\n" "прйубойе\n" "\n" "ьФБ РТПЗТБННБ БЧФПНБФЙЮЕУЛЙ ПРТЕДЕМСЕФ ЛПДЙТПЧЛХ ЧИПДОПЗП\n" "ДПЛХНЕОФБ Й РТЕПВТБЪХЕФ ДПЛХНЕОФ Ч ЛПДЙТПЧЛХ, чБН ОХЦОХА.\n" "чБЦОПК ПУПВЕООПУФША РТПЗТБННЩ СЧМСЕФУС ЧЪБЙНОП ПДОПЪОБЮОБС РЕТЕЛПДЙТПЧЛБ,\n" "ЛПФПТБС РТЕДПИТБОСЕФ ПФ РПЧТЕЦДЕОЙК чБЫ ЖБКМ. еУМЙ РТЕПВТБЪПЧБОЙЕ РТПЫМП\n" "ОЕЛПТТЕЛФОП, ЙМЙ ДБЦЕ ЕУМЙ ЧЩ РТЕПВТБЪПЧБМЙ ДЧПЙЮОЩК ЖБКМ, чЩ ЧУЕЗДБ НПЦЕФЕ\n" "чпууфбопчйфш ЙУИПДОЩК ЖБКМ ПВТБФОЩН РТЕПВТБЪПЧБОЙЕН (ЕУМЙ, ЛПОЕЮОП, чЩ\n" "ОЕ ЧПУРПМШЪПЧБМЙУШ ДПРПМОЙФЕМШОЩНЙ ПРГЙСНЙ -l, -q ЙМЙ -t).\n" "\n" "мйгеоъйс\n" "\n" "рТПЗТБННБ СЧМСЕФУС і-ware, йНЕООП, ЕЈ НПЦОП УЧПВПДОП ТБУРТПУФТБОСФШ\n" "НПДЙЖЙГЙТПЧБФШ, Й ДБЦЕ ДЙЪБУУЕНВМЙТПЧБФШ ЛБЛ Ч ДЧПЙЮОПН ЧЙДЕ, ФБЛ Й Ч\n" "ЙУИПДОПН ФЕЛУФЕ. пДОБЛП, ЙУРПМШЪХС ЬФХ РТПЗТБННХ, ЧЩ ДПМЦОЩ\n" "ЙУРПМШЪПЧБФШ ВХЛЧХ і ЧП ЧУЕИ ФЕЛУФБИ, ЛПФПТЩЕ ОБВЙТБЕФЕ ОБ ЛПНРШАФЕТБИ:\n" "ОБЮЙОБС У ЬМЕЛФТПООЩИ РЙУЕН Й ЪБЛБОЮЙЧБС ЛТХРОПК РТПЪБЙЮЕУЛПК ЖПТНПК.\n" "\n" "лпдщ чщипдб\n" "\n" "рТПЗТБННБ ЧЩИПДЙФ У ЛПДПН 0 ФПМШЛП РТЙ ХУМПЧЙЙ, ЮФП ПОБ\n" "ДЕКУФЧЙФЕМШОП ЧЩРПМОЙМБ ФП, ДМС ЮЕЗП РТЕДОБЪОБЮБМБУШ: РЕТЕЛПДЙТПЧБМБ\n" "ЖБКМ. чП ЧУЕИ ПУФБМШОЩИ УМХЮБСИ ЛПД ЧПЪЧТБФБ ОЕОХМЕЧПК.\n" "ч ЮБУФОПУФЙ, ЧЩДБЮБ РПДУЛБЪЛЙ ЧПЪЧТБЭБЕФ ОЕОХМЕЧПК ЛПД ERROR_HELP.\n" "пЫЙВЛЙ, УЧСЪБООЩЕ УП ЧЪБЙНПДЕКУФЧЙЕН У ПРЕТБГЙПООПК УЙУФЕНПК ЙНЕАФ\n" "ЛПД >=16. ч ВХДХЭЙИ ЧЕТУЙСИ НПЗХФ ДПВБЧМСФШУС ДТХЗЙЕ ЛПДЩ ЧЩИПДБ, ОП\n" "ФЕЛХЭЙЕ ЙЪНЕОСФШУС ОЕ ВХДХФ." "\n" " фбвмйгб лпдпч чщипдб:\n" , /* msg_encodings */ "дтхзйе ретелмаюбфемй\n" "\n" "рЕТЕЛМАЮБФЕМШ -- ПУФБОБЧМЙЧБЕФ ТБЪВПТ БТЗХНЕОФПЧ ЛПНБОДОПК УФТПЛЙ\n" "Й УМЕДХАЭЙЕ РБТБНЕФТЩ ТБУУНБФТЙЧБАФУС ХЦЕ ЛБЛ ЙНЕОБ ЖБКМПЧ.\n" "(ФБЛЙН ПВТБЪПН НПЦОП ПВТБВБФЩЧБФШ ЖБКМЩ, ОБЪЧБОЙС ЛПФПТЩИ ОБЮЙОБАФУС\n" "УП ЪОБЛБ ДЕЖЙУБ - ;)\n" "\n" "рЕТЕЛМАЮБФЕМШ -У РЕТЕЧПДЙФ xcode Ч ТЕЦЙН ЧЩДБЮЙ ЙОЖПТНБГЙЙ П ЛПДЙТПЧЛЕ\n" "ЖБКМБ. рТПЗТБННБ ФПЗДБ ЧЩДБЈФ Ч ЧЩИПДОПК ЖБКМ УФТПЛХ ЧЙДБ\n" " ЛПДЙТПЧЛБ: ЙНС_ЧИПДОПЗП_ЖБКМБ\n" "еУМЙ ЙУРПМШЪПЧБМУС УФБОДБТФОЩК ЧЧПД, ФП ЙНС ЧИПДОПЗП ЖБКМБ <<stdin>>.\n" "рТЙ ЛПНВЙОЙТПЧБОЙЙ У -d ЧЩДБЈФУС 3 ЛПДЙТПЧЛЙ: \n" " from->to, result: ЙНС_ЧИПДОПЗП_ЖБКМБ\n" "ЗДЕ from->to --- ТЕЛПНЕОДХЕНПЕ РТЕПВТБЪПЧБОЙЕ, ЮФПВЩ РПМХЮЙФШ ЖБКМ\n" "РТЕДРПМПЦЙФЕМШОП Ч ЛПДЙТПЧЛЕ result.\n" "йУРПМШЪПЧБОЙЕ РЕТЕЛМАЮБФЕМС -c РТЙЧПДЙФ Л ЧЛМАЮЕОЙА РЕТЕЛМАЮБФЕМС -s,\n" "Ф.Е. ЙОЖПТНБГЙС П ЛПДЙТПЧЛБИ Ч РПФПЛ ПЫЙВПЛ ОЕ ДХВМЙТХЕФУС.\n" "дМС РТПУНПФТБ ЙОЖПТНБГЙЙ П ЛПДЙТПЧЛЕ html-ЖБКМПЧ Ч ФЕЛХЭЕК ДЙТЕЛФПТЙЙ\n" "РПД bash Ч GNU ОБВЕТЙФЕ УМЕДХАЭЙК УЛТЙРФ Ч ЛПНБОДОПК УФТПЛЕ:\n" " for f in *.html; do xcode -c $f; done\n" "дМС ЧЩРПМОЕОЙС БОБМПЗЙЮОПК ЪБДБЮЙ Ч ЖБКМПЧПН НЕОЕДЦЕТЕ Far РПД Win32\n" "(Й РТПЮЙИ ДЕФСИ ЛПНБОДЙТБ оПТФПОБ), ЧЩДЕМЙФЕ ЖБКМЩ, ОБЦНЙФЕ Ctrl-G Й\n" "ОБВЕТЙФЕ ЛПНБОДХ\n" " xcode -c !.!\n" "\n" "уМЕДХАЭЙНЙ РЕТЕЛМАЮБФЕМСНЙ НПЦОП ХУФБОПЧЙФШ ЧИПДОХА Й ЧЩИПДОХА " "ЛПДЙТПЧЛЙ. \nпДОБЛП, " "БЧФПНБФЙЮЕУЛПЕ ПРТЕДЕМЕОЙЕ ЛПДЙТПЧЛЙ ТБВПФБЕФ ФПМШЛП ДМС РЕТЧЩИ 5.\n" "дБМШОЕКЫХА ЙОЖПТНБГЙА УН. ОБ УФТБОЙГЕ \n" " " SELF_URL_BASE "/xcode.html\n", /* msg_version */ "рТПЗТБННХ "XCODE" ЧЕТУЙС %s ОБРЙУБМ д.ч.иНЕМЈЧ\n" "(РПДТПВОПУФЙ УН. http://www.rusf.ru/books/yo/xcode.html)\n" "\n" "бЧФПТ ЧПЪДЕТЦЙЧБЕФУС ПФ ЧУСЮЕУЛЙИ ЗБТБОФЙК\n" "ОБДЈЦОПУФЙ РТПЗТБННЩ Й УОЙНБЕФ У УЕВС \n" "ПФЧЕФУФЧЕООПУФШ ЪБ ЧПЪНПЦОХА РПФЕТА ДБООЩИ РТЙ ЕЈ\n" "ЙУРПМШЪПЧБОЙЙ. фЕН ОЕ НЕОЕЕ, БЧФПТ РПУФБТБМУС\n" "УДЕМБФШ ЧУЈ ЧПЪНПЦОПЕ, ЮФПВЩ РПФЕТЙ ДБООЩИ НПЦОП\n" "ВЩМП ЙЪВЕЦБФШ.\n", /* msg_help */ "чЩЪПЧ: " XCODE" -E -[hH?] -[wkaim1234567890] +[wkaim1234567890] [-q] " "[in [out]]\n" "-E -h in English (don't forget to add -h or -H switch!)\n" "-v ЙОЖПТНБГЙС П ЧЕТУЙЙ\n" "-H рПМОБС УРТБЧЛБ, УРЙУПЛ 14 РПДДЕТЦЙЧБЕНЩИ ЛПДЙТПЧПЛ Й МЙГЕОЪЙС і-ware\n" "-d ДЧПКОБС РЕТЕЛПДЙТПЧЛБ (РТПВХКФЕ, ЕУМЙ РТПУФП ЛПНБОДБ '"XCODE"' ОЕ УТБВПФБМБ)\n" "-q ДЕЛПДЙТПЧБОЙЕ \"quoted-pritable\" УЙНЧПМПЧ, ЙУРПМШЪХЕНЩИ Ч MIME\n" "-l ДЕЛПДЙТПЧБОЙЕ html-хОЙЛПД ФЕЛУФБ (ЧТПДЕ Дима)\n" "-c ПРТЕДЕМЙФШ ЛПДЙТПЧЛХ Й ЧЩДБФШ ЕЈ Ч ЧЩИПДОПК ЖБКМ (РПДТПВОБС УРТБЧЛБ РП -H)\n" "-t РТПЙЪЧЕУФЙ unix2dos РТЕПВТБЪПЧБОЙЕ (РТЕЧТБФЙФШ LF Ч CR/LF) Ч DOS/WIN\n" "-p ТЕЦЙН ФТХВЩ (ФТЕВХЕФУС ФПМШЛП Ч DOS/Win ПЛТХЦЕОЙЙ)\n" "-s ТЕЦЙН silent --- ОЕ ЧЩЧПДЙФШ ЙОЖПТНБГЙА П ЛПДЙТПЧЛБИ\n" "еУМЙ ЧИПДОПК/ЧЩИПДОПК ЖБКМ ОЕ ХЛБЪБО, ЙУРПМШЪХЕФУС УФБОДБТФОЩК ЧЧПД/ЧЩЧПД.\n", /* msg_out */ "-%c ЧЩЧПДЙН Ч ЛПДЙТПЧЛЕ %-10s ", /* msg_forc */ "+%c ОБ ЧИПДЕ ЛПДЙТПЧЛБ %-10s \n", /* msg_defl */ " (РП ХНПМЮБОЙА) \n", /* msg_info */ "-%d ЧЩЧПД Ч ЛПДЙТПЧЛЕ %-10s +%d ЧИПДОБС ЛПДЙТПЧЛБ %-10s\n", /* msg_err_temp_file */ "оЕ НПЗХ УПЪДБФШ ЧТЕНЕООЩК ЖБКМ. оЕФ НЕУФБ ОБ ДЙУЛЕ?\n", /* msg_guessinp */ "хЗБДБОБ ЧИПДОБС ЛПДЙТПЧЛБ %s\n", /* msg_forceinp */ "ч ЛБЮЕУФЧЕ ЧИПДОПК ХУФБОПЧМЕОБ ЛПДЙТПЧЛБ %s\n", /* msg_outpenc */ "чЩИПДОБС ЛПДЙТПЧЛБ %s\n", /* msg_double_recode */ "дЧПКОБС РЕТЕЛПДЙТПЧЛБ: %s->%s, %s->%s\n", /* msg_erropenfile */ "оЕ НПЗХ ПФЛТЩФШ ЧЩИПДОПК ЖБКМ %s\n", /* msg_err_in_file */ "оЕ НПЗХ ПФЛТЩФШ ЧИПДОПК ЖБКМ %s\n", /* msg_cant_write_temp_file */ "оЕ НПЗХ РЙУБФШ ЧП ЧТЕНЕООЩК ЖБКМ. дЙУЛ РПМПО?\n", /* msg_pipe */ "дМС ЙУРПМШЪПЧБОЙС Ч ТЕЦЙНЕ ФТХВЩ ЪБРХУФЙФЕ РТПЗТБННХ У ПРГЙЕК -p\n", /* msg_tryhelp */ "рПРТПВХКФЕ ЪБРХУФЙФШ `"XCODE" -h' ДМС УРТБЧЛЙ РП РТПЗТБННЕ.\n", /* msg_uni_qp */ "оЕМШЪС ЙУРПМШЪПЧБФШ РЕТЕЛМАЮБФЕМЙ -q Й -l УПЧНЕУФОП.\n" "чПУРПМШЪХКФЕУШ ФТХВПК 'xcode -l|xcode -q' ДМС РПМХЮЕОЙС ЦЕМБЕНПЗП ТЕЪХМШФБФБ.\n", /* msg_conflict_force_inform */ "оЕДПРХУФЙНП ЙУРПМШЪПЧБОЙЕ ЛМАЮБ -c УПЧНЕУФОП У МАВЩН\n" "ЙЪ ЛМАЮЕК -l, +[awikm], +1, +2, ...\n", /* msg_wrong_argument */ "*** пыйвлб ч бтзхнеофе ртпзтбннщ ***\n", }; typedef enum{msg_descr, msg_encodings,msg_version,msg_help,msg_out, msg_forc,msg_defl,msg_info, msg_err_temp_file, msg_guessinp, msg_forceinp, msg_outpenc, msg_double_recode, msg_erropenfile,msg_err_in_file, msg_cant_write_temp_file, msg_pipe, msg_tryhelp,msg_uni_qp, msg_conflict_force_inform, msg_wrong_argument, msg_last} msg_id; char *msg(msg_id id){ assert(id<msg_last); if(Russian) return _rec(msgs_rus[id]); return _rec(msgs_eng[id]); } void print_version(void){ char *r; strcpy(VERSION,VERSIONR+11); r=strchr(VERSION,' '); *r=0; printf(msg(msg_version),VERSION); exit(ERROR_VERSION); } void print_short_help(void){ int j; printf(msg(msg_help)); for(j=0;j<NUMCOD;j++){ printf(msg(msg_out),encLetter[j], encoding_name[j]); if(j!=enc) printf("\n"); else printf(msg(msg_defl)); } for(j=0;j<NUMCOD;j++){ printf(msg(msg_forc),encLetter[j], encoding_name[j]); } } #define _STR(x) #x #define _XSTR(x) _STR(x) #define err(x) printf(" %2d %s\n",x,_XSTR(x)) void print_long_help(void){ int j; print_short_help(); printf(msg(msg_descr)); err(ERROR_OK); err(ERROR_VERSION); err(ERROR_HELP); err(ERROR_WRONG_ARGUMENT); err(ERROR_INFORM_ENCODING); err(ERROR_STAT_FILE); err(ERROR_OPEN_FILE_READ); err(ERROR_OPEN_FILE_WRITE); err(ERROR_WRITE_FILE); printf("\n"); printf(msg(msg_encodings)); for(j=0;j<TOTAL_ENCODING_NUMBER;j++){ printf(msg(msg_info), j+1,encoding_name[j],j+1,encoding_name[j]); } } #undef err unsigned char to_koi_recode_table[NUMCOD][128]={ { //dos 225,226,247,231,228,229,246,250,233,234,235,236,237,238,239,240, 242,243,244,245,230,232,227,254,251,253,255,249,248,252,224,241, 193,194,215,199,196,197,214,218,201,202,203,204,205,206,207,208, 128,129,130,131,132,133,134,135,136,137,186,139,140,141,142,143, 144,145,146,147,148,149,150,151,152,153,154,191,156,157,158,159, 160,161,162,176,164,165,166,167,168,169,170,171,172,173,174,175, 210,211,212,213,198,200,195,222,219,221,223,217,216,220,192,209, 179,163,'+','+','+','+','+','+',184,'+','+','+','+','+',190,' ' }, { //win '+','+', 39,'+', 34,'+','+','+','+','+','+', 39,'+','+','+','+', '+', 39, 39, 34, 34,'+','+','-','-','*','+', 39,'+','+','+','+', ' ','+','I','+','+','+','+','+',179,188,'E', 34,'+','+','*','I', 184,'+','i',199,'*','*','*','*',163,'N','e', 34,'j','S','s','i', 225,226,247,231,228,229,246,250,233,234,235,236,237,238,239,240, 242,243,244,245,230,232,227,254,251,253,255,249,248,252,224,241, 193,194,215,199,196,197,214,218,201,202,203,204,205,206,207,208, 210,211,212,213,198,200,195,222,219,221,223,217,216,220,192,209 }, { //koi8 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167,168,169,170,171,172,'-',174,175, 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 }, { //iso '+','+','+','+','+','+','+','+','+','+','+','+','+','+','+','+', '+','+','+','+','+','+','+','+','+','+','+','+','+','+','+','+', '*',179,'*','*','*','*','*','*','*','*','*','*','*','*','*','*', 225,226,247,231,228,229,246,250,233,234,235,236,237,238,239,240, 242,243,244,245,230,232,227,254,251,253,255,249,248,252,224,241, 193,194,215,199,196,197,214,218,201,202,203,204,205,206,207,208, 210,211,212,213,198,200,195,222,219,221,223,217,216,220,192,209, '*',163,'*','*','*','*','*','*','*','*','*','*','*','*','*','*' }, { //mac 225,226,247,231,228,229,246,250,233,234,235,236,237,238,239,240, 242,243,244,245,230,232,227,254,251,253,255,249,248,252,224,241, '*',184,'*','*','*','*','*','I','*','*','*','*','*','*','*','*', '*',179,177,178,'i','*',199,'J','E','e','I','i','*','*','*','*', 'j','S','*','*','f','*','*','*','*','*','*','*','*','*','*','s', '-','-', 34, 34, 39, 39,'*', 39,'*','*','*','*','N',163,179,209, 193,194,215,199,196,197,214,218,201,202,203,204,205,206,207,208, 210,211,212,213,198,200,195,222,219,221,223,217,216,220,192,'*' } }; int letter_frequency[32]= { 125,1606,331,65,598,1714,22,356,168,1312,206,636,1050,658,1295,2259, 544,447,887,1049,1217,572,200,823,398,400,355,168,67,78,285,4 }; int work_recode_table[256]; // Added by KIV // Yes, we have Quoted-Printable... // Disabled by Dima Khmelev // No, no Quoted-Printable (very annoying when recode html files) int hasQP = 0; int getQP(int first, int second) { if (!isdigit(first)) first = toupper(first) - 'A' + 1 +'9'; if (!isdigit(second)) second = toupper(second) - 'A' + 1 +'9'; return (first-'0')*16 + (second-'0'); } int fput_recode_table[256]; unsigned long input_freq[256]; void fput_and_value_c(int c, FILE*f){ int i; input_freq[c]++; if(putc(fput_recode_table[c],f)==EOF){ fprintf(stderr,msg(msg_cant_write_temp_file)); fclose(f); exit(ERROR_WRITE_FILE); } } int compute_rating(unsigned long * input_freq, double*bestrating){ int c,i,j; double rating[NUMCOD]; int decide[NUMCOD]; for(i=0;i<NUMCOD;i++){ rating[i]=0; decide[i]=1; } for(c=128;c<256;c++) for(i=0; i<NUMCOD; i++) if(to_koi_recode_table[i][c-128]>=192) rating[i]+=(0.0+input_freq[c]) *letter_frequency[((int)to_koi_recode_table[i][c-128]-192)%32]; for(i=0; i<NUMCOD; i++) for(j=0; j<NUMCOD; j++) if(i!=j && rating[i]<rating[j]) decide[i]=0; for(i=NUMCOD-1; i>=0; i--) if(decide[i]){ if(bestrating) *bestrating=rating[i]; return i; } return 0; } void compute_rating_two(unsigned long * input_freq, int resenc, int *res_recode_table, int *res_fr,int *res_to,int *res_a){ int c,from,to,b_from,b_to,j; double rating[NUMCOD][NUMCOD]; int a[NUMCOD][NUMCOD]; static int wt[256]; static int wt1[256]; static unsigned long in_freq[256]; for(from=0;from<NUMCOD;from++){ for(to=0;to<NUMCOD;to++){ if(from==to){continue;} fill_recode_table(wt,from,to); for(j=0;j<256;j++) in_freq[wt[j]]=input_freq[j]; a[from][to]=compute_rating(in_freq,&(rating[from][to])); } } b_from=0,b_to=1; for(from=0;from<NUMCOD;from++) for(to=0;to<NUMCOD;to++) if((from!=to)&&(rating[b_from][b_to]<rating[from][to])) b_from=from, b_to=to; fill_recode_table(wt,b_from,b_to); fill_recode_table(wt1,a[b_from][b_to],resenc); for(j=0;j<256;j++){res_recode_table[j]=wt1[wt[j]];} *res_fr=b_from; *res_to=b_to; *res_a=a[b_from][b_to]; } void read_qp(FILE*in,FILE*out){ enum {scan, eq, dig} state; int c; int dig1; state=scan; for(;;){ c=fgetc(in); if(state==scan){ if(c==EOF){return;} if(c=='='){state=eq; continue;} fput_and_value_c(c,out); continue; } if(state==eq){ if(c==EOF){ fput_and_value_c('=', out); return;} if(isxdigit(c)){ dig1=c; state=dig; continue;} if(c=='\r'){//пВТБВПФЛБ дПУПЧУЛЙИ УФТПЛ. c=fgetc(in); if(c=='\n'){ state=scan; continue; } fput_and_value_c('=', out); fput_and_value_c('\r', out); fput_and_value_c(c, out); continue; } if(c=='\n'){state=scan; continue;} fput_and_value_c('=',out); fput_and_value_c(c,out); state=scan; continue; } if(state==dig){ if(c==EOF){ fput_and_value_c('=', out); fput_and_value_c(dig1, out); return;} if(isxdigit(c)){ int cc=getQP(dig1,c); fput_and_value_c(cc,out); state=scan; continue; } fput_and_value_c('=', out); fput_and_value_c(dig1, out); fput_and_value_c(c,out); state=scan; continue; } } } void read_unicode_html(FILE*in,FILE*out,int output_encoding){ static unsigned int is_iso_russian_letter[256]; static int recode_table[256]; static char digs[5]; enum {scan, amp, diez, dig} state; int dignum=0; int c; int i; fill_recode_table(recode_table,ISO8859_5,output_encoding); for(i=0;i<256;i++) is_iso_russian_letter[i]=0; for(i=0;encoding_alphabet[ISO8859_5][i];i++){ is_iso_russian_letter[encoding_alphabet[ISO8859_5][i]]=1; } state=scan; for(;;){ c=fgetc(in); if(state==scan){ if(c=='&'){state=amp; continue;} if(c==EOF){return;} putc(c,out); continue; } if(state==amp){ if(c=='#'){state=diez; continue;} putc('&',out); if(c==EOF){return;} putc(c,out); continue; } if(state==diez){ if(isdigit(c)){ digs[dignum++]=c; state=dig; continue; } putc('&', out); putc('#', out); if(c==EOF) return; putc(c,out); state=scan; continue; } if(state==dig){ if(isdigit(c)){ if(dignum>=4) goto dropdigs; digs[dignum++]=c; state=dig; continue; } if(c==';'){ int num; if(dignum<4) goto dropdigs; digs[dignum]=0; num=atoi(digs); if((num<0x401)||(num>0x451)) goto dropdigs; if(!is_iso_russian_letter[num-0x400+0xA0]) goto dropdigs; putc(recode_table[num-0x400+0xA0],out); dignum=0; state=scan; continue; } dropdigs: putc('&', out); putc('#', out); for(i=0;i<dignum;i++) putc(digs[i],out); dignum=0; if(c==EOF){return;} putc(c,out); state=scan; continue; } } } void read_file(FILE*in, FILE*out){ int c; while((c=fgetc(in))!=EOF) fput_and_value_c(c,out); } FILE* openout(char*outfname,FILE*out,char*wt){ if(outfname){ out=fopen(outfname,wt); if(!out){ fprintf(stderr,msg(msg_erropenfile),outfname); exit(ERROR_OPEN_FILE_WRITE); } } return out; } int do_recode(char*fname, char*outfname, int enc, int force, int chkQP, int unicode_html, int double_recode, char*wt, int samefile, int inform_encoding_only, int silent){ int c=0, a=0, i, j; int fr,to; //ЙУРПМШЪХАФУС РТЙ ДЧПКОПК РЕТЕЛПДЙТПЧЛЕ FILE *f,*out,*in; for(i=0;i<256;i++) input_freq[i]=0; # ifdef STDOUT_PROBLEM_MINGW // ч DOS/WIN32 УФБОДБТФОЩК ЧЩЧПД ПФЛТЩФ Ч ТЕЦЙНЕ text // рПЬФПНХ ФТЕВХЕФУС РЕТЕЛМАЮЕОЙЕ Ч ТЕЦЙН binary { out=fdopen(fileno(stdout),"wb"); if(out==NULL) out=stdout; in=fdopen(fileno(stdin),"rb"); if(in==NULL) in=stdin; } # else # if defined(STDOUT_PROBLEM_DOS) { setmode(fileno(stdout),O_BINARY); setmode(fileno(stdin),O_BINARY); out=stdout; in=stdin; } # else out=stdout; in=stdin; # endif //STDOUT_PROBLEM_DOS # endif //STDOUT_PROBLEM_MINGW if(fname) { in=fopen(fname,"rb"); if(!in){ fprintf(stderr,msg(msg_err_in_file),fname); return ERROR_OPEN_FILE_READ; } } fill_recode_table(fput_recode_table,0,0); if(force>=0){ fill_recode_table(fput_recode_table,force,enc); if(!silent){ if(!unicode_html){ fprintf(stderr,msg(msg_forceinp),encoding_name[force]); fprintf(stderr,msg(msg_outpenc),encoding_name[enc]); } if(unicode_html){ fprintf(stderr,msg(msg_forceinp),"html-unicode"); fprintf(stderr,msg(msg_outpenc),encoding_name[enc]); } } if(samefile){ if(NULL==(f=tmpfile())){ fprintf(stderr,msg(msg_err_temp_file)); return ERROR_OPEN_FILE_WRITE; } if(chkQP) read_qp(in,f); else if(unicode_html) read_unicode_html(in,f,enc); else read_file(in,f); fclose(in); rewind(f); out=openout(outfname,out,wt); while((c=getc(f))!=EOF){ putc(c,out); } fclose(f); fclose(out); }else { out=openout(outfname,out,wt); if(chkQP) read_qp(in,out); else if(unicode_html) read_unicode_html(in,out,enc); else read_file(in,out); fclose(in); fclose(out); } return ERROR_OK; } f=tmpfile(); if(f==NULL){ fprintf(stderr,msg(msg_err_temp_file)); return ERROR_OPEN_FILE_WRITE; } if(chkQP) read_qp(in,f); else read_file(in,f); fclose(in); if(double_recode){ compute_rating_two(input_freq,enc,work_recode_table,&fr,&to,&a); if(!silent){ fprintf(stderr,msg(msg_double_recode),encoding_name[fr],encoding_name[to], encoding_name[a],encoding_name[enc]); } }else{ a=compute_rating(input_freq,NULL); if(!silent){ fprintf(stderr,msg(msg_guessinp),encoding_name[a]); fprintf(stderr,msg(msg_outpenc),encoding_name[enc]); } fill_recode_table(work_recode_table,a,enc); } rewind(f); out=openout(outfname,out,wt); if(inform_encoding_only){ char *displayfname=fname?fname:"<<stdin>>"; if(double_recode) fprintf(out, "%s->%s, %s: %s\n", encoding_name[fr],encoding_name[to], encoding_name[a], displayfname); else fprintf(out, "%s: %s\n", encoding_name[a], displayfname); fclose(f); fclose(out); return ERROR_INFORM_ENCODING; } while((c=getc(f))!=EOF){ putc(work_recode_table[c],out); } fclose(f); fclose(out); return ERROR_OK; } int samebuf(struct stat *a,struct stat *b){ return (a->st_size==b->st_size) && (a->st_mtime==b->st_mtime); } int main(int argc,char ** argv) { char *wt="wb"; int force=-1; int chkQP=0; int samefile; int do_pipe=0; int inform_encoding_only=0; int silent=0; int double_recode=0; char *filename; char *outfname; int version=0,help=0,Help=0; int unicode_html=0; int I=0; determine_self_encoding(argv[0]); for(I=1;argc>I&& (*argv[I]=='+'||*argv[I]=='-' # ifdef D_ALT ||*argv[I]=='/' # endif //D_ALT );I++) { if(isdigit(argv[I][1])){ int code; if(sscanf(argv[I]+1,"%d",&code)!=1){ printf(msg(msg_wrong_argument)); print_short_help(); return ERROR_WRONG_ARGUMENT; } if((code<1)||(code>TOTAL_ENCODING_NUMBER)){ printf(msg(msg_wrong_argument)); print_short_help(); return ERROR_WRONG_ARGUMENT; } if(*argv[I]=='+') force=code-1; else enc=code-1; continue; } switch(argv[I][1]) { default: help=2; printf(msg(msg_wrong_argument)); goto exit_commad_line_parser; case 'e': case 'E': Russian=0; break; case 'v': version=1; break; case 'h': case '?': help=1; break; case 'H': Help=1; break; case 't': wt="wt"; break; case 'p': do_pipe=1; break; case 's': silent=1; break; case 'l': unicode_html=1; break; case 'd': double_recode=1; break; case 'c': inform_encoding_only=1; silent=1; break; case 'a': case 'A': if(*argv[I]=='+') force=0; else enc=0; break; case 'w': case 'W': if(*argv[I]=='+') force=1; else enc=1; break; case 'k': case 'K': if(*argv[I]=='+') force=2; else enc=2; break; case 'i': case 'I': if(*argv[I]=='+') force=3; else enc=3; break; case 'm': case 'M': if(*argv[I]=='+') force=4; else enc=4; break; case 'q': case 'Q': chkQP = 1; break; /* рП ПРГЙЙ -- РТЕЛТБЭБЕН УЛБОЙТПЧБФШ УРЙУПЛ БТЗХНЕОФПЧ */ case '-': if(strcmp(argv[I],"--")==0) I++; else { printf(msg(msg_wrong_argument)); help=2; } goto exit_commad_line_parser; } if(argv[I][2]) help=2; } exit_commad_line_parser: if(help) { print_short_help(); if(help==1) return ERROR_HELP; else return ERROR_WRONG_ARGUMENT; } if(Help) { print_long_help(); if(help==1) return ERROR_HELP; else return ERROR_WRONG_ARGUMENT; } if(version) print_version(); if(unicode_html&&chkQP){ fprintf(stderr,msg(msg_uni_qp)); return ERROR_WRONG_ARGUMENT; } if(unicode_html) force=ISO8859_5; if(inform_encoding_only&&(force>=0)){ fprintf(stderr,msg(msg_conflict_force_inform)); return ERROR_WRONG_ARGUMENT; } if (I + 2 < argc) { print_short_help(); } else if(I == argc){ # ifdef D_ALT if(!do_pipe){ fprintf(stderr,msg(msg_pipe)); fprintf(stderr,msg(msg_tryhelp)); return ERROR_HELP; } # endif filename=NULL; outfname=NULL; samefile=0; }else if (I + 1 == argc) { filename=argv[I]; outfname=NULL; samefile=0; }else if (I + 2 == argc) { struct stat inbuf; struct stat outbuf; filename=argv[I]; outfname=argv[I+1]; if(stat(filename,&inbuf)<0){ perror(filename); return ERROR_STAT_FILE; } if(stat(outfname,&outbuf)<0) samefile=0; else samefile=samebuf(&inbuf,&outbuf); } return do_recode(filename,outfname, enc,force,chkQP,unicode_html,double_recode,wt, samefile,inform_encoding_only,silent); }