diff options
Diffstat (limited to 'wgt-locales.c')
-rw-r--r-- | wgt-locales.c | 105 |
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; +} + |