From 7356aa96c9c2332b9d3fe35f8e48b2c403620b08 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Sat, 8 May 2004 18:13:27 +0000 Subject: [project @ 2004-05-08 18:13:27 by bursa] Clean up and make more efficient. svn path=/import/netsurf/; revision=843 --- utils/messages.c | 134 +++++++++++++++++++++++++++++++------------------------ utils/messages.h | 17 +++---- 2 files changed, 85 insertions(+), 66 deletions(-) (limited to 'utils') diff --git a/utils/messages.c b/utils/messages.c index cddbfddeb..ae81ad467 100644 --- a/utils/messages.c +++ b/utils/messages.c @@ -2,33 +2,53 @@ * This file is part of NetSurf, http://netsurf.sourceforge.net/ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license - * Copyright 2003 James Bursa + * Copyright 2004 James Bursa + */ + +/** \file + * Localised message support (implementation). + * + * Native language messages are loaded from a file and stored hashed by key for + * fast access. */ #include +#include #include #include #include "netsurf/utils/log.h" #include "netsurf/utils/messages.h" #include "netsurf/utils/utils.h" -/* We store the messages in a fixed-size hash table. */ - +/** We store the messages in a fixed-size hash table. */ #define HASH_SIZE 77 -struct entry { - const char *key; - const char *value; - struct entry *next; /* next in this hash chain */ +/** Maximum length of a key. */ +#define MAX_KEY_LENGTH 16 + +/** Entry in the messages hash table. */ +struct messages_entry { + struct messages_entry *next; /**< Next entry in this hash chain. */ + char key[MAX_KEY_LENGTH]; + char value[1]; }; -static struct entry *table[HASH_SIZE]; +/** Localised messages hash table. */ +static struct messages_entry *messages_table[HASH_SIZE]; + static unsigned int messages_hash(const char *s); /** - * messages_load -- read a messages file into the hash table + * Read keys and values from messages file. + * + * \param path pathname of messages file + * + * The messages are merged with any previously loaded messages. Any keys which + * are present already are replaced with the new value. + * + * Exits through die() in case of error. */ void messages_load(const char *path) @@ -37,30 +57,44 @@ void messages_load(const char *path) FILE *fp; fp = fopen(path, "r"); - if (fp == 0) { - LOG(("failed to open file '%s'", path)); - return; + if (!fp) { + snprintf(s, sizeof s, "Unable to open messages file " + "\"%.100s\": %s", path, strerror(errno)); + s[sizeof s - 1] = 0; + LOG(("%s", s)); + die(s); } - while (fgets(s, 300, fp) != 0) { - char *colon; + while (fgets(s, sizeof s, fp)) { + char *colon, *value; unsigned int slot; - struct entry *entry; + struct messages_entry *entry; + size_t length; if (s[0] == 0 || s[0] == '#') continue; + + s[strlen(s) - 1] = 0; /* remove \n at end */ colon = strchr(s, ':'); - if (colon == 0) + if (!colon) continue; - s[strlen(s) - 1] = 0; /* remove \n at end */ *colon = 0; /* terminate key */ - - entry = xcalloc(1, sizeof(*entry)); - entry->key = xstrdup(s); - entry->value = xstrdup(colon + 1); + value = colon + 1; + length = strlen(value); + + entry = malloc(sizeof *entry + length + 1); + if (!entry) { + snprintf(s, sizeof s, "Not enough memory to load " + "messages file \"%.100s\".", path); + s[sizeof s - 1] = 0; + LOG(("%s", s)); + die(s); + } + strncpy(entry->key, s, MAX_KEY_LENGTH); + strcpy(entry->value, value); slot = messages_hash(entry->key); - entry->next = table[slot]; - table[slot] = entry; + entry->next = messages_table[slot]; + messages_table[slot] = entry; } fclose(fp); @@ -68,67 +102,51 @@ void messages_load(const char *path) /** - * messages_get -- fast lookup of a message by key + * Fast lookup of a message by key. + * + * \param key key of message + * \return value of message, or key if not found */ const char *messages_get(const char *key) { - char *colon; - const char *value = key; - char key2[40]; - unsigned int slot, len; - struct entry *entry; - - colon = strchr(key, ':'); - if (colon != 0) { - /* fallback appended to key */ - value = colon + 1; - len = colon - key; - if (39 < len) - len = 39; - strncpy(key2, key, len); - key2[len] = 0; - key = key2; - } + struct messages_entry *entry; - slot = messages_hash(key); - for (entry = table[slot]; - entry != 0 && strcasecmp(entry->key, key) != 0; + for (entry = messages_table[messages_hash(key)]; + entry && strcasecmp(entry->key, key) != 0; entry = entry->next) ; - if (entry == 0) { - LOG(("using fallback for key '%s'", key)); - return value; - } + if (!entry) + return key; return entry->value; } /** - * messages_hash -- hash function for keys + * Hash function for keys. */ unsigned int messages_hash(const char *s) { - unsigned int z = 0; - if (s == 0) + unsigned int i, z = 0; + if (!s) return 0; - for (; *s != 0; s++) - z += *s & 0x1f; /* lower 5 bits, case insensitive */ - return (z % (HASH_SIZE - 1)) + 1; + for (i = 0; i != MAX_KEY_LENGTH && s[i]; i++) + z += s[i] & 0x1f; /* lower 5 bits, case insensitive */ + return z % HASH_SIZE; } /** - * messages_dump -- dump contents of hash table + * Dump set of loaded messages. */ void messages_dump(void) { unsigned int i; for (i = 0; i != HASH_SIZE; i++) { - struct entry *entry; - for (entry = table[i]; entry != 0; entry = entry->next) - printf("%s:%s\n", entry->key, entry->value); + struct messages_entry *entry; + for (entry = messages_table[i]; entry; entry = entry->next) + printf("%.20s:%s\n", entry->key, entry->value); } } diff --git a/utils/messages.h b/utils/messages.h index fd8457da8..bef380edc 100644 --- a/utils/messages.h +++ b/utils/messages.h @@ -2,19 +2,20 @@ * This file is part of NetSurf, http://netsurf.sourceforge.net/ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license - * Copyright 2003 James Bursa + * Copyright 2004 James Bursa */ -/** +/** \file + * Localised message support (interface). + * * The messages module loads a file of keys and associated strings, and * provides fast lookup by key. The messages file consists of key:value lines, * comment lines starting with #, and other lines are ignored. Use - * messages_load() to read the file into memory. To lookup a key, use - * messages_get("key") or messages_get("key:fallback") . A pointer to the - * value is returned, and this is shared by all callers. If the key does not - * exist, the parameter will be returned in the first case and a pointer to - * the fallback string in the parameter in the second. Thus the parameter must - * be a constant string. + * messages_load() to read the file into memory. To lookup a key, use + * messages_get("key"). + * + * Only the first MAX_KEY_LENGTH (currently 16) characters of the key are + * significant. */ #ifndef _NETSURF_UTILS_MESSAGES_H_ -- cgit v1.2.3