Ethereal-dev: [Ethereal-dev] Basic i18n (Internationalization)

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Juan Toledo <toledo@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 16 May 2001 14:08:38 +0200
Ok. I've added the i18n infrastructure, and localized gtk/main.c into Spanish

To i18ize more files, this has to be added at the beginning

#ifdef ENABLE_NLS
#    include <libintl.h>
#    define _(String) gettext (String)
#    ifdef gettext_noop
#        define N_(String) gettext_noop (String)
#    else
#        define N_(String) (String)
#    endif
#else
/* Stubs that do something close enough.  */
#    define textdomain(String) (String)
#    define gettext(String) (String)
#    define dgettext(Domain,Message) (Message)
#    define dcgettext(Domain,Message,Type) (Message)
#    define bindtextdomain(Domain,Directory) (Domain)
#    define _(String) (String)
#    define N_(String) (String)
#endif

That's because I couldn't find an .h file that was included
by all programs...

To mark a string as translatable, it's extremely simple.
Instead of
	printf ("Hello, this is a translatable string");

you turn it into
	printf (_("Hello, this is a translatable string"));

The translators will do the rest in the po directory.
...only if the patch is approved, of course... :-)


-- 
EtherApe, a graphical network monitor modeled after etherman
http://etherape.sourceforge.net/
? intl
? po
? ethereal-ports
Index: Makefile.am
===================================================================
RCS file: /cvsroot/ethereal/Makefile.am,v
retrieving revision 1.317
diff -u -r1.317 Makefile.am
--- Makefile.am	2001/05/11 00:39:57	1.317
+++ Makefile.am	2001/05/16 11:58:09
@@ -697,7 +697,7 @@
 #dist-hook:
 #	@rm -f $(distdir)/register.c
 
-SUBDIRS = tools wiretap epan plugins packaging @ethereal_SUBDIRS@
+SUBDIRS = tools wiretap epan plugins packaging po intl @ethereal_SUBDIRS@
 
 ethereal.1: ethereal doc/ethereal.pod.template
 	(cd doc ; \
Index: acconfig.h
===================================================================
RCS file: /cvsroot/ethereal/acconfig.h,v
retrieving revision 1.18
diff -u -r1.18 acconfig.h
--- acconfig.h	2000/10/17 09:21:51	1.18
+++ acconfig.h	2001/05/16 11:58:09
@@ -24,7 +24,6 @@
  */
 
 #undef PACKAGE
-
 #undef VERSION
 
 #undef HAVE_PLUGINS
@@ -42,3 +41,10 @@
 #undef HAVE_LIBPCAP
 
 #undef PLUGIN_DIR
+
+#undef ENABLE_NLS
+#undef HAVE_CATGETS
+#undef HAVE_GETTEXT
+#undef HAVE_LC_MESSAGES
+#undef HAVE_STPCPY
+#undef PACKAGE_LOCALE_DIR
Index: configure.in
===================================================================
RCS file: /cvsroot/ethereal/configure.in,v
retrieving revision 1.123
diff -u -r1.123 configure.in
--- configure.in	2001/05/01 02:44:51	1.123
+++ configure.in	2001/05/16 11:58:10
@@ -34,6 +34,17 @@
 AC_SUBST(LEX)
 AC_SUBST(PYTHON)
 
+dnl Add the languages which your application supports here.
+ALL_LINGUAS="es"
+AM_GNU_GETTEXT
+
+dnl Set PACKAGE_LOCALE_DIR in config.h.
+if test "x${prefix}" = "xNONE"; then
+  AC_DEFINE_UNQUOTED(PACKAGE_LOCALE_DIR,
+"${ac_default_prefix}/${DATADIRNAME}/locale")
+else
+  AC_DEFINE_UNQUOTED(PACKAGE_LOCALE_DIR, "${prefix}/${DATADIRNAME}/locale")
+fi
 
 # Check for packaging utilities
 # For now, we check to see if the various packaging utilites are in our
@@ -553,6 +564,8 @@
   Makefile
   doc/Makefile
   gtk/Makefile
+  intl/Makefile
+  po/Makefile.in
   packaging/Makefile
   packaging/nsis/Makefile
   packaging/rpm/Makefile
Index: gtk/main.c
===================================================================
RCS file: /cvsroot/ethereal/gtk/main.c,v
retrieving revision 1.198
diff -u -r1.198 gtk/main.c
--- gtk/main.c	2001/05/01 00:41:46	1.198
+++ gtk/main.c	2001/05/16 11:58:16
@@ -106,6 +106,26 @@
 #include <conio.h>
 #endif
 
+#ifdef ENABLE_NLS
+#    include <libintl.h>
+#    define _(String) gettext (String)
+#    ifdef gettext_noop
+#        define N_(String) gettext_noop (String)
+#    else
+#        define N_(String) (String)
+#    endif
+#else
+/* Stubs that do something close enough.  */
+#    define textdomain(String) (String)
+#    define gettext(String) (String)
+#    define dgettext(Domain,Message) (Message)
+#    define dcgettext(Domain,Message,Type) (Message)
+#    define bindtextdomain(Domain,Directory) (Domain)
+#    define _(String) (String)
+#    define N_(String) (String)
+#endif
+
+
 #include <epan.h>
 #include <epan/filesystem.h>
 
@@ -176,6 +196,19 @@
 /* About Ethereal window */
 void
 about_ethereal( GtkWidget *w, gpointer data ) {
+  gchar *about;
+  
+  about = g_strdup_printf ("%s\n%s %s %s\n%s %s\n\n%s",
+			   _("Ethereal - Network Protocol Analyzer"),
+			   _("Version"),VERSION,_("(C) 1998-2000 Gerald Combs <gerald@xxxxxxxxxxxx>"),
+			   _("Compiled"), comp_info_str->str,
+			   _("Check the man page for complete documentation and\n"
+			     "for the list of contributors.\n"
+			     
+			     "\nSee http://www.ethereal.com/ for more information."));
+  simple_dialog(ESD_TYPE_INFO, NULL, about);
+  g_free (about);
+#if 0   
   simple_dialog(ESD_TYPE_INFO, NULL,
 		"Ethereal - Network Protocol Analyzer\n"
 		"Version " VERSION " (C) 1998-2000 Gerald Combs <gerald@xxxxxxxxxxxx>\n"
@@ -186,6 +219,7 @@
 
 		"\nSee http://www.ethereal.com/ for more information.",
                  comp_info_str->str);
+#endif   
 }
 
 void
@@ -213,9 +247,9 @@
 
     if (!finfo_selected) {
 	simple_dialog(ESD_TYPE_CRIT, NULL,
-		      "Error determining selected bytes.  Please make\n"
+		      _("Error determining selected bytes.  Please make\n"
 		      "sure you have selected a field within the tree\n"
-		      "view to be matched.");
+		      "view to be matched."));
 	return;
     }
 
