		Pointerize 0.1
		==============

A set of Internationalization aiding tools built on top of gettext.
===================================================================

Pointerize is a set of tools created with a simple goal: reduce the total
amount of disk space needed to hold an i18'zed (gettext-using) program
and its set of binary message catalogs (MO files, in gettext jargon).
That may help using gettext for i18n of programs that must be installed
on space-constrained systems (boot floppies, embedded systems, ...).

Technical details
-----------------

The format of a generated MO file is basically the following:

- a header (magic number, format revision, # of strings on the MO file,
  offsets to the following tables...)
- a table of length & offsets of the original strings
- a table of length & offsets of the translated strings
- a hash table
- the table of (NULL terminated) original strings
- the table of (NULL terminated) translated strings

We select the proper MO file using a code snippet like:
	setlocale (LC_ALL, "");
	bindtextdomain (PACKAGE, LOCALEDIR);
	textdomain (PACKAGE);
somewhere on our program, and access a translated string using:
	gettext("Original string)
or the shorter form:
	_("Original string")
provided we have defined the usual macro:
	#define _(String) gettext(String)

That's gettext stuff. Now enter pointerize.

Pointerize is a set of three tools (pointerize, trim-mo and gen-header)
and a tiny static library (libloadtrm.a).

- Using trim-mo on a MO file we generate a TRM file that contains:
  + a table of offsets of the translated strings
  + the table of (NULL terminated) translated strings

  Usage:
	$ trim-mo filename.mo > filename.trm

- Using gen-header on a MO file we generate a header file ("lang.h") that
contains (something like) the following:

[...]
#define TOTALNSTRINGS 123

char *translation[123];

int load_trmfile (char *file, char **messages_table, int tstrings);

#define LOAD_TRMFILE(fname) load_trmfile(fname,translation,123)
[...]

where 123 is the number of original (or translated) strings on the MO
file.

  Usage:
	$ genheader filename.mo 

- Using pointerize on a gettextized C source file and one of its related MO
files we obtain a new C source file where all the _("string") calls have
been changed to translation[NNN] pointers, where NNN is the place of the
string "string" on the table of original strings.

  Usage:
	$ pointerize [-m filename.mo] < whatever.c >whatever.tmp.c

- Now the picture is getting clearer, isn't it? The tiny static library
contains just the load_trmfile function. If you include the call:
	LOAD_TRMFILE("/path/to/whatever.trm");
somewhere in your program, it will load the whatever.trm TRM file, and
update the translation[] char * array to point to the just loaded table
of translated strings.

Quick recipe
------------
So, let's say you have a non-i18'zed source code, and want to use pointerize
to i18'ze it. What should you do?

1) Mark every translatable string using gettext's _("string") macros
("info gettext" for details).

2) Add the following line to each C source file containing translatable
strings:
	#include "lang.h"

3) Add the following line somewhere in your program:
	LOAD_TRMFILE("/path/to/whatever.trm");

4) Modify your Makefile so that it does the following to build your
program:
4a) Generates the lang.h header file using gen-header (you'll need a MO
file for this. It doesn't have to be a valid translation, as gen-header
will use just the original strings).
4b) Generates *.tmp.c source files from your *.c source files using
pointerize. (again, you'll need a MO file for this. Yes, pointerize
will use just the original strings too).
4c) Build the *.o object files using the *.tmp.c files, instead of the
original *.c files.
4d) Links the executable to the libloadtrm.a static library

And that's all!

How-to generate a simple MO file:
---------------------------------
(That's more or less the usual gettext stuff. If you need more
information about working with PO files and MO files, please see 
"info gettext").

1) Generate a template PO file. Something like:
$ xgettext -k_ --foreign-user *.c
on the directory that contains your C sources will generate a template PO
file called messages.po. ("info xgettext" for details).

2) Edit the template file to create a simple translation. (Better yet,
copy the template file to a different place, say program-name.pot, to
preserve it for other translators). If your are going to use just it for
gen-header and pointerize, it doesn't have to be a valid translation, you
may just copy the msgid strings to the msgstr ones. (In fact, you may use
that later to build a TRM file with the original strings, altough there's
a switch to trim-mo to do just that from any MO file).

3) Build the MO file from your translated PO file. You may use something
like:
$ msgfmt -v -o messages.mo messages.po 
("info msgfmt" for details).

What else is needed to run a pointerize-using program
-----------------------------------------------------
You will need at least one TRM file. Of course. (Use trim-mo to generate
TRM files from your previously generated MO files).


Bugs, comments and suggestions to:

		Enrique Zanardi <ezanard@debian.org>

or use Debian's bug tracking system. (See http://www.debian.org/Bugs for
details).
