site  contact  subhomenews

How to internationalize any C program

October 27, 2020 — BarryK

I received an email from James (jamesbond) about a very interesting fix for an audio problem -- will post about that later. In a reply, I mentioned a problem with the 'bluetoothctl' utility being English-only. I checked, all the utilities in the 'bluez' package are English-only.

In BluePup, 'bluetoothctl' output appears in an embedded vte terminal in the GUI, and if, for example "bluetoothctl connect <address>" is run, it will output the string "Connection successful". English only! Not so good if I want BluePup to be truly internationalized.

I taxed my brain, trying to recall, there was someone who figured out a simple method to internationalize any C program. So, searched the Murga Forum, and found the information -- it was Robert (robwoj44 in the forum), with input from Lutz (L18L or L16L). See posts:

http://www.murga-linux.com/puppy/viewtopic.php?t=86084&start=30

http://www.murga-linux.com/puppy/viewtopic.php?p=819879#819879

I examined the "before" and "after" C code. Looking at the 'ssh-gui' package, version 0.7.1, the file 'ssh_widget.c' has these changes:

Robert inserted this near the beginning of the file:

#include <libintl.h>
#include <locale.h>
#define _(STRING) gettext(STRING)

Then he modified output strings. Here are examples from 'ssh_widget.c', before and after:

printf("Out of memory\n");
printf(_("Out of memory\n"));

button[0] = gtk_button_new_with_label("Start SSH");
button[0] = gtk_button_new_with_label(_("Start SSH"));

base_label[2] = gtk_label_new("Username");
base_label[2] = gtk_label_new(_("Username"));

base_label[3] = gtk_label_new("Host");
base_label[3] = gtk_label_new(_("Host"));

auth_toggle[0] = gtk_check_button_new_with_label("RSA Authentification");
auth_toggle[0] = gtk_check_button_new_with_label(_("RSA Authentification"));

forw_toggle[1] = gtk_radio_button_new_with_label(NULL, "Local");
forw_toggle[1] = gtk_radio_button_new_with_label(NULL, _("Local"));

gtk_notebook_append_page(GTK_NOTEBOOK(notebook[0]), box[0], gtk_label_new("SSH Config"));
gtk_notebook_append_page(GTK_NOTEBOOK(notebook[0]), box[0], gtk_label_new(_("SSH Config")));

Here are examples from the gpptp 2.0 source, before and after:

snprintf(str, sizeof(str), "pptp process (%d) exited with %d\n", pid, status);
snprintf(str, sizeof(str), _("pptp process (%d) exited with %d\n"), pid, status);

snprintf(str, sizeof(str), "ppp process was NOT created!\n");
snprintf(str, sizeof(str), _("ppp process was NOT created!\n"));

snprintf(str, sizeof(str), "gpptp: Command failed: %s\n", err->message);
snprintf(str, sizeof(str), _("gpptp: Command failed: %s\n"), err->message);

log_add(w->log, tag_info, " Done! \n");
log_add(w->log, tag_info, _(" Done! \n"));

And in the main() function in 'gpptp.c':

     setlocale(LC_ALL, "");
bindtextdomain("gpptp", "/usr/share/locale");
textdomain("gpptp");

...the ssh-gui code has something similar in main().

Then to create the .pot file, using gpptp.c example:

# xgettext -d gpptp -s -o gpptp.pot --keyword=_ gpptp.c
A bit of understanding of C syntax is required to know where to place those "_( ... )". Looks doable, reckon I might have a go at a patch for 'bluetoothctl'. 

Tags: easy