MinGW/GCC 编译器修改 gettext 初始化路径使之能在任意位置输出中文消息
2013-11-10 23:12
218 查看
GCC 编译器支持 gettext 的本地化,MinGW 也一样,只是可惜他们在内部实现时使用了绝对路径。这个绝对路径的前缀(prefix) 由编译时传递给 configure 的 --prefix 设定,这样就导致了 MinGW 只有在指定的位置上才能实现编译消息本地化。
我所做的就是让 GCC 在初始化 gettext 时使用相对路径,这样就能使 MinGW 在任何地方都能使用本地化的字符串了。包含文件搜索路径也同理。
通过查找 bindtextdomain 函数可以知道 gcc 对 gettext 的初始化在 gcc\intl.c 中完成。包含文件搜索路径定义在 incpath.c 中。
由于我所做的是针对 Windows 下的修改,因此所有改动都要加上 #ifdef WIN32 ... #endif
首先在开头加上:
其中 DirectoryExists 是用来判断路径是否存在的。
然后修改 (void) bindtextdomain ("gcc", LOCALEDIR); 为:
这样重新编译后,无论 MinGW 位置在哪,它都能显示翻译后的消息了。
我所做的就是让 GCC 在初始化 gettext 时使用相对路径,这样就能使 MinGW 在任何地方都能使用本地化的字符串了。包含文件搜索路径也同理。
通过查找 bindtextdomain 函数可以知道 gcc 对 gettext 的初始化在 gcc\intl.c 中完成。包含文件搜索路径定义在 incpath.c 中。
void gcc_init_libintl (void) { #ifdef HAVE_LC_MESSAGES setlocale (LC_CTYPE, ""); setlocale (LC_MESSAGES, ""); #else setlocale (LC_ALL, ""); #endif (void) bindtextdomain ("gcc", LOCALEDIR); (void) textdomain ("gcc"); /* Opening quotation mark. */ open_quote = _("`"); /* Closing quotation mark. */ close_quote = _("'"); #if defined HAVE_LANGINFO_CODESET locale_encoding = nl_langinfo (CODESET); if (locale_encoding != NULL && (!strcasecmp (locale_encoding, "utf-8") || !strcasecmp (locale_encoding, "utf8"))) locale_utf8 = true; #endif if (!strcmp (open_quote, "`") && !strcmp (close_quote, "'")) { /* Untranslated quotes that it may be possible to replace with U+2018 and U+2019; but otherwise use "'" instead of "`" as opening quote. */ open_quote = "'"; #if defined HAVE_LANGINFO_CODESET if (locale_utf8) { open_quote = "\xe2\x80\x98"; close_quote = "\xe2\x80\x99"; } #endif } }
由于我所做的是针对 Windows 下的修改,因此所有改动都要加上 #ifdef WIN32 ... #endif
首先在开头加上:
#ifdef WIN32 #include <windows.h> BOOL DirectoryExists(LPSTR lpszPath) { WIN32_FIND_DATA wfd; BOOL bResult = FALSE; HANDLE hFind = FindFirstFile(lpszPath, &wfd); if ((hFind != INVALID_HANDLE_VALUE) && (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { bResult = TRUE; } FindClose(hFind); return bResult; } #endif
其中 DirectoryExists 是用来判断路径是否存在的。
然后修改 (void) bindtextdomain ("gcc", LOCALEDIR); 为:
#ifndef WIN32 (void) bindtextdomain ("gcc", LOCALEDIR); #else DWORD dwSize = MAX_PATH + 20; LPSTR lpszName = (LPSTR) xmalloc(dwSize); DWORD dwRealSize = GetModuleFileNameA(NULL, lpszName, dwSize) + 1; if (dwRealSize > dwSize) { lpszName = (LPSTR) xrealloc(lpszName, dwSize + 20); GetModuleFileNameA(NULL, lpszName, dwRealSize + 20); } /* 去掉文件名 */ int l = strlen(lpszName); while (l >= 0) { if (lpszName[l] == '\\') break; l--; } lpszName[l] = 0; /* 去掉一层文件夹 */ l = strlen(lpszName); while (l > 0) { if (lpszName[l] == '\\') break; l--; } /* 判断是否到根路径 */ if (lpszName[l] != '\\') (void) bindtextdomain ("gcc", LOCALEDIR); else { // 连接上 share\locale lpszName[l + 1] = 0; strcat(lpszName, "share\\locale"); if (DirectoryExists(lpszName)) (void) bindtextdomain ("gcc", lpszName); else (void) bindtextdomain ("gcc", LOCALEDIR); } free(lpszName); #endif
这样重新编译后,无论 MinGW 位置在哪,它都能显示翻译后的消息了。
相关文章推荐
- 在编译向该请求提供服务所需资源的过程中出现错误。请检查下列特定错误详细信息并适当地修改源代码。 编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\41c191fd\ff9345c5\App_Web_login.cshtml.65793277
- gcc中文手册, gcc输出include的绝对路径
- 修改Keepalived配置文件位置以及重定向Keepalived日志的输出路径
- 修改Keepalived配置文件位置以及重定向Keepalived日志的输出路径
- (2012.01.03) 输出程序中的指定位置的行数与该文件的路径及标题。
- Win7下IIS发布网站遇到 编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary
- C#项目,改变文件的输出路径,查看C#项目的版本号,修改版本号的规则
- 修改IntelliJ IDEA中tomcat的输出路径
- 引用 运行asp.net程序时候,编译器错误消息: CS0016: 未能写入输出文件“c:\WINDOWS\Microsoft.NET\Fra
- 解决log4cxx输出中文路径乱码问题
- 修改开源xlslib使得支持输出UTF8中文Excel文件不乱码
- 编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\ro
- 修改Zookeeper日志 zookeeper.out输出路径
- 输出gcc的编译器内部预设全部常量宏定义
- dom4j建立,修改XML文档,并解决格式化输出和中文
- VS 修改输出路径和文件名
- mysql5.7在windows7下my.ini文件加载路径及数据位置修改
- c++ 实现双向链表构造函数,拷贝构造函数,析构函数,输出操作符重载,赋值操作符重载,头插尾插,头删尾删,任意位置插入,任意位置删除,查找等
- gcc 和 arm-linux-gcc 编译器的默认搜索头文件路径
- 从键盘任意输入10个整数,用函数编程实现将其中最大数与最小数的位置对换后,再输出调整后的数组。