summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--configure.in11
-rw-r--r--engines/Makefile.am11
-rw-r--r--engines/russian.c25
-rw-r--r--src/Makefile.am2
-rw-r--r--src/engine.c12
-rw-r--r--src/engine.h2
-rw-r--r--src/internal.h6
-rw-r--r--src/librcc.c14
-rw-r--r--src/librcc.h10
-rw-r--r--src/plugin.c142
-rw-r--r--src/plugin.h23
-rw-r--r--src/rccconfig.c58
-rw-r--r--src/rccconfig.h8
-rw-r--r--src/rccxml.c83
-rw-r--r--src/rccxml.h2
16 files changed, 341 insertions, 70 deletions
diff --git a/Makefile.am b/Makefile.am
index 90d0a74..e4d2e40 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = src ui
+SUBDIRS = src engines ui
EXTRA_DIST = librcd.spec
ACLOCAL_AMFLAGS = -I m4
diff --git a/configure.in b/configure.in
index 7d50ab6..2b4c0fc 100644
--- a/configure.in
+++ b/configure.in
@@ -37,12 +37,14 @@ AC_PROG_CC
AC_PROG_INSTALL
AM_PROG_LIBTOOL
+pkgdatadir=${libdir}/rcc/
+AC_SUBST(pkgdatadir)
+
+dnl Checks for programs.
AC_PATH_PROG(RM, rm, /bin/rm)
AC_PATH_PROG(MV, mv, /bin/mv)
AC_PATH_PROG(TAR, tar, /bin/tar)
-dnl Checks for programs.
-
dnl Checks for header files.
AC_CHECK_HEADERS(iconv.h,, [AC_MSG_ERROR(Missing iconv header)])
AC_CHECK_HEADERS(mntent.h pwd.h sys/types.h sys/stat.h unistd.h)
@@ -118,6 +120,9 @@ AC_CHECK_HEADER(enca.h, [AC_CHECK_LIB(enca, enca_analyse, [
])])
fi
+AM_CONDITIONAL(HAVE_RCD, [ test $HAVE_RCD = yes ])
+AM_CONDITIONAL(HAVE_ENCA, [ test $HAVE_ENCA = yes ])
+
AC_SUBST(RCD_LIBS)
AC_SUBST(RCD_INCLUDES)
AC_SUBST(ENCA_LIBS)
@@ -162,7 +167,7 @@ AC_C_CONST
dnl Checks for library functions.
AC_CHECK_FUNCS(strcasecmp strncasecmp strdup)
-AC_OUTPUT(src/Makefile ui/Makefile examples/Makefile Makefile librcc.spec)
+AC_OUTPUT(src/Makefile engines/Makefile ui/Makefile examples/Makefile Makefile librcc.spec)
echo ""
echo "Configuration:"
diff --git a/engines/Makefile.am b/engines/Makefile.am
new file mode 100644
index 0000000..307fddf
--- /dev/null
+++ b/engines/Makefile.am
@@ -0,0 +1,11 @@
+lib_LTLIBRARIES =
+
+libdir = $(pkgdatadir)/engines
+
+if HAVE_RCD
+lib_LTLIBRARIES += librussian.la
+librussian_la_SOURCES = russian.c
+librussian_la_LDFLAGS = -module -avoid-version -export-symbols-regex "rccGetInfo"
+endif
+
+INCLUDES = -I../src @RCD_INCLUDES@
diff --git a/engines/russian.c b/engines/russian.c
new file mode 100644
index 0000000..f7e5146
--- /dev/null
+++ b/engines/russian.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+
+#include <librcd.h>
+#include <librcc.h>
+
+static rcc_charset_id AutoengineRussian(rcc_engine_context ctx, const char *buf, int len) {
+ return (rcc_charset_id)rcdGetRussianCharset(buf,len);
+}
+
+static rcc_engine russian_engine = {
+ "Russian", NULL, NULL, &AutoengineRussian, {"CP1251","KOI8-R","UTF-8","IBM866", NULL}
+};
+
+static rcc_engine ukrainian_engine = {
+ "Russian", NULL, NULL, &AutoengineRussian, {"CP1251","KOI8-U","UTF-8","IBM865", NULL}
+};
+
+rcc_engine *rccGetInfo(const char *lang) {
+ if (!lang) return NULL;
+
+ if (!strcmp(lang, "ru")) return &russian_engine;
+ if (!strcmp(lang, "uk")) return &ukrainian_engine;
+
+ return NULL;
+}
diff --git a/src/Makefile.am b/src/Makefile.am
index 1565f1a..5c105f3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,7 +20,7 @@ librcc_la_SOURCES = librcc.c \
internal.h
include_HEADERS = librcc.h
-INCLUDES = -I../src @XML_INCLUDES@ @DLOPEN_INCLUDES@ @RCD_INCLUDES@ @ENCA_INCLUDES@ @BDB_INCLUDES@
+INCLUDES = -I../src -DLIBRCC_DATA_DIR=\"${pkgdatadir}\" @XML_INCLUDES@ @DLOPEN_INCLUDES@ @RCD_INCLUDES@ @ENCA_INCLUDES@ @BDB_INCLUDES@
librcc_la_LIBADD = @XML_LIBS@ @DLOPEN_LIBS@ @RCD_LIBS@ @ENCA_LIBS@ @BDB_LIBS@
librcc_la_LDFLAGS = -version-info @LIBRCC_VERSION_INFO@
diff --git a/src/engine.c b/src/engine.c
index 5bb8b7a..0ff1aa1 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -143,3 +143,15 @@ rcc_engine_internal rccEngineGetInternal(rcc_engine_context ctx) {
return ctx->internal;
}
+
+rcc_language *rccEngineGetLanguage(rcc_engine_context ctx) {
+ if (!ctx) return NULL;
+
+ return ctx->language;
+}
+
+rcc_context rccEngineGetRccContext(rcc_engine_context ctx) {
+ if (!ctx) return NULL;
+
+ return ctx->ctx;
+}
diff --git a/src/engine.h b/src/engine.h
index 0d16d9f..37fefba 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -37,8 +37,6 @@ void rccEngineFree();
int rccEngineInitContext(rcc_engine_context engine_ctx, rcc_context ctx);
void rccEngineFreeContext(rcc_engine_context engine_ctx);
-rcc_engine_internal rccEngineGetInternal(rcc_engine_context ctx);
-
rcc_charset_id rccAutoengineRussian(rcc_engine_context ctx, const char *buf, int len);
#endif /* _RCC_ENGINE_H */
diff --git a/src/internal.h b/src/internal.h
index 258e6b0..9ffceb3 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -2,6 +2,11 @@
#define _RCC_INTERNAL_H
#include <iconv.h>
+
+#ifndef LIBRCC_DATA_DIR
+# define LIBRCC_DATA_DIR "/usr/lib/rcc"
+#endif /* LIBRCC_DATA_DIR */
+
#include "librcc.h"
#include "recode.h"
#include "engine.h"
@@ -11,6 +16,7 @@
#define STRNLEN(str,n) (n?strnlen(str,n):strlen(str))
+#define RCC_MAX_PLUGINS 32
#define RCC_MAX_STRING_CHARS 1024
#define RCC_MAX_PREFIX_CHARS 32
diff --git a/src/librcc.c b/src/librcc.c
index 34e0e3d..cb87917 100644
--- a/src/librcc.c
+++ b/src/librcc.c
@@ -49,8 +49,11 @@ int rccInit() {
#endif /* HAVE_PWD_H */
if (!rcc_home_dir) rcc_home_dir = strdup("/");
- err = rccEngineInit();
- if (!err) err = rccXmlInit();
+ 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);
+ if (!err) err = rccEngineInit();
if (err) {
rccFree();
@@ -68,8 +71,8 @@ void rccFree() {
rcc_default_ctx = NULL;
}
- rccXmlFree();
rccEngineFree();
+ rccXmlFree();
if (rcc_home_dir) {
free(rcc_home_dir);
@@ -89,6 +92,8 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu
rcc_language_config configs;
iconv_t *from, *to;
+ if (!initialized) return NULL;
+
if (!max_languages) {
if (flags&RCC_NO_DEFAULT_CONFIGURATION) max_languages = RCC_MAX_LANGUAGES;
else {
@@ -209,7 +214,8 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu
}
int rccInitDefaultContext(const char *locale_variable, unsigned int max_languages, unsigned int max_classes, rcc_class_ptr defclasses, rcc_init_flags flags) {
- if (rcc_default_ctx) return -1;
+ if (!initialized) return -1;
+ if (rcc_default_ctx) rccFreeContext(rcc_default_ctx);
rcc_default_ctx = rccCreateContext(locale_variable, max_languages, max_classes, defclasses, flags);
if (rcc_default_ctx) return 0;
return -1;
diff --git a/src/librcc.h b/src/librcc.h
index 87f09ec..4782418 100644
--- a/src/librcc.h
+++ b/src/librcc.h
@@ -306,6 +306,16 @@ rcc_config rccGetConfiguration();
int rccSave(rcc_context ctx, const char *name);
int rccLoad(rcc_context ctx, const char *name);
+/*******************************************************************************
+**************************** Engine Plugins ************************************
+*******************************************************************************/
+
+typedef rcc_engine *(*rcc_plugin_engine_info_function)(const char *lang);
+
+rcc_engine_internal rccEngineGetInternal(rcc_engine_context ctx);
+rcc_language *rccEngineGetLanguage(rcc_engine_context ctx);
+rcc_context rccEngineGetRccContext(rcc_engine_context ctx);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/plugin.c b/src/plugin.c
index 7935491..274cab9 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -1,5 +1,7 @@
#include <stdio.h>
+#include <string.h>
+#include "internal.h"
#include "plugin.h"
#ifdef RCC_PLUGINS
@@ -13,25 +15,149 @@
rcc_library_handle rccLibraryOpen(char *filename)
{
#ifdef RCC_PLUGINS
- return (rcc_library_handle)dlopen(filename, RTLD_NOW);
-#else
- return NULL;
+ if (filename) return (rcc_library_handle)dlopen(filename, RTLD_NOW);
#endif /* RCC_PLUGINS */
+
+ return NULL;
}
void rccLibraryClose(rcc_library_handle handle)
{
#ifdef RCC_PLUGINS
- puts("HHHHHHHHHHHHHHHHHHHH");
- dlclose(handle);
+ if (handle) dlclose(handle);
#endif /* RCC_PLUGINS */
}
void* rccLibraryFind(rcc_library_handle handle, const char *symbol)
{
#ifdef RCC_PLUGINS
- return dlsym(handle, symbol);
-#else
- return NULL;
+ if ((handle)||(symbol)) return dlsym(handle, symbol);
#endif /* RCC_PLUGINS */
+
+ return NULL;
+}
+
+
+static rcc_plugin_handle_s rcc_engine_handles[RCC_MAX_PLUGINS];
+
+int rccPluginInit() {
+ unsigned int i;
+
+ for (i=0;i<RCC_MAX_PLUGINS;i++)
+ rcc_engine_handles[i].sn = NULL;
+
+ return 0;
+}
+
+void rccPluginFree() {
+ unsigned int i;
+
+ for (i=0;i<RCC_MAX_PLUGINS;i++)
+ if (rcc_engine_handles[i].sn) {
+ rccLibraryClose(rcc_engine_handles[i].handle);
+ free(rcc_engine_handles[i].sn);
+ rcc_engine_handles[i].sn = NULL;
+ }
+}
+
+
+rcc_plugin_handle rccPluginGetHandleByName(rcc_plugin_type type, const char *name) {
+ unsigned int i;
+
+ rcc_plugin_handle handles;
+
+ if (!name) return NULL;
+
+ switch(type) {
+ case RCC_PLUGIN_TYPE_ENGINE:
+ handles = rcc_engine_handles;
+ break;
+ default:
+ return NULL;
+ }
+
+ for (i=0;i<RCC_MAX_PLUGINS;i++)
+ if ((handles[i].sn)&&(!strcasecmp(handles[i].sn, name))) return handles+i;
+
+ return NULL;
+}
+
+rcc_plugin_handle rccPluginGetFreeHandle(rcc_plugin_type type) {
+ unsigned int i;
+
+ rcc_plugin_handle handles;
+
+ switch(type) {
+ case RCC_PLUGIN_TYPE_ENGINE:
+ handles = rcc_engine_handles;
+ break;
+ default:
+ return NULL;
+ }
+
+ for (i=0;i<RCC_MAX_PLUGINS;i++)
+ if (!handles[i].sn) return handles+i;
+
+ return NULL;
+}
+
+rcc_plugin_handle rccPluginLoad(rcc_plugin_type type, const char *name) {
+ FILE *f;
+ void *res;
+ void *infofunc;
+ char *pluginfn;
+
+ rcc_plugin_handle plugin;
+
+ if (!name) return NULL;
+
+ plugin = rccPluginGetHandleByName(type, name);
+ if (plugin) return plugin;
+
+ plugin = rccPluginGetFreeHandle(type);
+ if (!plugin) return plugin;
+
+ switch (type) {
+ case RCC_PLUGIN_TYPE_ENGINE:
+ pluginfn = (char*)malloc((32 + strlen(rcc_home_dir) + strlen(name))*sizeof(char));
+ if (!pluginfn) return NULL;
+
+ sprintf(pluginfn, "%s/.rcc/engines/lib%s.so", rcc_home_dir, name);
+ res = dlopen(pluginfn, RTLD_NOW);
+ if (!res) {
+ sprintf(pluginfn, LIBRCC_DATA_DIR "/engines/lib%s.so", name);
+ res = dlopen(pluginfn, RTLD_NOW);
+ }
+ free(pluginfn);
+
+ if (res) {
+ infofunc = rccLibraryFind(res, "rccGetInfo");
+ if (infofunc) {
+ plugin->sn = strdup(name);
+ if (plugin->sn) {
+ plugin->handle = (rcc_library_handle)res;
+ plugin->info_function = infofunc;
+ return plugin;
+ } else rccLibraryClose(res);
+ } else rccLibraryClose(res);
+ }
+ break;
+ }
+
+ return NULL;
+}
+
+
+rcc_engine *rccPluginEngineGetInfo(const char *name, const char *language) {
+ int err;
+ rcc_plugin_handle handle;
+ rcc_plugin_engine_info_function infofunc;
+
+ handle = rccPluginLoad(RCC_PLUGIN_TYPE_ENGINE, name);
+ if (!handle) return NULL;
+
+ infofunc = (rcc_plugin_engine_info_function)(handle->info_function);
+ if (!infofunc) return NULL;
+
+ return infofunc(language);
}
diff --git a/src/plugin.h b/src/plugin.h
index 1325f03..e742d5f 100644
--- a/src/plugin.h
+++ b/src/plugin.h
@@ -13,4 +13,27 @@ rcc_library_handle rccLibraryOpen(char *filename);
void rccLibraryClose(rcc_library_handle handle);
void* rccLibraryFind(rcc_library_handle handle, const char *symbol);
+
+typedef enum rcc_plugin_type_t {
+ RCC_PLUGIN_TYPE_SYSTEMLIB = 0,
+ RCC_PLUGIN_TYPE_ENGINE,
+ RCC_PLUGIN_TYPE_MAX
+} rcc_plugin_type;
+
+struct rcc_plugin_handle_t {
+ const char *sn;
+ rcc_library_handle handle;
+ void *info_function;
+// rcc_library_type type;
+};
+
+typedef struct rcc_plugin_handle_t rcc_plugin_handle_s;
+typedef struct rcc_plugin_handle_t *rcc_plugin_handle;
+
+int rccPluginInit();
+void rccPluginFree();
+
+rcc_plugin_handle rccPluginLoad(rcc_plugin_type type, const char *name);
+rcc_engine *rccPluginEngineGetInfo(const char *name, const char *language);
+
#endif /* _RCC_PLUGIN_H */
diff --git a/src/rccconfig.c b/src/rccconfig.c
index e2a0740..37b6cc0 100644
--- a/src/rccconfig.c
+++ b/src/rccconfig.c
@@ -11,6 +11,8 @@ rcc_language_alias rcc_default_aliases[] = {
{ NULL, NULL}
};
+const char rcc_default_charset[] = "Default";
+const char rcc_utf8_charset[] = "UTF-8";
const char rcc_engine_nonconfigured[] = "Default";
const char rcc_option_nonconfigured[] = "DEFAULT";
@@ -22,74 +24,80 @@ rcc_engine rcc_russian_engine = {
"Russian", NULL, NULL, &rccAutoengineRussian, {"CP1251","KOI8-R","UTF-8","IBM866", NULL}
};
-rcc_language rcc_default_languages[RCC_MAX_LANGUAGES + 1] = {
-{"default", {"Default", NULL}, {
+rcc_engine rcc_ukrainian_engine = {
+ "Russian", NULL, NULL, &rccAutoengineRussian, {"CP1251","KOI8-U","UTF-8","IBM865", NULL}
+};
+
+rcc_language rcc_default_languages[RCC_MAX_LANGUAGES + 1];
+
+rcc_language rcc_default_languages_embeded[RCC_MAX_LANGUAGES + 1] = {
+{"default", {rcc_default_charset, NULL}, {
&rcc_default_engine,
NULL
}},
-{"off", {"Default", NULL}, {
+{"off", {rcc_default_charset, NULL}, {
&rcc_default_engine,
NULL
}},
-{"ru", {"Default","KOI8-R","CP1251","UTF-8","IBM866","MACCYRILLIC","ISO8859-5", NULL}, {
+{"ru", {rcc_default_charset,"KOI8-R","CP1251",rcc_utf8_charset,"IBM866","MACCYRILLIC","ISO8859-5", NULL}, {
&rcc_default_engine,
#ifdef RCC_RCD_SUPPORT
&rcc_russian_engine,
#endif /* RCC_RCD_SUPPORT */
NULL
}},
-{"uk", {"Default","KOI8-U","CP1251","UTF-8","IBM855","MACCYRILLIC","ISO8859-5","CP1125", NULL}, {
+{"uk", {rcc_default_charset,"KOI8-U","CP1251",rcc_utf8_charset,"IBM855","MACCYRILLIC","ISO8859-5","CP1125", NULL}, {
&rcc_default_engine,
#ifdef RCC_RCD_SUPPORT
- &rcc_russian_engine,
+ &rcc_ukrainian_engine,
#endif /* RCC_RCD_SUPPORT */
NULL
}},
-{"be", {"Default", "UTF-8", "CP1251", "IBM866", "ISO-8859-5", "KOI8-UNI", "maccyr" "IBM855", NULL},{
+{"be", {rcc_default_charset, rcc_utf8_charset, "CP1251", "IBM866", "ISO-8859-5", "KOI8-UNI", "maccyr" "IBM855", NULL},{
&rcc_default_engine,
NULL
}},
-{"bg", {"Default", "UTF-8", "CP1251", "ISO-8859-5", "IBM855", "maccyr", "ECMA-113", NULL},{
+{"bg", {rcc_default_charset, rcc_utf8_charset, "CP1251", "ISO-8859-5", "IBM855", "maccyr", "ECMA-113", NULL},{
&rcc_default_engine,
NULL
}},
-{"cz", {"Default", "UTF-8", "ISO-8859-2", "CP1250", "IBM852", "KEYBCS2", "macce", "KOI-8_CS_2", "CORK", NULL},{
+{"cz", {rcc_default_charset, rcc_utf8_charset, "ISO-8859-2", "CP1250", "IBM852", "KEYBCS2", "macce", "KOI-8_CS_2", "CORK", NULL},{
&rcc_default_engine,
NULL
}},
-{"es", {"Default", "UTF-8", "ISO-8859-4", "CP1257", "IBM775", "ISO-8859-13", "macce", "baltic", NULL},{
+{"es", {rcc_default_charset, rcc_utf8_charset, "ISO-8859-4", "CP1257", "IBM775", "ISO-8859-13", "macce", "baltic", NULL},{
&rcc_default_engine,
NULL
}},
-{"hr", {"Default", "UTF-8", "CP1250", "ISO-8859-2", "IBM852", "macce", "CORK", NULL},{
+{"hr", {rcc_default_charset, rcc_utf8_charset, "CP1250", "ISO-8859-2", "IBM852", "macce", "CORK", NULL},{
&rcc_default_engine,
NULL
}},
-{"hu", {"Default", "UTF-8", "ISO-8859-2", "CP1250", "IBM852", "macce", "CORK", NULL},{
+{"hu", {rcc_default_charset, rcc_utf8_charset, "ISO-8859-2", "CP1250", "IBM852", "macce", "CORK", NULL},{
&rcc_default_engine,
NULL
}},
-{"lt", {"Default", "UTF-8", "CP1257", "ISO-8859-4", "IBM775", "ISO-8859-13", "macce", "baltic", NULL},{
+{"lt", {rcc_default_charset, rcc_utf8_charset, "CP1257", "ISO-8859-4", "IBM775", "ISO-8859-13", "macce", "baltic", NULL},{
&rcc_default_engine,
NULL
}},
-{"lv", {"Default", "UTF-8", "CP1257", "ISO-8859-4", "IBM775", "ISO-8859-13", "macce", "baltic", NULL},{
+{"lv", {rcc_default_charset, rcc_utf8_charset, "CP1257", "ISO-8859-4", "IBM775", "ISO-8859-13", "macce", "baltic", NULL},{
&rcc_default_engine,
NULL
}},
-{"pl", {"Default", "UTF-8", "ISO-8859-2", "CP1250", "IBM852", "macce", "ISO-8859-13", "ISO-8859-16", "baltic", "CORK", NULL},{
+{"pl", {rcc_default_charset, rcc_utf8_charset, "ISO-8859-2", "CP1250", "IBM852", "macce", "ISO-8859-13", "ISO-8859-16", "baltic", "CORK", NULL},{
&rcc_default_engine,
NULL
}},
-{"sk", {"Default", "UTF-8", "CP1250", "ISO-8859-2", "IBM852", "KEYBCS2", "macce", "KOI-8_CS_2", "CORK", NULL},{
+{"sk", {rcc_default_charset, rcc_utf8_charset, "CP1250", "ISO-8859-2", "IBM852", "KEYBCS2", "macce", "KOI-8_CS_2", "CORK", NULL},{
&rcc_default_engine,
NULL
}},
-{"sl", {"Default", "UTF-8", "ISO-8859-2", "CP1250", "IBM852", "macce", "CORK", NULL},{
+{"sl", {rcc_default_charset, rcc_utf8_charset, "ISO-8859-2", "CP1250", "IBM852", "macce", "CORK", NULL},{
&rcc_default_engine,
NULL
}},
-{"zh", {"Default", "UTF-8", "GB2312", "GBK", "GB18030", "BIG5", NULL},{
+{"zh", {rcc_default_charset, rcc_utf8_charset, "GB2312", "GBK", "GB18030", "BIG5", NULL},{
&rcc_default_engine,
NULL
}},
@@ -100,7 +108,8 @@ rcc_option_value_name rcc_sn_boolean[] = { "OFF", "ON", NULL };
rcc_option_value_name rcc_sn_learning[] = { "OFF", "ON", "RELEARN", "LEARN", NULL };
rcc_option_value_name rcc_sn_clo[] = { "ALL", "CONFIGURED_AND_AUTO", "CONFIGURED_ONLY", NULL };
-rcc_option_description rcc_option_descriptions[] = {
+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},
@@ -129,3 +138,14 @@ rcc_option_description *rccGetOptionDescriptionByName(const char *name) {
return NULL;
}
+
+rcc_language_id rccDefaultGetLanguageByName(const char *name) {
+ unsigned int i;
+
+ if (!name) return (rcc_language_id)-1;
+
+ for (i=0;rcc_default_languages[i].sn;i++)
+ if (!strcasecmp(rcc_default_languages[i].sn, name)) return (rcc_language_id)i;
+
+ return (rcc_language_id)-1;
+}
diff --git a/src/rccconfig.h b/src/rccconfig.h
index fa644cc..868974f 100644
--- a/src/rccconfig.h
+++ b/src/rccconfig.h
@@ -7,18 +7,24 @@
#define RCC_LOCALE_VARIABLE "LC_CTYPE"
extern rcc_language_alias rcc_default_aliases[];
+extern const char rcc_default_charset[];
+extern const char rcc_utf8_charset[];
extern const char rcc_engine_nonconfigured[];
extern const char rcc_option_nonconfigured[];
extern rcc_engine rcc_default_engine;
extern rcc_engine rcc_russian_engine;
+extern rcc_engine rcc_ukrainian_engine;
+extern rcc_language rcc_default_languages_embeded[];
extern rcc_language rcc_default_languages[];
-
+extern rcc_option_description rcc_option_descriptions_embeded[];
extern rcc_option_description rcc_option_descriptions[];
rcc_option_description *rccGetOptionDescription(rcc_option option);
rcc_option_description *rccGetOptionDescriptionByName(const char *name);
+rcc_language_id rccDefaultGetLanguageByName(const char *name);
+
#endif /* _RCC_CONFIG_H */
diff --git a/src/rccxml.c b/src/rccxml.c
index bbeff42..4ce1764 100644
--- a/src/rccxml.c
+++ b/src/rccxml.c
@@ -13,6 +13,7 @@
#include "internal.h"
#include "rccconfig.h"
+#include "plugin.h"
#define MAX_HOME_CHARS 96
#define XPATH_LANGUAGE "//Language[@name]"
@@ -27,7 +28,7 @@ static const char *rccXmlGetText(xmlNodePtr node) {
if ((node)&&(node->children)&&(node->children->type == XML_TEXT_NODE)&&(node->children->content)) return node->children->content;
}
-int rccXmlInit() {
+int rccXmlInit(int LoadConfiguration) {
FILE *f;
char config[MAX_HOME_CHARS + 32];
@@ -35,28 +36,32 @@ int rccXmlInit() {
xmlXPathObjectPtr obj;
xmlNodeSetPtr node_set;
unsigned long i, nnodes;
- xmlNodePtr cnode, pnode, node;
+ xmlNodePtr enode, cnode, pnode, node;
xmlAttrPtr attr;
- const char *lang, *fullname;
- unsigned int pos, cpos;
+ const char *lang, *fullname, *engine_name;
+ unsigned int pos, lpos, epos, cpos;
+
+ rcc_engine *engine;
xmlInitParser();
xmlInitCharEncodingHandlers();
xmlKeepBlanksDefault(0);
- if (strlen(rcc_home_dir)>MAX_HOME_CHARS) config[0] = 0;
- else {
- sprintf(config, "%s/.rcc/rcc.xml", rcc_home_dir);
- f = fopen(config, "r");
- if (f) fclose(f);
- else config[0] = 0;
- }
- if (!config[0]) {
- strcpy(config, "/etc/rcc.xml");
- f = fopen(config, "r");
- if (f) fclose(f);
- else config[0] = 0;
- }
+ if (LoadConfiguration) {
+ if (strlen(rcc_home_dir)>MAX_HOME_CHARS) config[0] = 0;
+ else {
+ sprintf(config, "%s/.rcc/rcc.xml", rcc_home_dir);
+ f = fopen(config, "r");
+ if (f) fclose(f);
+ else config[0] = 0;
+ }
+ if (!config[0]) {
+ strcpy(config, "/etc/rcc.xml");
+ f = fopen(config, "r");
+ if (f) fclose(f);
+ else config[0] = 0;
+ }
+ } else config[0] = 0;
// Load Extra Languages
@@ -73,8 +78,7 @@ int rccXmlInit() {
node_set = obj->nodesetval;
if (!node_set) goto clear;
- for (pos = 0; rcc_default_languages[pos].sn; pos++);
- if (pos == RCC_MAX_LANGUAGES) goto clear;
+ for (lpos = 0; rcc_default_languages[lpos].sn; lpos++);
nnodes = node_set->nodeNr;
for (i=0;i<nnodes;i++) {
@@ -84,28 +88,47 @@ int rccXmlInit() {
if ((!lang)||(!lang[0])) continue;
- for (cpos=1,node=pnode->children;node;node=node->next) {
+ pos = rccDefaultGetLanguageByName(lang);
+ if (!pos) continue;
+ if (pos == (rcc_language_id)-1) pos = lpos;
+ else if (pos == RCC_MAX_LANGUAGES) continue;
+
+ for (epos = 1, cpos = 1,node=pnode->children;node;node=node->next) {
if (node->type != XML_ELEMENT_NODE) continue;
if (!xmlStrcmp(node->name, "Charsets")) {
- for (cpos = 0, cnode=node->children;cnode;cnode=cnode->next) {
+ for (cnode=node->children;cnode;cnode=cnode->next) {
if (cnode->type != XML_ELEMENT_NODE) continue;
if ((!xmlStrcmp(cnode->name, "Charset"))&&(rccXmlGetText(cnode))&&(cpos<RCC_MAX_CHARSETS)) {
rcc_default_languages[pos].charsets[cpos++] = rccXmlGetText(cnode);
}
}
}
+ if (!xmlStrcmp(node->name, "Engines")) {
+ for (enode=node->children;enode;enode=enode->next) {
+ if (enode->type != XML_ELEMENT_NODE) continue;
+ if ((!xmlStrcmp(enode->name, "Engine"))&&(rccXmlGetText(enode))&&(epos<RCC_MAX_ENGINES)) {
+ engine_name = rccXmlGetText(enode);
+ if (!engine_name) continue;
+ engine = rccPluginEngineGetInfo(engine_name, lang);
+ if (!engine) continue;
+
+ rcc_default_languages[pos].engines[epos++] = engine;
+ }
+ }
+ }
}
- if (cpos > 1) {
- rcc_default_languages[pos].sn = lang;
- rcc_default_languages[pos].charsets[0] = "Default";
- rcc_default_languages[pos].charsets[cpos] = NULL;
- rcc_default_languages[pos].engines[0] = &rcc_default_engine;
- rcc_default_languages[pos].engines[1] = NULL;
-
- rcc_default_languages[++pos].sn = NULL;
- if (pos == RCC_MAX_LANGUAGES) break;
+ rcc_default_languages[pos].sn = lang;
+ rcc_default_languages[pos].charsets[0] = rcc_default_charset;
+ if (cpos > 1) rcc_default_languages[pos].charsets[cpos] = NULL;
+ else {
+ rcc_default_languages[pos].charsets[1] = rcc_utf8_charset;
+ rcc_default_languages[pos].charsets[2] = NULL;
}
+ rcc_default_languages[pos].engines[0] = &rcc_default_engine;
+ rcc_default_languages[pos].engines[epos] = NULL;
+
+ if (pos == lpos) rcc_default_languages[++lpos].sn = NULL;
}
clear:
diff --git a/src/rccxml.h b/src/rccxml.h
index 3f0382e..d8d07bf 100644
--- a/src/rccxml.h
+++ b/src/rccxml.h
@@ -1,7 +1,7 @@
#ifndef _RCC_XML_H
#define _RCC_XML_H
-int rccXmlInit();
+int rccXmlInit(int LoadConfiguration);
void rccXmlFree();
#endif /* _RCC_XML_H */