summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2005-07-14 08:45:46 +0000
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2005-07-14 08:45:46 +0000
commitf15620c372b8813a87d07eee169cf2096c99c173 (patch)
treef1c59f41d4a9c9f5f45595695327b0e4a74b1408 /src
parent7233ff9095194b38586ce438379f08691a0fecdd (diff)
downloadlibrcc-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.c80
-rw-r--r--src/fs.h8
-rw-r--r--src/internal.h11
-rw-r--r--src/librcc.c65
-rw-r--r--src/librcc.h10
-rw-r--r--src/lng.c6
-rw-r--r--src/lngconfig.c137
-rw-r--r--src/lngconfig.h14
-rw-r--r--src/rccconfig.c13
-rw-r--r--src/rccconfig.h2
-rw-r--r--src/rccdb4.c8
-rw-r--r--src/rccdb4.h2
-rw-r--r--src/rcciconv.c48
-rw-r--r--src/rcciconv.h4
-rw-r--r--src/rcclocale.c2
-rw-r--r--src/rcclocale.h1
-rw-r--r--src/rccstring.c39
-rw-r--r--src/rccstring.h4
-rw-r--r--src/rccxml.c2
-rw-r--r--src/recode.c104
20 files changed, 323 insertions, 237 deletions
diff --git a/src/fs.c b/src/fs.c
index 1f61a9e..ba3ce34 100644
--- a/src/fs.c
+++ b/src/fs.c
@@ -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;
diff --git a/src/fs.h b/src/fs.h
index 1d65dd3..74ceb25 100644
--- a/src/fs.h
+++ b/src/fs.h
@@ -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;
diff --git a/src/lng.c b/src/lng.c
index 8625fb8..3f02895 100644
--- a/src/lng.c
+++ b/src/lng.c
@@ -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;
}