LibRCC
Macros | Enumerations | Functions | Variables
rcc-recode.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <locale.h>
#include <errno.h>
#include "config.h"
#include <librcc.h>

Macros

#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
 

Macro Definition Documentation

◆ RCC_OPTION_TRANSLATE_SKIP_PARENT

#define RCC_OPTION_TRANSLATE_SKIP_PARENT   RCC_OPTION_TRANSLATE_SKIP_PARRENT

Enumeration Type Documentation

◆ Modes

enum Modes
Enumerator
MODE_STDIN 
MODE_DIRECTORY 
MODE_FILE 
MODE_FILELIST 
53 {
54 MODE_STDIN = 0x1000,
58} Modes;
Modes
Definition: rcc-recode.c:53
@ MODE_FILE
Definition: rcc-recode.c:56
@ MODE_STDIN
Definition: rcc-recode.c:54
@ MODE_FILELIST
Definition: rcc-recode.c:57
@ MODE_DIRECTORY
Definition: rcc-recode.c:55

◆ Options

enum Options
Enumerator
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 
62 {
63 OPT_CONFIG = 'c',
64 OPT_ENCODING_IN = 'e',
65 OPT_FROM = 'f',
66 OPT_HELP = 'h',
67 OPT_LANGUAGE_IN = 'l',
68 OPT_TO = 't',
69 OPT_YES = 'y',
79} Options;
Options
Definition: rcc-recode.c:62
@ OPT_ENCODING_OUT
Definition: rcc-recode.c:70
@ OPT_CONFIG
Definition: rcc-recode.c:63
@ OPT_YES
Definition: rcc-recode.c:69
@ OPT_TO
Definition: rcc-recode.c:68
@ OPT_OFFLINE
Definition: rcc-recode.c:76
@ OPT_LANGUAGE_OUT
Definition: rcc-recode.c:71
@ OPT_ENCODING_IN
Definition: rcc-recode.c:64
@ OPT_TRANSLATION
Definition: rcc-recode.c:72
@ OPT_SUBDIRS
Definition: rcc-recode.c:78
@ OPT_TIMEOUT
Definition: rcc-recode.c:77
@ OPT_HELP
Definition: rcc-recode.c:66
@ OPT_CACHE
Definition: rcc-recode.c:74
@ OPT_LANGUAGE_IN
Definition: rcc-recode.c:67
@ OPT_AUTODETECT
Definition: rcc-recode.c:75
@ OPT_FROM
Definition: rcc-recode.c:65
@ OPT_CACHING
Definition: rcc-recode.c:73

Function Documentation

◆ Directory()

