About gettext It's come up recently on the FreeDOS Mailing List to create a "smaller" version of Cats to provide i18n. I'm not against it. I chose to implement 'catgets' because (1) it was easy, and (2) it was a UNIX standard. I feel that adhering to standards (even standards borrowed from other operating systems) is important. Standards will lend flexibility to any FreeDOS program that uses it. One solution that has been suggested is very similar to the GNU Gettext library, which the GNU people created to replace the UNIX standard 'catgets' library. The catgets implementation is defined in the X/Open Portability Guide, Volume 3, XSI Supplementary Definitions, Chapter 5. Here's a summary: [GNU gettext manual] The interface to the catgets implementation consists of three functions which correspond to those used in file access: catopen to open the catalog for using, catgets for accessing the message tables, and catclose for closing after work is done. The catgets function is used like this: char *translation = catgets (catd, set_no, msg_id, "original string"); The first parameter is this catalog descriptor. The second parameter specifies the set of messages in this catalog, in which the message described by msg_id is obtained. catgets therefore uses a three-stage addressing: catalog name => set number => message ID => translation The fourth argument is not used to address the translation. It is given as a default value in case when one of the addressing stages fail. One important thing to remember is that although the return type of catgets is char * the resulting string must not be changed. It should better be const char *, but the standard is published in 1988, one year before ANSI C. [... so the problem is that to refer to a translation in a catalog, you have three "coordinates" (catalog, set, message) to find it. The gettext library uses only one "coordinate" - the string itself. ...] The definition of the gettext interface comes from a Uniforum proposal and it is followed by at least one major Unix vendor (Sun) in its last developments. It is not specified in any official standard, though. It has a global domain which unqualified usages reference. Of course this domain is selectable by the user. char *textdomain (const char *domain_name); This provides the possibility to change or query the current status of the current global domain of the LC_MESSAGE category. The argument is a null-terminated string, whose characters must be legal in the use in filenames. If the domain_name argument is NULL, the function returns the current value. If no value has been set before, the name of the default domain is returned. Please note that although the return value of textdomain is of type char * no changing is allowed. It is also important to know that no checks of the availability are made. If the name is not available you will see this by the fact that no translations are provided. To use a domain set by textdomain the function char *gettext (const char *msgid); is to be used. This is the simplest reasonable form one can imagine. The translation of the string msgid is returned if it is available in the current domain. If not available the argument itself is returned. If the argument is NULL the result is undefined. I suppose you could implement a "micro" edition of gettext that implements only the 'textdomain' and 'gettext' functions. I had considered that when I was deciding which i18n library to implement for FreeDOS. But since 'catgets' could be mostly implemented in a small space, I decided on that. Note that the current catgets loads the catalog into memory with 'catopen', but the next major release (4.0) of catgets will provide a "database"-like thing that will have a smaller memory footprint. Probably something simple like fseek. The existing "load everything" mode will be available for programs that still need it (i.e. where the catalog is on removeable media.) -- Here's one idea on how to create a message catalog for gettext that would be easy to parse "on the run". Let the un-translated key be denoted by "<" and the translation be denoted by ">". There may only be one "<" line per key, but multiple lines for ">". This allows output strings that span multiple lines. For example: EXAMPLE.ES Hola mundo Fallo al escribir en la unidad A: To do a scan of the message catalog, you can just create a "search string" by prepending "<" to the string, then using strcmp to see if the string you are reading in the catalog matches the key you are searching for. Then return a string composed of all lines following that line, but that begin with ">". Or, to do this with a "database" ... you can scan the catalog when gettext is initialized (using textdomain?). Create a hash that represents the lines that start with ">", and store that hash in memory with a location that you can fseek to later. That way, you don't have to store every string in memory. The problem becomes in hash collision .. do you have to store the string anyway? (I guess that's why GNU created gperf). Such an idea is possible.