diff options
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.in | 11 | ||||
-rw-r--r-- | engines/Makefile.am | 11 | ||||
-rw-r--r-- | engines/russian.c | 25 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/engine.c | 12 | ||||
-rw-r--r-- | src/engine.h | 2 | ||||
-rw-r--r-- | src/internal.h | 6 | ||||
-rw-r--r-- | src/librcc.c | 14 | ||||
-rw-r--r-- | src/librcc.h | 10 | ||||
-rw-r--r-- | src/plugin.c | 142 | ||||
-rw-r--r-- | src/plugin.h | 23 | ||||
-rw-r--r-- | src/rccconfig.c | 58 | ||||
-rw-r--r-- | src/rccconfig.h | 8 | ||||
-rw-r--r-- | src/rccxml.c | 83 | ||||
-rw-r--r-- | src/rccxml.h | 2 |
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 */ |