FREEDOS CATS/KITTEN LIBRARY

WHAT'S NEW

28 Nov 2005 Sorry to say, I need to find a new maintainer for
Cats/KITTEN. I don't seem to have the time necessary to do a proper
job of maintaining the code, and providing the updates. If you are a
competent C programmer, and are interested in taking on the
Cats/KITTEN library, please email me.

22 Nov 2005 Others have been modifying KITTEN for use in their own
FreeDOS programs, and that's great. I've released kitten-c.zip that
seems to be the latest-and-greatest version of KITTEN out in the wild.

7 Jun 2005 Fox has written a Pascal version of Cats. It's a Pascal
library (TPU unit) which supports using CATS/Kitten formatted language
files into Pascal programs. With fox-cubs.zip, the programmer get a
new function, called "LoadMessage".


WHAT'S NEXT

    * Support a database file, instead of reading the entire file into
      memory at start-time. I suspect we'll add this at the same time
      we fork the library to create a gettext interface.


ABOUT CATS/KITTEN

Cats is an implementation of UNIX catgets for DOS based on an
in-memory key-value database. For those who don't know about the UNIX
catgets function, you just use it to return a pointer to a localized
string based on a message number. All your program's messages are
stored in a file (called a message catalog), with message numbers and
set numbers. "Hello world" might be message 1 in set 1. Your copyright
statement might be message 2 in set 1. "Failure writing to drive A:"
might be message 4 in set 7. Message catalogs are plain ascii files,
so it will be easy for a user to take one "catalog" and create a
translation that can immediately be used by another user (i.e. you
don't need to "re-compile" the message catalog before you use it.)

This message catalog might look like this: (English)

  1.1:Hello world
  7.4:Failure writing to drive A:

or: (Spanish)

  1.1:Hola mundo
  7.4:Fallo al escribir en la unidad A:

The smaller KITTEN library is a modification of Cats (thanks to Tom
Ehlert!) that provides only the "core" parts of Cats, without the
additional overhead of the UNIX-compatible catgets. Also, KITTEN has
been simplified somewhat by not using printf functions to display
debugging. Also, the get_line function was improved, and made a few
internal functions for low memory footprint file operation available
in kitten.h. This lends KITTEN to smaller RTL requirements, which
means a smaller executable size.

Since KITTEN provides a set of wrappers that emulate Cats, KITTEN is
basically a replacement of Cats. Please consider KITTEN to be Cats
version 4. I'll update the zip file to reflect this version number
soon, but I'll need to add some docs to it first.

The basics of KITTEN are this:

  nl_catd kittenopen(char *name);
  char *  kittengets( int set_number, int message_number,char
  *message);
  void    kittenclose (void);

These are simplified versions of the functions in Cats. Here's how
they relate to Cats:

  #define catopen(name,flag) kittenopen(name)
  #define catgets(catalog, set,message_number,message)
  #kittengets(set,message_number,message)
  #define catclose(catalog)  kittenclose()

Here's an example from the FreeDOS FIND program. Using Cats, the
message catalog is opened using:

  /* Message catalog */

  cat = catopen ("find", 0);

This is the same as making this call in KITTEN:

  /* Message catalog */

  cat = kittenopen ("find");

In Cats, only after a call to catopen does the message catalog
descriptor cat have any meaning. But as you can see in the set of
wrappers for KITTEN, the catalog descriptor isn't referenced (carrying
the descriptor is optional). KITTEN will only open one message file at
a time, by design. If you want to use a second message catalog, you
must call kittenclose before the next kittenopen.

In FreeDOS FIND, strings are pulled from the catalog with this call:

  s = catgets (cat, 0, 0, "Prints all lines of a file that contain a
  string");
  strWrite("FIND: ");
  strWrite(s);
  strWrite("\r\n");

Using KITTEN, you would use this instead:

  s = kittengets (0, 0, "Prints all lines of a file that contain a
  string");
  strWrite("FIND: ");
  strWrite(s);
  strWrite("\r\n");

In FreeDOS FIND, the catalog is closed with this call:

  /* Done */
  catclose (cat);

Using KITTEN, closing the catalog is just this:

  /* Done */
  kittenclose ();

Just as in Cats, KITTEN stores the entire contents of the message
catalog in memory. I'm planning a future version that will look up
strings from the catalog on disk. The tradeoff is less memory used,
but slower lookup times (because you are not pulling strings out of
memory.)

As a final example, here's a sample C program that demonstrates both
Cats and KITTEN. First, the Cats version:

  /* fail.c */

  #include <stdio.h>
  #include "catgets.h"			/* catopen/catgets */

  int
  main (void)
  {
    char *s;
    nl_catd cat;			/* catalog descriptor */
  
    cat = catopen ("fail", MCLoadAll);  /* MCLoadAll is ignored */
  
    s = catgets (cat, 7, 4, "Failure writing to drive A:");
    printf ("%s\n", s);
  
    catclose (cat);
    exit (0);
  }

And now, the KITTEN version. Note that the program is very similar. So
programming for KITTEN is basically the same as programming for Cats:

  /* fail.c */

  #include <stdio.h>
  #include "kitten.h"                   /* kittenopen/kittengets */

  int
  main (void)
  {
    char *s;
  
    kittenopen ("fail");                /* catalog descriptor not used
    */
  
    s = kittengets (7, 4, "Failure writing to drive A:");
    printf ("%s\n", s);
  
    kittenclose ();
    exit (0);
  }


TOOLS

Eric Auer has posted a new tool for use with Cats, the i18n helper
LOCALIZE. Eric writes: "Hi, with the install scripts of Bernd and
Jeremy in mind, I have written a LOCALIZE tool (3.5k UPXed com, can
certainly be even smaller). It is basically KITTEN (the version which
I use in FIND, not Toms original one) with a command line interface."
(localize-04nov2003.zip)