From a1bc4c6a222f446e4a74b9021a1d88dc616cfa8d Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 5 Feb 2016 15:36:18 +0000 Subject: [PATCH] remove need for glib in monkey frontend main --- monkey/main.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 4 deletions(-) diff --git a/monkey/main.c b/monkey/main.c index d2529d8c1..65e923d70 100644 --- a/monkey/main.c +++ b/monkey/main.c @@ -16,10 +16,10 @@ * along with this program. If not, see . */ -#include #include #include +#include "utils/config.h" #include "utils/log.h" #include "utils/messages.h" #include "utils/filepath.h" @@ -40,7 +40,13 @@ #include "monkey/schedule.h" #include "monkey/bitmap.h" -char **respaths; /** resource search path vector */ +/** maximum number of languages in language vector */ +#define LANGV_SIZE 32 +/** maximum length of all strings in language vector */ +#define LANGS_SIZE 4096 + +/** resource search path vector */ +char **respaths; static bool monkey_done = false; @@ -57,17 +63,118 @@ static void die(const char * const error) exit(EXIT_FAILURE); } +/** obtain language from environment + * + * start with GNU extension LANGUAGE environment variable and then try + * POSIX variables LC_ALL, LC_MESSAGES and LANG + * + */ +static const char *get_language(void) +{ + const char *lang; + + lang = getenv("LANGUAGE"); + if ((lang != NULL) && (lang[0] != '\0')) { + return lang; + } + + lang = getenv("LC_ALL"); + if ((lang != NULL) && (lang[0] != '\0')) { + return lang; + } + + lang = getenv("LC_MESSAGES"); + if ((lang != NULL) && (lang[0] != '\0')) { + return lang; + } + + lang = getenv("LANG"); + if ((lang != NULL) && (lang[0] != '\0')) { + return lang; + } + + return NULL; +} + + +/** provide a string vector of languages in preference order + * + * environment variables are processed to aquire a colon separated + * list of languages which are converted into a string vector. The + * vector will always have the C language as its last entry. + * + * This implementation creates an internal static representation of + * the vector when first called and returns that for all subsequent + * calls. i.e. changing the environment does not change the returned + * vector on repeated calls. + * + * If the environment variables have more than LANGV_SIZE languages or + * LANGS_SIZE bytes of data the results list will be curtailed. + */ +static const char * const *get_languagev(void) +{ + static const char *langv[LANGV_SIZE]; + int langidx = 0; /* index of next entry in vector */ + static char langs[LANGS_SIZE]; + char *curp; /* next language parameter in langs string */ + const char *lange; /* language from environment variable */ + int lang_len; + char *cln; /* colon in lange */ + + /* return cached vector */ + if (langv[0] != NULL) { + return &langv[0]; + } + + curp = &langs[0]; + + lange = get_language(); + + if (lange != NULL) { + lang_len = strlen(lange) + 1; + if (lang_len < (LANGS_SIZE - 2)) { + memcpy(curp, lange, lang_len); + while ((curp[0] != 0) && + (langidx < (LANGV_SIZE - 2))) { + /* avoid using strchrnul as it is not portable */ + cln = strchr(curp, ':'); + if (cln == NULL) { + langv[langidx++] = curp; + curp += lang_len; + break; + } else { + if ((cln - curp) > 1) { + /* only place non empty entries in vector */ + langv[langidx++] = curp; + } + *cln++ = 0; /* null terminate */ + lang_len -= (cln - curp); + curp = cln; + } + } + } + } + + /* ensure C language is present */ + langv[langidx++] = curp; + *curp++ = 'C'; + *curp++ = 0; + langv[langidx] = NULL; + + return &langv[0]; +} + /* Stolen from gtk/gui.c */ static char ** nsmonkey_init_resource(const char *resource_path) { - const gchar * const *langv; + const char * const *langv; char **pathv; /* resource path string vector */ char **respath; /* resource paths vector */ pathv = filepath_path_to_strvec(resource_path); - langv = g_get_language_names(); + langv = get_languagev(); respath = filepath_generate(pathv, langv);