diff options
author | Suren A. Chilingaryan <csa@dside.dyndns.org> | 2005-07-14 08:45:46 +0000 |
---|---|---|
committer | Suren A. Chilingaryan <csa@dside.dyndns.org> | 2005-07-14 08:45:46 +0000 |
commit | f15620c372b8813a87d07eee169cf2096c99c173 (patch) | |
tree | f1c59f41d4a9c9f5f45595695327b0e4a74b1408 /src | |
parent | 7233ff9095194b38586ce438379f08691a0fecdd (diff) | |
download | librcc-f15620c372b8813a87d07eee169cf2096c99c173.tar.gz librcc-f15620c372b8813a87d07eee169cf2096c99c173.tar.bz2 librcc-f15620c372b8813a87d07eee169cf2096c99c173.tar.xz librcc-f15620c372b8813a87d07eee169cf2096c99c173.zip |
IConv and DB4
Diffstat (limited to 'src')
-rw-r--r-- | src/fs.c | 80 | ||||
-rw-r--r-- | src/fs.h | 8 | ||||
-rw-r--r-- | src/internal.h | 11 | ||||
-rw-r--r-- | src/librcc.c | 65 | ||||
-rw-r--r-- | src/librcc.h | 10 | ||||
-rw-r--r-- | src/lng.c | 6 | ||||
-rw-r--r-- | src/lngconfig.c | 137 | ||||
-rw-r--r-- | src/lngconfig.h | 14 | ||||
-rw-r--r-- | src/rccconfig.c | 13 | ||||
-rw-r--r-- | src/rccconfig.h | 2 | ||||
-rw-r--r-- | src/rccdb4.c | 8 | ||||
-rw-r--r-- | src/rccdb4.h | 2 | ||||
-rw-r--r-- | src/rcciconv.c | 48 | ||||
-rw-r--r-- | src/rcciconv.h | 4 | ||||
-rw-r--r-- | src/rcclocale.c | 2 | ||||
-rw-r--r-- | src/rcclocale.h | 1 | ||||
-rw-r--r-- | src/rccstring.c | 39 | ||||
-rw-r--r-- | src/rccstring.h | 4 | ||||
-rw-r--r-- | src/rccxml.c | 2 | ||||
-rw-r--r-- | src/recode.c | 104 |
20 files changed, 323 insertions, 237 deletions
@@ -48,8 +48,7 @@ static char *rccCreateFullName(const char *path, const char *filename) { static int rccIsFile(const char *filename) { struct stat st; - stat(filename,&st); - if (S_ISREG(st.st_mode)) return 1; + if ((!stat(filename,&st))&&(S_ISREG(st.st_mode))) return 1; return 0; } @@ -64,11 +63,12 @@ static char *rccCheckFile(const char *prefix, const char *name) { } /* Converts: 'filename' to 'prefix/name' using 'fspath' */ -int rccFS0(rcc_context ctx, const char *fspath, const char *filename, char **prefix, char **name) { +int rccFS0(rcc_language_config config, const char *fspath, const char *filename, char **prefix, char **name) { FILE *mtab; struct mntent *fsentry; const char *tmp = NULL; size_t len; + char *lastprefix; if (fspath) { len = strlen(fspath); @@ -76,9 +76,11 @@ int rccFS0(rcc_context ctx, const char *fspath, const char *filename, char **pre if (!strncmp(filename, fspath, len)) tmp = filename + strlen(fspath); } else { + lastprefix = config->ctx->lastprefix; + /* only required with non-english mount directories */ - len = strlen(ctx->lastprefix); - if ((len)&&(!strncmp(filename, ctx->lastprefix, len))) { + len = strlen(lastprefix); + if ((len)&&(!strncmp(filename, lastprefix, len))) { tmp = filename + len; } @@ -89,10 +91,10 @@ int rccFS0(rcc_context ctx, const char *fspath, const char *filename, char **pre fsentry = getmntent(mtab); if ((fsentry)&&(fsentry->mnt_dir)) { len = strlen(fsentry->mnt_dir); - if (len) { + if (len > 1) { if (!strncmp(filename, fsentry->mnt_dir, len)) { tmp = filename + len; - if (len<RCC_MAX_PREFIX_CHARS) strcpy(ctx->lastprefix, fsentry->mnt_dir); + if (len<RCC_MAX_PREFIX_CHARS) strcpy(lastprefix, fsentry->mnt_dir); break; } } @@ -103,7 +105,7 @@ int rccFS0(rcc_context ctx, const char *fspath, const char *filename, char **pre } if (!tmp) return 1; - + *name = strdup(tmp); *prefix = strndup(filename, (tmp-filename)); @@ -123,7 +125,7 @@ returns: bit 1 Exact Match bit 2 Memory cleanup isn't required */ -int rccFS1(rcc_context ctx, const char *fspath, char **prefix, char **name) { +int rccFS1(rcc_language_config config, const char *fspath, char **prefix, char **name) { int err; int prefix_size; char *result, *tmp; @@ -142,7 +144,7 @@ int rccFS1(rcc_context ctx, const char *fspath, char **prefix, char **name) { // Checking without recoding in case of autodetection - if (rccGetOption(ctx, RCC_AUTODETECT_FS_NAMES)) { + if (rccGetOption(config->ctx, RCC_OPTION_AUTODETECT_FS_NAMES)) { if (rccIsFile(result)) { *prefix = NULL; *name = result; @@ -152,7 +154,7 @@ int rccFS1(rcc_context ctx, const char *fspath, char **prefix, char **name) { } } - if (rccFS0(ctx, fspath, result, prefix, name)) { + if (rccFS0(config, fspath, result, prefix, name)) { *prefix = NULL; *name = result; @@ -167,61 +169,63 @@ int rccFS1(rcc_context ctx, const char *fspath, char **prefix, char **name) { /* Checks if 'prefix/name' is accessible using 'icnv' recoding. In case of sucess returns pointer on statically allocated memory, and NULL overwise */ -const char *rccFS2(rcc_context ctx, iconv_t icnv, const char *prefix, const char *name) { - int err; - - if (icnv == (iconv_t)-1) return NULL; - if (icnv == (iconv_t)-2) { - strncpy(ctx->tmpbuffer, name, RCC_MAX_STRING_CHARS); - ctx->tmpbuffer[RCC_MAX_STRING_CHARS] = 0; +const char *rccFS2(rcc_language_config config, iconv_t icnv, const char *prefix, const char *name) { + size_t size; + char *tmpbuffer = config->ctx->tmpbuffer; + + if (icnv) { + size = rccIConv(config->ctx, icnv, name, 0); + if (size == (size_t)-1) return NULL; } else { - err = rccIConv(ctx, icnv, name, 0); - if (err<=0) return NULL; + strncpy(tmpbuffer, name, RCC_MAX_STRING_CHARS); + tmpbuffer[RCC_MAX_STRING_CHARS] = 0; } - return rccCheckFile(prefix, ctx->tmpbuffer); + + return rccCheckFile(prefix, tmpbuffer); } /* Tries to find 'name' encoding in 'prefix/name' file. Returns pointer on statically allocated string with correct filename or NULL. */ -const char *rccFS3(rcc_context ctx, rcc_language_id language_id, rcc_class_id class_id, const char *prefix, const char *name) { +const char *rccFS3(rcc_language_config config, rcc_class_id class_id, const char *prefix, const char *name) { unsigned int i; const char *result; rcc_charset charset; rcc_language *language; - iconv_t icnv = ctx->fsiconv; + iconv_t icnv = config->fsiconv; - if ((rccGetOption(ctx, RCC_AUTODETECT_FS_NAMES))&&(icnv != (iconv_t)-1)) { - result = rccFS2(ctx, icnv, prefix, name); + if ((rccGetOption(config->ctx, RCC_OPTION_AUTODETECT_FS_NAMES))&&(icnv)) { + result = rccFS2(config, icnv, prefix, name); if (result) return result; } - result = rccFS2(ctx, ctx->iconv_to[class_id], prefix, name); + result = rccFS2(config, config->iconv_to[class_id], prefix, name); if (result) { - if ((icnv != (iconv_t)-1)&&(icnv != (iconv_t)-2)) iconv_close(icnv); - ctx->fsiconv = (iconv_t)-1; + if (icnv) rccIConvClose(icnv); + config->fsiconv = NULL; return result; } - if (rccGetOption(ctx, RCC_AUTODETECT_FS_NAMES)) { - language = ctx->languages[language_id]; + if (rccGetOption(config->ctx, RCC_OPTION_AUTODETECT_FS_NAMES)) { + language = config->language; if (language->charsets[0]) { for (i=1;(!result);i++) { charset = language->charsets[i]; if (!charset) break; - if ((icnv != (iconv_t)-1)&&(icnv != (iconv_t)-2)) iconv_close(icnv); + if (icnv) rccIConvClose(icnv); + if (rccIsUTF8(charset)) icnv = NULL; + else { + icnv = rccIConvOpen(charset, "UTF-8"); + } - if ((!strcmp(charset, "UTF-8"))||(!strcmp(charset, "UTF8"))) icnv = (iconv_t)-2; - else icnv = iconv_open(charset, "UTF-8"); - - result = rccFS2(ctx, icnv, prefix, name); + result = rccFS2(config, icnv, prefix, name); } } } - if (result) ctx->fsiconv = icnv; + if (result) config->fsiconv = icnv; else { - if ((icnv != (iconv_t)-1)&&(icnv != (iconv_t)-2)) iconv_close(icnv); - ctx->fsiconv = (iconv_t)-1; + if (icnv) rccIConvClose(icnv); + config->fsiconv = NULL; } return result; @@ -1,9 +1,9 @@ #ifndef _RCC_FS_H #define _RCC_FS_H -int rccFS0(rcc_context ctx, const char *fspath, const char *filename, char **prefix, char **name); -int rccFS1(rcc_context ctx, const char *fspath, char **prefix, char **name); -char *rccFS2(rcc_context ctx, iconv_t icnv, const char *prefix, const char *name); -char *rccFS3(rcc_context ctx, rcc_language_id language_id, rcc_class_id class_id, const char *prefix, const char *name); +int rccFS0(rcc_language_config config, const char *fspath, const char *filename, char **prefix, char **name); +int rccFS1(rcc_language_config config, const char *fspath, char **prefix, char **name); +char *rccFS2(rcc_language_config config, iconv_t icnv, const char *prefix, const char *name); +char *rccFS3(rcc_language_config config, rcc_class_id class_id, const char *prefix, const char *name); #endif /* _RCC_FS_H */ diff --git a/src/internal.h b/src/internal.h index 9ffceb3..83a8028 100644 --- a/src/internal.h +++ b/src/internal.h @@ -1,8 +1,6 @@ #ifndef _RCC_INTERNAL_H #define _RCC_INTERNAL_H -#include <iconv.h> - #ifndef LIBRCC_DATA_DIR # define LIBRCC_DATA_DIR "/usr/lib/rcc" #endif /* LIBRCC_DATA_DIR */ @@ -13,6 +11,7 @@ #include "lngconfig.h" #include "rccstring.h" #include "rccdb4.h" +#include "rcciconv.h" #define STRNLEN(str,n) (n?strnlen(str,n):strlen(str)) @@ -39,13 +38,13 @@ struct rcc_context_t { rcc_engine_context_s engine_ctx; - iconv_t *iconv_from; - iconv_t *iconv_to; - iconv_t iconv_auto[RCC_MAX_CHARSETS]; + rcc_iconv *iconv_from; + rcc_iconv iconv_auto[RCC_MAX_CHARSETS]; + + rcc_iconv fsiconv; char tmpbuffer[RCC_MAX_STRING_CHARS+sizeof(rcc_string_header)+1]; char lastprefix[RCC_MAX_PREFIX_CHARS+1]; - iconv_t fsiconv; unsigned char configure; rcc_language_config current_config; diff --git a/src/librcc.c b/src/librcc.c index cb87917..90ec5aa 100644 --- a/src/librcc.c +++ b/src/librcc.c @@ -52,7 +52,8 @@ int rccInit() { memcpy(rcc_default_languages, rcc_default_languages_embeded, (RCC_MAX_LANGUAGES + 1)*sizeof(rcc_language)); memcpy(rcc_option_descriptions, rcc_option_descriptions_embeded, (RCC_MAX_OPTIONS + 1)*sizeof(rcc_option_description)); - err = rccXmlInit(1); + err = rccPluginInit(); + if (!err) err = rccXmlInit(1); if (!err) err = rccEngineInit(); if (err) { @@ -73,6 +74,7 @@ void rccFree() { rccEngineFree(); rccXmlFree(); + rccPluginFree(); if (rcc_home_dir) { free(rcc_home_dir); @@ -90,7 +92,7 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu rcc_language_ptr *languages; rcc_class_ptr *classes; rcc_language_config configs; - iconv_t *from, *to; + rcc_iconv *from; if (!initialized) return NULL; @@ -112,14 +114,12 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu ctx = (rcc_context)malloc(sizeof(struct rcc_context_t)); languages = (rcc_language_ptr*)malloc((max_languages+1)*sizeof(rcc_language_ptr)); classes = (rcc_class_ptr*)malloc((max_classes+1)*sizeof(rcc_class_ptr)); - from = (iconv_t*)malloc((max_classes)*sizeof(iconv_t)); - to = (iconv_t*)malloc((max_classes)*sizeof(iconv_t)); + from = (rcc_iconv*)malloc((max_classes)*sizeof(rcc_iconv)); configs = (rcc_language_config)malloc((max_languages)*sizeof(struct rcc_language_config_t)); if ((!ctx)||(!languages)||(!classes)) { if (from) free(from); - if (to) free(to); if (configs) free(configs); if (classes) free(classes); if (languages) free(languages); @@ -145,18 +145,11 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu ctx->n_classes = 0; classes[0] = NULL; - ctx->fsiconv = (iconv_t)-1; ctx->lastprefix[0] = 0; ctx->iconv_from = from; - ctx->iconv_to = to; - for (i=0;i<max_classes;i++) { - from[i] = (iconv_t)-1; - to[i] = (iconv_t)-1; - } - - for (i=0;i<RCC_MAX_CHARSETS;i++) - ctx->iconv_auto[i] = (iconv_t)-1; + for (i=0;i<max_classes;i++) from[i] = NULL; + for (i=0;i<RCC_MAX_CHARSETS;i++) ctx->iconv_auto[i] = NULL; ctx->configs = configs; for (i=0;i<max_languages;i++) @@ -225,27 +218,18 @@ int rccInitDefaultContext(const char *locale_variable, unsigned int max_language static void rccFreeIConv(rcc_context ctx) { unsigned int i; - if ((!ctx)||(!ctx->iconv_from)||(!ctx->iconv_to)) return; + if ((!ctx)||(!ctx->iconv_from)) return; - if ((ctx->fsiconv != (iconv_t)-1)&&(ctx->fsiconv != (iconv_t)-2)) { - iconv_close(ctx->fsiconv); - ctx->fsiconv = (iconv_t)-1; - } - for (i=0;i<ctx->n_classes;i++) { - if ((ctx->iconv_from[i] != (iconv_t)-1)&&(ctx->iconv_from[i] != (iconv_t)-2)) { - iconv_close(ctx->iconv_from[i]); - ctx->iconv_from[i] = (iconv_t)-1; - } - if ((ctx->iconv_to[i] != (iconv_t)-1)&&(ctx->iconv_to[i] != (iconv_t)-2)) { - iconv_close(ctx->iconv_to[i]); - ctx->iconv_to[i] = (iconv_t)-1; + if (ctx->iconv_from[i]) { + rccIConvClose(ctx->iconv_from[i]); + ctx->iconv_from[i] = NULL; } } for (i=0;i<RCC_MAX_CHARSETS;i++) { - if ((ctx->iconv_auto[i] != (iconv_t)-1)&&(ctx->iconv_auto[i] != (iconv_t)-2)) { - iconv_close(ctx->iconv_auto[i]); - ctx->iconv_auto[i] = (iconv_t)-1; + if (ctx->iconv_auto[i]) { + rccIConvClose(ctx->iconv_auto[i]); + ctx->iconv_auto[i] = NULL; } } } @@ -258,11 +242,10 @@ void rccFreeContext(rcc_context ctx) { rccEngineFreeContext(&ctx->engine_ctx); rccFreeIConv(ctx); if (ctx->iconv_from) free(ctx->iconv_from); - if (ctx->iconv_to) free(ctx->iconv_to); if (ctx->configs) { for (i=0;i<ctx->max_languages;i++) - rccConfigFree(ctx->configs+i); + rccConfigClear(ctx->configs+i); free(ctx->configs); } if (ctx->classes) free(ctx->classes); @@ -392,29 +375,19 @@ int rccConfigure(rcc_context ctx) { cfg = rccGetCurrentConfig(ctx); if (!cfg) return 1; - rccConfigGetCurrentCharsetName(cfg, (rcc_class_id)0); rccFreeIConv(ctx); for (i=0;i<ctx->n_classes;i++) { charset = rccConfigGetCurrentCharsetName(cfg, (rcc_class_id)i); - if (!charset) continue; - printf("Configure %i: %s\n", i, charset); - if (strcmp(charset, "UTF-8")&&strcmp(charset, "UTF8")) { - ctx->iconv_from[i] = iconv_open("UTF-8", charset); - ctx->iconv_to[i] = iconv_open(charset, "UTF-8"); - } else { - ctx->iconv_from[i] = (iconv_t)-2; - ctx->iconv_to[i] = (iconv_t)-2; - } + if ((!charset)||(rccIsUTF8(charset))) continue; + ctx->iconv_from[i] = rccIConvOpen("UTF-8", charset); } charsets = rccGetCurrentAutoCharsetList(ctx); if (charsets) { for (i=0;charsets[i];i++) { charset = charsets[i]; - if (strcmp(charset, "UTF-8")&&strcmp(charset, "UTF8")) - ctx->iconv_auto[i] = iconv_open("UTF-8", charset); - else - ctx->iconv_auto[i] = (iconv_t)-2; + if ((!charset)||(rccIsUTF8(charset))) continue; + ctx->iconv_auto[i] = rccIConvOpen("UTF-8", charset); } } diff --git a/src/librcc.h b/src/librcc.h index 4782418..87ded50 100644 --- a/src/librcc.h +++ b/src/librcc.h @@ -135,11 +135,13 @@ rcc_class_type rccGetClassType(rcc_context ctx, rcc_class_id class_id); *******************************************************************************/ typedef int rcc_option_value; +#define RCC_OPTION_LEARNING_FLAG_USE 1 +#define RCC_OPTION_LEARNING_FLAG_LEARN 2 typedef enum rcc_option_t { - RCC_LEARNING_MODE = 0, - RCC_AUTODETECT_FS_TITLES, - RCC_AUTODETECT_FS_NAMES, - RCC_CONFIGURED_LANGUAGES_ONLY, + RCC_OPTION_LEARNING_MODE = 0, + RCC_OPTION_AUTODETECT_FS_TITLES, + RCC_OPTION_AUTODETECT_FS_NAMES, + RCC_OPTION_CONFIGURED_LANGUAGES_ONLY, RCC_MAX_OPTIONS } rcc_option; @@ -44,21 +44,17 @@ static rcc_language_id rccGetDefaultLanguage(rcc_context ctx) { rcc_language_config config; char stmp[RCC_MAX_LANGUAGE_CHARS+1]; - printf("DL: %lu\n", ctx->default_language); if (ctx->default_language) return ctx->default_language; if (!rccLocaleGetLanguage(stmp, ctx->locale_variable, RCC_MAX_LANGUAGE_CHARS)) { for (i=0;ctx->languages[i];i++) { if (!strcmp(ctx->languages[i]->sn, stmp)) { - clo = rccGetOption(ctx, RCC_CONFIGURED_LANGUAGES_ONLY); - printf("CLO: %lu\n", clo); + clo = rccGetOption(ctx, RCC_OPTION_CONFIGURED_LANGUAGES_ONLY); if (clo) { config = rccCheckConfig(ctx, (rcc_language_id)i); if ((!config)||(!config->configured)) { if (clo == 1) { engines = ctx->languages[i]->engines; - printf("%p",engines[0]); - printf("%p",engines[1]); if ((!engines[0])||(!engines[1])) break; } else break; } diff --git a/src/lngconfig.c b/src/lngconfig.c index eded9da..6e42181 100644 --- a/src/lngconfig.c +++ b/src/lngconfig.c @@ -144,29 +144,75 @@ rcc_charset_id rccConfigGetAutoCharsetByName(rcc_language_config config, const c int rccConfigInit(rcc_language_config config, rcc_context ctx) { unsigned int i; rcc_charset_id *charsets; + rcc_charset_id *dcharsets; + rcc_iconv *iconv_to; if ((!ctx)||(!config)) return -1; charsets = (rcc_charset_id*)malloc((ctx->max_classes)*sizeof(rcc_charset_id)); - if (!charsets) return -1; + dcharsets = (rcc_charset_id*)malloc((ctx->max_classes)*sizeof(rcc_charset_id)); + iconv_to = (rcc_iconv*)malloc((ctx->max_classes)*sizeof(rcc_iconv)); + if ((!charsets)||(!dcharsets)||(!iconv_to)) { + if (dcharsets) free(dcharsets); + if (charsets) free(charsets); + if (iconv_to) free(iconv_to); + return -1; + } - for (i=0;i<ctx->max_classes;i++) - charsets[i] = 0; + for (i=0;i<ctx->max_classes;i++) { + dcharsets[i] = 0; + charsets[i] = 0; + iconv_to[i] = NULL; + } + + config->fsiconv = NULL; config->ctx = ctx; config->language = NULL; config->charset = charsets; config->engine = -1; - config->default_charset = 0; + config->default_charset = dcharsets; config->configured = 0; + config->iconv_to = iconv_to; + config->configure = 1; + return 0; } -int rccConfigFree(rcc_language_config config) { - if (config->charset) { - free(config->charset); - config->charset = NULL; +void rccConfigFreeIConv(rcc_language_config config) { + unsigned int i; + + if ((!config)||(!config->charset)) return; + + if (config->fsiconv) { + rccIConvClose(config->fsiconv); + config->fsiconv = NULL; + } + + for (i=0;i<config->ctx->n_classes;i++) { + if (config->iconv_to[i]) { + rccIConvClose(config->iconv_to[i]); + config->iconv_to[i] = NULL; + } + } +} + +void rccConfigClear(rcc_language_config config) { + if ((config)&&(config->charset)) { + rccConfigFreeIConv(config); + if (config->iconv_to) { + free(config->iconv_to); + config->iconv_to = NULL; + } + if (config->charset) { + free(config->charset); + config->charset = NULL; + } + if (config->default_charset) { + free(config->default_charset); + config->default_charset = NULL; + } } } @@ -310,18 +356,18 @@ rcc_charset_id rccConfigGetCurrentCharset(rcc_language_config config, rcc_class_ } } else defvalue = config->ctx->locale_variable; - if (config->default_charset) return config->default_charset; + if (config->default_charset[class_id]) return config->default_charset[class_id]; charset_id = rccConfigGetLocaleCharset(config, defvalue); if ((charset_id != 0)&&(charset_id != (rcc_charset_id)-1)) { - config->default_charset = charset_id; + config->default_charset[class_id] = charset_id; return charset_id; } if (cl->defvalue) { charset_id = rccConfigGetCharsetByName(config, defvalue); if ((charset_id != 0)&&(charset_id != (rcc_charset_id)-1)) { - config->default_charset = charset_id; + config->default_charset[class_id] = charset_id; return charset_id; } } @@ -334,16 +380,22 @@ rcc_charset_id rccConfigGetCurrentCharset(rcc_language_config config, rcc_class_ if (!strcasecmp(lang, defcharset[i].lang)) { charset_id = rccConfigGetCharsetByName(config, defcharset[i].charset); if ((charset_id != 0)&&(charset_id != (rcc_charset_id)-1)) { - config->default_charset = charset_id; + config->default_charset[class_id] = charset_id; return charset_id; } else break; } } } + charset_id = rccConfigGetLocaleUnicodeCharset(config, defvalue); + if ((charset_id != 0)&&(charset_id != (rcc_charset_id)-1)) { + config->default_charset[class_id] = charset_id; + return charset_id; + } + charsets=language->charsets; if ((charsets[0])&&(charsets[1])) { - config->default_charset=(rcc_charset_id)1; + config->default_charset[class_id]=(rcc_charset_id)1; return (rcc_charset_id)1; } return (rcc_charset_id)-1; @@ -373,6 +425,7 @@ int rccConfigSetEngine(rcc_language_config config, rcc_engine_id engine_id) { if (config->engine != engine_id) { if (config->ctx->current_config == config) config->ctx->configure = 1; + config->configure = 1; config->engine = engine_id; } return 0; @@ -404,6 +457,7 @@ int rccConfigSetCharset(rcc_language_config config, rcc_class_id class_id, rcc_c if (config->charset[class_id] != charset_id) { if (config->ctx->current_config == config) config->ctx->configure = 1; + config->configure = 1; config->charset[class_id] = charset_id; } @@ -420,28 +474,61 @@ int rccConfigSetCharsetByName(rcc_language_config config, rcc_class_id class_id, } rcc_charset_id rccConfigGetLocaleCharset(rcc_language_config config, const char *locale_variable) { - int err; + const char *lv; rcc_charset *charsets; rcc_language_id language_id; char stmp[RCC_MAX_CHARSET_CHARS+1]; if ((!config)||(!config->language)) return (rcc_charset_id)-1; - language_id = rccGetCurrentLanguage(config->ctx); - if (language_id) err = rccLocaleGetLanguage(stmp, locale_variable?locale_variable:config->ctx->locale_variable, RCC_MAX_CHARSET_CHARS); + lv = locale_variable?locale_variable:config->ctx->locale_variable; - if ((language_id == 0)||((!err)&&(!strcmp(rccGetCurrentLanguageName(config->ctx), stmp)))) - err = rccLocaleGetCharset(stmp, locale_variable?locale_variable:config->ctx->locale_variable, RCC_MAX_CHARSET_CHARS); - else - err = 1; + language_id = rccGetLanguageByName(config->ctx, config->language->sn); + if (language_id != (rcc_language_id)-1) { + if (!rccLocaleGetLanguage(stmp, lv, RCC_MAX_CHARSET_CHARS)) { + if (!strcmp(config->language->sn, stmp)) { + if (!rccLocaleGetCharset(stmp, lv, RCC_MAX_CHARSET_CHARS)) + return rccConfigGetCharsetByName(config, stmp); + } + } + } + + return (rcc_charset_id)-1; +} + +rcc_charset_id rccConfigGetLocaleUnicodeCharset(rcc_language_config config, const char *locale_variable) { + char stmp[RCC_MAX_CHARSET_CHARS+1]; + + if ((!config)||(!config->language)) return (rcc_charset_id)-1; + + if (!rccLocaleGetCharset(stmp, locale_variable?locale_variable:config->ctx->locale_variable, RCC_MAX_CHARSET_CHARS)) { + if (rccIsUTF8(stmp)) return rccConfigGetCharsetByName(config, stmp); + } - if (err) { - charsets=config->language->charsets; - if ((charsets[0])&&(charsets[1])) return (rcc_charset_id)1; - return (rcc_charset_id)-1; + return (rcc_charset_id)-1; +} + +int rccConfigConfigure(rcc_language_config config) { + rcc_context ctx; + const char *charset; + unsigned int i; + + if (!config) return -1; + if (!config->configure) return 0; + + ctx = config->ctx; + if (!ctx) return -1; + + rccConfigFreeIConv(config); + for (i=0;i<ctx->n_classes;i++) { + charset = rccConfigGetCurrentCharsetName(config, (rcc_class_id)i); + if ((!charset)||(rccIsUTF8(charset))) continue; + config->iconv_to[i] = rccIConvOpen(charset, "UTF-8"); } + + config->configure = 0; - return rccConfigGetCharsetByName(config, stmp); + return 0; } /* diff --git a/src/lngconfig.h b/src/lngconfig.h index d583ab6..edfd1d1 100644 --- a/src/lngconfig.h +++ b/src/lngconfig.h @@ -1,6 +1,7 @@ #ifndef _RCC_LNGCONFIG_H #define _RCC_LNGCONFIG_H +#include "rcciconv.h" struct rcc_language_config_t { rcc_context ctx; @@ -8,9 +9,14 @@ struct rcc_language_config_t { rcc_engine_id engine; rcc_charset_id *charset; + rcc_charset_id *default_charset; + + rcc_iconv *iconv_to; + unsigned char configure; - rcc_charset_id default_charset; unsigned char configured; + + rcc_iconv fsiconv; }; typedef struct rcc_language_config_t rcc_language_config_s; @@ -21,6 +27,10 @@ rcc_engine_ptr rccConfigGetCurrentEnginePointer(rcc_language_config config); rcc_engine_ptr rccConfigCheckCurrentEnginePointer(rcc_language_config config); int rccConfigInit(rcc_language_config config, rcc_context ctx); -int rccConfigFree(rcc_language_config config); +void rccConfigClear(rcc_language_config config); + +int rccConfigConfigure(rcc_language_config config); + +rcc_charset_id rccConfigGetLocaleUnicodeCharset(rcc_language_config config, const char *locale_variable); #endif /* _RCC_LNGCONFIG_H */ diff --git a/src/rccconfig.c b/src/rccconfig.c index 37b6cc0..3956b5f 100644 --- a/src/rccconfig.c +++ b/src/rccconfig.c @@ -110,10 +110,10 @@ rcc_option_value_name rcc_sn_clo[] = { "ALL", "CONFIGURED_AND_AUTO", "CONFIGURED rcc_option_description rcc_option_descriptions[RCC_MAX_OPTIONS+1]; rcc_option_description rcc_option_descriptions_embeded[RCC_MAX_OPTIONS+1] = { - {RCC_LEARNING_MODE, 1, { RCC_OPTION_RANGE_TYPE_MENU, 0, 3, 1 }, RCC_OPTION_TYPE_STANDARD, "LEARNING_MODE", rcc_sn_learning }, - {RCC_AUTODETECT_FS_NAMES, 1, { RCC_OPTION_RANGE_TYPE_BOOLEAN, 0, 0, 0}, RCC_OPTION_TYPE_STANDARD, "AUTODETECT_FS_NAMES", rcc_sn_boolean}, - {RCC_AUTODETECT_FS_TITLES, 1, { RCC_OPTION_RANGE_TYPE_BOOLEAN, 0, 0, 0}, RCC_OPTION_TYPE_INVISIBLE, "AUTODETECT_FS_TITLES", rcc_sn_boolean}, - {RCC_CONFIGURED_LANGUAGES_ONLY, 1, { RCC_OPTION_RANGE_TYPE_MENU, 0, 2, 1}, RCC_OPTION_TYPE_INVISIBLE, "CONFIGURED_LANGUAGES_ONLY", rcc_sn_clo}, + {RCC_OPTION_LEARNING_MODE, 1, { RCC_OPTION_RANGE_TYPE_MENU, 0, 3, 1 }, RCC_OPTION_TYPE_STANDARD, "LEARNING_MODE", rcc_sn_learning }, + {RCC_OPTION_AUTODETECT_FS_NAMES, 1, { RCC_OPTION_RANGE_TYPE_BOOLEAN, 0, 0, 0}, RCC_OPTION_TYPE_STANDARD, "AUTODETECT_FS_NAMES", rcc_sn_boolean}, + {RCC_OPTION_AUTODETECT_FS_TITLES, 1, { RCC_OPTION_RANGE_TYPE_BOOLEAN, 0, 0, 0}, RCC_OPTION_TYPE_INVISIBLE, "AUTODETECT_FS_TITLES", rcc_sn_boolean}, + {RCC_OPTION_CONFIGURED_LANGUAGES_ONLY, 1, { RCC_OPTION_RANGE_TYPE_MENU, 0, 2, 1}, RCC_OPTION_TYPE_INVISIBLE, "CONFIGURED_LANGUAGES_ONLY", rcc_sn_clo}, {RCC_MAX_OPTIONS} }; @@ -149,3 +149,8 @@ rcc_language_id rccDefaultGetLanguageByName(const char *name) { return (rcc_language_id)-1; } + +int rccIsUTF8(const char *name) { + if ((!name)||(strcasecmp(name, "UTF-8")&&strcasecmp(name, "UTF8"))) return 0; + return 1; +} diff --git a/src/rccconfig.h b/src/rccconfig.h index 868974f..b94a39b 100644 --- a/src/rccconfig.h +++ b/src/rccconfig.h @@ -27,4 +27,6 @@ rcc_option_description *rccGetOptionDescriptionByName(const char *name); rcc_language_id rccDefaultGetLanguageByName(const char *name); +int rccIsUTF8(const char *name); + #endif /* _RCC_CONFIG_H */ diff --git a/src/rccdb4.c b/src/rccdb4.c index 795b721..5e0894a 100644 --- a/src/rccdb4.c +++ b/src/rccdb4.c @@ -84,7 +84,7 @@ void rccDb4FreeContext(db4_context ctx) { } } -int rccDb4SetKey(db4_context ctx, const char *orig, size_t olen, const rcc_string string, size_t slen) { +int rccDb4SetKey(db4_context ctx, const char *orig, size_t olen, const rcc_string string) { int err; DBT key, data; @@ -94,9 +94,9 @@ int rccDb4SetKey(db4_context ctx, const char *orig, size_t olen, const rcc_strin memset(&data, 0, sizeof(data)); key.data = (char*)orig; - key.size = STRNLEN(orig, olen); + key.size = STRNLEN(orig, olen); /* No ending zero */ data.data = (char*)string; - data.size = STRNLEN(string, slen); + data.size = strlen(string)+1; if (key.size < MIN_CHARS) return -1; @@ -114,7 +114,7 @@ rcc_string rccDb4GetKey(db4_context ctx, const char *orig, size_t olen) { memset(&data, 0, sizeof(data)); key.data = (char*)orig; - key.size = STRNLEN(orig, olen); + key.size = STRNLEN(orig, olen); /* No ending zero */ data.flags = DB_DBT_REALLOC; diff --git a/src/rccdb4.h b/src/rccdb4.h index 0fb55b7..33457ef 100644 --- a/src/rccdb4.h +++ b/src/rccdb4.h @@ -17,7 +17,7 @@ typedef struct db4_context_t *db4_context; db4_context rccDb4CreateContext(const char *dbpath, rcc_db4_flags flags); void rccDb4FreeContext(db4_context ctx); -int rccDb4SetKey(db4_context ctx, const char *orig, size_t olen, const rcc_string string, size_t slen); +int rccDb4SetKey(db4_context ctx, const char *orig, size_t olen, const rcc_string string); rcc_string rccDb4GetKey(db4_context ctx, const char *orig, size_t olen); #endif /* _RCC_DB4_H */ diff --git a/src/rcciconv.c b/src/rcciconv.c index 0fb440f..1add9d9 100644 --- a/src/rcciconv.c +++ b/src/rcciconv.c @@ -92,49 +92,7 @@ loop: return outsize - out_left; } - - -size_t rccIConv(rcc_context ctx, iconv_t icnv, const char *buf, size_t len) { - char *in_buf, *out_buf, *res, err; - int in_left, out_left, olen; - int ub, utf_mode=0; - int errors=0; - - if ((!buf)||(!ctx)||(icnv == (iconv_t)-1)) return (size_t)-1; - - len = STRNLEN(buf,len); - - if (iconv(icnv, NULL, NULL, NULL, NULL) == -1) return (size_t)-1; - -loop_restart: - errors = 0; - in_buf = (char*)buf; /*DS*/ - in_left = len; - out_buf = ctx->tmpbuffer; - out_left = RCC_MAX_STRING_CHARS; - -loop: - err=iconv(icnv, &in_buf, &in_left, &out_buf, &out_left); - if (err<0) { - if (errno==E2BIG) { - *(int*)(ctx->tmpbuffer+(RCC_MAX_STRING_CHARS-sizeof(int)))=0; - } else if (errno==EILSEQ) { - if (errors++<RCC_MAX_ERRORS) { - for (ub=utf_mode?rccIConvUTFBytes(*in_buf):1;ub>0;ub--) - rccIConvCopySymbol(&in_buf, &in_left, &out_buf, &out_left); - if (in_left>0) goto loop; - } else if (!utf_mode) { - utf_mode = 1; - goto loop_restart; - } else { - return (size_t)-1; - } - } else { - return (size_t)-1; - } - } - - ctx->tmpbuffer[RCC_MAX_STRING_CHARS - out_left] = 0; - - return RCC_MAX_STRING_CHARS - out_left; +size_t rccIConv(rcc_context ctx, rcc_iconv icnv, const char *buf, size_t len) { + if (!ctx) return (size_t)-1; + return rccIConvRecode(icnv, ctx->tmpbuffer, RCC_MAX_STRING_CHARS, buf, len); } diff --git a/src/rcciconv.h b/src/rcciconv.h index 4a8fc78..cc1d1b9 100644 --- a/src/rcciconv.h +++ b/src/rcciconv.h @@ -1,11 +1,13 @@ #ifndef _RCC_ICONV_H #define _RCC_ICONV_H +#include <iconv.h> + struct rcc_iconv_t { iconv_t icnv; }; typedef struct rcc_iconv_t rcc_iconv_s; -size_t rccIConv(rcc_context ctx, iconv_t icnv, const char *buf, size_t len); +size_t rccIConv(rcc_context ctx, rcc_iconv icnv, const char *buf, size_t len); #endif /* _RCC_ICONV_H */ diff --git a/src/rcclocale.c b/src/rcclocale.c index 3e5b56e..838dfd6 100644 --- a/src/rcclocale.c +++ b/src/rcclocale.c @@ -11,7 +11,7 @@ #include "rccconfig.h" -static int rccLocaleGetClassByName(const char *locale) { +int rccLocaleGetClassByName(const char *locale) { if (!locale) return LC_CTYPE; if (!strcmp(locale, "LC_CTYPE")) return LC_CTYPE; diff --git a/src/rcclocale.h b/src/rcclocale.h index fbbfc24..dbc1364 100644 --- a/src/rcclocale.h +++ b/src/rcclocale.h @@ -1,6 +1,7 @@ #ifndef _RCC_LOCALE_H #define _RCC_LOCALE_H +int rccLocaleGetClassByName(const char *locale); int rccLocaleGetLanguage(char *result, const char *lv, unsigned int n); int rccLocaleGetCharset(char *result, const char *lv, unsigned int n); diff --git a/src/rccstring.c b/src/rccstring.c index 0df20d6..f1f7016 100644 --- a/src/rccstring.c +++ b/src/rccstring.c @@ -6,8 +6,8 @@ rcc_string rccCreateString(rcc_language_id language_id, const char *buf, size_t len, size_t *rlen) { char *res; - rcc_string_header header = {RCC_STRING_MAGIC, language_id}; - + rcc_string_header *header; + len = STRNLEN(buf, len); res = (char*)malloc(len+sizeof(rcc_string_header)+1); @@ -16,12 +16,45 @@ rcc_string rccCreateString(rcc_language_id language_id, const char *buf, size_t strncpy(res + sizeof(rcc_string_header), buf, len); res[sizeof(rcc_string_header) + len] = 0; - memcpy(res, &header, sizeof(rcc_string_header)); + memset(res, 0xFF, sizeof(rcc_string_header)); + header = (rcc_string_header*)res; + header->magic = RCC_STRING_MAGIC; + header->language_id = language_id; if (rlen) *rlen = len + sizeof(rcc_string_header); return (rcc_string)res; } +int rccStringSetLang(rcc_string string, const char *sn) { + if ((!string)||(!sn)||(strlen(sn)!=2)) return -1; + memcpy(&((rcc_string_header*)string)->language,sn,2); + return 0; +} + +int rccStringFixID(rcc_string string, rcc_context ctx) { + char lang[3]; + const char *curlang; + rcc_language_config config; + rcc_language_id language_id; + rcc_string_header *header; + + if ((!string)||(!ctx)||(!rccStringCheck(string))) return -1; + header = (rcc_string_header*)string; + + + memcpy(lang, header->language, 2); lang[3] = 0; + curlang = rccGetLanguageName(ctx, header->language_id); + if ((curlang)&&(!strcasecmp(lang, curlang))) return 0; + + language_id = rccGetLanguageByName(ctx, lang); + if ((language_id == (rcc_language_id)-1)||(language_id == 0)) return -1; + config = rccGetLanguageConfig(ctx, language_id); + if (!config) return -1; + + header->language_id = language_id; + return 0; +} + void rccStringFree(rcc_string str) { if (str) free(str); } diff --git a/src/rccstring.h b/src/rccstring.h index a9cfc9b..dbbd4c2 100644 --- a/src/rccstring.h +++ b/src/rccstring.h @@ -6,6 +6,7 @@ struct rcc_string_header_t { unsigned int magic; rcc_language_id language_id; + char language[2]; }; typedef struct rcc_string_header_t rcc_string_header; @@ -13,4 +14,7 @@ typedef struct rcc_string_header_t rcc_string_header; rcc_string rccCreateString(rcc_language_id language_id, const char *buf, size_t len, size_t *rlen); void rccStringFree(rcc_string str); +int rccStringSetLang(rcc_string string, const char *sn); +int rccStringFixID(rcc_string string, rcc_context ctx); + #endif /* _RCC_STRING_H */ diff --git a/src/rccxml.c b/src/rccxml.c index 4ce1764..5e60731 100644 --- a/src/rccxml.c +++ b/src/rccxml.c @@ -546,7 +546,7 @@ clear: xmlFreeDoc(doc); } - if ((!ctx->current_language)&&(rccGetOption(ctx, RCC_CONFIGURED_LANGUAGES_ONLY))) { + if ((!ctx->current_language)&&(rccGetOption(ctx, RCC_OPTION_CONFIGURED_LANGUAGES_ONLY))) { ctx->current_config = rccGetCurrentConfig(ctx); ctx->configure = 1; } diff --git a/src/recode.c b/src/recode.c index 9983992..2164a4d 100644 --- a/src/recode.c +++ b/src/recode.c @@ -20,7 +20,7 @@ static rcc_charset_id rccIConvAuto(rcc_context ctx, rcc_class_id class_id, const if (!buf) return (rcc_charset_id)-1; class_type = rccGetClassType(ctx, class_id); - if ((class_type == RCC_CLASS_STANDARD)||((class_type == RCC_CLASS_FS)&&(rccGetOption(ctx, RCC_AUTODETECT_FS_TITLES)))) { + if ((class_type == RCC_CLASS_STANDARD)||((class_type == RCC_CLASS_FS)&&(rccGetOption(ctx, RCC_OPTION_AUTODETECT_FS_TITLES)))) { engine = rccGetCurrentEnginePointer(ctx); if ((!engine)||(!engine->func)) return (rcc_charset_id)-1; return engine->func(&ctx->engine_ctx, buf, len); @@ -34,51 +34,52 @@ rcc_string rccFrom(rcc_context ctx, rcc_class_id class_id, const char *buf, size size_t ret; rcc_language_id language_id; rcc_charset_id charset_id; - iconv_t icnv = (iconv_t)-1; + rcc_iconv icnv = NULL; rcc_string result; + rcc_option_value usedb4; if (!ctx) { if (rcc_default_ctx) ctx = rcc_default_ctx; else return NULL; } if ((class_id<0)||(class_id>=ctx->n_classes)||(!buf)) return NULL; - - -/* - result = rccDb4GetKey(ctx->db4ctx, buf, len); - if (result) { - puts("Got a string"); - return result; - } -*/ - - err = rccConfigure(ctx); - if (err) return NULL; // Checking if rcc_string passed ret = rccStringSizedCheck(buf, len); if (ret) return NULL; + + usedb4 = rccGetOption(ctx, RCC_OPTION_LEARNING_MODE); + if (usedb4&RCC_OPTION_LEARNING_FLAG_USE) { + result = rccDb4GetKey(ctx->db4ctx, buf, len); + if (result) { + if (rccStringFixID(result, ctx)) free(result); + else return result; + } + } + + err = rccConfigure(ctx); + if (err) return NULL; + language_id = rccGetCurrentLanguage(ctx); - // DS: Learning. check database (language_id, check if language_id initialized) charset_id = rccIConvAuto(ctx, class_id, buf, len); if (charset_id != (rcc_charset_id)-1) icnv = ctx->iconv_auto[charset_id]; + else icnv = ctx->iconv_from[class_id]; - if (icnv == (iconv_t)-1) { - icnv = ctx->iconv_from[class_id]; - if (icnv == (iconv_t)-1) return NULL; - } - - if (icnv == (iconv_t)-2) { - result = rccCreateString(language_id, buf, len, rlen); - } else { + if (icnv) { ret = rccIConv(ctx, icnv, buf, len); if (ret == (size_t)-1) return NULL; result = rccCreateString(language_id, ctx->tmpbuffer, ret, rlen); + } else { + result = rccCreateString(language_id, buf, len, rlen); } - // DS: Learning. write database + if ((result)&&(usedb4&RCC_OPTION_LEARNING_FLAG_LEARN)) { + if (!rccStringSetLang(result, ctx->languages[language_id]->sn)) { + rccDb4SetKey(ctx->db4ctx, buf, len, result); + } + } return result; } @@ -89,10 +90,11 @@ char *rccTo(rcc_context ctx, rcc_class_id class_id, const rcc_string buf, size_t char *result; char *prefix, *name; const char *utfstring; + rcc_language_config config; rcc_language_id language_id; rcc_charset_id charset_id; rcc_class_type class_type; - iconv_t icnv; + rcc_iconv icnv; if (!ctx) { if (rcc_default_ctx) ctx = rcc_default_ctx; @@ -105,22 +107,22 @@ char *rccTo(rcc_context ctx, rcc_class_id class_id, const rcc_string buf, size_t language_id = rccStringGetLanguage(buf); utfstring = rccStringGetString(buf); + if ((!language_id)||(!utfstring)) return NULL; - /* COnfigure is only required in case of current language */ - err = rccConfigure(ctx); - if (err) return NULL; - /* Do something even in case of error (Language can be changed) */ + config = rccGetConfig(ctx, language_id); + if (!config) return NULL; - icnv = ctx->iconv_to[class_id]; + err = rccConfigConfigure(config); + if (err) return NULL; class_type = rccGetClassType(ctx, class_id); - if ((language_id)&&(class_type == RCC_CLASS_FS)&&(rccGetOption(ctx, RCC_AUTODETECT_FS_NAMES))) { + if ((class_type == RCC_CLASS_FS)&&(rccGetOption(ctx, RCC_OPTION_AUTODETECT_FS_NAMES))) { name = (char*)utfstring; prefix = NULL; - err = rccFS0(ctx, NULL, buf, &prefix, &name); + err = rccFS0(config, NULL, buf, &prefix, &name); if (err>=0) { - result = rccFS3(ctx, language_id, class_id, prefix, name); + result = rccFS3(config, class_id, prefix, name); if (!err) { if (prefix) free(prefix); free(name); @@ -129,17 +131,17 @@ char *rccTo(rcc_context ctx, rcc_class_id class_id, const rcc_string buf, size_t return result; } } - - if (icnv == (iconv_t)-1) return NULL; - if (icnv == (iconv_t)-2) { - result = rccStringExtractString(buf); - if (rlen) *rlen = newlen; - } else { + + icnv = config->iconv_to[class_id]; + if (icnv) { newlen = rccIConv(ctx, icnv, rccStringGetString(buf), len?newlen:0); if (newlen == (size_t)-1) return NULL; result = rccCreateResult(ctx, newlen, rlen); - } + } else { + result = rccStringExtractString(buf); + if (rlen) *rlen = newlen; + } return result; } @@ -159,7 +161,8 @@ char *rccRecode(rcc_context ctx, rcc_class_id from, rcc_class_id to, const char if ((from<0)||(from>=ctx->n_classes)||(to<0)||(to>=ctx->n_classes)||(!buf)) return NULL; class_type = rccGetClassType(ctx, to); - if ((class_type == RCC_CLASS_FS)&&(rccGetOption(ctx, RCC_AUTODETECT_FS_NAMES))) goto recoding; + if ((class_type == RCC_CLASS_FS)&&(rccGetOption(ctx, RCC_OPTION_AUTODETECT_FS_NAMES))) goto recoding; + if (rccGetOption(ctx, RCC_OPTION_LEARNING_MODE)&RCC_OPTION_LEARNING_FLAG_LEARN) goto recoding; from_charset_id = rccIConvAuto(ctx, from, buf, len); if (from_charset_id != (rcc_charset_id)-1) { @@ -180,13 +183,12 @@ recoding: return result; } - /*return rccTo(ctx, to, buf, len, rlen);*/ return NULL; } char *rccFS(rcc_context ctx, rcc_class_id from, rcc_class_id to, const char *fspath, const char *path, const char *filename) { int err; - rcc_language_id language_id; + rcc_language_config config; char *prefix = (char*)path, *name = (char*)filename; /*DS*/ rcc_string string; @@ -199,27 +201,35 @@ char *rccFS(rcc_context ctx, rcc_class_id from, rcc_class_id to, const char *fsp } if ((from<0)||(from>=ctx->n_classes)||(to<0)||(to>=ctx->n_classes)||(!filename)) return NULL; - err = rccFS1(ctx, fspath, &prefix, &name); + config = rccGetCurrentConfig(ctx); + if (!config) return NULL; + + err = rccFS1(config, fspath, &prefix, &name); if (err) { if (err < 0) return NULL; if (err&1) { if (err&2) return NULL; + if (rccGetOption(ctx, RCC_OPTION_LEARNING_MODE)&RCC_OPTION_LEARNING_FLAG_LEARN) { + string = rccFrom(ctx, from, name, 0, NULL); + if (string) free(string); + } return name; } } string = rccFrom(ctx, from, name, 0, NULL); if (string) { - language_id = rccGetCurrentLanguage(ctx); - result = rccFS3(ctx, language_id, to, prefix, rccStringGetString(string)); + config = rccGetConfig(ctx, rccStringGetLanguage(string)); + if (config) result = rccFS3(config, to, prefix, rccStringGetString(string)); + else result = NULL; free(string); } else result = NULL; + if (!(err&2)) { if (prefix) free(prefix); free(name); } - return result; } |