Prepare for switching to unlimited chains format.

Optimize chains lookup a bit.
This commit is contained in:
Andrey A. Chernov 2002-08-30 20:26:02 +00:00
parent 425289a9db
commit 8e52da4dfc
2 changed files with 46 additions and 23 deletions

View File

@ -49,7 +49,7 @@ int __collate_substitute_nontrivial;
u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN];
struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1];
struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE];
struct __collate_st_chain_pri *__collate_chain_pri_table;
void __collate_err(int ex, const char *f) __dead2;
@ -57,9 +57,8 @@ int
__collate_load_tables(const char *encoding)
{
FILE *fp;
int i, saverr;
char collate_version[STR_LEN];
char buf[PATH_MAX];
int i, saverr, chains;
char strbuf[STR_LEN], buf[PATH_MAX];
void *TMP_substitute_table, *TMP_char_pri_table, *TMP_chain_pri_table;
static char collate_encoding[ENCODING_LEN + 1];
@ -90,6 +89,37 @@ __collate_load_tables(const char *encoding)
if ((fp = fopen(buf, "r")) == NULL)
return (_LDP_ERROR);
if (fread(strbuf, sizeof(strbuf), 1, fp) != 1) {
saverr = errno;
(void)fclose(fp);
errno = saverr;
return (_LDP_ERROR);
}
chains = -1;
if (strcmp(strbuf, COLLATE_VERSION) == 0)
chains = 0;
else if (strcmp(strbuf, COLLATE_VERSION1_1) == 0)
chains = 1;
if (chains < 0) {
(void)fclose(fp);
errno = EFTYPE;
return (_LDP_ERROR);
}
if (chains) {
if (fread(strbuf, sizeof(strbuf), 1, fp) != 1) {
saverr = errno;
(void)fclose(fp);
errno = saverr;
return (_LDP_ERROR);
}
if ((chains = atoi(strbuf)) < 1) {
(void)fclose(fp);
errno = EFTYPE;
return (_LDP_ERROR);
}
} else
chains = TABLE_SIZE;
if ((TMP_substitute_table =
malloc(sizeof(__collate_substitute_table))) == NULL) {
saverr = errno;
@ -106,7 +136,7 @@ __collate_load_tables(const char *encoding)
return (_LDP_ERROR);
}
if ((TMP_chain_pri_table =
malloc(sizeof(__collate_chain_pri_table))) == NULL) {
malloc(sizeof(*__collate_chain_pri_table) * chains)) == NULL) {
saverr = errno;
free(TMP_substitute_table);
free(TMP_char_pri_table);
@ -128,18 +158,10 @@ __collate_load_tables(const char *encoding)
} \
}
FREAD(collate_version, sizeof(collate_version), 1, fp);
if (strcmp(collate_version, COLLATE_VERSION) != 0) {
free(TMP_substitute_table);
free(TMP_char_pri_table);
free(TMP_chain_pri_table);
(void)fclose(fp);
errno = EFTYPE;
return (_LDP_ERROR);
}
FREAD(TMP_substitute_table, sizeof(__collate_substitute_table), 1, fp);
FREAD(TMP_char_pri_table, sizeof(__collate_char_pri_table), 1, fp);
FREAD(TMP_chain_pri_table, sizeof(__collate_chain_pri_table), 1, fp);
FREAD(TMP_chain_pri_table,
sizeof(*__collate_chain_pri_table) * chains, 1, fp);
(void)fclose(fp);
(void)strcpy(collate_encoding, encoding);
@ -149,9 +171,9 @@ __collate_load_tables(const char *encoding)
if (__collate_char_pri_table_ptr != NULL)
free(__collate_char_pri_table_ptr);
__collate_char_pri_table_ptr = TMP_char_pri_table;
if (__collate_chain_pri_table_ptr != NULL)
free(__collate_chain_pri_table_ptr);
__collate_chain_pri_table_ptr = TMP_chain_pri_table;
if (__collate_chain_pri_table != NULL)
free(__collate_chain_pri_table);
__collate_chain_pri_table = TMP_chain_pri_table;
__collate_substitute_nontrivial = 0;
for (i = 0; i < UCHAR_MAX + 1; i++) {
@ -203,8 +225,9 @@ __collate_lookup(t, len, prim, sec)
*len = 1;
*prim = *sec = 0;
for (p2 = __collate_chain_pri_table; p2->str[0]; p2++) {
if (strncmp(t, p2->str, strlen(p2->str)) == 0) {
for (p2 = __collate_chain_pri_table; p2->str[0] != '\0'; p2++) {
if (*t == p2->str[0] &&
strncmp(t, p2->str, strlen(p2->str)) == 0) {
*len = strlen(p2->str);
*prim = p2->prim;
*sec = p2->sec;

View File

@ -36,7 +36,8 @@
#define STR_LEN 10
#define TABLE_SIZE 100
#define COLLATE_VERSION "1.0\n"
#define COLLATE_VERSION "1.0\n"
#define COLLATE_VERSION1_1 "1.1\n"
struct __collate_st_char_pri {
int prim, sec;
@ -52,8 +53,7 @@ extern int __collate_substitute_nontrivial;
extern u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN];
#define __collate_char_pri_table (*__collate_char_pri_table_ptr)
extern struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1];
#define __collate_chain_pri_table (*__collate_chain_pri_table_ptr)
extern struct __collate_st_chain_pri __collate_chain_pri_table[TABLE_SIZE];
extern struct __collate_st_chain_pri *__collate_chain_pri_table;
__BEGIN_DECLS
u_char *__collate_strdup(u_char *);