@@ -726,22 +760,30 @@
 
 static void 
 print_usage(void) {
+  gchar *about;
 
+  about = g_strdup_printf ("%s %s %s %s\n",
+			   _("This is GNU"), PACKAGE " " VERSION,
+			   _(", compiled"), comp_info_str->str);
+  fprintf(stderr, about);
+  g_free (about);
+#if 0   
   fprintf(stderr, "This is GNU " PACKAGE " " VERSION ", compiled %s\n",
 	  comp_info_str->str);
+#endif   
 #ifdef HAVE_LIBPCAP
-  fprintf(stderr, "%s [ -vh ] [ -klpQS ] [ -B <byte view height> ] [ -c count ]\n",
+  fprintf(stderr, _("%s [ -vh ] [ -klpQS ] [ -B <byte view height> ] [ -c count ]\n"),
 	  PACKAGE);
-  fprintf(stderr, "\t[ -f <capture filter> ] [ -i interface ] [ -m <medium font> ] \n");
-  fprintf(stderr, "\t[ -n ] [ -o <preference setting> ] ... [ -P <packet list height> ]\n");
-  fprintf(stderr, "\t[ -r infile ] [ -R <read filter> ] [ -s snaplen ] \n");
-  fprintf(stderr, "\t[ -t <time stamp format> ] [ -T <tree view height> ] [ -w savefile ]\n");
+  fprintf(stderr, _("\t[ -f <capture filter> ] [ -i interface ] [ -m <medium font> ] \n"));
+  fprintf(stderr, _("\t[ -n ] [ -o <preference setting> ] ... [ -P <packet list height> ]\n"));
+  fprintf(stderr, _("\t[ -r infile ] [ -R <read filter> ] [ -s snaplen ] \n"));
+  fprintf(stderr, _("\t[ -t <time stamp format> ] [ -T <tree view height> ] [ -w savefile ]\n"));
 #else
-  fprintf(stderr, "%s [ -vh ] [ -B <byte view height> ] [ -m <medium font> ] [ -n ]\n",
+  fprintf(stderr, _("%s [ -vh ] [ -B <byte view height> ] [ -m <medium font> ] [ -n ]\n"),
 	  PACKAGE);
-  fprintf(stderr, "\t[ -o <preference setting> ... [ -P <packet list height> ]\n");
-  fprintf(stderr, "\t[ -r infile ] [ -R <read filter> ] [ -t <time stamp format> ]\n");
-  fprintf(stderr, "\t[ -T <tree view height> ]\n");
+  fprintf(stderr, _("\t[ -o <preference setting> ... [ -P <packet list height> ]\n"));
+  fprintf(stderr, _("\t[ -r infile ] [ -R <read filter> ] [ -t <time stamp format> ]\n"));
+  fprintf(stderr, _("\t[ -T <tree view height> ]\n"));
 #endif
 }
 
@@ -763,17 +805,17 @@
 
   number = strtol(string, &p, 10);
   if (p == string || *p != '\0') {
-    fprintf(stderr, "ethereal: The specified %s \"%s\" is not a decimal number\n",
+    fprintf(stderr, _("ethereal: The specified %s \"%s\" is not a decimal number\n"),
 	    name, string);
     exit(1);
   }
   if (number < 0) {
-    fprintf(stderr, "ethereal: The specified %s \"%s\" is a negative number\n",
+    fprintf(stderr, _("ethereal: The specified %s \"%s\" is a negative number\n"),
 	    name, string);
     exit(1);
   }
   if (number > INT_MAX) {
-    fprintf(stderr, "ethereal: The specified %s \"%s\" is too large (greater than %d)\n",
+    fprintf(stderr, _("ethereal: The specified %s \"%s\" is too large (greater than %d)\n"),
 	    name, string, INT_MAX);
     exit(1);
   }
@@ -826,6 +868,13 @@
   char                *bold_font_name;
 
   ethereal_path = argv[0];
+   
+#ifdef ENABLE_NLS   
+   /* Set up gettext, for internationalization */
+   setlocale (LC_ALL, "");
+   bindtextdomain (PACKAGE, PACKAGE_LOCALE_DIR);
+   textdomain (PACKAGE);
+#endif   
 
 #ifdef WIN32
   /* Arrange that if we have no console window, and a GLib message logging
@@ -927,59 +976,59 @@
   /* Assemble the compile-time options */
   comp_info_str = g_string_new("");
 
-  g_string_append(comp_info_str, "with ");
+  g_string_append(comp_info_str, _("with "));
   g_string_sprintfa(comp_info_str,
 #ifdef GTK_MAJOR_VERSION
     "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
     GTK_MICRO_VERSION);
 #else
-    "GTK+ (version unknown)");
+    _("GTK+ (version unknown)"));
 #endif
 
-  g_string_append(comp_info_str, ", with ");
+  g_string_append(comp_info_str, _(", with "));
   g_string_sprintfa(comp_info_str,
 #ifdef GLIB_MAJOR_VERSION
     "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
     GLIB_MICRO_VERSION);
 #else
-    "GLib (version unknown)");
+    _("GLib (version unknown)"));
 #endif
 
 #ifdef HAVE_LIBPCAP
-  g_string_append(comp_info_str, ", with libpcap ");
+  g_string_append(comp_info_str, _(", with libpcap "));
   g_string_append(comp_info_str, pcap_version);
 #else
-  g_string_append(comp_info_str, ", without libpcap");
+  g_string_append(comp_info_str, _(", without libpcap"));
 #endif
 
 #ifdef HAVE_LIBZ
-  g_string_append(comp_info_str, ", with libz ");
+  g_string_append(comp_info_str, _(", with libz "));
 #ifdef ZLIB_VERSION
   g_string_append(comp_info_str, ZLIB_VERSION);
 #else /* ZLIB_VERSION */
-  g_string_append(comp_info_str, "(version unknown)");
+  g_string_append(comp_info_str, _("(version unknown)"));
 #endif /* ZLIB_VERSION */
 #else /* HAVE_LIBZ */
-  g_string_append(comp_info_str, ", without libz");
+  g_string_append(comp_info_str, _(", without libz"));
 #endif /* HAVE_LIBZ */
 
 /* Oh, this is pretty */
 #if defined(HAVE_UCD_SNMP_SNMP_H)
-  g_string_append(comp_info_str, ", with UCD SNMP ");
+  g_string_append(comp_info_str, _(", with UCD SNMP "));
 #ifdef HAVE_UCD_SNMP_VERSION_H
   g_string_append(comp_info_str, VersionInfo);
 #else /* HAVE_UCD_SNMP_VERSION_H */
-  g_string_append(comp_info_str, "(version unknown)");
+  g_string_append(comp_info_str, _("(version unknown)"));
 #endif /* HAVE_UCD_SNMP_VERSION_H */
 #elif defined(HAVE_SNMP_SNMP_H)
-  g_string_append(comp_info_str, ", with CMU SNMP ");
+  g_string_append(comp_info_str, _(", with CMU SNMP "));
 #ifdef HAVE_SNMP_VERSION_H
   g_string_append(comp_info_str, snmp_Version());
 #else /* HAVE_SNMP_VERSION_H */
-  g_string_append(comp_info_str, "(version unknown)");
+  g_string_append(comp_info_str, _("(version unknown)"));
 #endif /* HAVE_SNMP_VERSION_H */
 #else /* no SNMP */
-  g_string_append(comp_info_str, ", without SNMP");
+  g_string_append(comp_info_str, _(", without SNMP"));
 #endif
 
   /* Now get our args */
@@ -1041,13 +1090,13 @@
         switch (prefs_set_pref(optarg)) {
 
 	case PREFS_SET_SYNTAX_ERR:
-          fprintf(stderr, "ethereal: Invalid -o flag \"%s\"\n", optarg);
+          fprintf(stderr, _("ethereal: Invalid -o flag \"%s\"\n"), optarg);
           exit(1);
           break;
 
         case PREFS_SET_NO_SUCH_PREF:
-          fprintf(stderr, "ethereal: -o flag \"%s\" specifies unknown preference\n",
-			optarg);
+          fprintf(stderr, (_("ethereal: -o flag \"%s\" specifies unknown preference\n"),
+			optarg));
           exit(1);
           break;
         }
@@ -1107,10 +1156,10 @@
         else if (strcmp(optarg, "d") == 0)
           timestamp_type = DELTA;
         else {
-          fprintf(stderr, "ethereal: Invalid time stamp type \"%s\"\n",
+          fprintf(stderr, _("ethereal: Invalid time stamp type \"%s\"\n"),
             optarg);
-          fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
-          fprintf(stderr, "\"ad\" for absolute with date, or \"d\" for delta.\n");
+          fprintf(stderr, _("It must be \"r\" for relative, \"a\" for absolute,\n"));
+          fprintf(stderr, _("\"ad\" for absolute with date, or \"d\" for delta.\n"));
           exit(1);
         }
         break;
@@ -1148,7 +1197,7 @@
         /* associate stdout with pipe */
         i = atoi(optarg);
         if (dup2(i, 1) < 0) {
-          fprintf(stderr, "Unable to dup pipe handle\n");
+          fprintf(stderr, _("Unable to dup pipe handle\n"));
           exit(1);
         }
 #else
@@ -1180,7 +1229,7 @@
 
 #ifndef HAVE_LIBPCAP
   if (capture_option_specified)
-    fprintf(stderr, "This version of Ethereal was not built with support for capturing packets.\n");
+    fprintf(stderr, _("This version of Ethereal was not built with support for capturing packets.\n"));
 #endif
   if (arg_error)
     print_usage();
@@ -1195,12 +1244,12 @@
         switch (err) {
 
         case CANT_GET_INTERFACE_LIST:
-            fprintf(stderr, "ethereal: Can't get list of interfaces: %s\n",
+            fprintf(stderr, _("ethereal: Can't get list of interfaces: %s\n"),
 			err_str);
             break;
 
         case NO_INTERFACES_FOUND:
-            fprintf(stderr, "ethereal: There are no interfaces on which a capture can be done\n");
+            fprintf(stderr, _("ethereal: There are no interfaces on which a capture can be done\n"));
             break;
         }
         exit(2);
@@ -1213,7 +1262,7 @@
     if (cfile.save_file_fd == -1) {
       /* XXX - send this to the standard output as something our parent
          should put in an error message box? */
-      fprintf(stderr, "%s: \"-W\" flag not specified\n", CHILD_NAME);
+      fprintf(stderr, _("%s: \"-W\" flag not specified\n"), CHILD_NAME);
       exit(1);
     }
   }
@@ -1252,7 +1301,7 @@
 #ifdef HAVE_LIBPCAP
       if (!capture_child)
 #endif
-	fprintf(stderr, "ethereal: Warning: font %s not found - defaulting to 6x13 and 6x13bold\n",
+	fprintf(stderr, _("ethereal: Warning: font %s not found - defaulting to 6x13 and 6x13bold\n"),
 		prefs->gui_font_name);
     } else {
       gdk_font_unref(m_r_font);
@@ -1261,18 +1310,18 @@
 #ifdef HAVE_LIBPCAP
       if (!capture_child)
 #endif
-	fprintf(stderr, "ethereal: Warning: font %s not found - defaulting to 6x13 and 6x13bold\n",
+	fprintf(stderr, _("ethereal: Warning: font %s not found - defaulting to 6x13 and 6x13bold\n"),
 		bold_font_name);
     } else {
       gdk_font_unref(m_b_font);
     }
     g_free(bold_font_name);
     if ((m_r_font = gdk_font_load("6x13")) == NULL) {
-      fprintf(stderr, "ethereal: Error: font 6x13 not found\n");
+      fprintf(stderr, _("ethereal: Error: font 6x13 not found\n"));
       exit(1);
     }
     if ((m_b_font = gdk_font_load("6x13bold")) == NULL) {
-      fprintf(stderr, "ethereal: Error: font 6x13bold not found\n");
+      fprintf(stderr, _("ethereal: Error: font 6x13bold not found\n"));
       exit(1);
     }
     g_free(prefs->gui_font_name);
@@ -1352,7 +1401,7 @@
      box is more likely to come up on top of the main window. */
   if (gpf_path != NULL) {
       simple_dialog(ESD_TYPE_WARN, NULL,
-        "Could not open global preferences file\n\"%s\": %s.", gpf_path,
+        _("Could not open global preferences file\n\"%s\": %s."), gpf_path,
         strerror(gpf_open_errno));
   }
 
@@ -1361,7 +1410,7 @@
      box is more likely to come up on top of the main window. */
   if (pf_path != NULL) {
       simple_dialog(ESD_TYPE_WARN, NULL,
-        "Could not open your preferences file\n\"%s\": %s.", pf_path,
+        _("Could not open your preferences file\n\"%s\": %s."), pf_path,
         strerror(pf_open_errno));
   }
 
@@ -1370,7 +1419,7 @@
      box is more likely to come up on top of the main window. */
   if (cf_path != NULL) {
       simple_dialog(ESD_TYPE_WARN, NULL,
-        "Could not open your capture filter file\n\"%s\": %s.", cf_path,
+        _("Could not open your capture filter file\n\"%s\": %s."), cf_path,
         strerror(cf_open_errno));
       g_free(cf_path);
   }
@@ -1380,7 +1429,7 @@
      box is more likely to come up on top of the main window. */
   if (df_path != NULL) {
       simple_dialog(ESD_TYPE_WARN, NULL,
-        "Could not open your display filter file\n\"%s\": %s.", df_path,
+        _("Could not open your display filter file\n\"%s\": %s."), df_path,
         strerror(df_open_errno));
       g_free(df_path);
   }
@@ -1488,7 +1537,7 @@
 static void
 destroy_console(void)
 {
-  printf("\n\nPress any key to exit\n");
+  printf(_("\n\nPress any key to exit\n"));
   _getch();
   FreeConsole();
 }
@@ -1597,7 +1646,7 @@
   gtk_widget_set_name(top_level, "main window");
   gtk_signal_connect(GTK_OBJECT(top_level), "delete_event", 
     GTK_SIGNAL_FUNC(main_window_delete_event_cb), NULL);
-  gtk_window_set_title(GTK_WINDOW(top_level), "The Ethereal Network Analyzer");
+  gtk_window_set_title(GTK_WINDOW(top_level), _("The Ethereal Network Analyzer"));
   gtk_widget_set_usize(GTK_WIDGET(top_level), DEF_WIDTH, -1);
   gtk_window_set_policy(GTK_WINDOW(top_level), TRUE, TRUE, FALSE);
 
@@ -1691,7 +1740,7 @@
   gtk_box_pack_start(GTK_BOX(main_vbox), stat_hbox, FALSE, TRUE, 0);
   gtk_widget_show(stat_hbox);
 
-  filter_bt = gtk_button_new_with_label("Filter:");
+  filter_bt = gtk_button_new_with_label(_("Filter:"));
   gtk_signal_connect(GTK_OBJECT(filter_bt), "clicked",
     GTK_SIGNAL_FUNC(display_filter_construct_cb), &args);
   gtk_box_pack_start(GTK_BOX(stat_hbox), filter_bt, FALSE, TRUE, 0);
@@ -1710,7 +1759,7 @@
     GTK_SIGNAL_FUNC(filter_activate_cb), (gpointer) NULL);
   gtk_widget_show(filter_cm);
 
-  filter_reset = gtk_button_new_with_label("Reset");
+  filter_reset = gtk_button_new_with_label(_("Reset"));
   gtk_object_set_data(GTK_OBJECT(filter_reset), E_DFILTER_TE_KEY, filter_te);
   gtk_signal_connect(GTK_OBJECT(filter_reset), "clicked",
 		     GTK_SIGNAL_FUNC(filter_reset_cb), (gpointer) NULL);

Attachment: i18n.tgz
Description: GNU Unix tar archive