diff options
author | ache <ache@FreeBSD.org> | 2002-08-30 20:26:02 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 2002-08-30 20:26:02 +0000 |
commit | 1286c989d680b02f88a9c13952bbb57e99e7fbac (patch) | |
tree | cc03a67fbc20d6779a68e2600ee8cd1e1703c761 | |
parent | ac79a8c0ebce44313944033ddef7dd8eb5f9574a (diff) | |
download | FreeBSD-src-1286c989d680b02f88a9c13952bbb57e99e7fbac.zip FreeBSD-src-1286c989d680b02f88a9c13952bbb57e99e7fbac.tar.gz |
Prepare for switching to unlimited chains format.
Optimize chains lookup a bit.
-rw-r--r-- | lib/libc/locale/collate.c | 63 | ||||
-rw-r--r-- | lib/libc/locale/collate.h | 6 |
2 files changed, 46 insertions, 23 deletions
diff --git a/lib/libc/locale/collate.c b/lib/libc/locale/collate.c index 45493d4..614d5d5 100644 --- a/lib/libc/locale/collate.c +++ b/lib/libc/locale/collate.c @@ -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; diff --git a/lib/libc/locale/collate.h b/lib/libc/locale/collate.h index 413fdf3..ce03e74 100644 --- a/lib/libc/locale/collate.h +++ b/lib/libc/locale/collate.h @@ -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 *); |