static int seq_open_db(struct _citrus_lookup *cl, const char *name) { int ret; struct _region r; char path[PATH_MAX]; snprintf(path, sizeof(path), "%s.db", name); ret = _map_file(&r, path); if (ret) return ret; ret = _db_open(&cl->cl_db, &r, _CITRUS_LOOKUP_MAGIC, _db_hash_std, NULL); if (ret) { _unmap_file(&r); return ret; } cl->cl_dbfile = r; cl->cl_dbnum = _db_get_num_entries(cl->cl_db); cl->cl_dbidx = 0; cl->cl_rewind = 1; cl->cl_lookup = &seq_lookup_db; cl->cl_next = &seq_next_db; cl->cl_num_entries = &seq_get_num_entries_db; cl->cl_close = &seq_close_db; return 0; }
static int _db_and_parsers_setup(lms_t *lms, struct db **db_ret, void ***parser_match_ret) { void **parser_match; struct db *db; int r = 0; db = _db_open(lms->db_path); if (!db) { r = -1; return r; } if (lms_parsers_setup(lms, db->handle) != 0) { fprintf(stderr, "ERROR: could not setup parsers.\n"); r = -2; goto err; } if (_db_compile_all_stmts(db) != 0) { fprintf(stderr, "ERROR: could not compile statements.\n"); r = -3; goto err; } if (lms_parsers_start(lms, db->handle) != 0) { fprintf(stderr, "ERROR: could not start parsers.\n"); r = -4; goto err; } if (lms->n_parsers < 1) { fprintf(stderr, "ERROR: no parser could be started, exit.\n"); r = -5; goto err; } parser_match = malloc(lms->n_parsers * sizeof(*parser_match)); if (!parser_match) { perror("malloc"); r = -6; goto err; } *parser_match_ret = parser_match; *db_ret = db; return r; err: lms_parsers_finish(lms, db->handle); _db_close(db); return r; }
static int open_subdb(struct _citrus_db **subdb, struct _citrus_db *db, const char *src) { int ret; struct _region r; ret = _db_lookup_by_s(db, src, &r, NULL); if (ret) return ret; ret = _db_open(subdb, &r, _CITRUS_PIVOT_SUB_MAGIC, _db_hash_std, NULL); if (ret) return ret; return 0; }
/* * conv_esdb: * external representation -> local structure. */ static int conv_esdb(struct _citrus_esdb *esdb, struct _region *fr) { struct _citrus_db *db; const char *str; char buf[100]; uint32_t csid, i, num_charsets, tmp, version; int ret; /* open db */ ret = _db_open(&db, fr, _CITRUS_ESDB_MAGIC, &_db_hash_std, NULL); if (ret) goto err0; /* check version */ ret = _db_lookup32_by_s(db, _CITRUS_ESDB_SYM_VERSION, &version, NULL); if (ret) goto err1; switch (version) { case 0x00000001: /* current version */ /* initial version */ break; default: ret = EFTYPE; goto err1; } /* get encoding/variable */ ret = _db_lookupstr_by_s(db, _CITRUS_ESDB_SYM_ENCODING, &str, NULL); if (ret) goto err1; esdb->db_encname = strdup(str); if (esdb->db_encname == NULL) { ret = errno; goto err1; } esdb->db_len_variable = 0; esdb->db_variable = NULL; ret = _db_lookupstr_by_s(db, _CITRUS_ESDB_SYM_VARIABLE, &str, NULL); if (ret == 0) { esdb->db_len_variable = strlen(str) + 1; esdb->db_variable = strdup(str); if (esdb->db_variable == NULL) { ret = errno; goto err2; } } else if (ret != ENOENT) goto err2; /* get number of charsets */ ret = _db_lookup32_by_s(db, _CITRUS_ESDB_SYM_NUM_CHARSETS, &num_charsets, NULL); if (ret) goto err3; esdb->db_num_charsets = num_charsets; /* get invalid character */ ret = _db_lookup32_by_s(db, _CITRUS_ESDB_SYM_INVALID, &tmp, NULL); if (ret == 0) { esdb->db_use_invalid = 1; esdb->db_invalid = tmp; } else if (ret == ENOENT) esdb->db_use_invalid = 0; else goto err3; /* get charsets */ esdb->db_charsets = malloc(num_charsets * sizeof(*esdb->db_charsets)); if (esdb->db_charsets == NULL) { ret = errno; goto err3; } for (i = 0; i < num_charsets; i++) { snprintf(buf, sizeof(buf), _CITRUS_ESDB_SYM_CSID_PREFIX "%d", i); ret = _db_lookup32_by_s(db, buf, &csid, NULL); if (ret) goto err4; esdb->db_charsets[i].ec_csid = csid; snprintf(buf, sizeof(buf), _CITRUS_ESDB_SYM_CSNAME_PREFIX "%d", i); ret = _db_lookupstr_by_s(db, buf, &str, NULL); if (ret) goto err4; esdb->db_charsets[i].ec_csname = strdup(str); if (esdb->db_charsets[i].ec_csname == NULL) { ret = errno; goto err4; } } _db_close(db); return (0); err4: for (; i > 0; i--) free(esdb->db_charsets[i - 1].ec_csname); free(esdb->db_charsets); err3: free(esdb->db_variable); err2: free(esdb->db_encname); err1: _db_close(db); if (ret == ENOENT) ret = EFTYPE; err0: return (ret); }
static int find_best_pivot_pvdb(const char *src, const char *dst, char *pivot, size_t pvlen, unsigned long *rnorm) { int ret, num, i; struct _region fr, r1, r2; struct _citrus_db *db1, *db2, *db3; char buf[LINE_MAX]; unsigned long norm; uint32_t val32; ret = _map_file(&fr, CS_PIVOT ".pvdb"); if (ret) { if (ret == ENOENT) ret = NO_SUCH_FILE; return ret; } ret = _db_open(&db1, &fr, _CITRUS_PIVOT_MAGIC, _db_hash_std, NULL); if (ret) goto quit1; ret = open_subdb(&db2, db1, src); if (ret) goto quit2; num = _db_get_num_entries(db2); *rnorm = ULONG_MAX; for (i = 0; i < num; i++) { /* iterate each pivot */ ret = _db_get_entry(db2, i, &r1, &r2); if (ret) goto quit3; /* r1:pivot name, r2:norm among src and pivot */ ret = get32(&r2, &val32); if (ret) goto quit3; norm = val32; snprintf(buf, sizeof(buf), "%.*s", (int)_region_size(&r1), (char *)_region_head(&r1)); /* buf: pivot name */ ret = open_subdb(&db3, db1, buf); if (ret) goto quit3; if (_db_lookup_by_s(db3, dst, &r2, NULL) != 0) /* don't break the loop, test all src/dst pairs. */ goto quit4; /* r2: norm among pivot and dst */ ret = get32(&r2, &val32); if (ret) goto quit4; norm += val32; /* judge minimum norm */ if (norm < *rnorm) { *rnorm = norm; strlcpy(pivot, buf, pvlen); } quit4: _db_close(db3); if (ret) goto quit3; } quit3: _db_close(db2); quit2: _db_close(db1); quit1: _unmap_file(&fr); if (ret) return ret; if (*rnorm == ULONG_MAX) return ENOENT; return 0; }