Re: Internationalizing Linux

Bruce Korb (
Mon, 07 Dec 1998 08:26:59 -0800

(Alan Cox) wrote:
> To my mind the constant numbering and also correct handling of positional
> data are the killer issues.

One more killer issue please: extraction of the strings from the kernel
almost entirely (external drivers and panic messages excepted).
Several benefits ON TOP OF translatability:

1. Reduced kernel image size
2. Reduced space needs for log buffer
3. Reduced latency for interrupt level events (printk's).

All I need is a little encouragement about the acceptability of
a stylized comment near the site of the printk. Then I could
get the assistence of several volunteers to clean up the few hundred
printk's that do not convert automatically. (I already have
a program written that will convert 15,800 of the printk's,
but it skips several hundred. That is still well over 95% of them.)

Here is what happens:

printk( KERN_ERR "some %s data %d format\n", str, val );

is converted into:

/*=event.grp grp_212
* level: error
* fmt: "some %s data %d format\n"
* arg: arg1, char*
* arg: arg2
* doc: the grp event 212 needs help
GRP_ERROR_EVT_GRP_212( str, val );

The info inside that funny comment is extracted and used to fill
out any of several templates. One template would be a #define
for the 'GRP_ERROR_EVT_GRP_212' macro. The 'grp_212' can actually
be any C-variable-acceptable name. It is a little hard to choose
one with a program :). The 'doc:' string is intended to be emitted
as a self-help document for a user wondering what to do when
they encounter a particular event.

Phase one, the #define looks like this:

#define GRP_ERROR_EVT_GRP_212( arg1, arg2 ) \
printk( KERN_ERR "some %s data %d format\n", arg1, arg2 )
#define GRP_ERROR_EVT_GRP_212( arg1, arg2 ) do ; while(0)

Ultimately, it looks more like this:

#define GRP_ERROR_EVT_GRP_212( arg1, arg2 ) do { \
if (grp_min_event_level <= EVENT_LEVEL_ERROR) \
kevent( GRP_EVT_GRP_212_CODE, arg1, arg2 ); } while (0)
#define GRP_ERROR_EVT_GRP_212( arg1, arg2 ) do ; while(0)

Once the events (er, printk's) are macro-ized, then switching them
around, conditionalizing them or anything else becomes very easy.
By the way, when the output files are emitted, it becomes trivial
to source an alternate set of definitions that looks like this:

altfmt[GRP_EVT_GRP_212_ID] = "esta %2$d esta en %1$s idioma\n";

and suddenly, the phase one #define might look like this instead:

#define GRP_ERROR_EVT_GRP_212( arg1, arg2 ) \
printk( KERN_ERR "esta %2$d esta en %1$s idioma\n", arg1, arg2 )
#define GRP_ERROR_EVT_GRP_212( arg1, arg2 ) do ; while(0)

I can also stuff a unique identifier on the front of each.
I can do all this from one place (the #define macro template)
and simultaneously affect all the printk macros.

Bruce Korb                   | Data Design Systems, Inc.
Korb at DataDesign dot com   | 45 Cabot Dr., Suite 110
Voice:  408-260-0280         | Santa Clara,  CA   95051
Fax:    408-260-0281         | USA

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to Please read the FAQ at