summaryrefslogtreecommitdiffstats
path: root/wgt-locales.c
diff options
context:
space:
mode:
Diffstat (limited to 'wgt-locales.c')
-rw-r--r--wgt-locales.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/wgt-locales.c b/wgt-locales.c
new file mode 100644
index 0000000..d985b64
--- /dev/null
+++ b/wgt-locales.c
@@ -0,0 +1,105 @@
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include "wgt.h"
+
+struct locarr {
+ int count;
+ char **arr;
+};
+
+static struct locarr locarr = { 0, NULL };
+
+static int add(const char *locstr, int length)
+{
+ int i;
+ char *item, **ptr;
+
+ item = strndup(locstr, length);
+ if (item != NULL) {
+ for (i = 0 ; item[i] ; i++)
+ item[i] = tolower(item[i]);
+ for (i = 0 ; i < locarr.count ; i++)
+ if (!strcmp(item, locarr.arr[i])) {
+ free(item);
+ return 0;
+ }
+
+ ptr = realloc(locarr.arr, (1 + locarr.count) * sizeof(locarr.arr[0]));
+ if (ptr) {
+ locarr.arr = ptr;
+ locarr.arr[locarr.count++] = item;
+ return 0;
+ }
+ free(item);
+ }
+ errno = ENOMEM;
+ return -1;
+}
+
+void locales_reset()
+{
+ while (locarr.count)
+ free(locarr.arr[--locarr.count]);
+}
+
+int locales_add(const char *locstr)
+{
+ const char *stop, *next;
+ while (*locstr) {
+ stop = strchrnul(locstr, ',');
+ next = stop + !!*stop;
+ while (locstr != stop) {
+ if (add(locstr, stop - locstr))
+ return -1;
+ do { stop--; } while(stop > locstr && *stop != '-');
+ }
+ locstr = next;
+ }
+ return 0;
+}
+
+int locales_score(const char *lang)
+{
+ int i;
+
+ if (lang)
+ for (i = 0 ; i < locarr.count ; i++)
+ if (!strcasecmp(lang, locarr.arr[i]))
+ return i;
+
+ return INT_MAX;
+}
+
+char *locales_locate_file(const char *filename)
+{
+ int i;
+ char path[PATH_MAX];
+ char * result;
+
+ for (i = 0 ; i < locarr.count ; i++) {
+ if (snprintf(path, sizeof path, "locales/%s/%s", locarr.arr[i], filename) >= (int)(sizeof path)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ if (!access(path, F_OK)) {
+ result = strdup(path);
+ if (!result)
+ errno = ENOMEM;
+ return result;
+ }
+ }
+ if (access(filename, F_OK)) {
+ result = strdup(filename);
+ if (!result)
+ errno = ENOMEM;
+ return result;
+ }
+ errno = ENOENT;
+ return NULL;
+}
+