MinGW/GCC 编译器修改 gettext 初始化路径使之能在任意位置输出中文消息

        GCC 编译器支持 gettext 的本地化,MinGW 也一样,只是可惜他们在内部实现时使用了绝对路径。这个绝对路径的前缀(prefix) 由编译时传递给 configure 的 --prefix 设定,这样就导致了 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 位置在哪,它都能显示翻译后的消息了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值