Skip to content

Commit

Permalink
Added internationalization through GNU gettext() and new 'lang' XML a…
Browse files Browse the repository at this point in the history
…ttributes.

Added French translations.
  • Loading branch information
megastep committed May 2, 2000
1 parent 74302be commit 7b15d06
Show file tree
Hide file tree
Showing 14 changed files with 1,443 additions and 50 deletions.
2 changes: 2 additions & 0 deletions CHANGES
@@ -1,5 +1,7 @@

1.2.3:
St�phane Peter - Mon May 1 16:50:26 PDT 2000
* Added i18n support through GNU gettext and the "lang" element and attributes.
Sam Lantinga - Fri Apr 28 17:17:27 PDT 2000
* Added the COPYING file to the distribution - GNU General Public License
Jeroen Janssen - Thu Apr 20 16:33:30 PDT 2000
Expand Down
21 changes: 21 additions & 0 deletions Makefile
Expand Up @@ -8,6 +8,9 @@ libc := $(shell ./print_libc)

CC = gcc

# The supported locales so far
LOCALES = fr

OPTIMIZE = -Wall -g -O2 -funroll-loops
ifeq ($(arch), alpha)
OPTIMIZE += -mcpu=ev4 -Wa,-mall
Expand All @@ -25,6 +28,8 @@ OBJS = main.o install.o detect.o copy.o file.o network.o log.o install_log.o
CONSOLE_OBJS = $(OBJS) console_ui.o
GUI_OBJS = $(OBJS) gtk_ui.o

SRCS = $(OBJS:.o=.c) $(CONSOLE_OBJS:.o=.c) $(GUI_OBJS:.o=.c)

LIBS = `xml-config --prefix`/lib/libxml.a -lz
ifeq ($(USE_RPM),true)
LIBS += -lrpm -ldb
Expand Down Expand Up @@ -59,3 +64,19 @@ dist: clean
(cd $(DISTDIR)/$(PACKAGE) && rm -r `find . -name CVS`)
(cd $(DISTDIR) && tar zcvf $(PACKAGE).tar.gz $(PACKAGE))
rm -rf $(DISTDIR)/$(PACKAGE)

po/setup.po:
libglade-xgettext image/setup.data/setup.glade > po/setup.po
xgettext -p po -j -d setup --keyword=_ $(SRCS)

gettext: po/setup.po $(SRCS)
for lang in $(LOCALES); do \
msgfmt po/$$lang/setup.po -o image/setup.data/locale/$$lang/LC_MESSAGES/setup.mo; \
done

# This rule merges changes from the newest PO file in all the translated PO files
update-po: po/setup.po
for lang in $(LOCALES); do \
msgmerge po/$$lang/setup.po po/setup.po > po/$$lang/tmp; \
mv po/$$lang/tmp po/$$lang/setup.po; \
done
41 changes: 40 additions & 1 deletion README.xml
Expand Up @@ -94,8 +94,10 @@ body of that option:

<option>
Top-level option
<lang lang="locale">Translated 'Top-level option'</lang>
<option>
First dependent option
<lang lang="locale">Translated 'First dependent option'</lang>
</option>
<option>
Second dependent option
Expand Down Expand Up @@ -125,6 +127,15 @@ There are several optional attributes of the option element:
If this element isn't specified, setup will try to autodetect
the size of the install option itself.

The option element support the LANG sub-element, which is used to specify
translated strings for the option name. The only attribute of this element
is 'lang', which should be the name of the locale to be matched against
the current locale (i.e. "fr", "de", "it", etc...). See 'About locallization'
below for more details about locale matching.

If you don't specify translations for alternate locales, then the same
string will be used for all languages encountered by setup. Of course,
you can have several 'lang' elements per 'option' element.

The BINARY element:

Expand Down Expand Up @@ -172,6 +183,10 @@ There are several optional attributes of the binary element:
cdrom If this attribute has a "yes" value, then setup will look for
the file on one of the mounted CDROMs on the system.

lang The files are only installed if the current locale matches the
string of this attribute. See 'About localization' below for
more details.

