static int parse_file(struct _citrus_mapper_646 *m6, const char *path) { struct _memstream ms; struct _region r; const char *p; char *pp; size_t len; char buf[PATH_MAX]; int i, ret; ret = _map_file(&r, path); if (ret) return (ret); _memstream_bind(&ms, &r); for (i = 0; i < NUM_OF_SPECIALS; i++) { retry: p = _memstream_getln(&ms, &len); if (p == NULL) { ret = EINVAL; break; } p = _bcs_skip_ws_len(p, &len); if (*p == T_COMM || len==0) goto retry; if (!_bcs_isdigit(*p)) { ret = EINVAL; break; } snprintf(buf, sizeof(buf), "%.*s", (int)len, p); pp = __DECONST(void *, p); m6->m6_map[i] = strtoul(buf, (char **)&pp, 0); p = _bcs_skip_ws(buf); if (*p != T_COMM && !*p) { ret = EINVAL; break; } } _unmap_file(&r); 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; }
static void seq_close_plain(struct _citrus_lookup *cl) { _unmap_file(&cl->cl_plainr); }
static void seq_close_db(struct _citrus_lookup *cl) { _db_close(cl->cl_db); _unmap_file(&cl->cl_dbfile); }