I am writing some utility program using GNUWin32 libraries, libgw32.a and libintl.lib to contribute to GNU Win32 collection. I'd like to ask some question about message catalog path handling of NLS routine bindtextdomain(pkg_name, locale_dir). How the bindtextdomain() finds message catalog directory in PC Windows environment?
In Unix/Linux environment, the usual message catalog directory is semi-fixed like "/usr/share/locale" and with help of autoconf it is found at compile time.
But in Win32 environment and binary distribution, the program and message catalog data may be installed anywhere in directory structures, not just "C:\Program File\Gnu Win32\share\locale\".
But many GNU program that uses bindtextdomain() determines LOCALEDIR argument at compile time. So how can I cope with this problem without using autoconf and re-compile by end user? I don't want user to set NLS_PATH environment variable manually and use it as the bindtextdomain argument. Many GNU Win32 program works well with NLS without NLS_PATH set.
How this problem is handled by GNU Win32 distributions? Should I read Windows registry info about GNU Win32 install path and use it or get executable path and search message catalog directories in run-time? then how about binary only ZIP distribution?
Apart from this problem, is there any established convention of GNU Win32 distribution to choose package name argument of bindtextdomain()? If any, I will follow that. May I use name like "GNUWin32-supplement"?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2008-04-03
The approach I have taken in software I have ported to Windows is to have a DllMain() function (in case the software is a library, built as a DLL) store the HMODULE for the DLL, and then when pathnames for things like message catalogs or configuration files are needed, construct such pathnames at run-time, based on the location of the DLL as retrieved using GetModuleFileName() function. Typically, to minimize the impact on the source code, I then put in some header something like:
ifdef _WIN32
undef FOO_SOMEDIR
define FOO_SOMEDIR _foo_win32_get_somedir()
endif
Then the uses of FOO_SOMEDIR in the source code need not be ifdeffified.
In order to support installing in folders with any Unicode characters in the path name, you should use the wide character version of the API, GetModuleFileNameW(). But typically libraries you use (like libintl) don't have any wide character versions of their functions, so then you need to get the short (8.3) version of path names, using GetShortPathNameW().
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've adopted a variation of Tor's technique, for associating POSIX message catalogues, (gencat --> catopen/catgets), with applications in the MinGW world. However, since message catalogues are generally specific to a particular application, I use the path to the executable, rather than the path to any DLL, as the point of reference.
The logic I've adopted is (roughly) as follows:--
1) Identify the executable path name, using the global _pgmptr variable.
2) Strip off the final file name component from resultant path name.
3) If the new final directory name component is either bin' orsbin' (ignoring case), then also strip that off.
4) Append /share/locale' to the remaining path name.
5) Select message catalogues identified as%L/%N' [*], within this directory tree.
In any case, this logic is encapsulated within my port of catopen()' itself, so client applications need only to arrange to install their message catalogues within a./share/locale' subdirectory of their own installation tree, to ensure that they will be found at run time.
I have a great deal of respect for Tor's insight, (he also contributes to discussions on MinGW mailing lists), and I note his comments about the use of GetModuleFileNameW(), to correctly handle Unicode path names. It may well be that my use of _pgmptr in (1) isn't sufficient. I'd certainly welcome feed back, and more so patches, should this be the case; the MinGW implementation of catgets can be found in the MinGW Project CVS, on SourceForge: http://mingw.cvs.sourceforge.net/mingw/catgets/
Regards,
Keith.
Per POSIX specification, my port of catopen() uses the LC_MESSAGES or LANG environment variables to resolve the %L component of the effective NLSPATH. Since Win32 users will not typically have either of these set, I use the function call win32_iso639_default( "LANG" )', (an implementation may be found at http://mingw.cvs.sourceforge.net/mingw/man/src/win32/winlang.c?revision=1.1&view=markup), in each of my applications, conditional on _WIN32, (a #define in compat.h effectively makeswin32_iso639_default( anything )' a no-op for other platforms), before calling catopen().
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I see... Then how about setting some convention or guideline on such matter?
Unix/Linux has quite well-defined directory tree structure and conventions so many directory can be determined at compile time, like bin install path, library directory, message catalog directory, font or other program resource directories, document directory, etc. In windows environment, it is highly dependent on installation and varies widely among them.
Every directory or location of resources should be found in runtime or program install/setup time, So GNU programs ported to Win32 environment need some equivalent of windows registry database of these directories. ("Known Folder" in Windows taxonomy.).
Program itself will find the path once (at first run) and save search effort and start up faster. Missing path will be healed automagically.
It will benefit end user too. User can move install directories and change path value in the database manually by simple editing.
We just need few entry in registry or config INI file like "GNUWin32.ini" in fixed windows folder ( like %SYSTEMROOT% or %USERPROFILE% ) so that we have single place to look at such database.
It is desirable to be handled by centralized database and library than left to and attacked and handled by individual GNU Win32 contributors.
These guideline can be accomplished by some form of GNUWin32 specific extension to common library or simple header file change. Then individual GNU Win32 developer can enjoy such feature with minimal impact on GNU program source code.
We need such common library code or convention to find "Well-known Folder" or resource locations in run time in Windows environment.
Any though on setting up such common convention or add "resource finding standard routine" in GNW Win32 libraries?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2008-04-06
> Then how about setting some convention or guideline on such matter?
Well, who has the authority to set up such conventions or guidelines? I might be a pessimist, but trying to come up with some agreement among a group of people will just lead to endless flame wars when people who were left out (or ignored the effort) later still do things in other ways...
As can be seen even just by comparing my approach (no Registry or other centralized anything) to your ideas, opinions differ widely.
> GNU programs ported to Win32 environment
Don't restrict yourself to considering only GNU programs. Not all interesting Open Source software is "GNU" in some sense, or even use a GNU license.
> We just need few entry in registry or config INI file like "GNUWin32.ini" in fixed windows
> folder ( like %SYSTEMROOT% or %USERPROFILE% ) so that we have single place to look at such database.
As I said in my previous post, I personally don't like using some central registry needlessly. Software can find where it is installed quite fine at run-time (withut any "searching" as you seem to imply) by just asking Windows for the location of the .exe file (or a .dll), and then constructing pathnames needed from that.
> individual GNU Win32 contributors ... GNUWin32 specific extension
I think you are overestimating the position and authority of the gnuwin32 sourceforge project here. No offense to the gnuwin32 project people (or one guy, Kees?), your work is certainly extremely useful. But gnuwin32 is just one source for ports of common open source software to Windows. (Not all of the software offered by gnuwin32 have anything to do with GNU, btw.)
--tml
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am writing some utility program using GNUWin32 libraries, libgw32.a and libintl.lib to contribute to GNU Win32 collection. I'd like to ask some question about message catalog path handling of NLS routine bindtextdomain(pkg_name, locale_dir). How the bindtextdomain() finds message catalog directory in PC Windows environment?
In Unix/Linux environment, the usual message catalog directory is semi-fixed like "/usr/share/locale" and with help of autoconf it is found at compile time.
But in Win32 environment and binary distribution, the program and message catalog data may be installed anywhere in directory structures, not just "C:\Program File\Gnu Win32\share\locale\".
But many GNU program that uses bindtextdomain() determines LOCALEDIR argument at compile time. So how can I cope with this problem without using autoconf and re-compile by end user? I don't want user to set NLS_PATH environment variable manually and use it as the bindtextdomain argument. Many GNU Win32 program works well with NLS without NLS_PATH set.
How this problem is handled by GNU Win32 distributions? Should I read Windows registry info about GNU Win32 install path and use it or get executable path and search message catalog directories in run-time? then how about binary only ZIP distribution?
Apart from this problem, is there any established convention of GNU Win32 distribution to choose package name argument of bindtextdomain()? If any, I will follow that. May I use name like "GNUWin32-supplement"?
The approach I have taken in software I have ported to Windows is to have a DllMain() function (in case the software is a library, built as a DLL) store the HMODULE for the DLL, and then when pathnames for things like message catalogs or configuration files are needed, construct such pathnames at run-time, based on the location of the DLL as retrieved using GetModuleFileName() function. Typically, to minimize the impact on the source code, I then put in some header something like:
ifdef _WIN32
undef FOO_SOMEDIR
define FOO_SOMEDIR _foo_win32_get_somedir()
endif
Then the uses of FOO_SOMEDIR in the source code need not be ifdeffified.
In order to support installing in folders with any Unicode characters in the path name, you should use the wide character version of the API, GetModuleFileNameW(). But typically libraries you use (like libintl) don't have any wide character versions of their functions, so then you need to get the short (8.3) version of path names, using GetShortPathNameW().
I've adopted a variation of Tor's technique, for associating POSIX message catalogues, (gencat --> catopen/catgets), with applications in the MinGW world. However, since message catalogues are generally specific to a particular application, I use the path to the executable, rather than the path to any DLL, as the point of reference.
The logic I've adopted is (roughly) as follows:--
1) Identify the executable path name, using the global _pgmptr variable.
2) Strip off the final file name component from resultant path name.
3) If the new final directory name component is either
bin' orsbin' (ignoring case), then also strip that off.4) Append
/share/locale' to the remaining path name. 5) Select message catalogues identified as%L/%N' [*], within this directory tree.In any case, this logic is encapsulated within my port of
catopen()' itself, so client applications need only to arrange to install their message catalogues within a./share/locale' subdirectory of their own installation tree, to ensure that they will be found at run time.I have a great deal of respect for Tor's insight, (he also contributes to discussions on MinGW mailing lists), and I note his comments about the use of GetModuleFileNameW(), to correctly handle Unicode path names. It may well be that my use of _pgmptr in (1) isn't sufficient. I'd certainly welcome feed back, and more so patches, should this be the case; the MinGW implementation of catgets can be found in the MinGW Project CVS, on SourceForge:
http://mingw.cvs.sourceforge.net/mingw/catgets/
Regards,
Keith.
win32_iso639_default( "LANG" )', (an implementation may be found at http://mingw.cvs.sourceforge.net/mingw/man/src/win32/winlang.c?revision=1.1&view=markup), in each of my applications, conditional on _WIN32, (a #define in compat.h effectively makeswin32_iso639_default( anything )' a no-op for other platforms), before calling catopen().I see... Then how about setting some convention or guideline on such matter?
Unix/Linux has quite well-defined directory tree structure and conventions so many directory can be determined at compile time, like bin install path, library directory, message catalog directory, font or other program resource directories, document directory, etc. In windows environment, it is highly dependent on installation and varies widely among them.
Every directory or location of resources should be found in runtime or program install/setup time, So GNU programs ported to Win32 environment need some equivalent of windows registry database of these directories. ("Known Folder" in Windows taxonomy.).
Program itself will find the path once (at first run) and save search effort and start up faster. Missing path will be healed automagically.
It will benefit end user too. User can move install directories and change path value in the database manually by simple editing.
We just need few entry in registry or config INI file like "GNUWin32.ini" in fixed windows folder ( like %SYSTEMROOT% or %USERPROFILE% ) so that we have single place to look at such database.
It is desirable to be handled by centralized database and library than left to and attacked and handled by individual GNU Win32 contributors.
These guideline can be accomplished by some form of GNUWin32 specific extension to common library or simple header file change. Then individual GNU Win32 developer can enjoy such feature with minimal impact on GNU program source code.
We need such common library code or convention to find "Well-known Folder" or resource locations in run time in Windows environment.
Any though on setting up such common convention or add "resource finding standard routine" in GNW Win32 libraries?
> Then how about setting some convention or guideline on such matter?
Well, who has the authority to set up such conventions or guidelines? I might be a pessimist, but trying to come up with some agreement among a group of people will just lead to endless flame wars when people who were left out (or ignored the effort) later still do things in other ways...
As can be seen even just by comparing my approach (no Registry or other centralized anything) to your ideas, opinions differ widely.
> GNU programs ported to Win32 environment
Don't restrict yourself to considering only GNU programs. Not all interesting Open Source software is "GNU" in some sense, or even use a GNU license.
> We just need few entry in registry or config INI file like "GNUWin32.ini" in fixed windows
> folder ( like %SYSTEMROOT% or %USERPROFILE% ) so that we have single place to look at such database.
As I said in my previous post, I personally don't like using some central registry needlessly. Software can find where it is installed quite fine at run-time (withut any "searching" as you seem to imply) by just asking Windows for the location of the .exe file (or a .dll), and then constructing pathnames needed from that.
> individual GNU Win32 contributors ... GNUWin32 specific extension
I think you are overestimating the position and authority of the gnuwin32 sourceforge project here. No offense to the gnuwin32 project people (or one guy, Kees?), your work is certainly extremely useful. But gnuwin32 is just one source for ports of common open source software to Windows. (Not all of the software offered by gnuwin32 have anything to do with GNU, btw.)
--tml