#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <locale.h>
#include <errno.h>
#include "config.h"
#include <librcc.h>
Defines | |
#define | RCC_OPTION_TRANSLATE_SKIP_PARENT RCC_OPTION_TRANSLATE_SKIP_PARRENT |
Enumerations | |
enum | Modes { MODE_STDIN = 0x1000, MODE_DIRECTORY, MODE_FILE, MODE_FILELIST } |
enum | Options { OPT_CONFIG = 'c', OPT_ENCODING_IN = 'e', OPT_FROM = 'f', OPT_HELP = 'h', OPT_LANGUAGE_IN = 'l', OPT_TO = 't', OPT_YES = 'y', OPT_ENCODING_OUT, OPT_LANGUAGE_OUT, OPT_TRANSLATION, OPT_CACHING, OPT_CACHE, OPT_AUTODETECT, OPT_OFFLINE, OPT_TIMEOUT, OPT_SUBDIRS } |
Functions | |
void | Usage (int argc, char *argv[]) |
rcc_class_id | GetClass (const char *name) |
char * | Translate (const char *source) |
int | Stdin (const char *arg) |
int | Directory (const char *arg) |
int | main (int argc, char *argv[]) |
char * | Fullname (const char *path, const char *name) |
Variables | |
int | mode = MODE_STDIN |
#define RCC_OPTION_TRANSLATE_SKIP_PARENT RCC_OPTION_TRANSLATE_SKIP_PARRENT |
Referenced by main().
enum Modes |
00053 { 00054 MODE_STDIN = 0x1000, 00055 MODE_DIRECTORY, 00056 MODE_FILE, 00057 MODE_FILELIST 00058 } Modes;
enum Options |
OPT_CONFIG | |
OPT_ENCODING_IN | |
OPT_FROM | |
OPT_HELP | |
OPT_LANGUAGE_IN | |
OPT_TO | |
OPT_YES | |
OPT_ENCODING_OUT | |
OPT_LANGUAGE_OUT | |
OPT_TRANSLATION | |
OPT_CACHING | |
OPT_CACHE | |
OPT_AUTODETECT | |
OPT_OFFLINE | |
OPT_TIMEOUT | |
OPT_SUBDIRS |
00062 { 00063 OPT_CONFIG = 'c', 00064 OPT_ENCODING_IN = 'e', 00065 OPT_FROM = 'f', 00066 OPT_HELP = 'h', 00067 OPT_LANGUAGE_IN = 'l', 00068 OPT_TO = 't', 00069 OPT_YES = 'y', 00070 OPT_ENCODING_OUT, 00071 OPT_LANGUAGE_OUT, 00072 OPT_TRANSLATION, 00073 OPT_CACHING, 00074 OPT_CACHE, 00075 OPT_AUTODETECT, 00076 OPT_OFFLINE, 00077 OPT_TIMEOUT, 00078 OPT_SUBDIRS, 00079 } Options;
int Directory | ( | const char * | arg | ) |
References Fullname(), and Translate().
Referenced by main().
00556 { 00557 int err; 00558 struct stat st; 00559 00560 DIR *dir; 00561 struct dirent *entry; 00562 char *res; 00563 char answer; 00564 00565 char stmp[255]; 00566 char *fn, *nfn; 00567 00568 if (!arg) arg = "."; 00569 00570 printf("Processing directory: %s\n", arg); 00571 00572 dir = opendir(arg); 00573 if (!dir) { 00574 fprintf(stderr, "*** Failed to process directory: %s\n", arg); 00575 return -1; 00576 } 00577 00578 entry = readdir(dir); 00579 while (entry) { 00580 if (entry->d_name[0] == '.') { 00581 entry = readdir(dir); 00582 continue; 00583 } 00584 00585 res = Translate(entry->d_name); 00586 if (res) { 00587 if (strcmp(res, entry->d_name)) { 00588 if (ask) { 00589 printf("Rename \"%s\" to \"%s\" (y/[n]) ", entry->d_name, res); 00590 scanf("%c", &answer); 00591 if (answer != '\n') fgets(stmp, 255, stdin); 00592 answer = ((answer=='y')||(answer=='Y'))?1:0; 00593 } else { 00594 answer = 1; 00595 } 00596 00597 if (answer) { 00598 fn = Fullname(arg, entry->d_name); 00599 nfn = Fullname(arg, res); 00600 if ((fn)&&(nfn)) { 00601 if (!lstat(nfn, &st)) { 00602 if (!ask) { 00603 printf("Trying rename \"%s\" to \"%s\"\n", entry->d_name, res); 00604 } 00605 00606 if (S_ISDIR(st.st_mode)) { 00607 printf("*** Directory with that name exists, skipping\n"); 00608 answer = 0; 00609 } else { 00610 printf("*** File exists, overwrite (y/[n]) "); 00611 scanf("%c", &answer); 00612 if (answer != '\n') fgets(stmp, 255, stdin); 00613 answer = ((answer=='y')||(answer=='Y'))?1:0; 00614 } 00615 } 00616 if (answer) { 00617 err = rename(fn, nfn); 00618 } 00619 } else err = ENOMEM; 00620 00621 if (fn) free(fn); 00622 if (nfn) free(nfn); 00623 00624 if (err) { 00625 printf("*** Renaming \"%s\" to \"%s\" is failed (errno: %u)\n", entry->d_name, res, errno); 00626 } else if (!ask) { 00627 printf("Rename completed: \"%s\" to \"%s\"\n", entry->d_name, res); 00628 } 00629 } 00630 } 00631 free(res); 00632 } 00633 entry = readdir(dir); 00634 } 00635 closedir(dir); 00636 00637 if (process_subdirs) { 00638 dir = opendir(arg); 00639 if (!dir) return 0; 00640 00641 entry = readdir(dir); 00642 while (entry) { 00643 if (entry->d_name[0] == '.') { 00644 entry = readdir(dir); 00645 continue; 00646 } 00647 00648 fn = Fullname(arg, entry->d_name); 00649 if (fn) { 00650 if ((!lstat(fn, &st))&&((S_ISDIR(st.st_mode)))) { 00651 Directory(fn); 00652 } 00653 free(fn); 00654 } 00655 entry = readdir(dir); 00656 } 00657 closedir(dir); 00658 } 00659 00660 00661 return 0; 00662 }
char* Fullname | ( | const char * | path, | |
const char * | name | |||
) |
Referenced by Directory().
rcc_class_id GetClass | ( | const char * | name | ) |
References rcc_class_t::name.
Referenced by main().
00195 { 00196 int i; 00197 00198 for (i = 1; classes[i].name; i++) { 00199 if ((!strcasecmp(name, classes[i].name))||(!strcasecmp(name, classes[i].fullname))) 00200 return i; 00201 } 00202 return (rcc_class_id)-1; 00203 }
int main | ( | int | argc, | |
char * | argv[] | |||
) |
References Directory(), GetClass(), mode, MODE_DIRECTORY, MODE_FILE, MODE_FILELIST, MODE_STDIN, OPT_AUTODETECT, OPT_CACHE, OPT_CACHING, OPT_CONFIG, OPT_ENCODING_IN, OPT_ENCODING_OUT, OPT_FROM, OPT_HELP, OPT_LANGUAGE_IN, OPT_LANGUAGE_OUT, OPT_OFFLINE, OPT_SUBDIRS, OPT_TIMEOUT, OPT_TO, OPT_TRANSLATION, OPT_YES, RCC_OPTION_AUTODETECT_LANGUAGE, RCC_OPTION_CONFIGURED_LANGUAGES_ONLY, RCC_OPTION_LEARNING_FLAG_LEARN, RCC_OPTION_LEARNING_FLAG_USE, RCC_OPTION_LEARNING_MODE, RCC_OPTION_OFFLINE, RCC_OPTION_TIMEOUT, RCC_OPTION_TRANSLATE, RCC_OPTION_TRANSLATE_FULL, RCC_OPTION_TRANSLATE_OFF, RCC_OPTION_TRANSLATE_SKIP_PARENT, RCC_OPTION_TRANSLATE_SKIP_RELATED, RCC_OPTION_TRANSLATE_TO_ENGLISH, RCC_OPTION_TRANSLATE_TRANSLITERATE, rccFree(), rccGetCurrentLanguage(), rccGetCurrentLanguageName(), rccGetLanguageByName(), rccGetLanguageName(), rccInit(), rccInitDb4(), rccInitDefaultContext(), rccLoad(), rccSetLanguage(), rccSetOption(), Stdin(), and Usage().
00218 { 00219 rcc_language_id language_id, current_language_id, english_language_id; 00220 00221 unsigned char c; 00222 00223 char *arg = NULL; 00224 00225 char *config_name = NULL; 00226 char *cache_name = NULL; 00227 00228 char *from = "in"; 00229 char *to = "out"; 00230 00231 unsigned char from_forced = 0; 00232 unsigned char to_forced = 0; 00233 00234 char *lfrom = NULL; 00235 char *lto = NULL; 00236 00237 int cache = RCC_OPTION_LEARNING_FLAG_USE; 00238 00239 int ldetect = 0; 00240 int ldetect_all = 0; 00241 int ldetect_force = 0; 00242 00243 unsigned long timeout = 0; 00244 char offline = 0; 00245 00246 int option_index = 0; 00247 while ((c = getopt_long(argc, argv, "yhe:f:l:t:", long_options, &option_index)) != (unsigned char)-1) { 00248 switch (c) { 00249 case 0: 00250 break; 00251 case OPT_HELP: 00252 Usage(argc, argv); 00253 exit(0); 00254 break; 00255 case OPT_CONFIG: 00256 config_name = optarg; 00257 break; 00258 case OPT_CACHE: 00259 cache_name = optarg; 00260 case OPT_FROM: 00261 from_forced = 1; 00262 from = optarg; 00263 break; 00264 case OPT_TO: 00265 to_forced = 1; 00266 to = optarg; 00267 break; 00268 case OPT_ENCODING_IN: 00269 efrom = optarg; 00270 break; 00271 case OPT_ENCODING_OUT: 00272 eto = optarg; 00273 break; 00274 case OPT_LANGUAGE_IN: 00275 lfrom = optarg; 00276 /* 00277 Selects main language, but for translation we can switch on 00278 autodetection. Should do it manualy. 00279 */ 00280 if (!ldetect_force) { 00281 ldetect = 0; 00282 ldetect_force = 1; 00283 } 00284 00285 break; 00286 case OPT_LANGUAGE_OUT: 00287 lto = optarg; 00288 break; 00289 case OPT_TRANSLATION: 00290 if (!optarg) 00291 translate = RCC_OPTION_TRANSLATE_TO_ENGLISH; 00292 else if (!strcasecmp(optarg, "full")) 00293 translate = RCC_OPTION_TRANSLATE_FULL; 00294 else if (!strcasecmp(optarg, "skip_parent")) 00295 translate = RCC_OPTION_TRANSLATE_SKIP_PARENT; 00296 else if (!strcasecmp(optarg, "skip_related")) 00297 translate = RCC_OPTION_TRANSLATE_SKIP_RELATED; 00298 else if (!strcasecmp(optarg, "english")) 00299 translate = RCC_OPTION_TRANSLATE_TO_ENGLISH; 00300 else if (!strcasecmp(optarg, "transliterate")) 00301 translate = RCC_OPTION_TRANSLATE_TRANSLITERATE; 00302 else if (!strcasecmp(optarg, "off")) 00303 translate = RCC_OPTION_TRANSLATE_OFF; 00304 else { 00305 fprintf(stderr, "*** Unknown translation mode: %s\n\n", optarg); 00306 Usage(argc, argv); 00307 exit(0); 00308 } 00309 00310 if (!ldetect_force) { 00311 if (!strcasecmp(optarg, "off")) 00312 ldetect = 0; 00313 else 00314 ldetect = 1; 00315 } 00316 break; 00317 case OPT_CACHING: 00318 if (!optarg) 00319 cache = RCC_OPTION_LEARNING_FLAG_USE; 00320 else if (!strcasecmp(optarg, "off")) 00321 cache = 0; 00322 else if (!strcasecmp(optarg, "use")) 00323 cache = RCC_OPTION_LEARNING_FLAG_USE; 00324 else if (!strcasecmp(optarg, "add")) 00325 cache = RCC_OPTION_LEARNING_FLAG_USE|RCC_OPTION_LEARNING_FLAG_LEARN; 00326 else if (!strcasecmp(optarg, "replace")) 00327 cache = RCC_OPTION_LEARNING_FLAG_LEARN; 00328 else { 00329 fprintf(stderr, "*** Unknown caching mode: %s\n\n", optarg); 00330 Usage(argc, argv); 00331 exit(0); 00332 } 00333 break; 00334 case OPT_AUTODETECT: 00335 ldetect_force = 1; 00336 00337 if (!optarg) ldetect = 1; 00338 else if (!strcasecmp(optarg, "off")) { 00339 ldetect = 0; 00340 ldetect_force = 1; 00341 } else if (!strcasecmp(optarg, "on")) { 00342 ldetect = 1; 00343 ldetect_all = 0; 00344 ldetect_force = 1; 00345 } else if (!strcasecmp(optarg, "all")) { 00346 ldetect = 1; 00347 ldetect_all = 1; 00348 ldetect_force = 1; 00349 } 00350 break; 00351 case OPT_TIMEOUT: 00352 timeout = atoi(optarg); 00353 break; 00354 case OPT_OFFLINE: 00355 offline = 1; 00356 break; 00357 case OPT_SUBDIRS: 00358 process_subdirs = 0; 00359 break; 00360 case OPT_YES: 00361 ask = 0; 00362 break; 00363 default: 00364 Usage(argc, argv); 00365 exit(0); 00366 } 00367 } 00368 00369 if (optind < argc) { 00370 if ((optind + 1) < argc) { 00371 fprintf(stderr, "*** Invalid non-option arguments:\n"); 00372 for (;optind < argc;optind++) { 00373 puts(argv[optind]); 00374 } 00375 fprintf(stderr, "\n\n"); 00376 Usage(argc,argv); 00377 exit(0); 00378 } 00379 arg = argv[optind]; 00380 } 00381 00382 switch (mode) { 00383 case MODE_DIRECTORY: 00384 if (!from_forced) from = "fs"; 00385 if (!to_forced) to = "fs"; 00386 break; 00387 default: 00388 ; 00389 } 00390 00391 setlocale(LC_ALL, ""); 00392 00393 00394 00395 rccInit(); 00396 rccInitDefaultContext(NULL, 0, 0, classes, 0); 00397 rccInitDb4(NULL, cache_name, 0); 00398 00399 if (timeout) rccSetOption(NULL, RCC_OPTION_TIMEOUT, timeout); 00400 00401 if (config_name) rccLoad(NULL, config_name); 00402 00403 00404 rccSetOption(NULL, RCC_OPTION_LEARNING_MODE, cache); 00405 00406 if (translate != RCC_OPTION_TRANSLATE_OFF) 00407 rccSetOption(NULL, RCC_OPTION_TRANSLATE, translate); 00408 00409 if (ldetect) { 00410 rccSetOption(NULL, RCC_OPTION_AUTODETECT_LANGUAGE, 1); 00411 if (ldetect_all) { 00412 rccSetOption(NULL, RCC_OPTION_CONFIGURED_LANGUAGES_ONLY, 0); 00413 } 00414 } 00415 00416 // DS: More checks, sometimes we can skip that. 00417 if ((lfrom)||(lto)) { 00418 // if (lfrom) rccSetOption(NULL, RCC_OPTION_AUTODETECT_LANGUAGE, 1); 00419 rccSetOption(NULL, RCC_OPTION_CONFIGURED_LANGUAGES_ONLY, 0); 00420 } 00421 00422 #ifdef RCC_OPTION_OFFLINE 00423 if (offline) 00424 rccSetOption(NULL, RCC_OPTION_OFFLINE, 1); 00425 #endif /* RCC_OPTION_OFFLINE */ 00426 00427 if (from) { 00428 source_class_id = GetClass(from); 00429 if (source_class_id == (rcc_class_id)-1) { 00430 rccFree(); 00431 fprintf(stderr, "*** Invalid source class (%s) specified\n", from); 00432 exit(1); 00433 } 00434 } 00435 if (to) { 00436 target_class_id = GetClass(to); 00437 if (target_class_id == (rcc_class_id)-1) { 00438 rccFree(); 00439 fprintf(stderr, "*** Invalid target class (%s) specified\n", to); 00440 exit(1); 00441 } 00442 } 00443 00444 current_language_id = rccGetCurrentLanguage(NULL); 00445 english_language_id = rccGetLanguageByName(NULL, "en"); 00446 00447 if (lfrom) { 00448 source_language_id = rccGetLanguageByName(NULL, lfrom); 00449 if (source_language_id == (rcc_language_id)-1) { 00450 rccFree(); 00451 fprintf(stderr, "*** Invalid source language (%s) specified\n", lfrom); 00452 exit(1); 00453 } 00454 } else source_language_id = current_language_id; 00455 00456 if (lto) { 00457 target_language_id = rccGetLanguageByName(NULL, lto); 00458 if (target_language_id == (rcc_language_id)-1) { 00459 rccFree(); 00460 fprintf(stderr, "*** Invalid target language (%s) specified\n", lto); 00461 exit(1); 00462 } 00463 } else target_language_id = current_language_id; 00464 00465 if (source_language_id == target_language_id) { 00466 language_id = source_language_id; 00467 00468 if (language_id != current_language_id) { 00469 if ((rccSetLanguage(NULL, language_id))||(!rccGetCurrentLanguageName(NULL))) { 00470 rccFree(); 00471 fprintf(stderr, "*** Unable to set the specified language (%s)\n", rccGetLanguageName(NULL, language_id)); 00472 exit(1); 00473 } 00474 } else { 00475 // Automatic 00476 if (!rccGetCurrentLanguageName(NULL)) { 00477 if (current_language_id != english_language_id) { 00478 language_id = english_language_id; 00479 rccSetLanguage(NULL, english_language_id); 00480 } 00481 00482 if (!rccGetCurrentLanguageName(NULL)) { 00483 rccFree(); 00484 fprintf(stderr, "*** Default language (%s) is not configured\n", rccGetLanguageName(NULL, current_language_id)); 00485 exit(1); 00486 } 00487 } 00488 } 00489 00490 } else { 00491 language_id = (rcc_language_id)-1; 00492 00493 // Checking if languages are selectable 00494 if ((rccSetLanguage(NULL, source_language_id))||(!rccGetCurrentLanguageName(NULL))) { 00495 rccFree(); 00496 fprintf(stderr, "*** Unable to set source language (%s)\n", rccGetLanguageName(NULL, source_language_id)); 00497 exit(1); 00498 } 00499 if ((rccSetLanguage(NULL, target_language_id))||(!rccGetCurrentLanguageName(NULL))) { 00500 rccFree(); 00501 fprintf(stderr, "*** Unable to set target language (%s)\n", rccGetLanguageName(NULL, target_language_id)); 00502 exit(1); 00503 } 00504 } 00505 00506 switch (mode) { 00507 case MODE_STDIN: 00508 Stdin(arg); 00509 break; 00510 case MODE_DIRECTORY: 00511 Directory(arg); 00512 break; 00513 case MODE_FILE: 00514 fprintf(stderr, "*** Mode (FILE) is not supported in current version\n"); 00515 break; 00516 case MODE_FILELIST: 00517 fprintf(stderr, "*** Mode (FILELIST) is not supported in current version\n"); 00518 break; 00519 } 00520 00521 00522 rccFree(); 00523 00524 return 0; 00525 }
int Stdin | ( | const char * | arg | ) |
References Translate().
Referenced by main().
00528 { 00529 char *res; 00530 char buf[16384]; 00531 00532 while (fgets(buf,16384,stdin)) { 00533 res = Translate(buf); 00534 fprintf(stdout, res?res:buf); 00535 if (res) free(res); 00536 } 00537 00538 return 0; 00539 }
char * Translate | ( | const char * | source | ) |
References RCC_OPTION_TRANSLATE_OFF, rccFrom, rccFromCharset, rccRecodeCharsets, rccSetLanguage(), rccTo, and rccToCharset.
Referenced by Directory(), and Stdin().
00664 { 00665 rcc_string rccstring; 00666 char *recoded, *stmp; 00667 00668 if (strlen(source)<2) return NULL; 00669 00670 if (source_language_id != target_language_id) { 00671 rccSetLanguage(NULL, source_language_id); 00672 } 00673 00674 if (efrom) rccstring = rccFromCharset(NULL, efrom, source); 00675 else rccstring = rccFrom(NULL, source_class_id, source); 00676 00677 if (!rccstring) return NULL; 00678 00679 if (source_language_id != target_language_id) 00680 rccSetLanguage(NULL, target_language_id); 00681 00682 if (eto) { 00683 if (translate = RCC_OPTION_TRANSLATE_OFF) { 00684 stmp = rccTo(NULL, target_class_id, rccstring); 00685 if (stmp) { 00686 recoded = rccRecodeCharsets(NULL, "UTF-8", eto, stmp); 00687 if (recoded) free(stmp); 00688 else recoded = stmp; 00689 } else recoded = NULL; 00690 00691 } else { 00692 recoded = rccToCharset(NULL, eto, rccstring); 00693 } 00694 } else recoded = rccTo(NULL, target_class_id, rccstring); 00695 00696 free(rccstring); 00697 return recoded; 00698 }
void Usage | ( | int | argc, | |
char * | argv[] | |||
) |
Referenced by main().
00107 { 00108 printf( 00109 "Usage:\n" 00110 " %s [options] [mode] [file|directory]\n" 00111 " Modes:\n" 00112 " --stdin - Convert stdin to stdout\n" 00113 " --directory - Convert file names in specified directory\n" 00114 " --file - Convert specified file\n" 00115 " --filelist - Convert all files writed on stdin\n" 00116 " --help - Help message\n" 00117 "\n" 00118 " Options:\n" 00119 " -c <config> - Specify configuration name\n" 00120 " -f <class> - Source class ('in' is default)\n" 00121 " -t <class> - Output class ('out' is default)\n" 00122 " -e <enc> - Force specified source encoding (autodetection)\n" 00123 " -l <lang> - Force specified source language (from LC_CTYPE)\n" 00124 " --force-target-encoding=<enc>\n" 00125 " - Convert to the specified encoding\n" 00126 " --force-target-language=<enc>\n" 00127 " - Translate to the specified language\n" 00128 " --caching=[mode]\n" 00129 " - Use recodings cache. Following modes are supported\n" 00130 " off - Turn off\n" 00131 " use - Use cached values (default)\n" 00132 " add - Add new recodings to cache\n" 00133 " replace - Replace encodings in cache\n" 00134 " --cache=<name>\n" 00135 " - Use specified cache database instead of default one\n" 00136 " --translation=[mode]\n" 00137 " - Enable translation. Following modes are supported:\n" 00138 " full - Full\n" 00139 " skip_parent - Skip translation to parent lang\n" 00140 " skip_related - Skip translation between related langs\n" 00141 " english - Translate to english (default)\n" 00142 " transliterate - Transliterate\n" 00143 " --language-detection=[mode]\n" 00144 " - Lanuage autodetection. Following modes are supported:\n" 00145 " off - Current language is considered\n" 00146 " on - Use only configured langs (default)\n" 00147 " all - Try everything (slow)\n" 00148 " --timeout=<us>\n" 00149 " - Specify recoding timeout in microseconds (1s default)\n" 00150 "\n" 00151 " -y - Do not ask any question\n" 00152 " --disable-subdirs\n" 00153 " - Do not descend into the sub directories\n" 00154 "\n" 00155 " Language Relations:\n" 00156 " To prevent unneccesary translations the concept of related/parent languages is\n" 00157 " introduced. For each language you can specify a parent language.\n" 00158 " skip_parent translation option will turn off translation to parent language\n" 00159 " skip_related translation option will additionaly turn off translation from\n" 00160 " parent language.\n" 00161 "\n" 00162 " For example, in the default configuration Russian is parent of Ukrainian, and\n" 00163 " English is parent of all other languages. With \"skip_parrent\" option the\n" 00164 " translation from Russian to Ukrainian would be turned off, but translation\n" 00165 " from Ukrainian to Russian would operate. With \"skip_related\" option the\n" 00166 " translation in both directions would be disabled\n" 00167 "\n\n" 00168 " Language Detection:\n" 00169 " Current version uses aspell dictionaries to autodetect language. Therefore,\n" 00170 " only languages with aspell available in the system aspell dictionaries are\n" 00171 " autodected. Beware, if your system contains a lot of installed languages,\n" 00172 " the autodection may take considerable amount of time.\n" 00173 "\n\n", 00174 argv[0]); 00175 }