On Sun, Oct 5, 2025 at 3:08 PM Jim Hall <[email protected]> wrote: > [..] > > **For those interested, I'll write a brief history of Kitten in > another email reply.
Unix and DOS have different methods to support multiple languages. Original MS-DOS created language-specific versions. So there was a version of MS-DOS compiled with English messages, a version with Spanish language messages, a version with French language messages .. and so on. Unix (Big Unix systems and Linux) use one compiled version of the program, plus a language "catalog" that contains messages for each supported language. Usually the program has a "default" language. For example, the original "Big Unix" implementation used a function called catopen() to open a message catalog for a specific language, then used catgets() to get a string from that catalog. Each string had a "message ID" in a "message set," so you might group errors into one set, and status messages into another set, and so on. If set 1 was "errors" then message 1.1 might be "Failure" .. and if set 2 was "status" then message 2.1 might be "Please wait." When retrieving the message with catgets(), you also supplied the default string. So you might do this: puts( catgets(cat, 2, 1, "Please wait") ); That's what I implemented in 1999 as the "Cats" library. I looked at my original code, and it was poorly written, so it was really slow. But it worked. Thankfully, others helped contribute fixes to it, and made it better. Cats became a de facto standard for FreeDOS programs to support multiple languages. In 2003, Tom rewrote Cats to be smaller and more efficient, using a simplified calling interface. This new library was called "Kitten" (because it's a smaller version of "Cats"). The basic features remained the same: you opened a catalog with kittenopen() and you retrieved messages with kittengets(). Cats only supported one catalog file at a time anyway, so Kitten removed the 'cat' parameter to get a string from the catalog. If set 2 was "status" messages, and message 2.1 was "Please wait," then you might do this: puts( kittengets(2, 1, "Please wait") ); Both Cats and Kitten used files to store the messages. You put the files in the NLSPATH, with each file named as "program name" dot "2-letter language." The language code was stored in the LANG environment variable. If NLSPATH was C:\freedos\nls, then the Spanish language messages for the FIND command might be saved to: C:\freedos\nls\FIND.es At run-time, the program would interpret the LANG and NLSPATH variables to find the language catalog for that program, then load the messages into memory with the kittenopen() function. In 2021, Tom made a new program called KITTENC (the "Kitten Compiler") that attaches all the language resources to the end of the EXE program, so the program doesn't need to read from a file. You still use the LANG variable to set the language, but now the FIND program might support several languages .. they're just attached at the end of the FIND.EXE program itself. From the KITTENC readme file: > KITTENC 'compiles' language resources to strings and attaches > these strings to the executable program such that the program can > retrieve these strings at execution time. This way it is enough to > copy a file to another place WITHOUT taking care that the resources > (in the NLS directory) are also copied. [..] > this saves a lot of disk space compared old KITTEN/NLS approach as everything > is stored in a single file with cluster slack exactly once, not once for each > message file. also, the new runtime KITTEN.C is 600 byte smaller then the > original > as all the intelligence, parsing etc. are done at compile time. > > it's implementation also saves a few byte for each message translation call > bcause clever;) And that's the brief history of Cats/Kitten. _______________________________________________ Freedos-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/freedos-devel
