diff options
Diffstat (limited to 'utils/messages.c')
-rw-r--r-- | utils/messages.c | 149 |
1 files changed, 68 insertions, 81 deletions
diff --git a/utils/messages.c b/utils/messages.c index 8ae616b86..27038e4e2 100644 --- a/utils/messages.c +++ b/utils/messages.c @@ -17,8 +17,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -/** \file - * Localised message support (implementation). +/** + * \file + * Localised message support implementation. * * Native language messages are loaded from a file and stored hashed by key for * fast access. @@ -37,7 +38,7 @@ #include "utils/utils.h" #include "utils/hashtable.h" -/** We store the messages in a fixed-size hash table. */ +/** Messages are stored in a fixed-size hash table. */ #define HASH_SIZE 101 /** The hash table used to store the standard Messages file for the old API */ @@ -47,32 +48,38 @@ static struct hash_table *messages_hash = NULL; * Read keys and values from messages file. * * \param path pathname of messages file - * \param ctx struct hash_table to merge with, or NULL for a new one. - * \return struct hash_table containing the context or NULL in case of error. + * \param ctx reference of hash table to merge with. + * \return NSERROR_OK on sucess and ctx updated or error code on faliure. */ - -struct hash_table *messages_load_ctx(const char *path, struct hash_table *ctx) +static nserror messages_load_ctx(const char *path, struct hash_table **ctx) { - char s[400]; - gzFile fp; + char s[400]; /* line buffer */ + gzFile fp; /* compressed file handle */ + struct hash_table *nctx; /* new context */ assert(path != NULL); - ctx = (ctx != NULL) ? ctx : hash_create(HASH_SIZE); + fp = gzopen(path, "r"); + if (!fp) { + LOG(("Unable to open messages file \"%.100s\": %s", + path, strerror(errno))); - if (ctx == NULL) { - LOG(("Unable to create hash table for messages file %s", path)); - return NULL; + return NSERROR_NOT_FOUND; } - fp = gzopen(path, "r"); - if (!fp) { - snprintf(s, sizeof s, "Unable to open messages file " - "\"%.100s\": %s", path, strerror(errno)); - s[sizeof s - 1] = 0; - LOG(("%s", s)); - hash_destroy(ctx); - return NULL; + if (*ctx == NULL) { + nctx = hash_create(HASH_SIZE); + } else { + /** + * \note The passed hash is not copied here so this + * updates in place. + */ + nctx = *ctx; + } + if (nctx == NULL) { + LOG(("Unable to create hash table for messages file %s", path)); + gzclose(fp); + return NSERROR_NOMEM; } while (gzgets(fp, s, sizeof s)) { @@ -88,53 +95,25 @@ struct hash_table *messages_load_ctx(const char *path, struct hash_table *ctx) *colon = 0; /* terminate key */ value = colon + 1; - if (hash_add(ctx, s, value) == false) { + if (hash_add(nctx, s, value) == false) { LOG(("Unable to add %s:%s to hash table of %s", s, value, path)); gzclose(fp); - hash_destroy(ctx); - return NULL; + if (*ctx == NULL) { + hash_destroy(nctx); + } + return NSERROR_INVALID; } } gzclose(fp); - return ctx; -} - -/** - * Read keys and values from messages file into the standard Messages hash. - * - * \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. - */ + *ctx = nctx; -void messages_load(const char *path) -{ - struct hash_table *m; - char s[400]; - - if (path == NULL) - return; - - LOG(("Loading Messages from '%s'", path)); - - m = messages_load_ctx(path, messages_hash); - if (m == NULL) { - LOG(("Unable to open Messages file '%s'. Possible reason: %s", - path, strerror(errno))); - snprintf(s, sizeof s, - "Unable to open Messages file '%s'.", path); - die(s); - } - - messages_hash = m; + return NSERROR_OK; } + /** * Fast lookup of a message by key. * @@ -142,22 +121,42 @@ void messages_load(const char *path) * \param ctx context of messages file to look up in * \return value of message, or key if not found */ - -const char *messages_get_ctx(const char *key, struct hash_table *ctx) +static const char * +messages_get_ctx(const char *key, struct hash_table *ctx) { - const char *r; + const char *r = NULL; assert(key != NULL); - /* If we're called with no context, it's nicer to return the - * key rather than explode - this allows attempts to get messages - * before messages_hash is set up to fail gracefully, for example */ - if (ctx == NULL) - return key; + /* allow attempts to retrieve messages before context is set up. */ + if (ctx != NULL) { + r = hash_get(ctx, key); + } + + /* If called with no context or unable to retrive a value + * return the key. + */ + if (r == NULL) { + r = key; + } + + return r; +} + +/* exported interface documented in messages.h */ +nserror messages_load(const char *path) +{ + nserror err; + + if (path == NULL) { + err = NSERROR_BAD_PARAMETER; + } else { + LOG(("Loading Messages from '%s'", path)); - r = hash_get(ctx, key); + err = messages_load_ctx(path, &messages_hash); + } - return r ? r : key; + return err; } /* exported interface documented in messages.h */ @@ -189,26 +188,14 @@ char *messages_get_buff(const char *key, ...) } -/** - * Fast lookup of a message by key from the standard Messages hash. - * - * \param key key of message - * \return value of message, or key if not found - */ - +/* exported function documented in utils/messages.h */ const char *messages_get(const char *key) { return messages_get_ctx(key, messages_hash); } -/** - * lookup of a message by errorcode from the standard Messages hash. - * - * \param code errorcode of message - * \return message text - */ - +/* exported function documented in utils/messages.h */ const char *messages_get_errorcode(nserror code) { switch (code) { |