You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							158 lines
						
					
					
						
							3.8 KiB
						
					
					
				
			
		
		
	
	
							158 lines
						
					
					
						
							3.8 KiB
						
					
					
				| /*
 | |
|  * Copyright 2021 Vincent Sanders <vince@netsurf-browser.org>
 | |
|  *
 | |
|  * This file is part of NetSurf, http://www.netsurf-browser.org/
 | |
|  *
 | |
|  * NetSurf is free software; you can redistribute it and/or modify
 | |
|  * it under the terms of the GNU General Public License as published by
 | |
|  * the Free Software Foundation; version 2 of the License.
 | |
|  *
 | |
|  * NetSurf is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|  * GNU General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU General Public License
 | |
|  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| 
 | |
| extern "C" {
 | |
| 
 | |
| #include "utils/errors.h"
 | |
| #include "utils/filepath.h"
 | |
| 
 | |
| }
 | |
| 
 | |
| #include "qt/resources.h"
 | |
| 
 | |
| /** resource search path vector */
 | |
| char **respaths;
 | |
| 
 | |
| /** maximum number of languages in language vector */
 | |
| #define LANGV_SIZE 32
 | |
| /** maximum length of all strings in language vector */
 | |
| #define LANGS_SIZE 4096
 | |
| 
 | |
| /**
 | |
|  * 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];
 | |
| }
 | |
| 
 | |
| 
 | |
| /* exported interface documented in qt/resources.h */
 | |
| nserror nsqt_init_resource_path(const char *resource_path)
 | |
| {
 | |
| 	const char * const *langv;
 | |
| 	char **pathv; /* resource path string vector */
 | |
| 
 | |
| 	pathv = filepath_path_to_strvec(resource_path);
 | |
| 
 | |
| 	langv = get_languagev();
 | |
| 
 | |
| 	respaths = filepath_generate(pathv, langv);
 | |
| 
 | |
| 	filepath_free_strvec(pathv);
 | |
| 
 | |
| 	return NSERROR_OK;
 | |
| }
 |