summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2014-10-25 12:39:21 +0100
committerVincent Sanders <vince@kyllikki.org>2014-10-25 12:45:32 +0100
commit94ab63319f5ce6eb8fb081d8f38f9fe53808970e (patch)
tree1543f9bf4117cb58af3a7ce87516dfcd34cb79aa
parent808783c2ebb692ba84d21b9b5f8670b1ae61f03e (diff)
downloadnetsurf-94ab63319f5ce6eb8fb081d8f38f9fe53808970e.tar.gz
netsurf-94ab63319f5ce6eb8fb081d8f38f9fe53808970e.tar.bz2
Improve the message loading API to return error codes.
Returning an error instead of simply calling die allows more robust error handling. Secondly initialisation may continue even if the messages have not been loaded which is more friendly than simply dropping dead with no communication to the user.
-rw-r--r--utils/messages.c149
-rw-r--r--utils/messages.h20
2 files changed, 85 insertions, 84 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) {
diff --git a/utils/messages.h b/utils/messages.h
index 81c380515..795c10009 100644
--- a/utils/messages.h
+++ b/utils/messages.h
@@ -36,9 +36,23 @@
#include "utils/errors.h"
#include "utils/hashtable.h"
-void messages_load(const char *path);
-struct hash_table *messages_load_ctx(const char *path, struct hash_table *ctx);
-const char *messages_get_ctx(const char *key, struct hash_table *ctx);
+/**
+ * Read keys and values from messages file into the standard Messages hash.
+ *
+ * The messages are merged with any previously loaded messages. Any keys which
+ * are present already are replaced with the new value.
+ *
+ * \param path pathname of messages file.
+ * \return NSERROR_OK on success or error code on faliure.
+ */
+nserror messages_load(const char *path);
+
+/**
+ * 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
+ */
const char *messages_get(const char *key);
/**