summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/log.h26
-rw-r--r--utils/messages.c169
-rw-r--r--utils/messages.h29
-rw-r--r--utils/utils.c30
-rw-r--r--utils/utils.h23
5 files changed, 277 insertions, 0 deletions
diff --git a/utils/log.h b/utils/log.h
new file mode 100644
index 0000000..65417b9
--- /dev/null
+++ b/utils/log.h
@@ -0,0 +1,26 @@
+/*
+ * 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 <bursa@users.sourceforge.net>
+ * Copyright 2004 John Tytgat <John.Tytgat@aaug.net>
+ */
+
+#include <stdio.h>
+
+#ifndef _NETSURF_LOG_H_
+#define _NETSURF_LOG_H_
+
+#ifdef NDEBUG
+# define LOG(x) ((void) 0)
+#else
+# ifdef __GNUC__
+# define LOG(x) (printf(__FILE__ " %s %i: ", __PRETTY_FUNCTION__, __LINE__), printf x, fputc('\n', stdout))
+# elif defined(__CC_NORCROFT)
+# define LOG(x) (printf(__FILE__ " %s %i: ", __func__, __LINE__), printf x, fputc('\n', stdout))
+# else
+# define LOG(x) (printf(__FILE__ " %i: ", __LINE__), printf x, fputc('\n', stdout))
+# endif
+#endif
+
+#endif
diff --git a/utils/messages.c b/utils/messages.c
new file mode 100644
index 0000000..7cc10bb
--- /dev/null
+++ b/utils/messages.c
@@ -0,0 +1,169 @@
+/*
+ * 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 2004 James Bursa <bursa@users.sourceforge.net>
+ */
+
+/** \file
+ * Localised message support (implementation).
+ *
+ * Native language messages are loaded from a file and stored hashed by key for
+ * fast access.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include "nstheme/utils/log.h"
+#include "nstheme/utils/messages.h"
+#include "nstheme/utils/utils.h"
+
+/** We store the messages in a fixed-size hash table. */
+#define HASH_SIZE 77
+
+/** Maximum length of a key. */
+#define MAX_KEY_LENGTH 24
+
+/** 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];
+};
+
+/** Localised messages hash table. */
+static struct messages_entry *messages_table[HASH_SIZE];
+
+
+static unsigned int messages_hash(const char *s);
+
+
+/**
+ * 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)
+{
+ char s[300];
+ FILE *fp;
+
+ fp = fopen(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));
+ die(s);
+ }
+
+ while (fgets(s, sizeof s, fp)) {
+ char *colon, *value;
+ unsigned int slot;
+ 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)
+ continue;
+ *colon = 0; /* terminate key */
+ 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 = messages_table[slot];
+ messages_table[slot] = entry;
+ }
+
+ fclose(fp);
+}
+
+
+/**
+ * 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)
+{
+ struct messages_entry *entry;
+
+ for (entry = messages_table[messages_hash(key)];
+ entry && strcasecmp(entry->key, key) != 0;
+ entry = entry->next)
+ ;
+ if (!entry)
+ return key;
+ return entry->value;
+}
+
+/**
+ * Retrieve the key associated with a value
+ *
+ * \param value The value as returned by messages_get
+ * \return The key associated with the value or NULL if not found
+ */
+const char *messages_get_key(const char *value)
+{
+ const char *key = value - MAX_KEY_LENGTH;
+ const char *temp_value = messages_get(key);
+
+ if (strcmp(value, temp_value) == 0)
+ return key;
+
+ return NULL;
+}
+
+
+/**
+ * Hash function for keys.
+ */
+
+unsigned int messages_hash(const char *s)
+{
+ unsigned int i, z = 0;
+ if (!s)
+ return 0;
+ for (i = 0; i != MAX_KEY_LENGTH && s[i]; i++)
+ z += s[i] & 0x1f; /* lower 5 bits, case insensitive */
+ return z % HASH_SIZE;
+}
+
+
+/**
+ * Dump set of loaded messages.
+ */
+
+void messages_dump(void)
+{
+ unsigned int i;
+ for (i = 0; i != HASH_SIZE; i++) {
+ 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
new file mode 100644
index 0000000..33b2fc3
--- /dev/null
+++ b/utils/messages.h
@@ -0,0 +1,29 @@
+/*
+ * 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 2004 James Bursa <bursa@users.sourceforge.net>
+ */
+
+/** \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").
+ *
+ * Only the first MAX_KEY_LENGTH (currently 24) characters of the key are
+ * significant.
+ */
+
+#ifndef _NETSURF_UTILS_MESSAGES_H_
+#define _NETSURF_UTILS_MESSAGES_H_
+
+void messages_load(const char *path);
+const char *messages_get(const char *key);
+const char *messages_get_key(const char *value);
+void messages_dump(void);
+
+#endif
diff --git a/utils/utils.c b/utils/utils.c
new file mode 100644
index 0000000..4e7d80f
--- /dev/null
+++ b/utils/utils.c
@@ -0,0 +1,30 @@
+/*
+ * 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 2004 James Bursa <bursa@users.sourceforge.net>
+ * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
+ * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk>
+ * Copyright 2004 John Tytgat <John.Tytgat@aaug.net>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "nstheme/utils/utils.h"
+
+/**
+ * Check if a directory exists.
+ */
+
+bool is_dir(const char *path)
+{
+ struct stat s;
+
+ if (stat(path, &s))
+ return false;
+
+ return S_ISDIR(s.st_mode) ? true : false;
+}
diff --git a/utils/utils.h b/utils/utils.h
new file mode 100644
index 0000000..7f52acf
--- /dev/null
+++ b/utils/utils.h
@@ -0,0 +1,23 @@
+/*
+ * 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 2004 James Bursa <bursa@users.sourceforge.net>
+ * Copyright 2004 John Tytgat <John.Tytgat@aaug.net>
+ */
+
+#ifndef _NETSURF_UTILS_UTILS_H_
+#define _NETSURF_UTILS_UTILS_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <regex.h>
+#include "libxml/encoding.h"
+
+void die(const char * const error);
+bool is_dir(const char *path);
+void warn_user(const char *warning, const char *detail);
+
+#endif