int Directory ( const char *  arg)
556 {
557 int err;
558 struct stat st;
559
560 DIR *dir;
561 struct dirent *entry;
562 char *res;
563 char answer;
564
565 char stmp[255];
566 char *fn, *nfn;
567
568 if (!arg) arg = ".";
569
570 printf("Processing directory: %s\n", arg);
571
572 dir = opendir(arg);
573 if (!dir) {
574 fprintf(stderr, "*** Failed to process directory: %s\n", arg);
575 return -1;
576 }
577
578 entry = readdir(dir);
579 while (entry) {
580 if (entry->d_name[0] == '.') {
581 entry = readdir(dir);
582 continue;
583 }
584
585 res = Translate(entry->d_name);
586 if (res) {
587 if (strcmp(res, entry->d_name)) {
588 if (ask) {
589 printf("Rename \"%s\" to \"%s\" (y/[n]) ", entry->d_name, res);
590 scanf("%c", &answer);
591 if (answer != '\n') fgets(stmp, 255, stdin);
592 answer = ((answer=='y')||(answer=='Y'))?1:0;
593 } else {
594 answer = 1;
595 }
596
597 if (answer) {
598 fn = Fullname(arg, entry->d_name);
599 nfn = Fullname(arg, res);
600 if ((fn)&&(nfn)) {
601 if (!lstat(nfn, &st)) {
602 if (!ask) {
603 printf("Trying rename \"%s\" to \"%s\"\n", entry->d_name, res);
604 }
605
606 if (S_ISDIR(st.st_mode)) {
607 printf("*** Directory with that name exists, skipping\n");
608 answer = 0;
609 } else {
610 printf("*** File exists, overwrite (y/[n]) ");
611 scanf("%c", &answer);
612 if (answer != '\n') fgets(stmp, 255, stdin);
613 answer = ((answer=='y')||(answer=='Y'))?1:0;
614 }
615 }
616 if (answer) {
617 err = rename(fn, nfn);
618 }
619 } else err = ENOMEM;
620
621 if (fn) free(fn);
622 if (nfn) free(nfn);
623
624 if (err) {
625 printf("*** Renaming \"%s\" to \"%s\" is failed (errno: %u)\n", entry->d_name, res, errno);
626 } else if (!ask) {
627 printf("Rename completed: \"%s\" to \"%s\"\n", entry->d_name, res);
628 }
629 }
630 }
631 free(res);
632 }
633 entry = readdir(dir);
634 }
635 closedir(dir);
636
637 if (process_subdirs) {
638 dir = opendir(arg);
639 if (!dir) return 0;
640
641 entry = readdir(dir);
642 while (entry) {
643 if (entry->d_name[0] == '.') {
644 entry = readdir(dir);
645 continue;
646 }
647
648 fn = Fullname(arg, entry->d_name);
649 if (fn) {
650 if ((!lstat(fn, &st))&&((S_ISDIR(st.st_mode)))) {
651 Directory(fn);
652 }
653 free(fn);
654 }
655 entry = readdir(dir);
656 }
657 closedir(dir);
658 }
659
660
661 return 0;
662}
int Directory(const char *arg)
Definition: rcc-recode.c:556
char * Fullname(const char *path, const char *name)
Definition: rcc-recode.c:541
char * Translate(const char *source)
Definition: rcc-recode.c:664

References Translate().

◆ Fullname()

char * Fullname ( const char *  path,
const char *  name 
)
541 {
542 char *res;
543
544 res = (char*)malloc(strlen(path) + strlen(name) + 2);
545 if (res) {
546 if (path[strlen(path)-1] == '/')
547 sprintf(res, "%s%s",path,name);
548 else
549 sprintf(res, "%s/%s",path,name);
550 }
551 return res;
552}

◆ GetClass()

rcc_class_id GetClass ( const char *  name)
195 {
196 int i;
197
198 for (i = 1; classes[i].name; i++) {
199 if ((!strcasecmp(name, classes[i].name))||(!strcasecmp(name, classes[i].fullname)))
200 return i;
201 }
202 return (rcc_class_id)-1;
203}
int rcc_class_id
Definition: librcc.h:75
const char * name
Definition: librcc.h:369

◆ main()

