make framebuffer use the language environment for the UI resources

This commit is contained in:
Vincent Sanders 2019-02-17 00:08:28 +00:00
parent cfb6c461fc
commit 54371c28f0
18 changed files with 181 additions and 32 deletions

3
.gitignore vendored
View File

@ -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

View File

@ -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
# ---------------------------------------------------------------------------

View File

@ -17,29 +17,128 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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);

View File

@ -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 */

View File

@ -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.

View File

@ -1 +1 @@
../../../resources/en/Messages
en/Messages

View File

@ -0,0 +1 @@
../../../../resources/de/welcome.html

View File

@ -0,0 +1 @@
../../../../resources/en/credits.html

View File

@ -0,0 +1 @@
../../../../resources/en/licence.html

View File

@ -0,0 +1 @@
../../../../resources/en/maps.html

View File

@ -0,0 +1 @@
../../../../resources/en/welcome.html

View File

@ -0,0 +1 @@
../../../../resources/it/credits.html

View File

@ -0,0 +1 @@
../../../../resources/it/licence.html

View File

@ -0,0 +1 @@
../../../../resources/ja/welcome.html

View File

@ -0,0 +1 @@
../../../../resources/nl/credits.html

View File

@ -0,0 +1 @@
../../../../resources/nl/licence.html

View File

@ -0,0 +1 @@
../../../../resources/nl/welcome.html

View File

@ -16,10 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \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 <sys/types.h>
@ -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);
}