diff options
author | Suren A. Chilingaryan <csa@dside.dyndns.org> | 2007-04-14 22:20:10 +0000 |
---|---|---|
committer | Suren A. Chilingaryan <csa@dside.dyndns.org> | 2007-04-14 22:20:10 +0000 |
commit | 8ca43646a6c87d00d5b2cb74cebf65a8d0ea5e8e (patch) | |
tree | 724ddc9ab6cb3a362051fe1e081b3ccdcd7c0d5c /src | |
parent | b91203daf1a2b5865bfd284821c0c0b103f5b8e7 (diff) | |
download | librcc-8ca43646a6c87d00d5b2cb74cebf65a8d0ea5e8e.tar.gz librcc-8ca43646a6c87d00d5b2cb74cebf65a8d0ea5e8e.tar.bz2 librcc-8ca43646a6c87d00d5b2cb74cebf65a8d0ea5e8e.tar.xz librcc-8ca43646a6c87d00d5b2cb74cebf65a8d0ea5e8e.zip |
DB4 & Postponed processing
- New DB4 database type
- Postponed processing in external module
+ User may allow external module to finish required processing before
termination. This could be useful for translation services while using
console applications (if network connection is slow, the external will
never finish translation before program termination)
- SKIP_PARRENT options are renamed to SKIP_PARENT
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/internal.h | 11 | ||||
-rw-r--r-- | src/librcc.c | 128 | ||||
-rw-r--r-- | src/librcc.h | 41 | ||||
-rw-r--r-- | src/lngconfig.c | 16 | ||||
-rw-r--r-- | src/plugin.c | 1 | ||||
-rw-r--r-- | src/rccconfig.c | 7 | ||||
-rw-r--r-- | src/rccconfig.h | 1 | ||||
-rw-r--r-- | src/rccdb4.c | 33 | ||||
-rw-r--r-- | src/rccexternal.c | 19 | ||||
-rw-r--r-- | src/rccexternal.h | 8 | ||||
-rw-r--r-- | src/rcchome.c | 52 | ||||
-rw-r--r-- | src/rcchome.h | 8 | ||||
-rw-r--r-- | src/rcclock.c | 108 | ||||
-rw-r--r-- | src/rcclock.h | 12 | ||||
-rw-r--r-- | src/rccspell.c | 26 | ||||
-rw-r--r-- | src/rccspell.h | 2 | ||||
-rw-r--r-- | src/rcctranslate.c | 4 | ||||
-rw-r--r-- | src/rccxml.c | 15 | ||||
-rw-r--r-- | src/recode.c | 26 |
20 files changed, 336 insertions, 184 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 6d1ca98..79976c6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,7 @@ lib_LTLIBRARIES = librcc.la librcc_la_SOURCES = librcc.c \ + rcchome.c rcchome.h \ + rcclock.c rcclock.h \ rcclocale.c rcclocale.h \ lng.c lng.h \ opt.c opt.h \ diff --git a/src/internal.h b/src/internal.h index c5170be..98ef6d7 100644 --- a/src/internal.h +++ b/src/internal.h @@ -5,11 +5,7 @@ # define LIBRCC_DATA_DIR "/usr/lib/rcc" #endif /* LIBRCC_DATA_DIR */ -#ifndef LIBRCC_LOCK_WAIT -# define LIBRCC_LOCK_WAIT 3000 /* ms */ -#endif /* LIBRCC_LOCK_WAIT */ - -#define RCC_MAX_LANGUAGE_PARRENTS 4 +#define RCC_MAX_LANGUAGE_PARENTS 4 #define RCC_MAX_RELATIONS RCC_MAX_LANGUAGES #ifdef HAVE_STRNLEN @@ -38,11 +34,11 @@ #define RCC_MAX_DISABLED_CHARSETS 64 -typedef rcc_language_id rcc_language_parrent_list[RCC_MAX_LANGUAGE_PARRENTS]; +typedef rcc_language_id rcc_language_parent_list[RCC_MAX_LANGUAGE_PARENTS]; struct rcc_language_internal_t { rcc_language language; - rcc_language_id parrents[RCC_MAX_LANGUAGE_PARRENTS + 1]; + rcc_language_id parents[RCC_MAX_LANGUAGE_PARENTS + 1]; unsigned char latin; }; typedef struct rcc_language_internal_t rcc_language_internal; @@ -102,6 +98,5 @@ int rccConfigure(rcc_context ctx); char *rccCreateResult(rcc_context ctx, size_t len); extern rcc_context rcc_default_ctx; -extern char *rcc_home_dir; #endif /* _RCC_INTERNAL_H */ diff --git a/src/librcc.c b/src/librcc.c index 6d3ce24..a39fef2 100644 --- a/src/librcc.c +++ b/src/librcc.c @@ -35,9 +35,10 @@ #include "rccxml.h" #include "rccexternal.h" #include "rcctranslate.h" +#include "rcclock.h" +#include "rcchome.h" static int initialized = 0; -char *rcc_home_dir = NULL; rcc_context rcc_default_ctx = NULL; static rcc_compiled_configuration_s compiled_configuration; @@ -64,27 +65,12 @@ rcc_compiled_configuration rccGetCompiledConfiguration() { int rccInit() { int err; - char *tmp; unsigned long i, rpos; - -#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("/"); - + rccHomeSet(); + memcpy(rcc_default_languages, rcc_default_languages_embeded, (RCC_MAX_LANGUAGES + 1)*sizeof(rcc_language)); memcpy(rcc_default_aliases, rcc_default_aliases_embeded, (RCC_MAX_ALIASES + 1)*sizeof(rcc_language_alias)); memcpy(rcc_default_relations, rcc_default_relations_embeded, (RCC_MAX_RELATIONS + 1)*sizeof(rcc_language_relation)); @@ -101,10 +87,10 @@ int rccInit() { if (!strcasecmp(rcc_default_languages[i].sn, rcc_english_language_sn)) continue; rcc_default_relations[rpos].lang = rcc_default_languages[i].sn; - rcc_default_relations[rpos++].parrent = rcc_english_language_sn; + rcc_default_relations[rpos++].parent = rcc_english_language_sn; } rcc_default_relations[rpos].lang = NULL; - rcc_default_relations[rpos].parrent = NULL; + rcc_default_relations[rpos].parent = NULL; err = rccPluginInit(); if (!err) err = rccTranslateInit(); @@ -134,97 +120,11 @@ void rccFree() { rccExternalFree(); - if (rcc_home_dir) { - free(rcc_home_dir); - rcc_home_dir = NULL; - } + rccHomeFree(); initialized = 0; } -static int lockfd = -1; - -int rccLock() { -# ifdef HAVE_SYS_FILE_H - int err, i; - int size; - char *stmp; - struct timespec wait = { 0, 10000000 }; - - if (lockfd>=0) return -1; - - size = strlen(rcc_home_dir) + 32; - stmp = (char*)malloc(size*sizeof(char)); - if (!stmp) return -1; - - sprintf(stmp,"%s/.rcc/", rcc_home_dir); - mkdir(stmp, 00755); - - sprintf(stmp,"%s/.rcc/locks/", rcc_home_dir); - mkdir(stmp, 00700); - - sprintf(stmp,"%s/.rcc/locks/rcc.lock", rcc_home_dir); - - lockfd = open(stmp, O_RDWR|O_CREAT, 0644); - if (lockfd >= 0) { - for (err = -1, i = 0; i < (LIBRCC_LOCK_WAIT/10); i++) { - err = flock(lockfd, LOCK_EX|LOCK_NB); - if ((err)&&(errno == EWOULDBLOCK)) nanosleep(&wait, NULL); - else break; - } - - if (err) { - close(lockfd); - - // Removing invalid lock - if (i == (LIBRCC_LOCK_WAIT/10)) { - remove(stmp); - - lockfd = open(stmp, O_RDWR|O_CREAT, 0644); - if (lockfd >= 0) { - for (err = -1, i = 0; i < (LIBRCC_LOCK_WAIT/10); i++) { - err = flock(lockfd, LOCK_EX|LOCK_NB); - if ((err)&&(errno == EWOULDBLOCK)) nanosleep(&wait, NULL); - else break; - } - - if (err) close(lockfd); - else return 0; - } - } - - lockfd = -1; - return -1; - } - - return 0; - } - - return -1; -# else /* HAVE_SYS_FILE_H */ - return 0; -# endif /* HAVE_SYS_FILE_H */ -} - -void rccUnLock() { -#ifdef HAVE_SYS_FILE_H - int size; - char *stmp; - - if (lockfd<0) return; - - size = strlen(rcc_home_dir) + 32; - stmp = (char*)malloc(size*sizeof(char)); - if (!stmp) return; - - sprintf(stmp,"%s/.rcc/locks/rcc.lock", rcc_home_dir); - - flock(lockfd, LOCK_UN); - close(lockfd); - lockfd = -1; -#endif /* HAVE_SYS_FILE_H */ -} - rcc_context rccCreateContext(const char *locale_variable, unsigned int max_languages, unsigned int max_classes, rcc_class_ptr defclasses, rcc_init_flags flags) { unsigned int i; @@ -470,7 +370,7 @@ rcc_language_id rccRegisterLanguage(rcc_context ctx, rcc_language *language) { if (ctx->n_languages == ctx->max_languages) return (rcc_language_id)-1; memcpy(ctx->ilang + ctx->n_languages, language, sizeof(rcc_language)); - ctx->ilang[ctx->n_languages].parrents[0] = (rcc_language_id)-1; + ctx->ilang[ctx->n_languages].parents[0] = (rcc_language_id)-1; ctx->ilang[ctx->n_languages].latin = 0; for (i=0;language->charsets[i];i++) @@ -539,7 +439,7 @@ rcc_relation_id rccRegisterLanguageRelation(rcc_context ctx, rcc_language_relati unsigned int i; rcc_language_id language_id; const char *lang; - const char *parrent; + const char *parent; rcc_language_id *list; if (!ctx) { @@ -549,22 +449,22 @@ rcc_relation_id rccRegisterLanguageRelation(rcc_context ctx, rcc_language_relati if (!relation) return (rcc_relation_id)-1; lang = relation->lang; - parrent = relation->parrent; - if ((!lang)||(!parrent)||(!strcasecmp(lang,parrent))) return (rcc_relation_id)-1; + parent = relation->parent; + if ((!lang)||(!parent)||(!strcasecmp(lang,parent))) return (rcc_relation_id)-1; language_id = rccGetLanguageByName(ctx, lang); if (language_id == (rcc_language_id)-1) return (rcc_relation_id)-1; - list = ((rcc_language_internal*)ctx->languages[language_id])->parrents; + list = ((rcc_language_internal*)ctx->languages[language_id])->parents; - language_id = rccGetLanguageByName(ctx, parrent); + language_id = rccGetLanguageByName(ctx, parent); if (language_id == (rcc_language_id)-1) return (rcc_relation_id)0; for (i=0;list[i]!=(rcc_language_id)-1;i++) if (list[i] == language_id) return (rcc_relation_id)0; - if (i<RCC_MAX_LANGUAGE_PARRENTS) { + if (i<RCC_MAX_LANGUAGE_PARENTS) { list[i++] = language_id; list[i] = (rcc_language_id)-1; } else return (rcc_relation_id)-1; diff --git a/src/librcc.h b/src/librcc.h index 98ca1a6..e5749cd 100644 --- a/src/librcc.h +++ b/src/librcc.h @@ -234,17 +234,17 @@ typedef rcc_language_alias_ptr rcc_language_alias_list[RCC_MAX_ALIASES+1]; /** * Language relations. - * Meaning: sentence in considered language may contain words from all his parrents. This + * Meaning: sentence in considered language may contain words from all his parents. This * knowledge will help Autodetection Engine to guess right language. * - * For example: Russian is parrent language for Ukrainian. This means it is possible + * For example: Russian is parent language for Ukrainian. This means it is possible * to encounter russian words in ukrainian sentence. * * All languages by default are related to english language. */ struct rcc_language_relation_t { const char *lang; /**< Coresponded language ISO-639-1 name */ - const char *parrent; /**< Parrent language */ + const char *parent; /**< Parent language */ }; typedef struct rcc_language_relation_t rcc_language_relation; @@ -349,7 +349,7 @@ typedef const struct rcc_class_default_charset_t rcc_class_default_charset; struct rcc_class_t { const char *name; /**< Short class name */ const rcc_class_type class_type; /**< specifies type of class (Standard, File System, Known) */ - const char *defvalue; /**< locale variable name or parrent name or multibyte encoding name */ + const char *defvalue; /**< locale variable name or parent name or multibyte encoding name */ rcc_class_default_charset *defcharset; /**< default class encodings. Should be specified on per-language basys */ const char *fullname; /**< Full name of the class */ const unsigned long flags; /**< Class flags. (CONST, SKIP_SAVELOAD) */ @@ -430,7 +430,7 @@ typedef enum rcc_option_translate_t { RCC_OPTION_TRANSLATE_TRANSLITERATE, /**< Transliterate data. */ RCC_OPTION_TRANSLATE_TO_ENGLISH, /**< Translate data to english language (Current language don't matter). */ RCC_OPTION_TRANSLATE_SKIP_RELATED, /**< Skip translation of the text's between related languages. */ - RCC_OPTION_TRANSLATE_SKIP_PARRENT, /**< Skip translation of the text's from parrent languages (from english). */ + RCC_OPTION_TRANSLATE_SKIP_PARENT, /**< Skip translation of the text's from parent languages (from english). */ RCC_OPTION_TRANSLATE_FULL /**< Translate whole data to the current language */ } rcc_option_translate; @@ -446,6 +446,7 @@ typedef enum rcc_option_t { RCC_OPTION_AUTODETECT_LANGUAGE, /**< Enables language detection */ RCC_OPTION_TRANSLATE, /**< Translate #rcc_string if it's language differs from current one */ RCC_OPTION_TIMEOUT, /**< Recoding timeout. Currently it is only used to limit translation time */ + RCC_OPTION_OFFLINE, /**< Allows external module to finish it's job in offline after the main program is terminated */ RCC_MAX_OPTIONS, RCC_OPTION_ALL } rcc_option; @@ -887,7 +888,7 @@ const char *rccConfigGetSelectedCharsetName(rcc_language_config config, rcc_clas * Return current encoding_id. The default value will be resolved to paticular encoding id. * The following procedure is used to detect default encoding: * - If Unicode encoding selected for the same class english language. Return this encoding. - * - If the parrent class is defined in #defcharset, - return current encoding of parrent class. + * - If the parent class is defined in #defcharset, - return current encoding of parent class. * - If the locale variable is defined in #defcharset and either config language coincide with locale language or unciode encoding defined, use locale encoding. * - If the default value for config language is defined in #defvalue return that default value. * - If the default value for all languages is defined in #defvalue return that default value. @@ -1146,6 +1147,15 @@ void rccTranslateClose(rcc_translate translate); */ int rccTranslateSetTimeout(rcc_translate translate, unsigned long us); +/* + * Allows translation engine to perform pending task after the main program is + * being terminated + * + * @param translate is translating context + * @return non-zero value is returned in the case of errror + */ +int rccTranslateAllowOfflineMode(rcc_translate translate); + /** * Translate string. * @@ -1168,9 +1178,9 @@ typedef struct rcc_speller_t *rcc_speller; */ typedef enum rcc_speller_result_t { RCC_SPELLER_INCORRECT = 0, /**< Word not found in dictionaries */ - RCC_SPELLER_ALMOST_PARRENT, /**< Similliar word is found in parrents dictionary */ + RCC_SPELLER_ALMOST_PARENT, /**< Similliar word is found in parents dictionary */ RCC_SPELLER_ALMOST_CORRECT, /**< Similliar word is found in dictionary */ - RCC_SPELLER_PARRENT, /**< Word is found in parrent dictionary */ + RCC_SPELLER_PARENT, /**< Word is found in parent dictionary */ RCC_SPELLER_CORRECT /**< Word is found in dictionary */ } rcc_speller_result; @@ -1194,13 +1204,13 @@ rcc_speller rccSpellerCreate(const char *lang); */ void rccSpellerFree(rcc_speller speller); /** - * Add parrent to the spelling context. + * Add parent to the spelling context. * * @param speller is spelling context - * @param parrent is parrent spelling context + * @param parent is parent spelling context * @return non-zero value in the case of error */ -int rccSpellerAddParrent(rcc_speller speller, rcc_speller parrent); +int rccSpellerAddParent(rcc_speller speller, rcc_speller parent); /** * Spell a word. * @@ -1515,6 +1525,15 @@ 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); + +/** + * For compatibilty reasons + */ +#define RCC_OPTION_TRANSLATE_SKIP_PARRENT RCC_OPTION_TRANSLATE_SKIP_PARENT +#define RCC_SPELLER_ALMOST_PARRENT RCC_SPELLER_ALMOST_PARENT +#define RCC_SPELLER_PARRENT RCC_SPELLER_PARENT +#define rccSpellerAddParrent rccSpellerAddParent + #ifdef __cplusplus } #endif diff --git a/src/lngconfig.c b/src/lngconfig.c index 631abd1..67e05c6 100644 --- a/src/lngconfig.c +++ b/src/lngconfig.c @@ -437,7 +437,7 @@ rcc_speller rccConfigGetSpeller(rcc_language_config config) { unsigned int i; rcc_speller speller; rcc_language_config pconfig; - rcc_language_id *parrents; + rcc_language_id *parents; rcc_language_id language_id; if (!config) return NULL; @@ -447,12 +447,12 @@ rcc_speller rccConfigGetSpeller(rcc_language_config config) { if (config->speller) language_id = rccConfigGetLanguage(config); else language_id = (rcc_language_id)-1; - if (language_id != (rcc_language_id)-1) parrents = ((rcc_language_internal*)config->language)->parrents; - else parrents = NULL; + if (language_id != (rcc_language_id)-1) parents = ((rcc_language_internal*)config->language)->parents; + else parents = NULL; - if (parrents) { - for (i = 0; parrents[i]!=(rcc_language_id)-1; i++) { - pconfig = rccGetConfig(config->ctx, parrents[i]); + if (parents) { + for (i = 0; parents[i]!=(rcc_language_id)-1; i++) { + pconfig = rccGetConfig(config->ctx, parents[i]); if (pconfig) { speller = rccConfigGetSpeller(pconfig); rccSpellerAddParrent(config->speller, speller); @@ -467,6 +467,7 @@ rcc_speller rccConfigGetSpeller(rcc_language_config config) { rcc_translate rccConfigGetTranslator(rcc_language_config config, rcc_language_id to) { rcc_option_value timeout; + rcc_option_value offline; if (!config) return NULL; @@ -482,6 +483,9 @@ rcc_translate rccConfigGetTranslator(rcc_language_config config, rcc_language_id config->translang = to; timeout = rccGetOption(config->ctx, RCC_OPTION_TIMEOUT); if (timeout) rccTranslateSetTimeout(config->trans, timeout); + + offline = rccGetOption(config->ctx, RCC_OPTION_OFFLINE); + if (offline) rccTranslateAllowOfflineMode(config->trans); } } rccMutexUnLock(config->mutex); diff --git a/src/plugin.c b/src/plugin.c index b3289b7..c1f0074 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -3,6 +3,7 @@ #include <string.h> #include "internal.h" +#include "rcchome.h" #include "plugin.h" #ifdef RCC_PLUGINS diff --git a/src/rccconfig.c b/src/rccconfig.c index ae47a63..6723825 100644 --- a/src/rccconfig.c +++ b/src/rccconfig.c @@ -134,7 +134,7 @@ rcc_language rcc_default_languages_embeded[RCC_MAX_LANGUAGES + 1] = { 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_value_name rcc_sn_translate[] = { "OFF", "TRANSLITERATE", "TO_ENGLISH", "SKIP_RELATED", "SKIP_PARRENT", "FULL", NULL }; +rcc_option_value_name rcc_sn_translate[] = { "OFF", "TRANSLITERATE", "TO_ENGLISH", "SKIP_RELATED", "SKIP_PARENT", "FULL", NULL }; rcc_option_description rcc_option_descriptions[RCC_MAX_OPTIONS+1]; rcc_option_description rcc_option_descriptions_embeded[RCC_MAX_OPTIONS+1] = { @@ -162,6 +162,7 @@ rcc_option_description rcc_option_descriptions_embeded[RCC_MAX_OPTIONS+1] = { #else {RCC_OPTION_TIMEOUT, RCC_DEFAULT_RECODING_TIMEOUT, { RCC_OPTION_RANGE_TYPE_RANGE, 0, 5000000, 50000}, RCC_OPTION_TYPE_INVISIBLE, "TIMEOUT", NULL }, #endif /* HAVE_LIBTRANSLATE */ + {RCC_OPTION_OFFLINE, 0, { RCC_OPTION_RANGE_TYPE_BOOLEAN, 0, 0, 0 }, RCC_OPTION_TYPE_INVISIBLE, "OFFLINE_PROCESSING", rcc_sn_boolean}, {RCC_MAX_OPTIONS} }; @@ -215,11 +216,11 @@ unsigned int rccDefaultDropLanguageRelations(const char *lang) { if (strcasecmp(lang, rcc_default_relations[i].lang)) { if (j<i) { rcc_default_relations[j].lang = rcc_default_relations[i].lang; - rcc_default_relations[j++].parrent = rcc_default_relations[i].parrent; + rcc_default_relations[j++].parent = rcc_default_relations[i].parent; } else j++; } } rcc_default_relations[j].lang = NULL; - rcc_default_relations[j].parrent = NULL; + rcc_default_relations[j].parent = NULL; return j; } diff --git a/src/rccconfig.h b/src/rccconfig.h index 8b5ac0d..c84403a 100644 --- a/src/rccconfig.h +++ b/src/rccconfig.h @@ -5,6 +5,7 @@ #undef RCC_DEBUG #undef RCC_DEBUG_LANGDETECT +//#define RCC_DEBUG_LANGDETECT 5 #define RCC_LOCALE_VARIABLE "LC_CTYPE" extern const char rcc_default_all[]; diff --git a/src/rccdb4.c b/src/rccdb4.c index a4e0976..1eb5d44 100644 --- a/src/rccdb4.c +++ b/src/rccdb4.c @@ -5,6 +5,7 @@ #include "../config.h" #include "internal.h" +#include "rcchome.h" #include "rccdb4.h" #define DATABASE "autolearn.db" @@ -15,21 +16,36 @@ db4_context rccDb4CreateContext(const char *dbpath, rcc_db4_flags flags) { #ifdef HAVE_DB_H DB_ENV *dbe; DB *db; - + +# if 0 char stmp[160]; +# endif err = db_env_create(&dbe, 0); if (err) return NULL; +# if 1 + dbe->set_flags(dbe, DB_LOG_AUTOREMOVE, 1); + dbe->set_lg_max(dbe, 131072); + + err = rccLock(); + if (!err) { + err = dbe->open(dbe, dbpath, DB_CREATE|DB_INIT_TXN|DB_USE_ENVIRON|DB_INIT_LOCK|DB_INIT_MPOOL|DB_RECOVER, 00644); + rccUnLock(); + } +# else err = dbe->open(dbe, dbpath, DB_CREATE|DB_INIT_CDB|DB_INIT_MPOOL, 00644); if (err == DB_VERSION_MISMATCH) { - if (!rccLock()) { err = dbe->open(dbe, dbpath, DB_CREATE|DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_MPOOL|DB_INIT_TXN|DB_USE_ENVIRON|DB_PRIVATE|DB_RECOVER, 0); + dbe->close(dbe, 0); + dbe->remove(dbe, dbpath, 0); rccUnLock(); - } else err = -1; - - dbe->close(dbe, 0); + } else { + err = -1; + dbe->close(dbe, 0); + } + if (err) return NULL; if (strlen(dbpath)<128) { @@ -43,8 +59,10 @@ db4_context rccDb4CreateContext(const char *dbpath, rcc_db4_flags flags) { err = dbe->open(dbe, dbpath, DB_CREATE|DB_INIT_CDB|DB_INIT_MPOOL, 00644); } - +# endif + if (err) { +// fprintf(stderr, "BerkelyDB initialization failed: %i (%s)\n", err, db_strerror(err)); dbe->close(dbe, 0); return NULL; } @@ -55,6 +73,7 @@ db4_context rccDb4CreateContext(const char *dbpath, rcc_db4_flags flags) { return NULL; } + err = db->open(db, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0); if (err) { db->close(db, 0); @@ -71,7 +90,7 @@ db4_context rccDb4CreateContext(const char *dbpath, rcc_db4_flags flags) { #endif /* HAVE_DB_H */ return NULL; } - + #ifdef HAVE_DB_H ctx->db = db; ctx->dbe = dbe; diff --git a/src/rccexternal.c b/src/rccexternal.c index be9f97d..58b8a23 100644 --- a/src/rccexternal.c +++ b/src/rccexternal.c @@ -38,6 +38,7 @@ # include <sys/wait.h> #endif /* HAVE_SYS_WAIT_H */ +#include "rcchome.h" #include "rccexternal.h" #include "internal.h" @@ -92,7 +93,7 @@ void rccExternalFree() { res = waitpid(pid, NULL, WNOHANG); if (res) break; - else timeout.tv_nsec*10; + else timeout.tv_nsec*=10; } pid = (pid_t)-1; @@ -225,3 +226,19 @@ void rccExternalClose(int s) { close(s); } } + +int rccExternalAllowOfflineMode() { + int sock; + int err; + rcc_external_option opt = RCC_EXTERNAL_OPTION_OFFLINE; + unsigned long opt_value = 1; + + sock = rccExternalConnect(RCC_EXTERNAL_MODULE_OPTIONS); + if (sock) { + err = rccExternalWrite(sock, (char*)&opt, sizeof(rcc_external_option), 0); + if (!err) err = rccExternalWrite(sock, (char*)&opt_value, sizeof(unsigned long), 0); + rccExternalClose(sock); + return err; + } + return -1; +} diff --git a/src/rccexternal.h b/src/rccexternal.h index 236e2df..1038329 100644 --- a/src/rccexternal.h +++ b/src/rccexternal.h @@ -3,6 +3,7 @@ typedef enum rcc_external_module_t { RCC_EXTERNAL_MODULE_CONTROL = 0, + RCC_EXTERNAL_MODULE_OPTIONS, RCC_EXTERNAL_MODULE_LIBRTRANSLATE, RCC_EXTERNAL_MODULE_MAX } rcc_external_module; @@ -13,6 +14,11 @@ struct rcc_external_info_t { typedef struct rcc_external_info_t rcc_external_info_s; typedef struct rcc_external_info_t *rcc_external_info; +typedef enum rcc_external_option_t { + RCC_EXTERNAL_OPTION_OFFLINE = 0, + RCC_EXTERNAL_OPTION_MAX +} rcc_external_option; + struct rcc_external_command_t { unsigned long size; unsigned char cmd; @@ -25,6 +31,8 @@ typedef struct rcc_external_command_t *rcc_external_command; int rccExternalInit(); void rccExternalFree(); +int rccExternalAllowOfflineMode(); + size_t rccExternalWrite(int s, const char *buffer, ssize_t size, unsigned long timeout); size_t rccExternalRead(int s, char *buffer, ssize_t size, unsigned long timeout); int rccExternalConnect(unsigned char module); diff --git a/src/rcchome.c b/src/rcchome.c new file mode 100644 index 0000000..a88a667 --- /dev/null +++ b/src/rcchome.c @@ -0,0 +1,52 @@ +#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_SYS_STAT_H +# include <sys/stat.h> +#endif /* HAVE_SYS_STAT_H */ + +#ifdef HAVE_PWD_H +# include <pwd.h> +#endif /* HAVE_PWD_H */ + +#include "rcchome.h" + +char *rcc_home_dir = NULL; + +void rccHomeSet() { + char *tmp; + +#ifdef HAVE_PWD_H + struct passwd *pw; +#endif /* HAVE_PWD_H */ + + 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("/"); +} + +void rccHomeFree() { + if (rcc_home_dir) { + free(rcc_home_dir); + rcc_home_dir = NULL; + } +} diff --git a/src/rcchome.h b/src/rcchome.h new file mode 100644 index 0000000..0712eab --- /dev/null +++ b/src/rcchome.h @@ -0,0 +1,8 @@ +#ifndef _RCC_HOME_H +#define _RCC_HOME_H + +extern char *rcc_home_dir; +void rccHomeSet(); +void rccHomeFree(); + +#endif /* _RCC_HOME_H */ diff --git a/src/rcclock.c b/src/rcclock.c new file mode 100644 index 0000000..b8f0e8f --- /dev/null +++ b/src/rcclock.c @@ -0,0 +1,108 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <errno.h> + +#include "../config.h" + +#ifdef HAVE_SYS_FILE_H +# include <sys/file.h> +#endif /* HAVE_SYS_FILE_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_SYS_STAT_H +# include <sys/stat.h> +#endif /* HAVE_SYS_STAT_H */ + +#include "rcchome.h" +#include "rcclock.h" + +static int lockfd = -1; + +int rccLock() { +# ifdef HAVE_SYS_FILE_H + int err, i; + int size; + char *stmp; + struct timespec wait = { 0, 10000000 }; + + if (lockfd>=0) return -1; + + size = strlen(rcc_home_dir) + 32; + stmp = (char*)malloc(size*sizeof(char)); + if (!stmp) return -1; + + sprintf(stmp,"%s/.rcc/", rcc_home_dir); + mkdir(stmp, 00755); + + sprintf(stmp,"%s/.rcc/locks/", rcc_home_dir); + mkdir(stmp, 00700); + + sprintf(stmp,"%s/.rcc/locks/rcc.lock", rcc_home_dir); + + lockfd = open(stmp, O_RDWR|O_CREAT, 0644); + if (lockfd >= 0) { + for (err = -1, i = 0; i < (LIBRCC_LOCK_WAIT/10); i++) { + err = flock(lockfd, LOCK_EX|LOCK_NB); + if ((err)&&(errno == EWOULDBLOCK)) nanosleep(&wait, NULL); + else break; + } + + if (err) { + close(lockfd); + + // Removing invalid lock + if (i == (LIBRCC_LOCK_WAIT/10)) { + remove(stmp); + + lockfd = open(stmp, O_RDWR|O_CREAT, 0644); + if (lockfd >= 0) { + for (err = -1, i = 0; i < (LIBRCC_LOCK_WAIT/10); i++) { + err = flock(lockfd, LOCK_EX|LOCK_NB); + if ((err)&&(errno == EWOULDBLOCK)) nanosleep(&wait, NULL); + else break; + } + + if (err) close(lockfd); + else return 0; + } + } + + lockfd = -1; + return -1; + } + + return 0; + } + + return -1; +# else /* HAVE_SYS_FILE_H */ + return 0; +# endif /* HAVE_SYS_FILE_H */ +} + +void rccUnLock() { +#ifdef HAVE_SYS_FILE_H + int size; + char *stmp; + + if (lockfd<0) return; + + size = strlen(rcc_home_dir) + 32; + stmp = (char*)malloc(size*sizeof(char)); + if (!stmp) return; + + sprintf(stmp,"%s/.rcc/locks/rcc.lock", rcc_home_dir); + + flock(lockfd, LOCK_UN); + close(lockfd); + lockfd = -1; +#endif /* HAVE_SYS_FILE_H */ +} diff --git a/src/rcclock.h b/src/rcclock.h new file mode 100644 index 0000000..e043150 --- /dev/null +++ b/src/rcclock.h @@ -0,0 +1,12 @@ +#ifndef _RCC_LOCK_H +#define _RCC_LOCK_H + +#ifndef LIBRCC_LOCK_WAIT +# define LIBRCC_LOCK_WAIT 3000 /* ms */ +#endif /* LIBRCC_LOCK_WAIT */ + +int rccLock(); +void rccUnLock(); + +#endif /* _RCC_LOCK_H */ + diff --git a/src/rccspell.c b/src/rccspell.c index da5e4d1..19b5abc 100644 --- a/src/rccspell.c +++ b/src/rccspell.c @@ -29,7 +29,7 @@ rcc_speller rccSpellerCreate(const char *lang) { } rccspeller->speller = speller; - rccspeller->parrents[0] = NULL; + rccspeller->parents[0] = NULL; return rccspeller; #else return NULL; @@ -49,14 +49,14 @@ int rccSpellerGetError(rcc_speller rccspeller) { return 0; } -int rccSpellerAddParrent(rcc_speller speller, rcc_speller parrent) { +int rccSpellerAddParent(rcc_speller speller, rcc_speller parent) { unsigned int i; - if ((!speller)||(!parrent)) return -1; + if ((!speller)||(!parent)) return -1; - for (i=0;speller->parrents[i];i++); - if (i >= RCC_MAX_LANGUAGE_PARRENTS) return -1; - speller->parrents[i++] = parrent; - speller->parrents[i] = NULL; + for (i=0;speller->parents[i];i++); + if (i >= RCC_MAX_LANGUAGE_PARENTS) return -1; + speller->parents[i++] = parent; + speller->parents[i] = NULL; return 0; } @@ -70,10 +70,10 @@ rcc_speller_result rccSpellerSized(rcc_speller speller, const char *word, size_t if (rccSpellerGetError(speller)) return (rcc_speller_result)RCC_SPELLER_INCORRECT; if (recursion) { - for (i=0; speller->parrents[i]; i++) { - result = rccSpellerSized(speller->parrents[i], word, len, 0); - if ((result == RCC_SPELLER_CORRECT)||(result == RCC_SPELLER_PARRENT)) return RCC_SPELLER_PARRENT; - if ((result == RCC_SPELLER_ALMOST_CORRECT)||(result == RCC_SPELLER_ALMOST_PARRENT)) saved_result = RCC_SPELLER_ALMOST_PARRENT; + for (i=0; speller->parents[i]; i++) { + result = rccSpellerSized(speller->parents[i], word, len, 0); + if ((result == RCC_SPELLER_CORRECT)||(result == RCC_SPELLER_PARENT)) return RCC_SPELLER_PARENT; + if ((result == RCC_SPELLER_ALMOST_CORRECT)||(result == RCC_SPELLER_ALMOST_PARENT)) saved_result = RCC_SPELLER_ALMOST_PARENT; } } @@ -95,12 +95,12 @@ int rccSpellerResultIsOwn(rcc_speller_result res) { } int rccSpellerResultIsPrecise(rcc_speller_result res) { - if ((res == RCC_SPELLER_PARRENT)||(res == RCC_SPELLER_CORRECT)) return 1; + if ((res == RCC_SPELLER_PARENT)||(res == RCC_SPELLER_CORRECT)) return 1; return 0; } int rccSpellerResultIsCorrect(rcc_speller_result res) { if ((res == RCC_SPELLER_ALMOST_CORRECT)||(res == RCC_SPELLER_CORRECT)) return 1; - if ((res == RCC_SPELLER_ALMOST_PARRENT)||(res == RCC_SPELLER_PARRENT)) return 1; + if ((res == RCC_SPELLER_ALMOST_PARENT)||(res == RCC_SPELLER_PARENT)) return 1; return 0; } diff --git a/src/rccspell.h b/src/rccspell.h index 49d5c99..4943e93 100644 --- a/src/rccspell.h +++ b/src/rccspell.h @@ -15,7 +15,7 @@ struct rcc_speller_t { #else void *speller; #endif /* HAVE_ASPELL */ - rcc_speller parrents[RCC_MAX_LANGUAGE_PARRENTS+1]; + rcc_speller parents[RCC_MAX_LANGUAGE_PARENTS+1]; }; typedef struct rcc_speller_t rcc_speller_s; diff --git a/src/rcctranslate.c b/src/rcctranslate.c index 37f0f01..98c0f1b 100644 --- a/src/rcctranslate.c +++ b/src/rcctranslate.c @@ -83,6 +83,10 @@ int rccTranslateSetTimeout(rcc_translate translate, unsigned long us) { return 0; } +int rccTranslateAllowOfflineMode(rcc_translate translate) { + return rccExternalAllowOfflineMode(); +} + #define RCC_UNLOCK_W 1 #define RCC_UNLOCK_R 2 #define RCC_UNLOCK_RW 3 diff --git a/src/rccxml.c b/src/rccxml.c index db13750..e5283af 100644 --- a/src/rccxml.c +++ b/src/rccxml.c @@ -31,6 +31,7 @@ #include "internal.h" #include "rccconfig.h" #include "plugin.h" +#include "rcchome.h" #define MAX_HOME_CHARS 96 #define XPATH_LANGUAGE "//Language[@name]" @@ -58,7 +59,7 @@ int rccXmlInit(int LoadConfiguration) { xmlAttrPtr attr; const char *lang, *engine_name; unsigned int pos, lpos, epos, cpos; - const char *alias, *parrent; + const char *alias, *parent; unsigned int j, apos, rpos; rcc_engine *engine; @@ -115,9 +116,9 @@ int rccXmlInit(int LoadConfiguration) { if (pos == (rcc_language_id)-1) { for (rpos=0;rcc_default_relations[rpos].lang;rpos++); if (rpos < RCC_MAX_RELATIONS) { - rcc_default_relations[rpos].parrent = rcc_english_language_sn; + rcc_default_relations[rpos].parent = rcc_english_language_sn; rcc_default_relations[rpos++].lang = lang; - rcc_default_relations[rpos].parrent = NULL; + rcc_default_relations[rpos].parent = NULL; rcc_default_relations[rpos].lang = NULL; } @@ -172,11 +173,11 @@ int rccXmlInit(int LoadConfiguration) { for (enode=node->children;enode;enode=enode->next) { if (enode->type != XML_ELEMENT_NODE) continue; if ((!xmlStrcmp(enode->name, "Parrent"))&&(rpos<RCC_MAX_RELATIONS)) { - parrent = rccXmlGetText(enode); - if (!parrent) continue; - rcc_default_relations[rpos].parrent = parrent; + parent = rccXmlGetText(enode); + if (!parent) continue; + rcc_default_relations[rpos].parent = parent; rcc_default_relations[rpos++].lang = lang; - rcc_default_relations[rpos].parrent = NULL; + rcc_default_relations[rpos].parent = NULL; rcc_default_relations[rpos].lang = NULL; } } diff --git a/src/recode.c b/src/recode.c index 8c6cc40..e1e8e81 100644 --- a/src/recode.c +++ b/src/recode.c @@ -53,7 +53,7 @@ static rcc_language_id rccDetectLanguageInternal(rcc_context ctx, rcc_class_id c char *best_string = NULL; rcc_language_id bestfixlang = (rcc_language_id)-1; unsigned long k; - rcc_language_id *parrents; + rcc_language_id *parents; size_t chars = 0; char llang[RCC_MAX_LANGUAGE_CHARS]; rcc_language_id locale_lang; @@ -109,11 +109,11 @@ static rcc_language_id rccDetectLanguageInternal(rcc_context ctx, rcc_class_id c if (bestfixlang != (rcc_language_id)-1) { - parrents = ((rcc_language_internal*)config->language)->parrents; - for (k = 0;parrents[k] != (rcc_language_id)-1;k++) - if (parrents[k] == bestfixlang) break; + parents = ((rcc_language_internal*)config->language)->parents; + for (k = 0;parents[k] != (rcc_language_id)-1;k++) + if (parents[k] == bestfixlang) break; - if (parrents[k] != bestfixlang) continue; + if (parents[k] != bestfixlang) continue; } speller = rccConfigGetSpeller(config); @@ -281,17 +281,17 @@ rcc_language_id rccDetectLanguage(rcc_context ctx, rcc_class_id class_id, const } -static int rccIsParrentLanguage(rcc_language_config config, rcc_language_id parrent) { +static int rccIsParrentLanguage(rcc_language_config config, rcc_language_id parent) { unsigned int i; rcc_language_id language; rcc_language_id *list; language = rccConfigGetLanguage(config); - if (parrent == language) return 1; + if (parent == language) return 1; - list = ((rcc_language_internal*)config->language)->parrents; + list = ((rcc_language_internal*)config->language)->parents; for (i=0;list[i] != (rcc_language_id)-1;i++) - if (list[i] == parrent) return 1; + if (list[i] == parent) return 1; return 0; } @@ -349,7 +349,7 @@ static char *rccRecodeTranslate(rcc_language_config *config, rcc_class_id class_ } else current_language_id = rccGetCurrentLanguage(ctx); } - + if (current_language_id == (rcc_language_id)-1) return NULL; if (language_id == current_language_id) return NULL; @@ -357,7 +357,7 @@ static char *rccRecodeTranslate(rcc_language_config *config, rcc_class_id class_ if (!curconfig) return NULL; if (rccConfigConfigure(curconfig)) return NULL; - + if (translate == RCC_OPTION_TRANSLATE_TRANSLITERATE) { if (!strcasecmp((*config)->language->sn, rcc_russian_language_sn)) { translated = rccSizedRecodeCharsets(ctx, "UTF-8", "KOI8-R", utfstring, 0, NULL); @@ -405,7 +405,7 @@ static char *rccRecodeTranslate(rcc_language_config *config, rcc_class_id class_ if (rccAreRelatedLanguages(curconfig, *config)) return NULL; } - if (translate == RCC_OPTION_TRANSLATE_SKIP_PARRENT) { + if (translate == RCC_OPTION_TRANSLATE_SKIP_PARENT) { if (rccIsParrentLanguage(curconfig, language_id)) return NULL; } @@ -770,7 +770,7 @@ char *rccSizedToCharset(rcc_context ctx, const char *charset, rcc_const_string b res = rccStringCheck(buf); if (!res) return NULL; - + icnv = rccIConvOpen(charset, "UTF-8"); if (icnv) { rccMutexLock(ctx->mutex); |