diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/internal.h | 1 | ||||
-rw-r--r-- | src/librcc.c | 71 | ||||
-rw-r--r-- | src/librcc.h | 15 | ||||
-rw-r--r-- | src/lngconfig.c | 26 | ||||
-rw-r--r-- | src/opt.c | 23 | ||||
-rw-r--r-- | src/opt.h | 5 | ||||
-rw-r--r-- | src/rccconfig.c | 77 | ||||
-rw-r--r-- | src/rccconfig.h | 1 | ||||
-rw-r--r-- | src/rccxml.c | 464 | ||||
-rw-r--r-- | src/rccxml.h (renamed from src/xml.h) | 3 | ||||
-rw-r--r-- | src/xml.c | 14 |
12 files changed, 670 insertions, 32 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index b45d4b1..bef8240 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,7 +11,7 @@ librcc_la_SOURCES = librcc.c \ rccenca.c rccenca.h \ engine.c engine.h \ rccstring.c rccstring.h \ - xml.c xml.h \ + rccxml.c rccxml.h \ rcciconv.c rcciconv.h \ fs.c fs.h \ recode.c recode.h \ diff --git a/src/internal.h b/src/internal.h index 24e9cc8..1706ff5 100644 --- a/src/internal.h +++ b/src/internal.h @@ -15,6 +15,7 @@ struct rcc_context_t { rcc_language_alias_list aliases; rcc_option_value options[RCC_MAX_OPTIONS]; + unsigned char default_options[RCC_MAX_OPTIONS]; unsigned int max_languages; unsigned int n_languages; diff --git a/src/librcc.c b/src/librcc.c index d6acc72..5b6a66f 100644 --- a/src/librcc.c +++ b/src/librcc.c @@ -1,22 +1,79 @@ #include <stdio.h> +#include <stdlib.h> #include <string.h> +#include "../config.h" + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif /* HAVE_UNISTD_H */ + +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif /* HAVE_SYS_TYPES_H */ + +#ifdef HAVE_PWD_H +# include <pwd.h> +#endif /* HAVE_PWD_H */ + #include <librcd.h> #include "internal.h" #include "rccconfig.h" #include "rccenca.h" #include "rcclist.h" +#include "rccenca.h" +#include "rccxml.h" - +static int initialized = 0; +char *rcc_home_dir = NULL; int rccInit() { - /*DS: Load addition languages from config! */ - return rccEncaInit(); + int err; + char *tmp; + +#ifdef HAVE_PWD_H + struct passwd *pw; +#endif /* HAVE_PWD_H */ + + if (initialized) return 0; + + tmp = getenv ("HOME"); + if (tmp) rcc_home_dir = strdup (tmp); +#ifdef HAVE_PWD_H + else { + setpwent (); + pw = getpwuid(getuid ()); + endpwent (); + if ((pw)&&(pw->pw_dir)) rcc_home_dir = strdup (pw->pw_dir); + } +#endif /* HAVE_PWD_H */ + if (!rcc_home_dir) rcc_home_dir = strdup("/"); + + + err = rccEncaInit(); + if (!err) err = rccXmlInit(); + + if (err) { + rccFree(); + return err; + } + + initialized = 1; + + return 0; } void rccFree() { + rccXmlFree(); rccEncaFree(); + + if (rcc_home_dir) { + free(rcc_home_dir); + rcc_home_dir = NULL; + } + + initialized = 0; } rcc_context rccCreateContext(const char *locale_variable, unsigned int max_languages, unsigned int max_classes, rcc_class_ptr defclasses, rcc_init_flags flags) { @@ -137,8 +194,10 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu } } - for (i=0;i<RCC_MAX_OPTIONS;i++) - ctx->options[i] = 0; + for (i=0;i<RCC_MAX_OPTIONS;i++) { + ctx->options[i] = rccGetOptionDefaultValue((rcc_option)i); + ctx->default_options[i] = 1; + } ctx->configure = 1; @@ -258,12 +317,10 @@ rcc_alias_id rccRegisterLanguageAlias(rcc_context ctx, rcc_language_alias *alias } rcc_class_id rccRegisterClass(rcc_context ctx, rcc_class *cl) { - puts("yes"); if ((!ctx)||(!cl)) return -1; if (ctx->configuration_lock) return -3; if (ctx->n_classes == ctx->max_classes) return -2; - puts(" -----> New class"); ctx->configure = 1; ctx->classes[ctx->n_classes++] = cl; ctx->classes[ctx->n_classes] = NULL; diff --git a/src/librcc.h b/src/librcc.h index 6e40130..1f5ee72 100644 --- a/src/librcc.h +++ b/src/librcc.h @@ -140,6 +140,8 @@ typedef enum rcc_option_t { struct rcc_option_name_t { rcc_option option; const char *name; + + const char *sn; }; typedef struct rcc_option_name_t rcc_option_name; @@ -158,6 +160,8 @@ int rccSetLanguageByName(rcc_context ctx, const char *name); /* opt.c */ rcc_option_value rccGetOption(rcc_context ctx, rcc_option option); +int rccOptionIsDefault(rcc_context ctx, rcc_option option); +int rccOptionSetDefault(rcc_context ctx, rcc_option option); int rccSetOption(rcc_context ctx, rcc_option option, rcc_option_value value); /* lngconfig.c */ @@ -169,6 +173,7 @@ rcc_engine_id rccConfigGetEngineByName(rcc_language_config config, const char *n rcc_charset_id rccConfigGetCharsetByName(rcc_language_config config, const char *name); rcc_charset_id rccConfigGetAutoCharsetByName(rcc_language_config config, const char *name); +rcc_language_config rccCheckConfig(rcc_context ctx, rcc_language_id language_id); rcc_language_config rccGetConfig(rcc_context ctx, rcc_language_id language_id); rcc_language_config rccGetConfigByName(rcc_context ctx, const char *name); rcc_language_config rccGetCurrentConfig(rcc_context ctx); @@ -226,6 +231,16 @@ rcc_engine_ptr *rccGetCurrentEngineList(rcc_context ctx); rcc_charset *rccGetCurrentAutoCharsetList(rcc_context ctx); rcc_class_ptr *rccGetClassList(rcc_context ctx); +/******************************************************************************* +************************ Default Configuaration ******************************** +*******************************************************************************/ + +/* rccconfig.c */ +const char *rccGetOptionName(rcc_option option); +const char *rccGetOptionFullName(rcc_option option); +rcc_option_value rccGetOptionDefaultValue(rcc_option option); +const char *rccGetLanguageFullName(const char *lang); + /******************************************************************************* ************************ RCC_STRING Manipulations ****************************** diff --git a/src/lngconfig.c b/src/lngconfig.c index ad87189..67b7e0b 100644 --- a/src/lngconfig.c +++ b/src/lngconfig.c @@ -127,6 +127,17 @@ int rccConfigFree(rcc_language_config config) { } } +rcc_language_config rccCheckConfig(rcc_context ctx, rcc_language_id language_id) { + rcc_language_id new_language_id; + int err; + + new_language_id = rccGetRealLanguage(ctx, language_id); + if ((language_id<=0)||(new_language_id != language_id)) return NULL; + if (!ctx->configs[language_id].charset) return NULL; + if (!strcasecmp(ctx->languages[language_id]->sn, "off")) return NULL; + + return ctx->configs + language_id; +} rcc_language_config rccGetConfig(rcc_context ctx, rcc_language_id language_id) { int err; @@ -271,10 +282,12 @@ const char *rccConfigGetCurrentCharsetName(rcc_language_config config, rcc_class int rccConfigSetEngine(rcc_language_config config, rcc_engine_id engine_id) { unsigned int i; - if ((!config)||(!config->language)||(engine_id < 0)) return -1; + if ((!config)||(!config->language)||(engine_id < -1)) return -1; - for (i=0;config->language->engines[i];i++); - if (engine_id >= i) return -1; + if (engine_id != (rcc_engine_id)-1) { + for (i=0;config->language->engines[i];i++); + if (engine_id >= i) return -1; + } if (config->engine != engine_id) { if (config->ctx->current_config == config) config->ctx->configure = 1; @@ -285,7 +298,12 @@ int rccConfigSetEngine(rcc_language_config config, rcc_engine_id engine_id) { int rccConfigSetEngineByName(rcc_language_config config, const char *name) { rcc_engine_id engine_id; - + + if (!config) return -1; + + if ((!name)||(!strcasecmp(name,rcc_engine_nonconfigured))) + return rccConfigSetEngine(config, (rcc_engine_id)-1); + engine_id = rccConfigGetEngineByName(config, name); if (engine_id < 0) return -1; @@ -9,9 +9,32 @@ rcc_option_value rccGetOption(rcc_context ctx, rcc_option option) { return ctx->options[option]; } +int rccOptionIsDefault(rcc_context ctx, rcc_option option) { + if ((!ctx)||(option<0)||(option>=RCC_MAX_OPTIONS)) return -1; + + return ctx->default_options[option]; +} + int rccSetOption(rcc_context ctx, rcc_option option, rcc_option_value value) { if ((!ctx)||(option>=RCC_MAX_OPTIONS)) return -1; + ctx->default_options[option] = 0; + + if (ctx->options[option] != value) { + ctx->configure = 1; + ctx->options[option]=value; + } + + return 0; +} + +int rccOptionSetDefault(rcc_context ctx, rcc_option option) { + rcc_option_value value; + if ((!ctx)||(option>=RCC_MAX_OPTIONS)) return -1; + + ctx->default_options[option] = 1; + value = rccGetOptionDefaultValue(option); + if (ctx->options[option] != value) { ctx->configure = 1; ctx->options[option]=value; @@ -1,5 +1,10 @@ #ifndef _RCC_OPT_H #define _RCC_OPT_H +struct rcc_option_defval_t { + rcc_option option; + rcc_option_value value; +}; +typedef struct rcc_option_defval_t rcc_option_defval; #endif /* _RCC_OPT_H */ diff --git a/src/rccconfig.c b/src/rccconfig.c index 6d0a372..e1ac34a 100644 --- a/src/rccconfig.c +++ b/src/rccconfig.c @@ -3,6 +3,7 @@ #include "internal.h" #include "rccconfig.h" +#include "opt.h" static rcc_charset_id rcc_autoengine_russian(rcc_engine_context ctx, const char *buf, int len) { return (rcc_charset_id)rcdGetRussianCharset(buf,len); @@ -14,7 +15,8 @@ rcc_language_alias rcc_default_aliases[] = { { NULL, NULL} }; -const char rcc_engine_nonconfigured[] = "NonConfigured"; +const char rcc_engine_nonconfigured[] = "default"; +const char rcc_option_nonconfigured[] = "default"; rcc_engine rcc_default_engine = { "Off", NULL, NULL, NULL, {NULL} @@ -24,7 +26,7 @@ rcc_engine rcc_russian_engine = { "Russian", NULL, NULL, &rcc_autoengine_russian, {"CP1251","KOI8-R","UTF-8","IBM866", NULL} }; -rcc_language rcc_default_languages[] = { +rcc_language rcc_default_languages[RCC_MAX_LANGUAGES + 1] = { {"default", {"Default", NULL}, { &rcc_default_engine, NULL @@ -115,8 +117,71 @@ rcc_language_name rcc_default_language_names[RCC_MAX_LANGUAGES+1] = { }; rcc_option_name rcc_default_option_names[] = { - { RCC_LEARNING_MODE, "Learning Mode" }, - { RCC_AUTODETECT_FS_TITLES, "Autodetect FS Encoding" }, - { RCC_AUTODETECT_FS_NAMES, "Autodetect File Names" }, - { RCC_MAX_OPTIONS, NULL} + { RCC_LEARNING_MODE, "Learning Mode", "LEARNING_MODE" }, + { RCC_AUTODETECT_FS_TITLES, "Autodetect FS Encoding", "AUTODETECT_FS_TITLES" }, + { RCC_AUTODETECT_FS_NAMES, "Autodetect File Names", "AUTODETECT_FS_NAMES" }, + { RCC_MAX_OPTIONS, NULL, NULL} }; + +rcc_option_defval rcc_default_option_values[] = { + { RCC_LEARNING_MODE, 0 }, + { RCC_AUTODETECT_FS_TITLES, 1}, + { RCC_AUTODETECT_FS_NAMES, 1}, + { RCC_MAX_OPTIONS, 0} +}; + +const char *rccGetLanguageFullName(const char *lang) { + unsigned int i; + rcc_language_name *names; + + if (!lang) return NULL; + + names = rcc_default_language_names; + + for (i=0;names[i].sn;i++) + if (!strcmp(lang, names[i].sn)) return names[i].name; + + return NULL; +} + +const char *rccGetOptionName(rcc_option option) { + unsigned int i; + rcc_option_name *names; + + if ((option<0)||(option>=RCC_MAX_OPTIONS)) return NULL; + + names = rcc_default_option_names; + + for (i=0;names[i].option!=RCC_MAX_OPTIONS;i++) + if (names[i].option == option) return names[i].sn; + + return NULL; +} + +const char *rccGetOptionFullName(rcc_option option) { + unsigned int i; + rcc_option_name *names; + + if ((option<0)||(option>=RCC_MAX_OPTIONS)) return NULL; + + names = rcc_default_option_names; + + for (i=0;names[i].option!=RCC_MAX_OPTIONS;i++) + if (names[i].option == option) return names[i].name; + + return NULL; +} + +rcc_option_value rccGetOptionDefaultValue(rcc_option option) { + unsigned int i; + rcc_option_defval *values; + + if ((option<0)||(option>=RCC_MAX_OPTIONS)) return 0; + + values = rcc_default_option_values; + + for (i=0;values[i].option!=RCC_MAX_OPTIONS;i++) + if (values[i].option == option) return values[i].value; + + return 0; +} diff --git a/src/rccconfig.h b/src/rccconfig.h index 8ca4810..89bbac8 100644 --- a/src/rccconfig.h +++ b/src/rccconfig.h @@ -8,6 +8,7 @@ extern rcc_language_alias rcc_default_aliases[]; extern const char rcc_engine_nonconfigured[]; +extern const char rcc_option_nonconfigured[]; extern rcc_engine rcc_default_engine; extern rcc_engine rcc_russian_engine; diff --git a/src/rccxml.c b/src/rccxml.c new file mode 100644 index 0000000..8283a39 --- /dev/null +++ b/src/rccxml.c @@ -0,0 +1,464 @@ +#include <stdio.h> +#include <stdarg.h> + +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/file.h> + +#include <libxml/parser.h> +#include <libxml/tree.h> +#include <libxml/xpath.h> + +#include "internal.h" +#include "rccconfig.h" + +extern char *rcc_home_dir; + +#define MAX_HOME_CHARS 96 +#define XPATH_LANGUAGE "//Language[@name]" + +static xmlDocPtr xmlctx = NULL; + +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() { + FILE *f; + char config[MAX_HOME_CHARS + 32]; + + xmlXPathContextPtr xpathctx; + xmlXPathObjectPtr obj; + xmlNodeSetPtr node_set; + unsigned long i, nnodes; + xmlNodePtr cnode, pnode, node; + xmlAttrPtr attr; + const char *lang, *fullname; + unsigned int pos, cpos, npos; + + 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; + } + + + // Load Extra Languages + if (config[0]) { + xmlctx = xmlReadFile(config, NULL, 0); + if (!xmlctx) goto clear; + + xpathctx = xmlXPathNewContext(xmlctx); + if (!xpathctx) goto clear; + + obj = xmlXPathEvalExpression(XPATH_LANGUAGE, xpathctx); + if (!obj) goto clear; + + node_set = obj->nodesetval; + if (!node_set) return 0; + + for (pos = 0; rcc_default_languages[pos].sn; pos++); + if (pos == RCC_MAX_LANGUAGES) goto clear; + + for (npos = 0; rcc_default_language_names[npos].sn; npos++); + puts("+++"); + + + nnodes = node_set->nodeNr; + for (i=0;i<nnodes;i++) { + pnode = node_set->nodeTab[i]; + attr = xmlHasProp(pnode, "name"); + lang = attr->children->content; + + if ((!lang)||(!lang[0])) continue; + puts(lang); + + for (cpos=1,fullname=NULL,node=pnode->children;node;node=node->next) { + if (node->type != XML_ELEMENT_NODE) continue; + puts(node->name); + if (!xmlStrcmp(node->name, "Charsets")) { + for (cpos = 0, 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); + } + } + } else if (!xmlStrcmp(node->name, "FullName")) { + if (rccXmlGetText(node)) fullname = rccXmlGetText(node); + } + } + + 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; + if ((fullname)&&(npos<RCC_MAX_LANGUAGES)) { + rcc_default_language_names[npos].sn = lang; + rcc_default_language_names[npos].name = fullname; + rcc_default_language_names[++npos].sn = NULL; + rcc_default_language_names[npos].name = NULL; + } + + rcc_default_languages[++pos].sn = NULL; + if (pos == RCC_MAX_LANGUAGES) break; + } + } + +clear: + if (xmlctx) { + if (xpathctx) { + xmlXPathFreeContext(xpathctx); + if (obj) { + xmlXPathFreeObject(obj); + } + } + } + } +} + +void rccXmlFree() { + if (xmlctx) { + xmlFreeDoc(xmlctx); + xmlctx = NULL; + } + + xmlCleanupCharEncodingHandlers(); + xmlCleanupParser(); +} + + +static xmlNodePtr rccNodeFind(xmlXPathContextPtr xpathctx, const char *request, ...) { + xmlXPathObjectPtr obj; + xmlNodeSetPtr node_set; + xmlNodePtr res = NULL; + + unsigned int i, args = 0; + unsigned int size = 64; + va_list ap; + char *req; + + for (req = strstr(request, "%s"); req; req = strstr(req + 1, "%s")) args++; + + if (args) { + va_start(ap, request); + for (i=0;i<args;i++) { + req = va_arg(ap, char*); + size += strlen(req); + } + va_end(ap); + + req = (char*)malloc(size*sizeof(char)); + if (!req) return NULL; + + va_start(ap, request); + vsprintf(req,request,ap); + va_end(ap); + } else req = (char*)request; + + obj = xmlXPathEvalExpression(req, xpathctx); + if (obj) { + node_set = obj->nodesetval; + if (node_set->nodeNr > 0) { + res = node_set->nodeTab[0]; + } + xmlXPathFreeObject(obj); + } + + if (args) free(req); + + return res; +} + +#define XPATH_SELECTED "/Config" +#define XPATH_SELECTED_LANGUAGE "/Config/Language" +#define XPATH_SELECTED_OPTIONS "/Config/Options" +#define XPATH_SELECTED_OPTION "/Config/Options/Option[@name=\"%s\"]" + +#define XPATH_SELECTED_LANGS "/Config/Languages" +#define XPATH_SELECTED_LANG "/Config/Languages/Language[@name=\"%s\"]" +#define XPATH_SELECTED_ENGINE "/Config/Languages/Language[@name=\"%s\"]/Engine" +#define XPATH_SELECTED_CLASSES "/Config/Languages/Language[@name=\"%s\"]/Classes" +#define XPATH_SELECTED_CLASS "/Config/Languages/Language[@name=\"%s\"]/Classes/Class[@name=\"%s\"]" + +int rccSave(rcc_context ctx, const char *name) { + int fd; + char *config; + struct stat st; + + unsigned int i, j, size; + + rcc_language_ptr *languages; + rcc_language_ptr language; + rcc_language_config cfg; + rcc_class_ptr *classes; + rcc_class_ptr cl; + + xmlXPathContextPtr xpathctx; + xmlDocPtr doc = NULL; + xmlNodePtr pnode, lnode, onode, llnode, cnode, enode, node; + unsigned char oflag = 0, llflag = 0, cflag; + const char *oname; + char value[16]; + + int memsize; + xmlChar *mem; + + if ((!name)||(!strcmp(name, "rcc"))||(strlen(rcc_home_dir)<3)) name = "default"; + + size = strlen(rcc_home_dir) + strlen(name) + 32; + config = (char*)malloc(size*sizeof(char)); + if (!config) return -1; + + sprintf(config,"%s/.rcc/",rcc_home_dir); + mkdir(config, 00644); + + sprintf(config,"%s/.rcc/%s.xml",rcc_home_dir,name); + fd = open(config, O_CREAT|O_RDWR,00644); + if (fd == -1) goto clear; + flock(fd, LOCK_EX); + + if ((!fstat(fd, &st))&&(st.st_size)) { + doc = xmlReadFd(fd, config, NULL, 0); + } + + if (!doc) { + doc = xmlNewDoc("1.0"); + if (!doc) goto clear; + } + + xpathctx = xmlXPathNewContext(doc); + if (!xpathctx) goto clear; + + pnode = rccNodeFind(xpathctx, XPATH_SELECTED); + if (pnode) { + lnode = rccNodeFind(xpathctx, XPATH_SELECTED_LANGUAGE); + onode = rccNodeFind(xpathctx, XPATH_SELECTED_OPTIONS); + llnode = rccNodeFind(xpathctx, XPATH_SELECTED_LANGS); + } else { + pnode = xmlNewChild((xmlNodePtr)doc, NULL, "Config", NULL); + lnode = NULL; + onode = NULL; + llnode = NULL; + } + + if (lnode) xmlNodeSetContent(lnode, rccGetSelectedLanguageName(ctx)); + else lnode = xmlNewChild(pnode,NULL, "Language", rccGetSelectedLanguageName(ctx)); + + if (onode) oflag = 1; + else onode = xmlNewChild(pnode, NULL, "Options", NULL); + + for (i=0;i<RCC_MAX_OPTIONS;i++) { + oname = rccGetOptionName(i); + if (!oname) continue; + + if (oflag) node = rccNodeFind(xpathctx, XPATH_SELECTED_OPTION, oname); + else node = NULL; + + if (rccOptionIsDefault(ctx, (rcc_option)i)) strcpy(value, rcc_option_nonconfigured); + else sprintf(value, "%i", rccGetOption(ctx, (rcc_option)i)); + + if (node) xmlNodeSetContent(node, value); + else { + node = xmlNewChild(onode, NULL, "Option", value); + xmlSetProp(node, "name", oname); + } + } + + if (llnode) llflag = 1; + else llnode = xmlNewChild(pnode, NULL, "Languages", NULL); + + languages = ctx->languages; + classes = ctx->classes; + for (i=1;languages[i];i++) { + language = languages[i]; + cfg = rccCheckConfig(ctx, (rcc_language_id)i); + if (!cfg) continue; + + if (llflag) lnode = rccNodeFind(xpathctx, XPATH_SELECTED_LANG, language->sn); + else lnode = NULL; + + if (lnode) { + enode = rccNodeFind(xpathctx, XPATH_SELECTED_ENGINE, language->sn); + cnode = rccNodeFind(xpathctx, XPATH_SELECTED_CLASSES, language->sn); + } else { + lnode = xmlNewChild(llnode, NULL, "Language", NULL); + xmlSetProp(lnode, "name", language->sn); + enode = NULL; + cnode = NULL; + } + + if (enode) xmlNodeSetContent(enode, rccConfigGetSelectedEngineName(cfg)); + else xmlNewChild(lnode, NULL, "Engine", rccConfigGetSelectedEngineName(cfg)); + + if (cnode) cflag = 1; + else { + cnode = xmlNewChild(lnode, NULL, "Classes", NULL); + cflag = 0; + } + + for (j=0;classes[j];j++) { + cl = classes[j]; + + if (cflag) node = rccNodeFind(xpathctx, XPATH_SELECTED_CLASS, language->sn, cl->name); + else node = NULL; + + if (node) xmlNodeSetContent(node, rccConfigGetSelectedCharsetName(cfg, (rcc_class_id)j)); + else { + node = xmlNewChild(cnode, NULL, "Class", rccConfigGetSelectedCharsetName(cfg, (rcc_class_id)j)); + xmlSetProp(node, "name", cl->name); + } + } + } + + xmlDocDumpFormatMemory(doc,&mem,&memsize,1); + ftruncate(fd, 0); + lseek(fd, SEEK_SET, 0); + if (mem) { + write(fd, mem, memsize); + free(mem); + } + +clear: + if (config) { + if (fd != -1) { + if (doc) { + if (xpathctx) { + xmlXPathFreeContext(xpathctx); + } + xmlFreeDoc(doc); + } + fsync(fd); + flock(fd, LOCK_UN); + close(fd); + } + free(config); + } + + return 0; +} + +int rccLoad(rcc_context ctx, const char *name) { + int err; + + int fd; + char *config; + struct stat st; + + unsigned int i, j, size; + const char *tmp; + const char *oname; + + rcc_language_config cfg; + rcc_language_ptr *languages; + rcc_language_ptr language; + rcc_class_ptr *classes; + rcc_class_ptr cl; + + xmlXPathContextPtr xpathctx; + xmlDocPtr doc = NULL; + xmlNodePtr node, lnode; + + if ((!name)||(!strcmp(name, "rcc"))||(strlen(rcc_home_dir)<3)) name = "default"; + + size = strlen(rcc_home_dir) + strlen(name) + 32; + config = (char*)malloc(size*sizeof(char)); + if (!config) return -1; + + sprintf(config,"%s/.rcc/%s.xml",rcc_home_dir,name); + fd = open(config, O_RDONLY); + if (fd == -1) goto clear; + flock(fd, LOCK_EX); + + if ((!fstat(fd, &st))&&(st.st_size)) { + doc = xmlReadFd(fd, config, NULL, 0); + } else goto clear; + + xpathctx = xmlXPathNewContext(doc); + if (!xpathctx) goto clear; + + node = rccNodeFind(xpathctx, XPATH_SELECTED_LANGUAGE); + if (node) { + tmp = rccXmlGetText(node); + if (tmp) err = rccSetLanguageByName(ctx, tmp); + else err = -1; + } else err = -1; + if (err) rccSetLanguage(ctx, 0); + + for (i=0;i<RCC_MAX_OPTIONS;i++) { + oname = rccGetOptionName((rcc_option)i); + if (!oname) continue; + + node = rccNodeFind(xpathctx, XPATH_SELECTED_OPTION, oname); + if (node) { + tmp = rccXmlGetText(node); + if ((tmp)&&(strcasecmp(tmp,rcc_option_nonconfigured))) err = rccSetOption(ctx, (rcc_option)i, (rcc_option_value)atoi(tmp)); + else err = -1; + } else err = -1; + if (err) rccOptionSetDefault(ctx, (rcc_option)i); + } + + + languages = ctx->languages; + classes = ctx->classes; + for (i=1;languages[i];i++) { + language = languages[i]; + + lnode = rccNodeFind(xpathctx, XPATH_SELECTED_LANG, language->sn); + if (!lnode) continue; + + cfg = rccGetConfig(ctx, (rcc_language_id)i); + if (!cfg) continue; + + node = rccNodeFind(xpathctx, XPATH_SELECTED_ENGINE, language->sn); + if (node) { + tmp = rccXmlGetText(node); + if (tmp) err = rccConfigSetEngineByName(cfg, tmp); + else err = -1; + } else err = -1; + if (err) rccConfigSetEngineByName(cfg, NULL); + + for (j=0;classes[j];j++) { + cl = classes[j]; + + node = rccNodeFind(xpathctx, XPATH_SELECTED_CLASS, language->sn, cl->name); + if (node) { + tmp = rccXmlGetText(node); + if (tmp) err = rccConfigSetCharsetByName(cfg, (rcc_class_id)j, tmp); + else err = -1; + } else err = -1; + if (err) rccConfigSetCharset(cfg, (rcc_class_id)j, 0); + } + } + +clear: + if (config) { + if (fd != -1) { + if (doc) { + if (xpathctx) { + xmlXPathFreeContext(xpathctx); + } + xmlFreeDoc(doc); + } + close(fd); + } + free(config); + } + + return 0; +} @@ -1,4 +1,7 @@ #ifndef _RCC_XML_H #define _RCC_XML_H +int rccXmlInit(); +void rccXmlFree(); + #endif /* _RCC_XML_H */ diff --git a/src/xml.c b/src/xml.c deleted file mode 100644 index 459bccf..0000000 --- a/src/xml.c +++ /dev/null @@ -1,14 +0,0 @@ -#include <stdio.h> -#include "internal.h" - -/* pass programm name */ - -/* Load and Then Save */ -/* flock */ -int rccSave(rcc_context ctx, const char *name) { - return 0; -} - -int rccLoad(rcc_context ctx, const char *name) { - return 0; -} |