From 54371c28f07e638694ad2148e8900e1bae71e3d4 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 17 Feb 2019 00:08:28 +0000 Subject: make framebuffer use the language environment for the UI resources --- .gitignore | 3 +- frontends/framebuffer/Makefile | 15 ++++- frontends/framebuffer/findfile.c | 107 ++++++++++++++++++++++++++++-- frontends/framebuffer/findfile.h | 2 +- frontends/framebuffer/gui.c | 5 +- frontends/framebuffer/res/Messages | 2 +- frontends/framebuffer/res/de/welcome.html | 1 + frontends/framebuffer/res/en/credits.html | 1 + frontends/framebuffer/res/en/licence.html | 1 + frontends/framebuffer/res/en/maps.html | 1 + frontends/framebuffer/res/en/welcome.html | 1 + frontends/framebuffer/res/it/credits.html | 1 + frontends/framebuffer/res/it/licence.html | 1 + frontends/framebuffer/res/ja/welcome.html | 1 + frontends/framebuffer/res/nl/credits.html | 1 + frontends/framebuffer/res/nl/licence.html | 1 + frontends/framebuffer/res/nl/welcome.html | 1 + utils/filepath.c | 68 +++++++++++++------ 18 files changed, 181 insertions(+), 32 deletions(-) create mode 120000 frontends/framebuffer/res/de/welcome.html create mode 120000 frontends/framebuffer/res/en/credits.html create mode 120000 frontends/framebuffer/res/en/licence.html create mode 120000 frontends/framebuffer/res/en/maps.html create mode 120000 frontends/framebuffer/res/en/welcome.html create mode 120000 frontends/framebuffer/res/it/credits.html create mode 120000 frontends/framebuffer/res/it/licence.html create mode 120000 frontends/framebuffer/res/ja/welcome.html create mode 120000 frontends/framebuffer/res/nl/credits.html create mode 120000 frontends/framebuffer/res/nl/licence.html create mode 120000 frontends/framebuffer/res/nl/welcome.html diff --git a/.gitignore b/.gitignore index fa42a2031..4e84e7538 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,7 @@ frontends/riscos/appdir/Resources/fr/Templates,fec frontends/riscos/appdir/Resources/de/Templates,fec frontends/riscos/appdir/Resources/nl/Templates,fec resources/*/Messages -frontends/gtk/res/*/Messages -frontends/windows/res/*/Messages +frontends/*/res/*/Messages codedocs nsgtk nsgtk3 diff --git a/frontends/framebuffer/Makefile b/frontends/framebuffer/Makefile index 06e7afbaa..9bb042f4a 100644 --- a/frontends/framebuffer/Makefile +++ b/frontends/framebuffer/Makefile @@ -1,5 +1,10 @@ +# +# Makefile for NetSurf Framebuffer frontend +# +# This file is part of NetSurf +# # ---------------------------------------------------------------------------- -# Framebuffer target setup +# Framebuffer flag setup (using pkg-config) # ---------------------------------------------------------------------------- CFLAGS += -std=c99 -g \ @@ -50,6 +55,14 @@ LDFLAGS += -Wl,--whole-archive $(eval $(call pkg_config_find_and_add,libnsfb,libnsfb)) LDFLAGS += -Wl,--no-whole-archive +# --------------------------------------------------------------------------- +# Target setup +# --------------------------------------------------------------------------- + +# The filter and target for split messages +MESSAGES_FILTER=fb +MESSAGES_TARGET=$(FRONTEND_RESOURCES_DIR) + # --------------------------------------------------------------------------- # HOST specific feature flags # --------------------------------------------------------------------------- diff --git a/frontends/framebuffer/findfile.c b/frontends/framebuffer/findfile.c index 67312f452..44a07b383 100644 --- a/frontends/framebuffer/findfile.c +++ b/frontends/framebuffer/findfile.c @@ -17,29 +17,128 @@ */ #include +#include +#include #include "utils/filepath.h" +#include "utils/log.h" #include "framebuffer/findfile.h" char **respaths; /** resource search path vector */ -/** Create an array of valid paths to search for resources. +#define MAX_LANGV_SIZE 32 + +/** + * goes through the environment in appropriate order to find configured language + * + * \return language to use or "C" if nothing appropriate is set + */ +static const char *get_language_env(void) +{ + const char *envstr; + + envstr = getenv("LANGUAGE"); + if ((envstr != NULL) && (envstr[0] != 0)) { + return envstr; + } + + envstr = getenv("LC_ALL"); + if ((envstr != NULL) && (envstr[0] != 0)) { + return envstr; + } + + envstr = getenv("LC_MESSAGES"); + if ((envstr != NULL) && (envstr[0] != 0)) { + return envstr; + } + + envstr = getenv("LANG"); + if ((envstr != NULL) && (envstr[0] != 0)) { + return envstr; + } + + return "C"; +} + +/** + * build a string vector of language names + */ +static char **get_language_names(void) +{ + char **langv; /* output string vector of languages */ + int langc; /* count of languages in vector */ + const char *envlang; /* colon separated list of languages from environment */ + int lstart = 0; /* offset to start of current language */ + int lunder = 0; /* offset to underscore in current language */ + int lend = 0; /* offset to end of current language */ + char *nlang; + + langv = calloc(MAX_LANGV_SIZE + 2, sizeof(char *)); + if (langv == NULL) { + return NULL; + } + + envlang = get_language_env(); + + for (langc = 0; langc < MAX_LANGV_SIZE; langc++) { + /* work through envlang splitting on : */ + while ((envlang[lend] != 0) && + (envlang[lend] != ':') && + (envlang[lend] != '.')) { + if (envlang[lend] == '_') { + lunder = lend; + } + lend++; + } + /* place language in string vector */ + nlang = malloc(lend - lstart + 1); + memcpy(nlang, envlang + lstart, lend - lstart); + nlang[lend - lstart] = 0; + langv[langc] = nlang; + + /* add language without specialisation to vector */ + if (lunder != lstart) { + nlang = malloc(lunder - lstart + 1); + memcpy(nlang, envlang + lstart, lunder - lstart); + nlang[lunder - lstart] = 0; + langv[++langc] = nlang; + } + + /* if we stopped at the dot, move to the colon delimiter */ + while ((envlang[lend] != 0) && + (envlang[lend] != ':')) { + lend++; + } + if (envlang[lend] == 0) { + /* reached end of environment language list */ + break; + } + lend++; + lstart = lunder = lend; + } + return langv; +} + +/** + * Create an array of valid paths to search for resources. * * The idea is that all the complex path computation to find resources * is performed here, once, rather than every time a resource is * searched for. */ char ** -fb_init_resource(const char *resource_path) +fb_init_resource_path(const char *resource_path) { char **pathv; /* resource path string vector */ char **respath; /* resource paths vector */ - const char *lang = NULL; + char **langv; pathv = filepath_path_to_strvec(resource_path); - respath = filepath_generate(pathv, &lang); + langv = get_language_names(); + + respath = filepath_generate(pathv, (const char * const *)langv); filepath_free_strvec(pathv); diff --git a/frontends/framebuffer/findfile.h b/frontends/framebuffer/findfile.h index 1f3db6eb1..5e9e3186b 100644 --- a/frontends/framebuffer/findfile.h +++ b/frontends/framebuffer/findfile.h @@ -27,6 +27,6 @@ extern char **respaths; * is performed here, once, rather than every time a resource is * searched for. */ -char **fb_init_resource(const char *resource_path); +char **fb_init_resource_path(const char *resource_path); #endif /* NETSURF_FB_FINDFILE_H */ diff --git a/frontends/framebuffer/gui.c b/frontends/framebuffer/gui.c index 1e27dafb6..95e35fb30 100644 --- a/frontends/framebuffer/gui.c +++ b/frontends/framebuffer/gui.c @@ -2104,7 +2104,8 @@ static struct gui_misc_table framebuffer_misc_table = { .quit = gui_quit, }; -/** Entry point from OS. +/** + * Entry point from OS. * * /param argc The number of arguments in the string vector. * /param argv The argument string vector. @@ -2134,7 +2135,7 @@ main(int argc, char** argv) die("NetSurf operation table failed registration"); } - respaths = fb_init_resource(NETSURF_FB_RESPATH":"NETSURF_FB_FONTPATH); + respaths = fb_init_resource_path(NETSURF_FB_RESPATH":"NETSURF_FB_FONTPATH); /* initialise logging. Not fatal if it fails but not much we * can do about it either. diff --git a/frontends/framebuffer/res/Messages b/frontends/framebuffer/res/Messages index 43148a263..75bfdf53d 120000 --- a/frontends/framebuffer/res/Messages +++ b/frontends/framebuffer/res/Messages @@ -1 +1 @@ -../../../resources/en/Messages \ No newline at end of file +en/Messages \ No newline at end of file diff --git a/frontends/framebuffer/res/de/welcome.html b/frontends/framebuffer/res/de/welcome.html new file mode 120000 index 000000000..b77e23743 --- /dev/null +++ b/frontends/framebuffer/res/de/welcome.html @@ -0,0 +1 @@ +../../../../resources/de/welcome.html \ No newline at end of file diff --git a/frontends/framebuffer/res/en/credits.html b/frontends/framebuffer/res/en/credits.html new file mode 120000 index 000000000..f73ecd4aa --- /dev/null +++ b/frontends/framebuffer/res/en/credits.html @@ -0,0 +1 @@ +../../../../resources/en/credits.html \ No newline at end of file diff --git a/frontends/framebuffer/res/en/licence.html b/frontends/framebuffer/res/en/licence.html new file mode 120000 index 000000000..0c3b430b7 --- /dev/null +++ b/frontends/framebuffer/res/en/licence.html @@ -0,0 +1 @@ +../../../../resources/en/licence.html \ No newline at end of file diff --git a/frontends/framebuffer/res/en/maps.html b/frontends/framebuffer/res/en/maps.html new file mode 120000 index 000000000..507a4b248 --- /dev/null +++ b/frontends/framebuffer/res/en/maps.html @@ -0,0 +1 @@ +../../../../resources/en/maps.html \ No newline at end of file diff --git a/frontends/framebuffer/res/en/welcome.html b/frontends/framebuffer/res/en/welcome.html new file mode 120000 index 000000000..543f31ddd --- /dev/null +++ b/frontends/framebuffer/res/en/welcome.html @@ -0,0 +1 @@ +../../../../resources/en/welcome.html \ No newline at end of file diff --git a/frontends/framebuffer/res/it/credits.html b/frontends/framebuffer/res/it/credits.html new file mode 120000 index 000000000..2b7c99542 --- /dev/null +++ b/frontends/framebuffer/res/it/credits.html @@ -0,0 +1 @@ +../../../../resources/it/credits.html \ No newline at end of file diff --git a/frontends/framebuffer/res/it/licence.html b/frontends/framebuffer/res/it/licence.html new file mode 120000 index 000000000..92afce85b --- /dev/null +++ b/frontends/framebuffer/res/it/licence.html @@ -0,0 +1 @@ +../../../../resources/it/licence.html \ No newline at end of file diff --git a/frontends/framebuffer/res/ja/welcome.html b/frontends/framebuffer/res/ja/welcome.html new file mode 120000 index 000000000..8b603f3df --- /dev/null +++ b/frontends/framebuffer/res/ja/welcome.html @@ -0,0 +1 @@ +../../../../resources/ja/welcome.html \ No newline at end of file diff --git a/frontends/framebuffer/res/nl/credits.html b/frontends/framebuffer/res/nl/credits.html new file mode 120000 index 000000000..71b27e40a --- /dev/null +++ b/frontends/framebuffer/res/nl/credits.html @@ -0,0 +1 @@ +../../../../resources/nl/credits.html \ No newline at end of file diff --git a/frontends/framebuffer/res/nl/licence.html b/frontends/framebuffer/res/nl/licence.html new file mode 120000 index 000000000..5aaf1cb44 --- /dev/null +++ b/frontends/framebuffer/res/nl/licence.html @@ -0,0 +1 @@ +../../../../resources/nl/licence.html \ No newline at end of file diff --git a/frontends/framebuffer/res/nl/welcome.html b/frontends/framebuffer/res/nl/welcome.html new file mode 120000 index 000000000..ef7a97cc9 --- /dev/null +++ b/frontends/framebuffer/res/nl/welcome.html @@ -0,0 +1 @@ +../../../../resources/nl/welcome.html \ No newline at end of file diff --git a/utils/filepath.c b/utils/filepath.c index 9c1e7667b..b87e2bf0d 100644 --- a/utils/filepath.c +++ b/utils/filepath.c @@ -16,10 +16,12 @@ * along with this program. If not, see . */ -/** \file +/** + * \file * Provides utility functions for finding readable files. * - * These functions are intended to make finding resource files more straightforward. + * These functions are intended to make finding resource files more + * straightforward. */ #include @@ -37,7 +39,7 @@ #include "utils/filepath.h" /** maximum number of elements in the resource vector */ -#define MAX_RESPATH 128 +#define MAX_RESPATH 128 /* exported interface documented in filepath.h */ char *filepath_vsfindfile(char *str, const char *format, va_list ap) @@ -61,20 +63,21 @@ char *filepath_vsfindfile(char *str, const char *format, va_list ap) } realpathname = realpath(pathname, str); - + free(pathname); - + if (realpathname != NULL) { /* sucessfully expanded pathname */ if (access(realpathname, R_OK) != 0) { /* unable to read the file */ return NULL; - } + } } return realpathname; } + /* exported interface documented in filepath.h */ char *filepath_sfindfile(char *str, const char *format, ...) { @@ -88,6 +91,7 @@ char *filepath_sfindfile(char *str, const char *format, ...) return ret; } + /* exported interface documented in filepath.h */ char *filepath_findfile(const char *format, ...) { @@ -120,6 +124,7 @@ char *filepath_sfind(char **respathv, char *filepath, const char *filename) return NULL; } + /* exported interface documented in filepath.h */ char *filepath_find(char **respathv, const char *filename) { @@ -141,6 +146,7 @@ char *filepath_find(char **respathv, const char *filename) return ret; } + /* exported interface documented in filepath.h */ char * filepath_sfinddef(char **respathv, @@ -163,7 +169,7 @@ filepath_sfinddef(char **respathv, snprintf(t, PATH_MAX, "%s/%s/%s", getenv("HOME"), def + 1, filename); } else { snprintf(t, PATH_MAX, "%s/%s", def, filename); - } + } if (realpath(t, ret) == NULL) { strncpy(ret, t, PATH_MAX); } @@ -182,23 +188,41 @@ filepath_generate(char * const *pathv, const char * const *langv) int langc = 0; int respathc = 0; struct stat dstat; - char tmppath[PATH_MAX]; + char *tmppath; + int tmppathlen; respath = calloc(MAX_RESPATH, sizeof(char *)); while ((respath != NULL) && (pathv[pathc] != NULL)) { - if ((stat(pathv[pathc], &dstat) == 0) && + if ((stat(pathv[pathc], &dstat) == 0) && S_ISDIR(dstat.st_mode)) { /* path element exists and is a directory */ langc = 0; while (langv[langc] != NULL) { - snprintf(tmppath, sizeof tmppath, "%s/%s", pathv[pathc],langv[langc]); - if ((stat(tmppath, &dstat) == 0) && + tmppathlen = snprintf(NULL, + 0, + "%s/%s", + pathv[pathc], + langv[langc]); + tmppath = malloc(tmppathlen + 1); + if (tmppath == NULL) { + break; + } + snprintf(tmppath, + tmppathlen + 1, + "%s/%s", + pathv[pathc], + langv[langc]); + + if ((stat(tmppath, &dstat) == 0) && S_ISDIR(dstat.st_mode)) { /* path element exists and is a directory */ - respath[respathc++] = strdup(tmppath); + respath[respathc++] = tmppath; + } else { + free(tmppath); } + langc++; } respath[respathc++] = strdup(pathv[pathc]); @@ -208,6 +232,7 @@ filepath_generate(char * const *pathv, const char * const *langv) return respath; } + /** * expand ${} in a string into environment variables. * @@ -236,20 +261,20 @@ expand_path(const char *path, int pathlen) explen = pathlen; while (exp[cloop] != 0) { - if ((exp[cloop] == '$') && + if ((exp[cloop] == '$') && (exp[cloop + 1] == '{')) { cstart = cloop; cloop++; - } - + } + if ((cstart != -1) && (exp[cloop] == '}')) { replen = cloop - cstart; exp[cloop] = 0; envv = getenv(exp + cstart + 2); if (envv == NULL) { - memmove(exp + cstart, - exp + cloop + 1, + memmove(exp + cstart, + exp + cloop + 1, explen - cloop); explen -= replen; } else { @@ -261,8 +286,8 @@ expand_path(const char *path, int pathlen) return NULL; } exp = tmp; - memmove(exp + cstart + envlen, - exp + cloop + 1, + memmove(exp + cstart + envlen, + exp + cloop + 1, explen - cloop ); memmove(exp + cstart, envv, envlen); explen += envlen - replen; @@ -282,6 +307,7 @@ expand_path(const char *path, int pathlen) return exp; } + /* exported interface documented in filepath.h */ char ** filepath_path_to_strvec(const char *path) @@ -319,12 +345,13 @@ filepath_path_to_strvec(const char *path) /* check for termination */ if (*eend == 0) break; - + estart = eend; } return strvec; } + /* exported interface documented in filepath.h */ void filepath_free_strvec(char **pathv) { @@ -335,4 +362,3 @@ void filepath_free_strvec(char **pathv) } free(pathv); } - -- cgit v1.2.3