int main ( int  argc,
char *  argv[] 
)
218 {
219 rcc_language_id language_id, current_language_id, english_language_id;
220
221 unsigned char c;
222
223 char *arg = NULL;
224
225 char *config_name = NULL;
226 char *cache_name = NULL;
227
228 char *from = "in";
229 char *to = "out";
230
231 unsigned char from_forced = 0;
232 unsigned char to_forced = 0;
233
234 char *lfrom = NULL;
235 char *lto = NULL;
236
238
239 int ldetect = 0;
240 int ldetect_all = 0;
241 int ldetect_force = 0;
242
243 unsigned long timeout = 0;
244 char offline = 0;
245
246 int option_index = 0;
247 while ((c = getopt_long(argc, argv, "yhe:f:l:t:", long_options, &option_index)) != (unsigned char)-1) {
248 switch (c) {
249 case 0:
250 break;
251 case OPT_HELP:
252 Usage(argc, argv);
253 exit(0);
254 break;
255 case OPT_CONFIG:
256 config_name = optarg;
257 break;
258 case OPT_CACHE:
259 cache_name = optarg;
260 case OPT_FROM:
261 from_forced = 1;
262 from = optarg;
263 break;
264 case OPT_TO:
265 to_forced = 1;
266 to = optarg;
267 break;
268 case OPT_ENCODING_IN:
269 efrom = optarg;
270 break;
271 case OPT_ENCODING_OUT:
272 eto = optarg;
273 break;
274 case OPT_LANGUAGE_IN:
275 lfrom = optarg;
276/*
277 Selects main language, but for translation we can switch on
278 autodetection. Should do it manualy.
279*/
280 if (!ldetect_force) {
281 ldetect = 0;
282 ldetect_force = 1;
283 }
284
285 break;
286 case OPT_LANGUAGE_OUT:
287 lto = optarg;
288 break;
289 case OPT_TRANSLATION:
290 if (!optarg)
292 else if (!strcasecmp(optarg, "full"))
293 translate = RCC_OPTION_TRANSLATE_FULL;
294 else if (!strcasecmp(optarg, "skip_parent"))
296 else if (!strcasecmp(optarg, "skip_related"))
298 else if (!strcasecmp(optarg, "english"))
300 else if (!strcasecmp(optarg, "transliterate"))
302 else if (!strcasecmp(optarg, "off"))
303 translate = RCC_OPTION_TRANSLATE_OFF;
304 else {
305 fprintf(stderr, "*** Unknown translation mode: %s\n\n", optarg);
306 Usage(argc, argv);
307 exit(0);
308 }
309
310 if (!ldetect_force) {
311 if (!strcasecmp(optarg, "off"))
312 ldetect = 0;
313 else
314 ldetect = 1;
315 }
316 break;
317 case OPT_CACHING:
318 if (!optarg)
320 else if (!strcasecmp(optarg, "off"))
321 cache = 0;
322 else if (!strcasecmp(optarg, "use"))
324 else if (!strcasecmp(optarg, "add"))
326 else if (!strcasecmp(optarg, "replace"))
328 else {
329 fprintf(stderr, "*** Unknown caching mode: %s\n\n", optarg);
330 Usage(argc, argv);
331 exit(0);
332 }
333 break;
334 case OPT_AUTODETECT:
335 ldetect_force = 1;
336
337 if (!optarg) ldetect = 1;
338 else if (!strcasecmp(optarg, "off")) {
339 ldetect = 0;
340 ldetect_force = 1;
341 } else if (!strcasecmp(optarg, "on")) {
342 ldetect = 1;
343 ldetect_all = 0;
344 ldetect_force = 1;
345 } else if (!strcasecmp(optarg, "all")) {
346 ldetect = 1;
347 ldetect_all = 1;
348 ldetect_force = 1;
349 }
350 break;
351 case OPT_TIMEOUT:
352 timeout = atoi(optarg);
353 break;
354 case OPT_OFFLINE:
355 offline = 1;
356 break;
357 case OPT_SUBDIRS:
358 process_subdirs = 0;
359 break;
360 case OPT_YES:
361 ask = 0;
362 break;
363 default:
364 Usage(argc, argv);
365 exit(0);
366 }
367 }
368
369 if (optind < argc) {
370 if ((optind + 1) < argc) {
371 fprintf(stderr, "*** Invalid non-option arguments:\n");
372 for (;optind < argc;optind++) {
373 puts(argv[optind]);
374 }
375 fprintf(stderr, "\n\n");
376 Usage(argc,argv);
377 exit(0);
378 }
379 arg = argv[optind];
380 }
381
382 switch (mode) {
383 case MODE_DIRECTORY:
384 if (!from_forced) from = "fs";
385 if (!to_forced) to = "fs";
386 break;
387 default:
388 ;
389 }
390
391 setlocale(LC_ALL, "");
392
393
394
395 rccInit();
396 rccInitDefaultContext(NULL, 0, 0, classes, 0);
397 rccInitDb4(NULL, cache_name, 0);
398
399 if (timeout) rccSetOption(NULL, RCC_OPTION_TIMEOUT, timeout);
400
401 if (config_name) rccLoad(NULL, config_name);
402
403
405
406 if (translate != RCC_OPTION_TRANSLATE_OFF)
407 rccSetOption(NULL, RCC_OPTION_TRANSLATE, translate);
408
409 if (ldetect) {
411 if (ldetect_all) {
413 }
414 }
415
416 // DS: More checks, sometimes we can skip that.
417 if ((lfrom)||(lto)) {
418// if (lfrom) rccSetOption(NULL, RCC_OPTION_AUTODETECT_LANGUAGE, 1);
420 }
421
422#ifdef RCC_OPTION_OFFLINE
423 if (offline)
425#endif /* RCC_OPTION_OFFLINE */
426
427 if (from) {
428 source_class_id = GetClass(from);
429 if (source_class_id == (rcc_class_id)-1) {
430 rccFree();
431 fprintf(stderr, "*** Invalid source class (%s) specified\n", from);
432 exit(1);
433 }
434 }
435 if (to) {
436 target_class_id = GetClass(to);
437 if (target_class_id == (rcc_class_id)-1) {
438 rccFree();
439 fprintf(stderr, "*** Invalid target class (%s) specified\n", to);
440 exit(1);
441 }
442 }
443
444 current_language_id = rccGetCurrentLanguage(NULL);
445 english_language_id = rccGetLanguageByName(NULL, "en");
446
447 if (lfrom) {
448 source_language_id = rccGetLanguageByName(NULL, lfrom);
449 if (source_language_id == (rcc_language_id)-1) {
450 rccFree();
451 fprintf(stderr, "*** Invalid source language (%s) specified\n", lfrom);
452 exit(1);
453 }
454 } else source_language_id = current_language_id;
455
456 if (lto) {
457 target_language_id = rccGetLanguageByName(NULL, lto);
458 if (target_language_id == (rcc_language_id)-1) {
459 rccFree();
460 fprintf(stderr, "*** Invalid target language (%s) specified\n", lto);
461 exit(1);
462 }
463 } else target_language_id = current_language_id;
464
465 if (source_language_id == target_language_id) {
466 language_id = source_language_id;
467
468 if (language_id != current_language_id) {
469 if ((rccSetLanguage(NULL, language_id))||(!rccGetCurrentLanguageName(NULL))) {
470 rccFree();
471 fprintf(stderr, "*** Unable to set the specified language (%s)\n", rccGetLanguageName(NULL, language_id));
472 exit(1);
473 }
474 } else {
475 // Automatic
476 if (!rccGetCurrentLanguageName(NULL)) {
477 if (current_language_id != english_language_id) {
478 language_id = english_language_id;
479 rccSetLanguage(NULL, english_language_id);
480 }
481
482 if (!rccGetCurrentLanguageName(NULL)) {
483 rccFree();
484 fprintf(stderr, "*** Default language (%s) is not configured\n", rccGetLanguageName(NULL, current_language_id));
485 exit(1);
486 }
487 }
488 }
489
490 } else {
491 language_id = (rcc_language_id)-1;
492
493 // Checking if languages are selectable
494 if ((rccSetLanguage(NULL, source_language_id))||(!rccGetCurrentLanguageName(NULL))) {
495 rccFree();
496 fprintf(stderr, "*** Unable to set source language (%s)\n", rccGetLanguageName(NULL, source_language_id));
497 exit(1);
498 }
499 if ((rccSetLanguage(NULL, target_language_id))||(!rccGetCurrentLanguageName(NULL))) {
500 rccFree();
501 fprintf(stderr, "*** Unable to set target language (%s)\n", rccGetLanguageName(NULL, target_language_id));
502 exit(1);
503 }
504 }
505
506 switch (mode) {
507 case MODE_STDIN:
508 Stdin(arg);
509 break;
510 case MODE_DIRECTORY:
511 Directory(arg);
512 break;
513 case MODE_FILE:
514 fprintf(stderr, "*** Mode (FILE) is not supported in current version\n");
515 break;
516 case MODE_FILELIST:
517 fprintf(stderr, "*** Mode (FILELIST) is not supported in current version\n");
518 break;
519 }
520
521
522 rccFree();
523
524 return 0;
525}
@ RCC_OPTION_OFFLINE
Definition: librcc.h:468
@ RCC_OPTION_TRANSLATE
Definition: librcc.h:466
@ RCC_OPTION_LEARNING_MODE
Definition: librcc.h:460
@ RCC_OPTION_AUTODETECT_LANGUAGE
Definition: librcc.h:465
@ RCC_OPTION_TIMEOUT
Definition: librcc.h:467
@ RCC_OPTION_CONFIGURED_LANGUAGES_ONLY
Definition: librcc.h:463
int rccInitDefaultContext(const char *locale_variable, unsigned int max_languages, unsigned int max_classes, rcc_class_ptr defclasses, rcc_init_flags flags)
const char * rccGetCurrentLanguageName(rcc_context ctx)
#define RCC_OPTION_LEARNING_FLAG_LEARN
Definition: librcc.h:445
const char * rccGetLanguageName(rcc_context ctx, rcc_language_id language_id)
@ RCC_OPTION_TRANSLATE_TO_ENGLISH
Definition: librcc.h:450
@ RCC_OPTION_TRANSLATE_OFF
Definition: librcc.h:448
@ RCC_OPTION_TRANSLATE_SKIP_RELATED
Definition: librcc.h:451
@ RCC_OPTION_TRANSLATE_FULL
Definition: librcc.h:453
@ RCC_OPTION_TRANSLATE_TRANSLITERATE
Definition: librcc.h:449
int rccInit()
int rccLoad(rcc_context ctx, const char *name)
int rccSetLanguage(rcc_context ctx, rcc_language_id language_id)
int rccSetOption(rcc_context ctx, rcc_option option, rcc_option_value value)
int rccInitDb4(rcc_context ctx, const char *name, rcc_db4_flags flags)
#define RCC_OPTION_LEARNING_FLAG_USE
Definition: librcc.h:441
rcc_language_id rccGetCurrentLanguage(rcc_context ctx)
unsigned char rcc_language_id
Definition: librcc.h:43
void rccFree()
rcc_language_id rccGetLanguageByName(rcc_context ctx, const char *name)
int mode
Definition: rcc-recode.c:60
rcc_class_id GetClass(const char *name)
Definition: rcc-recode.c:195
#define RCC_OPTION_TRANSLATE_SKIP_PARENT
Definition: rcc-recode.c:50
void Usage(int argc, char *argv[])
Definition: rcc-recode.c:107
int Stdin(const char *arg)
Definition: rcc-recode.c:528