The FILES element:

The files element contains a list of files and directories, one per line,
Expand All @@ -186,6 +201,9 @@ There are several optional attributes of the files element:
cdrom If this attribute has a "yes" value, then setup will look for
the files on one of the mounted CDROMs on the system.

lang The files are only installed if the current locale matches the
string of this attribute. See 'About localization' below for
more details.

The SCRIPT element:

Expand All @@ -204,7 +222,11 @@ For example:
sh setup.data/stage1.sh
</script>

There are no attributes for the script element.
There only supported attribute for the script element is the 'lang' element:

lang The script is only installed if the current locale matches the
string of this attribute. See 'About localization' below for
more details.

The following environment variables are defined while in the shell script:
SETUP_PRODUCTNAME : Product name from the XML file
Expand All @@ -216,6 +238,18 @@ The following environment variables are defined while in the shell script:
the XML file designates that some components
are to be installed from CD-ROM.

About localization :

The 'lang' values are matched against the value of the LANG environment
variable. The special value 'none' is matched only when there is no LANG
environment variable set (the default locale).

A locale is matched if the specified value is found at the beginning of
LANG. For example, "fr" will match both the "fr" and "fr_CA" values. In
order for the more specialized locale values to be matched correctly,
the longer values should be be specified last (i.e. if you have different
translations, list "fr" before "fr_CA" in the XML file).

-------------------------------------------------------------------------

Example XML product specification:
Expand Down Expand Up @@ -244,8 +278,13 @@ Example XML product specification:
<binary arch="any" libc="any" symlink="foo" icon="icon.xpm">
foo
</binary>
<files lang="fr">
README.fr
<files>
<files lang="none">
README
<files>
<files>
icon.xpm
edit.xpm
data/*.dat
Expand Down
45 changes: 23 additions & 22 deletions console_ui.c
Expand Up @@ -14,6 +14,9 @@
/* The README viewer program - on all Linux sytems */
#define PAGER_COMMAND "more"

static const char *yes_letter = gettext_noop("Y");
static const char *no_letter = gettext_noop("N");

static int prompt_user(const char *prompt, const char *default_answer,
char *answer, int maxlen)
{
Expand Down Expand Up @@ -47,14 +50,13 @@ static yesno_answer console_prompt(const char *prompt, yesno_answer suggest)
fprintf(stderr, _("Warning, invalid yesno prompt: %s\n"), prompt);
return(RESPONSE_INVALID);
}
switch (toupper(line[0])) {
case 'Y':
return RESPONSE_YES;
case 'N':
return RESPONSE_NO;
default:
return RESPONSE_INVALID;
}
if(!strncasecmp(line, gettext (yes_letter), 1)) {
return RESPONSE_YES;
} else if(!strncasecmp(line, gettext (no_letter), 1)) {
return RESPONSE_NO;
} else {
return RESPONSE_INVALID;
}
}


Expand All @@ -74,22 +76,21 @@ static yesno_answer prompt_yesnohelp(const char *prompt, yesno_answer suggest)
fprintf(stderr, _("Warning, invalid yesno prompt: %s\n"), prompt);
return(RESPONSE_INVALID);
}
switch (toupper(line[0])) {
case 'Y':
return RESPONSE_YES;
case 'N':
return RESPONSE_NO;
case '?':
return RESPONSE_HELP;
default:
return RESPONSE_INVALID;
}
if(!strncasecmp(line, gettext (yes_letter), 1)) {
return RESPONSE_YES;
} else if(!strncasecmp(line, gettext (no_letter), 1)) {
return RESPONSE_NO;
} else if(!strncasecmp(line, "?", 1)) {
return RESPONSE_HELP;
} else {
return RESPONSE_INVALID;
}
}

static yesno_answer prompt_warning(const char *warning)
{
printf("%s\n", warning);
return (console_prompt(_("Continue?"), RESPONSE_NO));
printf("%s\n", warning);
return (console_prompt(_("Continue?"), RESPONSE_NO));
}

