示例#1
0
const char *BPY_app_translations_py_pgettext(const char *msgctxt, const char *msgid)
{
#define STATIC_LOCALE_SIZE 32  /* Should be more than enough! */

	GHashKey *key;
	static char locale[STATIC_LOCALE_SIZE] = "";
	const char *tmp;

	/* Just in case, should never happen! */
	if (!_translations)
		return msgid;

	tmp = BLF_lang_get();
	if (strcmp(tmp, locale) || !_translations_cache) {
		PyGILState_STATE _py_state;

		BLI_strncpy(locale, tmp, STATIC_LOCALE_SIZE);

		/* Locale changed or cache does not exist, refresh the whole cache! */
		/* This func may be called from C (i.e. outside of python interpreter 'context'). */
		_py_state = PyGILState_Ensure();

		_build_translations_cache(_translations->py_messages, locale);

		PyGILState_Release(_py_state);
	}

	/* And now, simply create the key (context, messageid) and find it in the cached dict! */
	key = _ghashutil_keyalloc(msgctxt, msgid);

	tmp = BLI_ghash_lookup(_translations_cache, key);

	_ghashutil_keyfree((void *)key);

	return tmp ? tmp : msgid;

#undef STATIC_LOCALE_SIZE
}
示例#2
0
static void _build_translations_cache(PyObject *py_messages, const char *locale)
{
	PyObject *uuid, *uuid_dict;
	Py_ssize_t pos = 0;
	char *language = NULL, *language_country = NULL, *language_variant = NULL;

	/* For each py dict, we'll search for full locale, then language+country, then language+variant,
	 * then only language keys... */
	BLT_lang_locale_explode(locale, &language, NULL, NULL, &language_country, &language_variant);

	/* Clear the cached ghash if needed, and create a new one. */
	_clear_translations_cache();
	_translations_cache = BLI_ghash_new(_ghashutil_keyhash, _ghashutil_keycmp, __func__);

	/* Iterate over all py dicts. */
	while (PyDict_Next(py_messages, &pos, &uuid, &uuid_dict)) {
		PyObject *lang_dict;

#if 0
		PyObject_Print(uuid_dict, stdout, 0);
		printf("\n");
#endif

		/* Try to get first complete locale, then language+country, then language+variant, then only language */
		lang_dict = PyDict_GetItemString(uuid_dict, locale);
		if (!lang_dict && language_country) {
			lang_dict = PyDict_GetItemString(uuid_dict, language_country);
			locale = language_country;
		}
		if (!lang_dict && language_variant) {
			lang_dict = PyDict_GetItemString(uuid_dict, language_variant);
			locale = language_variant;
		}
		if (!lang_dict && language) {
			lang_dict = PyDict_GetItemString(uuid_dict, language);
			locale = language;
		}

		if (lang_dict) {
			PyObject *pykey, *trans;
			Py_ssize_t ppos = 0;

			if (!PyDict_Check(lang_dict)) {
				printf("WARNING! In translations' dict of \"");
				PyObject_Print(uuid, stdout, Py_PRINT_RAW);
				printf("\":\n");
				printf("    Each language key must have a dictionary as value, \"%s\" is not valid, skipping: ",
				       locale);
				PyObject_Print(lang_dict, stdout, Py_PRINT_RAW);
				printf("\n");
				continue;
			}

			/* Iterate over all translations of the found language dict, and populate our ghash cache. */
			while (PyDict_Next(lang_dict, &ppos, &pykey, &trans)) {
				const char *msgctxt = NULL, *msgid = NULL;
				bool invalid_key = false;

				if ((PyTuple_CheckExact(pykey) == false) || (PyTuple_GET_SIZE(pykey) != 2)) {
					invalid_key = true;
				}
				else {
					PyObject *tmp = PyTuple_GET_ITEM(pykey, 0);
					if (tmp == Py_None) {
						msgctxt = BLT_I18NCONTEXT_DEFAULT_BPYRNA;
					}
					else if (PyUnicode_Check(tmp)) {
						msgctxt = _PyUnicode_AsString(tmp);
					}
					else {
						invalid_key = true;
					}

					tmp = PyTuple_GET_ITEM(pykey, 1);
					if (PyUnicode_Check(tmp)) {
						msgid = _PyUnicode_AsString(tmp);
					}
					else {
						invalid_key = true;
					}
				}

				if (invalid_key) {
					printf("WARNING! In translations' dict of \"");
					PyObject_Print(uuid, stdout, Py_PRINT_RAW);
					printf("\", %s language:\n", locale);
					printf("    Keys must be tuples of (msgctxt [string or None], msgid [string]), "
					       "this one is not valid, skipping: ");
					PyObject_Print(pykey, stdout, Py_PRINT_RAW);
					printf("\n");
					continue;
				}
				if (PyUnicode_Check(trans) == false) {
					printf("WARNING! In translations' dict of \"");
					PyObject_Print(uuid, stdout, Py_PRINT_RAW);
					printf("\":\n");
					printf("    Values must be strings, this one is not valid, skipping: ");
					PyObject_Print(trans, stdout, Py_PRINT_RAW);
					printf("\n");
					continue;
				}

				/* Do not overwrite existing keys! */
				if (BPY_app_translations_py_pgettext(msgctxt, msgid) == msgid) {
					GHashKey *key = _ghashutil_keyalloc(msgctxt, msgid);
					BLI_ghash_insert(_translations_cache, key, BLI_strdup(_PyUnicode_AsString(trans)));
				}
			}
		}
	}

	/* Clean up! */
	MEM_SAFE_FREE(language);
	MEM_SAFE_FREE(language_country);
	MEM_SAFE_FREE(language_variant);
}