References RCC_OPTION_LEARNING_FLAG_USE.

◆ Stdin()

int Stdin ( const char *  arg)
528 {
529 char *res;
530 char buf[16384];
531
532 while (fgets(buf,16384,stdin)) {
533 res = Translate(buf);
534 fprintf(stdout, res?res:buf);
535 if (res) free(res);
536 }
537
538 return 0;
539}

References Translate().

◆ Translate()

char * Translate ( const char *  source)
664 {
665 rcc_string rccstring;
666 char *recoded, *stmp;
667
668 if (strlen(source)<2) return NULL;
669
670 if (source_language_id != target_language_id) {
671 rccSetLanguage(NULL, source_language_id);
672 }
673
674 if (efrom) rccstring = rccFromCharset(NULL, efrom, source);
675 else rccstring = rccFrom(NULL, source_class_id, source);
676
677 if (!rccstring) return NULL;
678
679 if (source_language_id != target_language_id)
680 rccSetLanguage(NULL, target_language_id);
681
682 if (eto) {
683 if (translate = RCC_OPTION_TRANSLATE_OFF) {
684 stmp = rccTo(NULL, target_class_id, rccstring);
685 if (stmp) {
686 recoded = rccRecodeCharsets(NULL, "UTF-8", eto, stmp);
687 if (recoded) free(stmp);
688 else recoded = stmp;
689 } else recoded = NULL;
690
691 } else {
692 recoded = rccToCharset(NULL, eto, rccstring);
693 }
694 } else recoded = rccTo(NULL, target_class_id, rccstring);
695
696 free(rccstring);
697 return recoded;
698}
#define rccFromCharset(ctx, charset, buf)
Definition: librcc.h:1457
#define rccToCharset(ctx, charset, buf)
Definition: librcc.h:1458
char * rcc_string
Definition: librcc.h:1032
#define rccTo(ctx, class_id, buf)
Definition: librcc.h:1454
#define rccFrom(ctx, class_id, buf)
Definition: librcc.h:1453
#define rccRecodeCharsets(ctx, from, to, buf)
Definition: librcc.h:1461