static void parse_option(install_info *info, xmlNodePtr node)
Expand Down Expand Up @@ -335,8 +336,8 @@ static install_state console_complete(install_info *info)
new_state = SETUP_PLAY;
if ( getuid() == 0 ) {
const char *warning_text =
_("If you run a game as root, the preferences will be stored in\n")
_("root's home directory instead of your user account directory.");
_("If you run a game as root, the preferences will be stored in\n"
"root's home directory instead of your user account directory.");

if ( prompt_warning(warning_text) != RESPONSE_YES ) {
new_state = SETUP_EXIT;
Expand Down
36 changes: 24 additions & 12 deletions copy.c
Expand Up @@ -60,7 +60,7 @@ int parse_line(const char **srcpp, char *buf, int maxlen)
char *token = 0;
const char *end;

if (!*srcpp) { // assert
if (!*srcpp) { /* assert */
*buf = 0;
return 0;
}
Expand All @@ -76,22 +76,22 @@ int parse_line(const char **srcpp, char *buf, int maxlen)
if ( (dstp-buf) >= maxlen ) {
break;
}
if (!*srcp && subst) { // if we're substituting and done
if (!*srcp && subst) { /* if we're substituting and done */
srcp = subst;
subst = 0;
}
if ((!subst) && (*srcp == '$') && (*(srcp+1) == '{')) {
getToken(srcp+2, &end);
if (end) { // we've got a good token
if (end) { /* we've got a good token */
if (token) free(token);
token = calloc((end-(srcp+2))+1, 1);
memcpy(token, srcp+2, (end-(srcp+2)));
strtok(token, "|"); // in case a default val is specified
strtok(token, "|"); /* in case a default val is specified */
tokenval = getenv(token);
if (!tokenval) // if no env set, check for default
if (!tokenval) /* if no env set, check for default */
tokenval = strtok(0, "|");
if (tokenval) {
subst = end+1; // where to continue after tokenval
subst = end+1; /* where to continue after tokenval */
srcp = tokenval;
}
}
Expand Down Expand Up @@ -721,7 +721,14 @@ size_t copy_node(install_info *info, xmlNodePtr node, const char *dest,
while ( node ) {
const char *path = xmlGetProp(node, "path");
const char *prop = xmlGetProp(node, "cdrom");
const char *lang_prop;
int from_cdrom = (prop && !strcasecmp(prop, "yes"));
int lang_matched = 1;

lang_prop = xmlGetProp(node, "lang");
if (lang_prop) {
lang_matched = MatchLocale(lang_prop);
}

if (!path)
path = dest;
Expand All @@ -730,7 +737,7 @@ size_t copy_node(install_info *info, xmlNodePtr node, const char *dest,
path = tmppath;
}
/* printf("Checking node element '%s'\n", node->name); */
if ( strcmp(node->name, "files") == 0 ) {
if ( strcmp(node->name, "files") == 0 && lang_matched ) {
const char *str = xmlNodeListGetString(info->config, (node->parent)->childs, 1);

parse_line(&str, current_option, sizeof(current_option));
Expand All @@ -741,15 +748,15 @@ size_t copy_node(install_info *info, xmlNodePtr node, const char *dest,
size += copied;
}
}
if ( strcmp(node->name, "binary") == 0 ) {
if ( strcmp(node->name, "binary") == 0 && lang_matched ) {
copied = copy_binary(info, node,
xmlNodeListGetString(info->config, node->childs, 1),
path, from_cdrom, update);
if ( copied > 0 ) {
size += copied;
}
}
if ( strcmp(node->name, "script") == 0 ) {
if ( strcmp(node->name, "script") == 0 && lang_matched ) {
copy_script(info, node,
xmlNodeListGetString(info->config, node->childs, 1),
path);
Expand Down Expand Up @@ -881,8 +888,9 @@ size_t size_list(install_info *info, int from_cdrom, const char *filedesc)
/* Get the install size of an option node, in bytes */
size_t size_node(install_info *info, xmlNodePtr node)
{
const char *size_prop;
const char *size_prop, *lang_prop;
size_t size;
int lang_matched = 1;

size = 0;

Expand All @@ -892,6 +900,10 @@ size_t size_node(install_info *info, xmlNodePtr node)
size = atol(size_prop)*1024*1024;
}

lang_prop = xmlGetProp(node, "lang");
if (lang_prop) {
lang_matched = MatchLocale(lang_prop);
}
/* Now, if necessary, scan all the files to install */
if ( size == 0 ) {
node = node->childs;
Expand All @@ -900,11 +912,11 @@ size_t size_node(install_info *info, xmlNodePtr node)
int from_cdrom = (prop && !strcasecmp(prop, "yes"));

/* printf("Checking node element '%s'\n", node->name); */
if ( strcmp(node->name, "files") == 0 ) {
if ( strcmp(node->name, "files") == 0 && lang_matched ) {
size += size_list(info, from_cdrom,
xmlNodeListGetString(info->config, node->childs, 1));
}
if ( strcmp(node->name, "binary") == 0 ) {
if ( strcmp(node->name, "binary") == 0 && lang_matched ) {
size += size_binary(info, from_cdrom,
xmlNodeListGetString(info->config, node->childs, 1));
}
Expand Down
6 changes: 3 additions & 3 deletions gtk_ui.c
@@ -1,5 +1,5 @@
/* GTK-based UI
$Id: gtk_ui.c,v 1.31 2000-05-01 20:40:20 hercules Exp $
$Id: gtk_ui.c,v 1.32 2000-05-02 00:25:47 megastep Exp $
*/

#include <limits.h>
Expand Down Expand Up @@ -221,8 +221,8 @@ void setup_button_play_slot( GtkWidget* _widget, gpointer func_data )

if ( getuid() == 0 ) {
const char *warning_text =
_("If you run a game as root, the preferences will be stored in\n")
_("root's home directory instead of your user account directory.");
_("If you run a game as root, the preferences will be stored in\n"
"root's home directory instead of your user account directory.");

warning_dialog = WARNING_ROOT;
widget = glade_xml_get_widget(setup_glade, "setup_notebook");
Expand Down
Binary file added image/setup.data/locale/fr/LC_MESSAGES/setup.mo
Binary file not shown.
11 changes: 8 additions & 3 deletions image/setup.data/setup.glade
Expand Up @@ -9,7 +9,7 @@
<pixmaps_directory>pixmaps</pixmaps_directory>
<language>C</language>
<gnome_support>False</gnome_support>
<gettext_support>False</gettext_support>
<gettext_support>True</gettext_support>
<use_widget_names>False</use_widget_names>
<output_main_file>True</output_main_file>
<output_support_files>True</output_support_files>
Expand All @@ -21,7 +21,8 @@
<handler_header_file>callbacks.h</handler_header_file>
<support_source_file>support.c</support_source_file>
<support_header_file>support.h</support_header_file>
<translatable_strings_file></translatable_strings_file>
<output_translatable_strings>True</output_translatable_strings>
<translatable_strings_file>setup.txt</translatable_strings_file>
</project>

<widget>
Expand Down Expand Up @@ -184,6 +185,8 @@
<widget>
<class>GtkCombo</class>
<name>install_path</name>
<value_in_list>False</value_in_list>
<ok_if_empty>True</ok_if_empty>
<case_sensitive>False</case_sensitive>
<use_arrows>True</use_arrows>
<use_arrows_always>False</use_arrows_always>
Expand Down Expand Up @@ -233,6 +236,8 @@
<widget>
<class>GtkCombo</class>
<name>binary_path</name>
<value_in_list>False</value_in_list>
<ok_if_empty>True</ok_if_empty>
<case_sensitive>False</case_sensitive>
<use_arrows>True</use_arrows>
<use_arrows_always>False</use_arrows_always>
Expand Down Expand Up @@ -1192,7 +1197,7 @@
<widget>
<class>GtkLabel</class>
<name>label49</name>
<label>Press &quot;Exit&quot; to clean up temporary files.</label>
<label>Press 'Exit' to clean up temporary files.</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
Expand Down

0 comments on commit 7b15d06

Please sign in to comment.