Referenced by Directory(), and Stdin().

◆ Usage()

void Usage ( int  argc,
char *  argv[] 
)
107 {
108 printf(
109"Usage:\n"
110" %s [options] [mode] [file|directory]\n"
111" Modes:\n"
112" --stdin - Convert stdin to stdout\n"
113" --directory - Convert file names in specified directory\n"
114" --file - Convert specified file\n"
115" --filelist - Convert all files writed on stdin\n"
116" --help - Help message\n"
117"\n"
118" Options:\n"
119" -c <config> - Specify configuration name\n"
120" -f <class> - Source class ('in' is default)\n"
121" -t <class> - Output class ('out' is default)\n"
122" -e <enc> - Force specified source encoding (autodetection)\n"
123" -l <lang> - Force specified source language (from LC_CTYPE)\n"
124" --force-target-encoding=<enc>\n"
125" - Convert to the specified encoding\n"
126" --force-target-language=<enc>\n"
127" - Translate to the specified language\n"
128" --caching=[mode]\n"
129" - Use recodings cache. Following modes are supported\n"
130" off - Turn off\n"
131" use - Use cached values (default)\n"
132" add - Add new recodings to cache\n"
133" replace - Replace encodings in cache\n"
134" --cache=<name>\n"
135" - Use specified cache database instead of default one\n"
136" --translation=[mode]\n"
137" - Enable translation. Following modes are supported:\n"
138" full - Full\n"
139" skip_parent - Skip translation to parent lang\n"
140" skip_related - Skip translation between related langs\n"
141" english - Translate to english (default)\n"
142" transliterate - Transliterate\n"
143" --language-detection=[mode]\n"
144" - Lanuage autodetection. Following modes are supported:\n"
145" off - Current language is considered\n"
146" on - Use only configured langs (default)\n"
147" all - Try everything (slow)\n"
148" --timeout=<us>\n"
149" - Specify recoding timeout in microseconds (1s default)\n"
150"\n"
151" -y - Do not ask any question\n"
152" --disable-subdirs\n"
153" - Do not descend into the sub directories\n"
154"\n"
155" Language Relations:\n"
156" To prevent unneccesary translations the concept of related/parent languages is\n"
157" introduced. For each language you can specify a parent language.\n"
158" skip_parent translation option will turn off translation to parent language\n"
159" skip_related translation option will additionaly turn off translation from\n"
160" parent language.\n"
161"\n"
162" For example, in the default configuration Russian is parent of Ukrainian, and\n"
163" English is parent of all other languages. With \"skip_parrent\" option the\n"
164" translation from Russian to Ukrainian would be turned off, but translation\n"
165" from Ukrainian to Russian would operate. With \"skip_related\" option the\n"
166" translation in both directions would be disabled\n"
167"\n\n"
168" Language Detection:\n"
169" Current version uses aspell dictionaries to autodetect language. Therefore,\n"
170" only languages with aspell available in the system aspell dictionaries are\n"
171" autodected. Beware, if your system contains a lot of installed languages,\n"
172" the autodection may take considerable amount of time.\n"
173"\n\n",
174argv[0]);
175}

Variable Documentation

◆ mode

int mode = MODE_STDIN