diff --git a/ps/Makefile.am b/ps/Makefile.am
index 84df5c23..b748f103 100644
--- a/ps/Makefile.am
+++ b/ps/Makefile.am
@@ -1,6 +1,6 @@
 AM_CPPFLAGS = -include $(top_builddir)/config.h
 
-AM_CFLAGS = -I../proc
+AM_CFLAGS = -I../proc -I../include
 AM_LDFLAGS = ../proc/libprocfs.la
 
 dist_man_MANS = ps.1
diff --git a/ps/TRANSLATION b/ps/TRANSLATION
deleted file mode 100644
index ff8df84e..00000000
--- a/ps/TRANSLATION
+++ /dev/null
@@ -1,39 +0,0 @@
-Initially I only want to translate the --help output and man page.
-Common error messages would be next on the list. I want to avoid
-run-time overhead and bloat.
-
-Translations of the --help output should not be longer than 22 lines long.
-Feel free to leave out the less useful options to save space. (not even
-the English help text has all the options)
-
-I think these are the most important options:
-
-*** selection ***
--C  by command name list
--G  by real group ID list (supports names)
--U  by real user ID list (supports names)
--u  by effective user ID list (supports names)
--e  all processes
--p  by process ID list
-
-*** output ***
---no-heading  No header line.
--o,o          user-defined output
--j,j          job control format
--l,l          long format
--f            full format
-s             signal format
-u             user-oriented format
---forest      ASCII art forest (process hierarchy)
-c             show true command name
-
-List of man page translators:
-
-de  Wed Jan 10 19:09:15 2001 by Martin Schulze <joey@infodrom.ffis.de>
-es  19 Jan 1999 by Diego Sevilla Ruiz (dsevilla@ditec.um.es)
-fr  09/06/1997 par Christophe Blaess (ccb@club-internet.fr)
-hu  Horv#th Andr#s (the '#' is 'a' w/ '/') <horvatha@rs1.szif.hu>
-it  Traduzione in italiano di Giovanni Bortolozzo <borto@dei.unipd.it>
-it  Revisione parziale di Daniele Giacomini <daniele@evo.it> 30/03/1999
-ja  Tue Nov 14 2000 by NAKANO Takeo <nakano@apm.seikei.ac.jp>
-nl  <manpages-nl@nl.linux.org>
diff --git a/ps/common.h b/ps/common.h
index a3c15783..e1b6fd5e 100644
--- a/ps/common.h
+++ b/ps/common.h
@@ -12,6 +12,8 @@
 #ifndef PROCPS_PS_H
 #define PROCPS_PS_H
 
+#include "c.h"
+#include "nls.h"
 #include "../proc/procps.h"
 #include "../proc/escape.h"
 #include "../proc/readproc.h"
diff --git a/ps/display.c b/ps/display.c
index dfd4e241..c9125e7a 100644
--- a/ps/display.c
+++ b/ps/display.c
@@ -45,11 +45,12 @@ static void signal_handler(int signo){
   if(signo==SIGPIPE) _exit(0);  /* "ps | head" will cause this */
   /* fprintf() is not reentrant, but we _exit() anyway */
   fprintf(stderr,
-    "\n\n"
-    "Signal %d (%s) caught by ps (%s).\n"
-    "Please send bug reports to <procps@freelists.org>\n",
+    _("\n\n"
+      "Signal %d (%s) caught by %s (%s).\n"
+      "Please send bug reports to <procps@freelists.org>\n"),
     signo,
     signal_number_to_name(signo),
+    program_invocation_short_name,
     procps_version
   );
   _exit(signo+128);
@@ -154,7 +155,7 @@ static void arg_show(void){
     case SEL_TTY : show_tty("TTY ", walk->n, walk->u); break;
     case SEL_SESS: show_pid("SESS", walk->n, walk->u); break;
     case SEL_COMM: show_cmd("COMM", walk->n, walk->u); break;
-    default: printf("Garbage typecode value!\n");
+    default: printf(_("Garbage typecode value!\n"));
     }
     walk = walk->next;
   }
@@ -253,7 +254,7 @@ static void lists_and_needs(void){
         t_end->need = 0;
         break;
       default:
-        fprintf(stderr, "please report this bug\n");
+        fprintf(stderr, _("please report this bug\n"));
         // FALL THROUGH
       case CF_PRINT_AS_NEEDED:
       case CF_PRINT_EVERY_TIME:
@@ -332,7 +333,7 @@ static void simple_spew(void){
 
   ptp = openproc(needs_for_format | needs_for_sort | needs_for_select | needs_for_threads);
   if(!ptp) {
-    fprintf(stderr, "Error: can not access /proc.\n");
+    fprintf(stderr, _("Error: can not access /proc.\n"));
     exit(1);
   }
   switch(thread_flags & (TF_show_proc|TF_loose_tasks|TF_show_task)){
@@ -380,7 +381,7 @@ static void prep_forest_sort(void){
 
   if(!sort_list) {     /* assume start time order */
     incoming = search_format_array("start_time");
-    if(!incoming) { fprintf(stderr, "Could not find start_time!\n"); exit(1); }
+    if(!incoming) { fprintf(stderr, _("Could not find start_time!\n")); exit(1); }
     tmp_list = malloc(sizeof(sort_node));
     tmp_list->reverse = 0;
     tmp_list->typecode = '?'; /* what was this for? */
@@ -391,7 +392,7 @@ static void prep_forest_sort(void){
   }
   /* this is required for the forest option */
   incoming = search_format_array("ppid");
-  if(!incoming) { fprintf(stderr, "Could not find ppid!\n"); exit(1); }
+  if(!incoming) { fprintf(stderr, _("Could not find ppid!\n")); exit(1); }
   tmp_list = malloc(sizeof(sort_node));
   tmp_list->reverse = 0;
   tmp_list->typecode = '?'; /* what was this for? */
@@ -505,7 +506,7 @@ static void fancy_spew(void){
 
   ptp = openproc(needs_for_format | needs_for_sort | needs_for_select | needs_for_threads);
   if(!ptp) {
-    fprintf(stderr, "Error: can not access /proc.\n");
+    fprintf(stderr, _("Error: can not access /proc.\n"));
     exit(1);
   }
 
@@ -562,9 +563,9 @@ int main(int argc, char *argv[]){
   arg_parse(argc,argv);
 
 /*  arg_show(); */
-  trace("screen is %ux%u\n",screen_cols,screen_rows);
+  trace(_("screen is %ux%u\n"),screen_cols,screen_rows);
 /*  printf("sizeof(proc_t) is %d.\n", sizeof(proc_t)); */
-  trace("======= ps output follows =======\n");
+  trace(_("======= ps output follows =======\n"));
 
   init_output(); /* must be between parser and output */
 
diff --git a/ps/global.c b/ps/global.c
index 2563f807..567d0298 100644
--- a/ps/global.c
+++ b/ps/global.c
@@ -157,7 +157,7 @@ static void set_screen_size(void){
   }
 
   if((screen_cols<9) || (screen_rows<2))
-    fprintf(stderr,"Your %dx%d screen size is bogus. Expect trouble.\n",
+    fprintf(stderr,_("Your %dx%d screen size is bogus. Expect trouble.\n"),
       screen_cols, screen_rows
     );
 }
@@ -230,7 +230,7 @@ static const char *set_personality(void){
   if(!s || !*s) s="unknown";   /* "Do The Right Thing[tm]" */
   if(getenv("I_WANT_A_BROKEN_PS")) s="old";
   sl = strlen(s);
-  if(sl > 15) return "Environment specified an unknown personality.";
+  if(sl > 15) return _("Environment specified an unknown personality.");
   strncpy(buf, s, sl);
   buf[sl] = '\0';
   if ((saved_personality_text = strdup(buf))==NULL) {
@@ -242,7 +242,7 @@ static const char *set_personality(void){
       sizeof(personality_table_struct), compare_personality_table_structs
   );
 
-  if(!found) return "Environment specified an unknown personality.";
+  if(!found) return _("Environment specified an unknown personality.");
 
   goto *(found->jump);    /* See gcc extension info.  :-)   */
 
@@ -462,39 +462,39 @@ void self_info(void){
   );
 
   display_version();
-  fprintf(stderr, "Linux version %d.%d.%d\n",
+  fprintf(stderr, _("Linux version %d.%d.%d\n"),
     LINUX_VERSION_MAJOR(linux_version_code),
     LINUX_VERSION_MINOR(linux_version_code),
     LINUX_VERSION_PATCH(linux_version_code)
   );
   /* __libc_print_version(); */  /* how can we get the run-time version? */
-  fprintf(stderr, "Compiled with: glibc %d.%d, gcc %d.%d\n\n",
+  fprintf(stderr, _("Compiled with: glibc %d.%d, gcc %d.%d\n\n"),
     __GLIBC__, __GLIBC_MINOR__, __GNUC__, __GNUC_MINOR__
   );
 
   fprintf(stderr,
-    "header_gap=%d lines_to_next_header=%d\n"
-    "screen_cols=%d screen_rows=%d\n"
-    "\n",
+    _("header_gap=%d lines_to_next_header=%d\n"
+      "screen_cols=%d screen_rows=%d\n"
+      "\n"),
     header_gap, lines_to_next_header,
     screen_cols, screen_rows
   );
 
   fprintf(stderr,
-    "personality=0x%08x (from \"%s\")\n"
-    "EUID=%d TTY=%d,%d Hertz=%Ld page_size=%d\n",
+    _("personality=0x%08x (from \"%s\")\n"
+      "EUID=%d TTY=%d,%d Hertz=%Ld page_size=%d\n"),
     personality, saved_personality_text,
     cached_euid, (int)major(cached_tty), (int)minor(cached_tty), Hertz,
     (int)(page_size)
   );
 
   fprintf(stderr,
-    "sizeof(proc_t)=%d sizeof(long)=%d sizeof(KLONG)=%d\n",
+    _("sizeof(proc_t)=%d sizeof(long)=%d sizeof(KLONG)=%d\n"),
     (int)sizeof(proc_t), (int)sizeof(long), (int)sizeof(KLONG)
   );
 
-  fprintf(stderr, "archdefs:%s\n", archdefs);
+  fprintf(stderr, _("archdefs:%s\n"), archdefs);
 
   open_psdb(namelist_file);
-  fprintf(stderr,"namelist_file=\"%s\"\n",namelist_file?namelist_file:"<no System.map file>");
+  fprintf(stderr,_("namelist_file=\"%s\"\n"),namelist_file?namelist_file:"<no System.map file>");
 }
diff --git a/ps/help.c b/ps/help.c
index 48e547c9..866f1a8f 100644
--- a/ps/help.c
+++ b/ps/help.c
@@ -17,92 +17,88 @@
 
 void __attribute__ ((__noreturn__)) usage(FILE * out, int section)
 {
+	fputs(USAGE_HEADER, out);
 	fprintf(out,
-		"\nUsage: %s [options]\n", program_invocation_short_name);
+		" %s [options]\n", program_invocation_short_name);
 	if (section == USAGE_SELECTION || section == USAGE_ALL) {
-		fprintf(out,
-		"\nSimple options:\n"
-		" -A               all processes\n"
-		" -N, --deselect   negate selection\n"
-		" -a               all without tty and session leader\n"
-		" -d               all except session leader\n"
-		" -e               all processes\n"
-		" T                all processes on this terminal\n"
-		" a                all without tty, including other users\n"
-		" g                obsolete, do not use\n"
-		" r                only running processes\n"
-		" x                processes without controlling ttys\n");
+	fputs(_("\nSimple options:\n"), out);
+	fputs(_(" -A               all processes\n"), out);
+	fputs(_(" -N, --deselect   negate selection\n"), out);
+	fputs(_(" -a               all without tty and session leader\n"), out);
+	fputs(_(" -d               all except session leader\n"), out);
+	fputs(_(" -e               all processes\n"), out);
+	fputs(_(" T                all processes on this terminal\n"), out);
+	fputs(_(" a                all without tty, including other users\n"), out);
+	fputs(_(" g                obsolete, do not use\n"), out);
+	fputs(_(" r                only running processes\n"), out);
+	fputs(_(" x                processes without controlling ttys\n"), out);
 	}
 	if (section == USAGE_LIST || section == USAGE_ALL) {
-		fprintf(out,
-		"\nSelection by list:\n"
-		" -C <command>         command name\n"
-		" U, -u, --user <uid>  effective user id or name\n"
-		" -U, --User <uid>     real user id or name\n"
-		" -G, --Group <gid>    real group id or name\n"
-		" -g, --group <group>  session or effective group name\n"
-		" -p, --pid <pid>      process id\n"
-		" --ppid <pid>         select by parent process id\n"
-		" -s, --sid <session>  session id\n"
-		" t, -t, --tty <tty>   terminal\n"
-		"\n selection <arguments> take csv list e.g. `-u root,nobody'\n");
+	fputs(_("\nSelection by list:\n"), out);
+	fputs(_(" -C <command>         command name\n"), out);
+	fputs(_(" U, -u, --user <uid>  effective user id or name\n"), out);
+	fputs(_(" -U, --User <uid>     real user id or name\n"), out);
+	fputs(_(" -G, --Group <gid>    real group id or name\n"), out);
+	fputs(_(" -g, --group <group>  session or effective group name\n"), out);
+	fputs(_(" -p, --pid <pid>      process id\n"), out);
+	fputs(_(" --ppid <pid>         select by parent process id\n"), out);
+	fputs(_(" -s, --sid <session>  session id\n"), out);
+	fputs(_(" t, -t, --tty <tty>   terminal\n"), out);
+	fputs(_("\n selection <arguments> take csv list e.g. `-u root,nobody'\n"), out);
 	}
 	if (section == USAGE_OUTPUT || section == USAGE_ALL) {
-		fprintf(out,
-		"\nOutput formats:\n"
-		" o, -o, --format <format>"
-		"                  user defined format\n"
-		" O  <format>      preloaded -o allowing sorting\n"
-		" -O <format>      preloaded, with default columns, allowing sorting\n"
-		" -j               jobs format\n"
-		" j                BSD job control format\n"
-		" -l               long format\n"
-		" l                BSD long format\n"
-		" y                do not show flags, show rrs in place addr (used with -l)\n"
-		" -f               full-format\n"
-		" -F               extra full\n"
-		" s                signal format\n"
-		" v                virtual memory\n"
-		" u                user-oriented format\n"
-		" X                register format\n"
-		" Z, -M            security data (for SE Linux)\n"
-		" f, --forest      ascii art process tree\n"
-		" -H               show process hierarchy\n"
-		" --context        display security context (for SE Linux)\n"
-		" --heading        repeat header lines\n"
-		" --no-headers     do not print header at all\n"
-		" --cols <num>     set screen width\n"
-		" --rows <num>     set screen height\n");
+	fputs(_("\nOutput formats:\n"), out);
+	fputs(_(" o, -o, --format <format>"), out);
+	fputs(_("                  user defined format\n"), out);
+	fputs(_(" O  <format>      preloaded -o allowing sorting\n"), out);
+	fputs(_(" -O <format>      preloaded, with default columns, allowing sorting\n"), out);
+	fputs(_(" -j               jobs format\n"), out);
+	fputs(_(" j                BSD job control format\n"), out);
+	fputs(_(" -l               long format\n"), out);
+	fputs(_(" l                BSD long format\n"), out);
+	fputs(_(" y                do not show flags, show rrs in place addr (used with -l)\n"), out);
+	fputs(_(" -f               full-format\n"), out);
+	fputs(_(" -F               extra full\n"), out);
+	fputs(_(" s                signal format\n"), out);
+	fputs(_(" v                virtual memory\n"), out);
+	fputs(_(" u                user-oriented format\n"), out);
+	fputs(_(" X                register format\n"), out);
+	fputs(_(" Z, -M            security data (for SE Linux)\n"), out);
+	fputs(_(" f, --forest      ascii art process tree\n"), out);
+	fputs(_(" -H               show process hierarchy\n"), out);
+	fputs(_(" --context        display security context (for SE Linux)\n"), out);
+	fputs(_(" --heading        repeat header lines\n"), out);
+	fputs(_(" --no-headers     do not print header at all\n"), out);
+	fputs(_(" --cols <num>     set screen width\n"), out);
+	fputs(_(" --rows <num>     set screen height\n"), out);
 	}
 	if (section == USAGE_THREADS || section == USAGE_ALL) {
-		fprintf(out,
-		"\nShow threads:\n"
-		" H                as if they where processes\n"
-		" -L               possibly with LWP and NLWP columns\n"
-		" -T               possibly with SPID column\n"
-		" m, -m            after processes\n");
+	fputs(_("\nShow threads:\n"), out);
+	fputs(_(" H                as if they where processes\n"), out);
+	fputs(_(" -L               possibly with LWP and NLWP columns\n"), out);
+	fputs(_(" -T               possibly with SPID column\n"), out);
+	fputs(_(" m, -m            after processes\n"), out);
 	}
 	if (section == USAGE_MISC || section == USAGE_ALL) {
-		fprintf(out,
-		"\nMisc options:\n"
-		" w, -w            unlimited output width\n"
-		" L                list format codes\n"
-		" c                true command name\n"
-		" n                display numeric uid and wchan\n"
-		" -y               do not show flags, show rss (only with -l)\n"
-		" -c               show scheduling class\n"
-		" --sort <spec>    specify sort order, can be a csv list\n"
-		" S, --cumulative  include some dead child process data\n"
-		" --info           print debuggin information\n"
-		" V,-V, --version  display version information and exit\n"
-		" --help <selection|list|output|threads|misc|all>\n"
-		"                  display help\n");
+	fputs(_("\nMisc options:\n"), out);
+	fputs(_(" w, -w            unlimited output width\n"), out);
+	fputs(_(" L                list format codes\n"), out);
+	fputs(_(" c                true command name\n"), out);
+	fputs(_(" n                display numeric uid and wchan\n"), out);
+	fputs(_(" -y               do not show flags, show rss (only with -l)\n"), out);
+	fputs(_(" -c               show scheduling class\n"), out);
+	fputs(_(" --sort <spec>    specify sort order, can be a csv list\n"), out);
+	fputs(_(" S, --cumulative  include some dead child process data\n"), out);
+	fputs(_(" --info           print debuggin information\n"), out);
+	fputs(_(" V,-V, --version  display version information and exit\n"), out);
+	fputs(_(" --help <selection|list|output|threads|misc|all>\n"), out);
+	fputs(_("                  display help\n"), out);
 	}
 	if (section == USAGE_DEFAULT)
-		fprintf(out,
-		"\n Try `%s --help <selection|list|output|threads|misc|all>'\n"
-		" for more information.\n", program_invocation_short_name);
-	fprintf(out, "\nFor more information see ps(1).\n");
+	fprintf(out,
+	      _("\n Try `%s --help <selection|list|output|threads|misc|all>'\n"
+		" for more information.\n"), program_invocation_short_name);
+	fprintf(out, USAGE_MAN_TAIL("ps(1)"));
 	exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
 }
 
diff --git a/ps/it b/ps/it
deleted file mode 100644
index 07fd6dce..00000000
--- a/ps/it
+++ /dev/null
@@ -1,35 +0,0 @@
-From ddainese@dsi.unive.it Sun Apr 18 14:12:27 1999
-
-here is a first translation of the text:
----------------------------------------------------------------------
-const char *help_message =
-"****** seleziona i processi *******   * seleziona una lista specificando: *\n"
-"-A tutti                              -C il nome del comando\n"
-"-N nega la selezione                  -G il real group ID (supporta i nomi)\n"
-"-a con tty, tranne i session leader   -U il real user ID (supporta i nomi)\n"
-"-d tutti, tranne i session leader     -g il session leader OPPURE il gruppo\n"
-"-e tutti                              -p l'ID del processo\n"
-"T  su questo terminale                -s la sessione\n"
-"a  con tty, di tutti gli utenti       -t il tty\n"
-"g  tutti, anche i leader di gruppo    -u l'effective user ID (supporta i nomi)\n"
-"r  in stato running                   U  una lista di utenti\n"
-"x  senza tty                          t  il tty\n"
-"******** formato dell'output ******   ********** opzioni lunghe **********\n"
-"-o,o definito dall'utente                --Group --User --pid --cols\n"
-"-j,j job              s segnali          --group --user --sid --rows\n"
-"-O,O -o preimpostato  v memoria virtuale --cumulative --format --deselect\n"
-"-l,l lungo            u utenti           --sort --tty --forest --version\n"
-"-f   completo         X registri         --heading --no-heading\n"
-"                    ******** opzioni varie *********\n"
-"-V,V versione           L  codici di formato       f  foresta di ASCII\n"
-"-m,m vista ad albero    S  figli in sum           -y  cambia il formato -l\n"
-"-n,N namelist file      c  nome reale del comando  n  WCHAN,UID numerici\n"
-"-w,w output ampio       e  mostra l'environment   -H  gerarchia dei processi\n"
-;
----------------------------------------------------------------------
-
-Unfortunately it isn't really understandable for a newbie, because
-there is too little space for a good translation; to make it more
-meaningful, I would need about an entire line for every option, thus
-if you really want the help text stays under 22 lines, it must
-contains only 22 options. What do you think about it?
diff --git a/ps/output.c b/ps/output.c
index f496ec92..2cb36a2f 100644
--- a/ps/output.c
+++ b/ps/output.c
@@ -1848,7 +1848,7 @@ void show_one_proc(const proc_t *restrict const p, const format_node *restrict f
     }
   }
   did_stuff = 1;
-  if(unlikely(active_cols>(int)OUTBUF_SIZE)) fprintf(stderr,"Fix bigness error.\n");
+  if(unlikely(active_cols>(int)OUTBUF_SIZE)) fprintf(stderr,_("Fix bigness error.\n"));
 
   /* print row start sequence */
   for(;;){
@@ -1923,7 +1923,7 @@ void show_one_proc(const proc_t *restrict const p, const format_node *restrict f
       break;
     }
     default:
-      fprintf(stderr, "bad alignment code\n");
+      fprintf(stderr, _("bad alignment code\n"));
       break;
     }
     /* At this point:
@@ -1996,7 +1996,7 @@ void init_output(void){
   case 32768: page_shift = 15; break;
   case 16384: page_shift = 14; break;
   case  8192: page_shift = 13; break;
-  default: fprintf(stderr, "Unknown page size! (assume 4096)\n");
+  default: fprintf(stderr, _("Unknown page size! (assume 4096)\n"));
   case  4096: page_shift = 12; break;
   case  2048: page_shift = 11; break;
   case  1024: page_shift = 10; break;
diff --git a/ps/parser.c b/ps/parser.c
index 08d3a4f2..3bd75ae5 100644
--- a/ps/parser.c
+++ b/ps/parser.c
@@ -48,7 +48,7 @@ static int not_pure_unix = 0;  /* set by BSD and GNU options */
 static int force_bsd = 0;  /* set when normal parsing fails */
 
 #define exclusive(x) if((ps_argc != 2) || strcmp(ps_argv[1],x))\
-  return "The " x " option is exclusive."
+  return _("The " x " option is exclusive.")
 
 
 /********** utility functions **********/
@@ -74,12 +74,10 @@ static const char *get_opt_arg(void){
 static const char *parse_pid(char *str, sel_union *ret){
   char *endp;
   unsigned long num;
-  static const char pidrange[]  = "Process ID out of range.";
-  static const char pidsyntax[] = "Process ID list syntax error.";
   num = strtoul(str, &endp, 0);
-  if(*endp != '\0')      return pidsyntax;
-  if(num<1)              return pidrange;
-  if(num > 0x7fffffffUL) return pidrange;
+  if(*endp != '\0')      return _("Process ID list syntax error.");
+  if(num<1)              return _("Process ID out of range.");
+  if(num > 0x7fffffffUL) return _("Process ID out of range.");
   ret->pid = num;
   return 0;
 }
@@ -88,15 +86,13 @@ static const char *parse_uid(char *str, sel_union *ret){
   struct passwd *passwd_data;
   char *endp;
   unsigned long num;
-  static const char uidrange[] = "User ID out of range.";
-  static const char uidexist[] = "User name does not exist.";
   num = strtoul(str, &endp, 0);
   if(*endp != '\0'){  /* hmmm, try as login name */
     passwd_data = getpwnam(str);
-    if(!passwd_data)    return uidexist;
+    if(!passwd_data)    return _("User name does not exist.");
     num = passwd_data->pw_uid;
   }
-  if(num > 0xfffffffeUL) return uidrange;
+  if(num > 0xfffffffeUL) return _("User ID out of range.");
   ret->uid = num;
   return 0;
 }
@@ -105,15 +101,13 @@ static const char *parse_gid(char *str, sel_union *ret){
   struct group *group_data;
   char *endp;
   unsigned long num;
-  static const char gidrange[] = "Group ID out of range.";
-  static const char gidexist[] = "Group name does not exist.";
   num = strtoul(str, &endp, 0);
   if(*endp != '\0'){  /* hmmm, try as login name */
     group_data = getgrnam(str);
-    if(!group_data)    return gidexist;
+    if(!group_data)    return _("Group name does not exist.");
     num = group_data->gr_gid;
   }
-  if(num > 0xfffffffeUL) return gidrange;
+  if(num > 0xfffffffeUL) return _("Group ID out of range.");
   ret->gid = num;
   return 0;
 }
@@ -126,12 +120,10 @@ static const char *parse_cmd(char *str, sel_union *ret){
 
 static const char *parse_tty(char *str, sel_union *ret){
   struct stat sbuf;
-  static const char missing[] = "TTY could not be found.";
-  static const char not_tty[] = "List member was not a TTY.";
   char path[4096];
   if(str[0]=='/'){
     if(stat(str, &sbuf) >= 0) goto found_it;
-    return missing;
+    return _("TTY could not be found.");;
   }
 #define lookup(p) \
   snprintf(path,4096,p,str); \
@@ -155,9 +147,9 @@ static const char *parse_tty(char *str, sel_union *ret){
     return 0;
   }
 #undef lookup
-  return missing;
+  return _("TTY could not be found.");;
 found_it:
-  if(!S_ISCHR(sbuf.st_mode)) return not_tty;
+  if(!S_ISCHR(sbuf.st_mode)) return _("List member was not a TTY.");
   ret->tty = sbuf.st_rdev;
   return 0;
 }
@@ -166,7 +158,7 @@ static int parse_usage_section(const char *opt)
 {
   if (!strcmp(opt, "s") || !strcmp(opt, "selection"))
     return USAGE_SELECTION;
-  if (!strcmp(opt, "e") || !strcmp(opt, "list"))
+  if (!strcmp(opt, "l") || !strcmp(opt, "list"))
     return USAGE_LIST;
   if (!strcmp(opt, "o") || !strcmp(opt, "output"))
     return USAGE_OUTPUT;
@@ -199,7 +191,7 @@ static const char *parse_list(const char *arg, const char *(*parse_fn)(char *, s
   need_item = 1; /* true */
   items = 0;
   walk = buf;
-  err = "Improper list.";
+  err = _("Improper list.");
   do{
     switch(*walk){
     case ' ': case ',': case '\t': case '\0':
@@ -253,40 +245,40 @@ static const char *parse_sysv_option(void){
 
     switch(*flagptr){
     case 'A':
-      trace("-A selects all processes.\n");
+      trace(_("-A selects all processes.\n"));
       all_processes = 1;
       break;
     case 'C': /* end */
-      trace("-C select by process name.\n");  /* Why only HP/UX and us? */
+      trace(_("-C select by process name.\n"));  /* Why only HP/UX and us? */
       arg=get_opt_arg();
-      if(!arg) return "List of command names must follow -C.";
+      if(!arg) return _("List of command names must follow -C.");
       err=parse_list(arg, parse_cmd);
       if(err) return err;
       selection_list->typecode = SEL_COMM;
       return NULL; /* can't have any more options */
     case 'F':  /* DYNIX/ptx -f plus sz,rss,psr=ENG between c and stime */
-      trace("-F does fuller listing\n");
+      trace(_("-F does fuller listing\n"));
       format_modifiers |= FM_F;
       format_flags |= FF_Uf;
       unix_f_option = 1; /* does this matter? */
       break;
     case 'G': /* end */
-      trace("-G select by RGID (supports names)\n");
+      trace(_("-G select by RGID (supports names)\n"));
       arg=get_opt_arg();
-      if(!arg) return "List of real groups must follow -G.";
+      if(!arg) return _("List of real groups must follow -G.");
       err=parse_list(arg, parse_gid);
       if(err) return err;
       selection_list->typecode = SEL_RGID;
       return NULL; /* can't have any more options */
     case 'H':     /* another nice HP/UX feature */
-      trace("-H Process hierarchy (like ASCII art forest option)\n");
+      trace(_("-H Process hierarchy (like ASCII art forest option)\n"));
       forest_type = 'u';
       break;
 #if 0
     case 'J':  // specify list of job IDs in hex (IRIX) -- like HP "-R" maybe?
-      trace("-J select by job ID\n");  // want a JID ("jid") for "-j" too
+      trace(_("-J select by job ID\n"));  // want a JID ("jid") for "-j" too
       arg=get_opt_arg();
-      if(!arg) return "List of jobs must follow -J.";
+      if(!arg) return _("List of jobs must follow -J.");
       err=parse_list(arg, parse_jid);
       if(err) return err;
       selection_list->typecode = SEL_JID;
@@ -299,33 +291,33 @@ static const char *parse_sysv_option(void){
        * Zombies are the only exception, with NLWP==0 and 1 output line.
        * SCO UnixWare uses -L too.
        */
-      trace("-L Print LWP (thread) info.\n");
+      trace(_("-L Print LWP (thread) info.\n"));
       thread_flags |= TF_U_L;
 //      format_modifiers |= FM_L;
       break;
     case 'M':  // typically the SE Linux context
-      trace("-M Print security label for Mandatory Access Control.\n");
+      trace(_("-M Print security label for Mandatory Access Control.\n"));
       format_modifiers |= FM_M;
       break;
     case 'N':
-      trace("-N negates.\n");
+      trace(_("-N negates.\n"));
       negate_selection = 1;
       break;
     case 'O': /* end */
-      trace("-O is preloaded -o.\n");
+      trace(_("-O is preloaded -o.\n"));
       arg=get_opt_arg();
-      if(!arg) return "Format or sort specification must follow -O.";
+      if(!arg) return _("Format or sort specification must follow -O.");
       defer_sf_option(arg, SF_U_O);
       return NULL; /* can't have any more options */
     case 'P':     /* SunOS 5 "psr" or unknown HP/UX feature */
-      trace("-P adds columns of PRM info (HP-UX), PSR (SunOS), or capabilities (IRIX)\n");
+      trace(_("-P adds columns of PRM info (HP-UX), PSR (SunOS), or capabilities (IRIX)\n"));
       format_modifiers |= FM_P;
       break;
 #if 0
     case 'R':    // unknown HP/UX feature, like IRIX "-J" maybe?
-      trace("-R select by PRM group\n");
+      trace(_("-R select by PRM group\n"));
       arg=get_opt_arg();
-      if(!arg) return "List of PRM groups must follow -R.";
+      if(!arg) return _("List of PRM groups must follow -R.");
       err=parse_list(arg, parse_prm);
       if(err) return err;
       selection_list->typecode = SEL_PRM;
@@ -337,55 +329,55 @@ static const char *parse_sysv_option(void){
        * Testing (w/ normal processes) shows 1 line/process, not 2.
        * Also, testing shows PID==SPID for all normal processes.
        */
-      trace("-T adds strange SPID column (old sproc() threads?)\n");
+      trace(_("-T adds strange SPID column (old sproc() threads?)\n"));
       thread_flags |= TF_U_T;
 //      format_modifiers |= FM_T;
       break;
     case 'U': /* end */
-      trace("-U select by RUID (supports names).\n");
+      trace(_("-U select by RUID (supports names).\n"));
       arg=get_opt_arg();
-      if(!arg) return "List of real groups must follow -U.";
+      if(!arg) return _("List of real groups must follow -U.");
       err=parse_list(arg, parse_uid);
       if(err) return err;
       selection_list->typecode = SEL_RUID;
       return NULL; /* can't have any more options */
     case 'V': /* single */
-      trace("-V prints version.\n");
+      trace(_("-V prints version.\n"));
       exclusive("-V");
       display_version();
       exit(0);
     // This must be verified against SVR4-MP. (UnixWare or Powermax)
     // Leave it undocumented until that problem is solved.
     case 'Z':     /* full Mandatory Access Control level info */
-      trace("-Z shows full MAC info\n");
+      trace(_("-Z shows full MAC info\n"));
       format_modifiers |= FM_M;
       break;
     case 'a':
-      trace("-a select all with a tty, but omit session leaders.\n");
+      trace(_("-a select all with a tty, but omit session leaders.\n"));
       simple_select |= SS_U_a;
       break;
     case 'c':
       /* HP-UX and SunOS 5 scheduling info modifier */
-      trace("-c changes scheduling info.\n");
+      trace(_("-c changes scheduling info.\n"));
       format_modifiers |= FM_c;
       break;
     case 'd':
-      trace("-d select all, but omit session leaders.\n");
+      trace(_("-d select all, but omit session leaders.\n"));
       simple_select |= SS_U_d;
       break;
     case 'e':
-      trace("-e selects all processes.\n");
+      trace(_("-e selects all processes.\n"));
       all_processes = 1;
       break;
     case 'f':
-      trace("-f does full listing\n");
+      trace(_("-f does full listing\n"));
       format_flags |= FF_Uf;
       unix_f_option = 1; /* does this matter? */
       break;
     case 'g': /* end */
-      trace("-g selects by session leader OR by group name\n");
+      trace(_("-g selects by session leader OR by group name\n"));
       arg=get_opt_arg();
-      if(!arg) return "List of session leaders OR effective group names must follow -g.";
+      if(!arg) return _("List of session leaders OR effective group names must follow -g.");
       err=parse_list(arg, parse_pid);
       if(!err){
         selection_list->typecode = SEL_SESS;
@@ -396,26 +388,26 @@ static const char *parse_sysv_option(void){
         selection_list->typecode = SEL_EGID;
         return NULL; /* can't have any more options */
       }
-      return "List of session leaders OR effective group IDs was invalid.";
+      return _("List of session leaders OR effective group IDs was invalid.");
     case 'j':
-      trace("-j jobs format.\n");
+      trace(_("-j jobs format.\n"));
       /* old Debian used RD_j and Digital uses JFMT */
       if(sysv_j_format) format_flags |= FF_Uj;
       else format_modifiers |= FM_j;
       break;
     case 'l':
-      trace("-l long format.\n");
+      trace(_("-l long format.\n"));
       format_flags |= FF_Ul;
       break;
     case 'm':
-      trace("-m shows threads.\n");
+      trace(_("-m shows threads.\n"));
       /* note that AIX shows 2 lines for a normal process */
       thread_flags |= TF_U_m;
       break;
     case 'n': /* end */
-      trace("-n sets namelist file.\n");
+      trace(_("-n sets namelist file.\n"));
       arg=get_opt_arg();
-      if(!arg) return "Alternate System.map file must follow -n.";
+      if(!arg) return _("Alternate System.map file must follow -n.");
       namelist_file = arg;
       return NULL; /* can't have any more options */
     case 'o': /* end */
@@ -424,96 +416,96 @@ static const char *parse_sysv_option(void){
       /* The result must be 2 columns: "PID NICE,tty=TERMINAL,comm"    */
       /* Yes, the second column has the name "NICE,tty=TERMINAL,comm"  */
       /* This parser looks for any excuse to ignore that braindamage.  */
-      trace("-o user-defined format.\n");
+      trace(_("-o user-defined format.\n"));
       arg=get_opt_arg();
-      if(!arg) return "Format specification must follow -o.";
+      if(!arg) return _("Format specification must follow -o.");
       not_pure_unix |= defer_sf_option(arg, SF_U_o);
       return NULL; /* can't have any more options */
     case 'p': /* end */
-      trace("-p select by PID.\n");
+      trace(_("-p select by PID.\n"));
       arg=get_opt_arg();
-      if(!arg) return "List of process IDs must follow -p.";
+      if(!arg) return _("List of process IDs must follow -p.");
       err=parse_list(arg, parse_pid);
       if(err) return err;
       selection_list->typecode = SEL_PID;
       return NULL; /* can't have any more options */
 #if 0
     case 'r':
-      trace("-r some Digital Unix thing about warnings...\n");
-      trace("   or SCO's option to chroot() for new /proc and /dev.\n");
-      return "The -r option is reserved.";
+      trace(_("-r some Digital Unix thing about warnings...\n"));
+      trace(_("   or SCO's option to chroot() for new /proc and /dev.\n"));
+      return _("The -r option is reserved.");
       break;
 #endif
     case 's': /* end */
-      trace("-s Select processes belonging to the sessions given.\n");
+      trace(_("-s Select processes belonging to the sessions given.\n"));
       arg=get_opt_arg();
-      if(!arg) return "List of session IDs must follow -s.";
+      if(!arg) return _("List of session IDs must follow -s.");
       err=parse_list(arg, parse_pid);
       if(err) return err;
       selection_list->typecode = SEL_SESS;
       return NULL; /* can't have any more options */
     case 't': /* end */
-      trace("-t select by tty.\n");
+      trace(_("-t select by tty.\n"));
       arg=get_opt_arg();
-      if(!arg) return "List of terminals (pty, tty...) must follow -t.";
+      if(!arg) return _("List of terminals (pty, tty...) must follow -t.");
       err=parse_list(arg, parse_tty);
       if(err) return err;
       selection_list->typecode = SEL_TTY;
       return NULL; /* can't have any more options */
     case 'u': /* end */
-      trace("-u select by user ID (the EUID?) (supports names).\n");
+      trace(_("-u select by user ID (the EUID?) (supports names).\n"));
       arg=get_opt_arg();
-      if(!arg) return "List of users must follow -u.";
+      if(!arg) return _("List of users must follow -u.");
       err=parse_list(arg, parse_uid);
       if(err) return err;
       selection_list->typecode = SEL_EUID;
       return NULL; /* can't have any more options */
     case 'w':
-      trace("-w wide output.\n");
+      trace(_("-w wide output.\n"));
       w_count++;
       break;
     case 'x':  /* behind personality until "ps -ax" habit is uncommon */
       if(personality & PER_SVR4_x){
         // Same as -y, but for System V Release 4 MP
-        trace("-x works like Sun Solaris & SCO Unixware -y option\n");
+        trace(_("-x works like Sun Solaris & SCO Unixware -y option\n"));
         format_modifiers |= FM_y;
         break;
       }
       if(personality & PER_HPUX_x){
-        trace("-x extends the command line\n");
+        trace(_("-x extends the command line\n"));
         w_count += 2;
         unix_f_option = 1;
         break;
       }
-      return "Must set personality to get -x option.";
+      return _("Must set personality to get -x option.");
     case 'y':  /* Sun's -l hack (also: Irix "lnode" resource control info) */
-      trace("-y Print lnone info in UID/USER column or do Sun -l hack.\n");
+      trace(_("-y Print lnone info in UID/USER column or do Sun -l hack.\n"));
       format_modifiers |= FM_y;
       break;
 #if 0
     // This must be verified against SVR4-MP (UnixWare or Powermax)
     case 'z':     /* alias of Mandatory Access Control level info */
-      trace("-z shows aliased MAC info\n");
+      trace(_("-z shows aliased MAC info\n"));
       format_modifiers |= FM_M;
       break;
     // Solaris 10 does this
     case 'z':     /* select by zone */
-      trace("-z secects by zone\n");
+      trace(_("-z secects by zone\n"));
       arg=get_opt_arg();
-      if(!arg) return "List of zones (contexts, labels, whatever?) must follow -z.";
+      if(!arg) return _("List of zones (contexts, labels, whatever?) must follow -z.");
       err=parse_list(arg, parse_zone);
       if(err) return err;
       selection_list->typecode = SEL_ZONE;
       return NULL; /* can't have any more options */
 #endif
     case '-':
-      return "Embedded '-' among SysV options makes no sense.";
+      return _("Embedded '-' among SysV options makes no sense.");
       break;
     case '\0':
-      return "Please report the \"SysV \\0 can't happen\" bug.";
+      return _("Please report the \"SysV \\0 can't happen\" bug.");
       break;
     default:
-      return "Unsupported SysV option.";
+      return _("Unsupported SysV option.");
     } /* switch */
   } /* while */
   return NULL;
@@ -526,20 +518,20 @@ static const char *parse_bsd_option(void){
 
   flagptr = ps_argv[thisarg];  /* assume we _have_ a '-' */
   if(flagptr[0]=='-'){
-    if(!force_bsd) return "Can't happen!  Problem #1.";
+    if(!force_bsd) return _("Can't happen!  Problem #1.");
   }else{
     flagptr--; /* off beginning, will increment before use */
     if(personality & PER_FORCE_BSD){
-      if(!force_bsd) return "Can't happen!  Problem #2.";
+      if(!force_bsd) return _("Can't happen!  Problem #2.");
     }else{
-      if(force_bsd) return "2nd chance parse failed, not BSD or SysV.";
+      if(force_bsd) return _("2nd chance parse failed, not BSD or SysV.");
     }
   }
 
   while(*++flagptr){
     switch(*flagptr){
     case '0' ... '9': /* end */
-      trace("0..9  Old BSD-style select by process ID\n");
+      trace(_("0..9  Old BSD-style select by process ID\n"));
       arg=flagptr;
       err=parse_list(arg, parse_pid);
       if(err) return err;
@@ -548,48 +540,48 @@ static const char *parse_bsd_option(void){
 #if 0
     case 'A':
       /* maybe this just does a larger malloc() ? */
-      trace("A Increases the argument space (Digital Unix)\n");
-      return "Option A is reserved.";
+      trace(_("A Increases the argument space (Digital Unix)\n"));
+      return _("Option A is reserved.");
       break;
     case 'C':
       /* should divide result by 1-(e**(foo*log(bar))) */
-      trace("C Use raw CPU time for %%CPU instead of decaying ave\n");
-      return "Option C is reserved.";
+      trace(_("C Use raw CPU time for %%CPU instead of decaying ave\n"));
+      return _("Option C is reserved.");
       break;
 #endif
     case 'H':    // The FreeBSD way (NetBSD:s OpenBSD:k FreeBSD:H  -- NIH???)
-      trace("H Print LWP (thread) info.\n");   // was: Use /vmcore as c-dumpfile\n");
+      trace(_("H Print LWP (thread) info.\n"));   // was: Use /vmcore as c-dumpfile\n");
       thread_flags |= TF_B_H;
       //format_modifiers |= FM_L;    // FIXME: determine if we need something like this
       break;
     case 'L': /* single */
-      trace("L List all format specifiers\n");
+      trace(_("L List all format specifiers\n"));
       exclusive("L");
       print_format_specifiers();
       exit(0);
     case 'M':   // undocumented for now: these are proliferating!
-      trace("M MacOS X thread display, like AIX/Tru64\n");
+      trace(_("M MacOS X thread display, like AIX/Tru64\n"));
       thread_flags |= TF_B_m;
       break;
     case 'N': /* end */
-      trace("N Specify namelist file\n");
+      trace(_("N Specify namelist file\n"));
       arg=get_opt_arg();
-      if(!arg) return "Alternate System.map file must follow N.";
+      if(!arg) return _("Alternate System.map file must follow N.");
       namelist_file = arg;
       return NULL; /* can't have any more options */
     case 'O': /* end */
-      trace("O Like o + defaults, add new columns after PID. Also sort.\n");
+      trace(_("O Like o + defaults, add new columns after PID. Also sort.\n"));
       arg=get_opt_arg();
-      if(!arg) return "Format or sort specification must follow O.";
+      if(!arg) return _("Format or sort specification must follow O.");
       defer_sf_option(arg, SF_B_O);
       return NULL; /* can't have any more options */
       break;
     case 'S':
-      trace("S include dead kids in sum\n");
+      trace(_("S include dead kids in sum\n"));
       include_dead_children = 1;
       break;
     case 'T':
-      trace("T Select all processes on this terminal\n");
+      trace(_("T Select all processes on this terminal\n"));
       /* put our tty on a tiny list */
       {
         selection_node *node;
@@ -603,62 +595,62 @@ static const char *parse_bsd_option(void){
       }
       break;
     case 'U': /* end */
-      trace("U Select processes for specified users.\n");
+      trace(_("U Select processes for specified users.\n"));
       arg=get_opt_arg();
-      if(!arg) return "List of users must follow U.";
+      if(!arg) return _("List of users must follow U.");
       err=parse_list(arg, parse_uid);
       if(err) return err;
       selection_list->typecode = SEL_EUID;
       return NULL; /* can't have any more options */
     case 'V': /* single */
-      trace("V show version info\n");
+      trace(_("V show version info\n"));
       exclusive("V");
       display_version();
       exit(0);
     case 'W':
-      trace("W N/A get swap info from ... not /dev/drum.\n");
-      return "Obsolete W option not supported. (You have a /dev/drum?)";
+      trace(_("W N/A get swap info from ... not /dev/drum.\n"));
+      return _("Obsolete W option not supported. (You have a /dev/drum?)");
       break;
     case 'X':
-      trace("X Old Linux i386 register format\n");
+      trace(_("X Old Linux i386 register format\n"));
       format_flags |= FF_LX;
       break;
     case 'Z':  /* FreeBSD does MAC like SGI's Irix does it */
-      trace("Z Print security label for Mandatory Access Control.\n");
+      trace(_("Z Print security label for Mandatory Access Control.\n"));
       format_modifiers |= FM_M;
       break;
     case 'a':
-      trace("a Select all w/tty, including other users\n");
+      trace(_("a Select all w/tty, including other users\n"));
       simple_select |= SS_B_a;
       break;
     case 'c':
-      trace("c true command name\n");
+      trace(_("c true command name\n"));
       bsd_c_option = 1;
       break;
 //  case 'd':
-//    trace("d FreeBSD-style tree\n");
+//    trace(_("d FreeBSD-style tree\n"));
 //    forest_type = 'f';
 //    break;
     case 'e':
-      trace("e environment\n");
+      trace(_("e environment\n"));
       bsd_e_option = 1;
       break;
     case 'f':
-      trace("f ASCII art forest\n");
+      trace(_("f ASCII art forest\n"));
       forest_type = 'b';
       break;
     case 'g':
-      trace("g _all_, even group leaders!.\n");
+      trace(_("g _all_, even group leaders!.\n"));
       simple_select |= SS_B_g;
       break;
     case 'h':
-      trace("h Repeat header... yow.\n");
-      if(header_type) return "Only one heading option may be specified.";
+      trace(_("h Repeat header... yow.\n"));
+      if(header_type) return _("Only one heading option may be specified.");
       if(personality & PER_BSD_h) header_type = HEAD_MULTI;
       else                        header_type = HEAD_NONE;
       break;
     case 'j':
-      trace("j job control format\n");
+      trace(_("j job control format\n"));
       format_flags |= FF_Bj;
       break;
     case 'k':
@@ -666,17 +658,17 @@ static const char *parse_bsd_option(void){
       // trace("k Print LWP (thread) info.\n");   // was: Use /vmcore as c-dumpfile\n");
 
       // NetBSD, and soon (?) FreeBSD: sort-by-keyword
-      trace("k Specify sorting keywords.\n");
+      trace(_("k Specify sorting keywords.\n"));
       arg=get_opt_arg();
-      if(!arg) return "Long sort specification must follow 'k'.";
+      if(!arg) return _("Long sort specification must follow 'k'.");
       defer_sf_option(arg, SF_G_sort);
       return NULL; /* can't have any more options */
     case 'l':
-      trace("l Display long format\n");
+      trace(_("l Display long format\n"));
       format_flags |= FF_Bl;
       break;
     case 'm':
-      trace("m all threads, sort on mem use, show mem info\n");
+      trace(_("m all threads, sort on mem use, show mem info\n"));
       if(personality & PER_OLD_m){
         format_flags |= FF_Lm;
         break;
@@ -688,35 +680,35 @@ static const char *parse_bsd_option(void){
       thread_flags |= TF_B_m;
       break;
     case 'n':
-      trace("n Numeric output for WCHAN, and USER replaced by UID\n");
+      trace(_("n Numeric output for WCHAN, and USER replaced by UID\n"));
       wchan_is_number = 1;
       user_is_number = 1;
       /* TODO add tty_is_number too? */
       break;
     case 'o': /* end */
-      trace("o Specify user-defined format\n");
+      trace(_("o Specify user-defined format\n"));
       arg=get_opt_arg();
-      if(!arg) return "Format specification must follow o.";
+      if(!arg) return _("Format specification must follow o.");
       defer_sf_option(arg, SF_B_o);
       return NULL; /* can't have any more options */
     case 'p': /* end */
-      trace("p Select by process ID\n");
+      trace(_("p Select by process ID\n"));
       arg=get_opt_arg();
-      if(!arg) return "List of process IDs must follow p.";
+      if(!arg) return _("List of process IDs must follow p.");
       err=parse_list(arg, parse_pid);
       if(err) return err;
       selection_list->typecode = SEL_PID;
       return NULL; /* can't have any more options */
     case 'r':
-      trace("r Select running processes\n");
+      trace(_("r Select running processes\n"));
       running_only = 1;
       break;
     case 's':
-      trace("s Display signal format\n");
+      trace(_("s Display signal format\n"));
       format_flags |= FF_Bs;
       break;
     case 't': /* end */
-      trace("t Select by tty.\n");
+      trace(_("t Select by tty.\n"));
       /* List of terminals (tty, pty...) _should_ follow t. */
       arg=get_opt_arg();
       if(!arg){
@@ -736,29 +728,29 @@ static const char *parse_bsd_option(void){
       selection_list->typecode = SEL_TTY;
       return NULL; /* can't have any more options */
     case 'u':
-      trace("u Display user-oriented\n");
+      trace(_("u Display user-oriented\n"));
       format_flags |= FF_Bu;
       break;
     case 'v':
-      trace("v Display virtual memory\n");
+      trace(_("v Display virtual memory\n"));
       format_flags |= FF_Bv;
       break;
     case 'w':
-      trace("w wide output\n");
+      trace(_("w wide output\n"));
       w_count++;
       break;
     case 'x':
-      trace("x Select processes without controlling ttys\n");
+      trace(_("x Select processes without controlling ttys\n"));
       simple_select |= SS_B_x;
       break;
     case '-':
-      return "Embedded '-' among BSD options makes no sense.";
+      return _("Embedded '-' among BSD options makes no sense.");
       break;
     case '\0':
-      return "Please report the \"BSD \\0 can't happen\" bug.";
+      return _("Please report the \"BSD \\0 can't happen\" bug.");
       break;
     default:
-      return "Unsupported option (BSD syntax)";
+      return _("Unsupported option (BSD syntax)");
     } /* switch */
   } /* while */
   return NULL;
@@ -844,7 +836,7 @@ static const char *parse_gnu_option(void){
 
   s = ps_argv[thisarg]+2;
   sl = strcspn(s,":=");
-  if(sl > 15) return "Unknown gnu long option.";
+  if(sl > 15) return _("Unknown gnu long option.");
   strncpy(buf, s, sl);
   buf[sl] = '\0';
   flagptr = s+sl;
@@ -853,14 +845,14 @@ static const char *parse_gnu_option(void){
       sizeof(gnu_table_struct), compare_gnu_table_structs
   );
 
-  if(!found) return "Unknown gnu long option.";
+  if(!found) return _("Unknown gnu long option.");
 
   goto *(found->jump);    /* See gcc extension info.  :-)   */
 
   case_Group:
     trace("--Group\n");
     arg = grab_gnu_arg();
-    if(!arg) return "List of real groups must follow --Group.";
+    if(!arg) return _("List of real groups must follow --Group.");
     err=parse_list(arg, parse_gid);
     if(err) return err;
     selection_list->typecode = SEL_RGID;
@@ -868,7 +860,7 @@ static const char *parse_gnu_option(void){
   case_User:
     trace("--User\n");
     arg = grab_gnu_arg();
-    if(!arg) return "List of real users must follow --User.";
+    if(!arg) return _("List of real users must follow --User.");
     err=parse_list(arg, parse_uid);
     if(err) return err;
     selection_list->typecode = SEL_RUID;
@@ -887,15 +879,15 @@ static const char *parse_gnu_option(void){
         return NULL;
       }
     }
-    return "Number of columns must follow --cols, --width, or --columns.";
+    return _("Number of columns must follow --cols, --width, or --columns.");
   case_cumulative:
     trace("--cumulative\n");
-    if(s[sl]) return "Option --cumulative does not take an argument.";
+    if(s[sl]) return _("Option --cumulative does not take an argument.");
     include_dead_children = 1;
     return NULL;
   case_deselect:
     trace("--deselect\n");
-    if(s[sl]) return "Option --deselect does not take an argument.";
+    if(s[sl]) return _("Option --deselect does not take an argument.");
     negate_selection = 1;
     return NULL;
   case_no_header:
@@ -907,8 +899,8 @@ static const char *parse_gnu_option(void){
   case_noheading:
   case_noheadings:
     trace("--noheaders\n");
-    if(s[sl]) return "Option --no-heading does not take an argument.";
-    if(header_type) return "Only one heading option may be specified.";
+    if(s[sl]) return _("Option --no-heading does not take an argument.");
+    if(header_type) return _("Only one heading option may be specified.");
     header_type = HEAD_NONE;
     return NULL;
   case_header:
@@ -916,25 +908,25 @@ static const char *parse_gnu_option(void){
   case_heading:
   case_headings:
     trace("--headers\n");
-    if(s[sl]) return "Option --heading does not take an argument.";
-    if(header_type) return "Only one heading option may be specified.";
+    if(s[sl]) return _("Option --heading does not take an argument.");
+    if(header_type) return _("Only one heading option may be specified.");
     header_type = HEAD_MULTI;
     return NULL;
   case_forest:
     trace("--forest\n");
-    if(s[sl]) return "Option --forest does not take an argument.";
+    if(s[sl]) return _("Option --forest does not take an argument.");
     forest_type = 'g';
     return NULL;
   case_format:
     trace("--format\n");
     arg=grab_gnu_arg();
-    if(!arg) return "Format specification must follow --format.";
+    if(!arg) return _("Format specification must follow --format.");
     defer_sf_option(arg, SF_G_format);
     return NULL;
   case_group:
     trace("--group\n");
     arg = grab_gnu_arg();
-    if(!arg) return "List of effective groups must follow --group.";
+    if(!arg) return _("List of effective groups must follow --group.");
     err=parse_list(arg, parse_gid);
     if(err) return err;
     selection_list->typecode = SEL_EGID;
@@ -956,7 +948,7 @@ static const char *parse_gnu_option(void){
   case_pid:
     trace("--pid\n");
     arg = grab_gnu_arg();
-    if(!arg) return "List of process IDs must follow --pid.";
+    if(!arg) return _("List of process IDs must follow --pid.");
     err=parse_list(arg, parse_pid);
     if(err) return err;
     selection_list->typecode = SEL_PID;
@@ -964,7 +956,7 @@ static const char *parse_gnu_option(void){
   case_ppid:
     trace("--ppid\n");
     arg = grab_gnu_arg();
-    if(!arg) return "List of process IDs must follow --ppid.";
+    if(!arg) return _("List of process IDs must follow --ppid.");
     err=parse_list(arg, parse_pid);
     if(err) return err;
     selection_list->typecode = SEL_PPID;
@@ -982,11 +974,11 @@ static const char *parse_gnu_option(void){
         return NULL;
       }
     }
-    return "Number of rows must follow --rows or --lines.";
+    return _("Number of rows must follow --rows or --lines.");
   case_sid:
     trace("--sid\n");
     arg = grab_gnu_arg();
-    if(!arg) return "Some sid thing(s) must follow --sid.";
+    if(!arg) return _("Some sid thing(s) must follow --sid.");
     err=parse_list(arg, parse_pid);
     if(err) return err;
     selection_list->typecode = SEL_SESS;
@@ -994,13 +986,13 @@ static const char *parse_gnu_option(void){
   case_sort:
     trace("--sort\n");
     arg=grab_gnu_arg();
-    if(!arg) return "Long sort specification must follow --sort.";
+    if(!arg) return _("Long sort specification must follow --sort.");
     defer_sf_option(arg, SF_G_sort);
     return NULL;
   case_tty:
     trace("--tty\n");
     arg = grab_gnu_arg();
-    if(!arg) return "List of ttys must follow --tty.";
+    if(!arg) return _("List of ttys must follow --tty.");
     err=parse_list(arg, parse_tty);
     if(err) return err;
     selection_list->typecode = SEL_TTY;
@@ -1008,7 +1000,7 @@ static const char *parse_gnu_option(void){
   case_user:
     trace("--user\n");
     arg = grab_gnu_arg();
-    if(!arg) return "List of effective users must follow --user.";
+    if(!arg) return _("List of effective users must follow --user.");
     err=parse_list(arg, parse_uid);
     if(err) return err;
     selection_list->typecode = SEL_EUID;
@@ -1112,9 +1104,9 @@ static const char *parse_all_options(void){
   const char *err = NULL;
   int at;
   while(++thisarg < ps_argc){
-  trace("parse_all_options calling arg_type for \"%s\"\n", ps_argv[thisarg]);
+  trace(_("parse_all_options calling arg_type for \"%s\"\n"), ps_argv[thisarg]);
     at = arg_type(ps_argv[thisarg]);
-    trace("ps_argv[thisarg] is %s\n", ps_argv[thisarg]);
+    trace(_("ps_argv[thisarg] is %s\n"), ps_argv[thisarg]);
     if(at != ARG_SYSV) not_pure_unix = 1;
     switch(at){
     case ARG_GNU:
@@ -1125,7 +1117,7 @@ static const char *parse_all_options(void){
         err = parse_sysv_option();
         break;
     case ARG_BSD:
-        if(force_bsd && !(personality & PER_FORCE_BSD)) return "way bad";
+        if(force_bsd && !(personality & PER_FORCE_BSD)) return _("way bad");
       }
       prefer_bsd_defaults = 1;
       err = parse_bsd_option();
@@ -1138,12 +1130,12 @@ static const char *parse_all_options(void){
       break;
     case ARG_END:
     case ARG_FAIL:
-      trace("              FAIL/END on [%s]\n",ps_argv[thisarg]);
-      return "Garbage option.";
+      trace(_("              FAIL/END on [%s]\n"),ps_argv[thisarg]);
+      return _("Garbage option.");
       break;
     default:
-      printf("                  ?    %s\n",ps_argv[thisarg]);
-      return "Something broke.";
+      printf(_("                  ?    %s\n"),ps_argv[thisarg]);
+      return _("Something broke.");
     } /* switch */
     if(err) return err;
   } /* while */
@@ -1163,16 +1155,16 @@ static const char *thread_option_check(void){
   }
 
   if(forest_type){
-    return "Thread display conflicts with forest display.";
+    return _("Thread display conflicts with forest display.");
   }
   //thread_flags |= TF_no_forest;
 
   if((thread_flags&TF_B_H) && (thread_flags&(TF_B_m|TF_U_m)))
-    return "Thread flags conflict; can't use H with m or -m.";
+    return _("Thread flags conflict; can't use H with m or -m.");
   if((thread_flags&TF_B_m) && (thread_flags&TF_U_m))
-    return "Thread flags conflict; can't use both m and -m.";
+    return _("Thread flags conflict; can't use both m and -m.");
   if((thread_flags&TF_U_L) && (thread_flags&TF_U_T))
-    return "Thread flags conflict; can't use both -L and -T.";
+    return _("Thread flags conflict; can't use both -L and -T.");
 
   if(thread_flags&TF_B_H) thread_flags |= (TF_show_proc|TF_loose_tasks);
   if(thread_flags&(TF_B_m|TF_U_m)) thread_flags |= (TF_show_proc|TF_show_task|TF_show_both);
@@ -1181,7 +1173,7 @@ static const char *thread_option_check(void){
     if(thread_flags&(TF_B_m|TF_U_m|TF_B_H)){
       // Got a thread style, so format modification is a requirement?
       // Maybe -T/-L has H thread style though. (sorting interaction?)
-      //return "Huh? Tell procps@freelists.org what you expected.";
+      //return _("Huh? Tell procps@freelists.org what you expected.");
       thread_flags |= TF_must_use;
     }else{
       // using -L/-T thread style, so format from elsewhere is OK
@@ -1215,7 +1207,7 @@ int arg_parse(int argc, char *argv[]){
   return 0;
 
 try_bsd:
-  trace("--------- now try BSD ------\n");
+  trace(_("--------- now try BSD ------\n"));
 
   reset_global();
   reset_parser();
@@ -1262,7 +1254,7 @@ try_bsd:
   //   changing the actual behavior of ps in any way.  I know of no
   //   other 'ps' that produces this message.
   if(!(personality & PER_FORCE_BSD))
-    fprintf(stderr, "Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html\n");
+    fprintf(stderr, _("Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html\n"));
 #endif
   // Remember: contact procps@freelists.org
   // if you should feel tempted. Be damn sure you understand all
@@ -1274,7 +1266,7 @@ try_bsd:
 
 total_failure:
   reset_parser();
-  if(personality & PER_FORCE_BSD) fprintf(stderr, "ERROR: %s\n", err2);
-  else fprintf(stderr, "ERROR: %s\n", err);
+  if(personality & PER_FORCE_BSD) fprintf(stderr, _("ERROR: %s\n"), err2);
+  else fprintf(stderr, _("ERROR: %s\n"), err);
   usage(stderr, USAGE_DEFAULT);
 }
diff --git a/ps/select.c b/ps/select.c
index 2c52d02d..6b8220df 100644
--- a/ps/select.c
+++ b/ps/select.c
@@ -59,7 +59,7 @@ const char *select_bits_setup(void){
     simple_select = 0;
     break;
   default:
-    return "Process selection options conflict.";
+    return _("Process selection options conflict.");
     break;
   }
   return NULL;
@@ -83,7 +83,7 @@ static int proc_was_listed(proc_t *buf){
   while(sn){
     switch(sn->typecode){
     default:
-      printf("Internal error in ps! Please report this bug.\n");
+      printf(_("Internal error in ps! Please report this bug.\n"));
 
 #define return_if_match(foo,bar) \
         i=sn->n; while(i--) \
diff --git a/ps/sortformat.c b/ps/sortformat.c
index 82ee27c3..696e3ed2 100644
--- a/ps/sortformat.c
+++ b/ps/sortformat.c
@@ -136,7 +136,7 @@ static const char *aix_format_parse(sf_node *sfn){
     items++;
     c = *walk++;
     if(c)         goto initial;
-    return "Improper AIX field descriptor.";
+    return _("Improper AIX field descriptor.");
   looks_ok:
     ;
   }
@@ -157,12 +157,12 @@ static const char *aix_format_parse(sf_node *sfn){
       walk++;
       if(!aix){
         free(buf);
-        return "Unknown AIX field descriptor.";
+        return _("Unknown AIX field descriptor.");
       }
       fnode =  do_one_spec(aix->spec, aix->head);
       if(!fnode){
         free(buf);
-        return "AIX field descriptor processing bug.";
+        return _("AIX field descriptor processing bug.");
       }
     } else {
       int len;
@@ -279,7 +279,7 @@ out:
         snprintf(
           errbuf,
           sizeof(errbuf),
-          "Unknown user-defined format specifier \"%s\".",
+          _("Unknown user-defined format specifier \"%s\"."),
           walk
         );
       }
@@ -305,10 +305,10 @@ out:
 
   /* errors may cause a retry looking for AIX format codes */
   if(0) unknown:  err=errbuf;
-  if(0) empty:    err="Empty format list.";
-  if(0) improper: err="Improper format list.";
-  if(0) badwidth: err="Column widths must be unsigned decimal numbers.";
-  if(0) notmacro: err="Can't set width for a macro (multi-column) format specifier.";
+  if(0) empty:    err=_("Empty format list.");
+  if(0) improper: err=_("Improper format list.");
+  if(0) badwidth: err=_("Column widths must be unsigned decimal numbers.");
+  if(0) notmacro: err=_("Can't set width for a macro (multi-column) format specifier.");
   if(strchr(sfn->sf,'%')) err = aix_format_parse(sfn);
   return err;
 }
@@ -361,7 +361,7 @@ static const char *long_sort_parse(sf_node *sfn){
     case ' ': case ',': case '\t': case '\n': case '\0':
       if(need_item){
         free(buf);
-        return "Improper sort list";
+        return _("Improper sort list");
       }
       need_item=1;
       break;
@@ -372,12 +372,12 @@ static const char *long_sort_parse(sf_node *sfn){
   } while (*++walk);
   if(!items){
     free(buf);
-    return "Empty sort list.";
+    return _("Empty sort list.");
   }
 #ifdef STRICT_LIST
   if(need_item){    /* can't have trailing deliminator */
     free(buf);
-    return "Improper sort list.";
+    return _("Improper sort list.");
   }
 #else
   if(need_item){    /* allow 1 trailing deliminator */
@@ -393,7 +393,7 @@ static const char *long_sort_parse(sf_node *sfn){
     snode = do_one_sort_spec(walk);
     if(!snode){
       free(buf);
-      return "Unknown sort specifier.";
+      return _("Unknown sort specifier.");
     }
     endp = snode; while(endp->next) endp = endp->next;  /* find end */
     endp->next = sfn->s_cooked;
@@ -420,7 +420,7 @@ static const char *verify_short_sort(const char *arg){
   int i;
   const char *walk;
   int tmp;
-  if(strspn(arg,all) != strlen(arg)) return "Bad sorting code.";
+  if(strspn(arg,all) != strlen(arg)) return _("Bad sorting code.");
   for(i=256; i--;) checkoff[i] = 0;
   walk = arg;
   for(;;){
@@ -431,13 +431,13 @@ static const char *verify_short_sort(const char *arg){
     case '+':
     case '-':
       tmp = *(walk+1);
-      if(!tmp || tmp=='+' || tmp=='-') return "Bad sorting code.";
+      if(!tmp || tmp=='+' || tmp=='-') return _("Bad sorting code.");
       break;
     case 'P':
-      if(forest_type) return "PPID sort and forest output conflict.";
+      if(forest_type) return _("PPID sort and forest output conflict.");
       /* fall through */
     default:
-      if(checkoff[tmp]) return "Bad sorting code.";   /* repeated */
+      if(checkoff[tmp]) return _("Bad sorting code.");   /* repeated */
       /* ought to check against already accepted sort options */
       checkoff[tmp] = 1;
       break;
@@ -471,9 +471,9 @@ static const char *short_sort_parse(sf_node *sfn){
       break;
     default:
       ss = search_shortsort_array(tmp);
-      if(!ss) return "Unknown sort specifier.";
+      if(!ss) return _("Unknown sort specifier.");
       snode = do_one_sort_spec(ss->spec);
-      if(!snode) return "Unknown sort specifier.";
+      if(!snode) return _("Unknown sort specifier.");
       snode->reverse = direction;
       endp = snode; while(endp->next) endp = endp->next;  /* find end */
       endp->next = sfn->s_cooked;
@@ -509,14 +509,14 @@ static const char *parse_O_option(sf_node *sfn){
       break;
     case SF_U_O:                                /*** format ***/
       /* Can have -l -f f u... set already_parsed_format like DEC does */
-      if(already_parsed_format) return "option -O can not follow other format options.";
+      if(already_parsed_format) return _("option -O can not follow other format options.");
       err = format_parse(sfn);
       if(err) return err;
       already_parsed_format = 1;
       O_wrap(sfn,'u'); /* must wrap user format in default */
       break;
     case SF_B_O:                                /***  both  ***/
-      if(have_gnu_sort || already_parsed_sort) err = "Multiple sort options.";
+      if(have_gnu_sort || already_parsed_sort) err = _("Multiple sort options.");
       else err = verify_short_sort(sfn->sf);
       if(!err){ /* success as sorting code */
         short_sort_parse(sfn);
@@ -524,7 +524,7 @@ static const char *parse_O_option(sf_node *sfn){
         return NULL;
       }
       if(already_parsed_format){
-        err = "option O is neither first format nor sort order.";
+        err = _("option O is neither first format nor sort order.");
         break;
       }
       if(!format_parse(sfn)){ /* if success as format code */
@@ -534,12 +534,12 @@ static const char *parse_O_option(sf_node *sfn){
       }
       break;
     case SF_G_sort: case SF_B_m:                 /***  sort  ***/
-      if(already_parsed_sort) err = "Multiple sort options.";
+      if(already_parsed_sort) err = _("Multiple sort options.");
       else err = long_sort_parse(sfn);
       already_parsed_sort = 1;
       break;
     default:                                    /***  junk  ***/
-      return "Bug: parse_O_option got weirdness!";
+      return _("Bug: parse_O_option got weirdness!");
   }
   return err; /* could be NULL */
 }
@@ -651,7 +651,7 @@ static int fmt_delete(const char *findme){
 static const char *generate_sysv_list(void){
   format_node *fn;
   if((format_modifiers & FM_y) && !(format_flags & FF_Ul))
-    return "Modifier -y without format -l makes no sense.";
+    return _("Modifier -y without format -l makes no sense.");
   if(prefer_bsd_defaults){
     if(format_flags) PUSH("cmd");
     else PUSH("args");
@@ -754,7 +754,7 @@ const char *process_sf_options(int localbroken){
     if(err) return err;
   }
 
-  if(format_list) printf("Bug: must reset the list first!\n");
+  if(format_list) printf(_("Bug: must reset the list first!\n"));
 
   /* merge formatting info of sf_list into format_list here */
   sf_walk = sf_list;
@@ -792,7 +792,7 @@ const char *process_sf_options(int localbroken){
   // with sorting. Do the threads remain grouped, with sorting
   // by process, or do the threads get sorted by themselves?
   if(sort_list && (thread_flags&TF_no_sort)){
-    return "Tell procps@freelists.org what you expected.";
+    return _("Tell procps@freelists.org what you expected.");
   }
 
   // If nothing else, try to use $PS_FORMAT before the default.
@@ -802,7 +802,7 @@ const char *process_sf_options(int localbroken){
     if(tmp && *tmp){
       const char *err;
       sf_node sfn;
-      if(thread_flags&TF_must_use) return "Tell procps@freelists.org what you want. (-L/-T, -m/m/H, and $PS_FORMAT)";
+      if(thread_flags&TF_must_use) return _("Tell procps@freelists.org what you want. (-L/-T, -m/m/H, and $PS_FORMAT)");
       sfn.sf = tmp;
       sfn.f_cooked = NULL;
       err = format_parse(&sfn);
@@ -819,14 +819,14 @@ const char *process_sf_options(int localbroken){
         return NULL;
       }
       // FIXME: prove that this won't be hit on valid bogus-BSD options
-      fprintf(stderr, "Warning: $PS_FORMAT ignored. (%s)\n", err);
+      fprintf(stderr, _("Warning: $PS_FORMAT ignored. (%s)\n"), err);
     }
   }
 
   if(format_list){
-    if(format_flags) return "Conflicting format options.";
-    if(format_modifiers) return "Can't use output modifiers with user-defined output";
-    if(thread_flags&TF_must_use) return "-L/-T with H/m/-m and -o/-O/o/O is nonsense";
+    if(format_flags) return _("Conflicting format options.");
+    if(format_modifiers) return _("Can't use output modifiers with user-defined output");
+    if(thread_flags&TF_must_use) return _("-L/-T with H/m/-m and -o/-O/o/O is nonsense");
     return NULL;
   }
 
@@ -834,7 +834,7 @@ const char *process_sf_options(int localbroken){
     const char *spec;
     switch(format_flags){
 
-    default:             return "Conflicting format options.";
+    default:             return _("Conflicting format options.");
 
     /* These can be NULL, which enables SysV list generation code. */
     case 0:              spec=NULL;           break;
@@ -884,9 +884,9 @@ const char *process_sf_options(int localbroken){
     if(format_modifiers & FM_j){
       fn = do_one_spec("pgid", NULL);
       if(!fmt_add_after("PPID", fn)) if(!fmt_add_after("PID", fn))
-        return "Internal error, no PID or PPID for -j option.";
+        return _("Internal error, no PID or PPID for -j option.");
       fn = do_one_spec("sid", NULL);
-      if(!fmt_add_after("PGID", fn)) return "Lost my PGID!";
+      if(!fmt_add_after("PGID", fn)) return _("Lost my PGID!");
     }
     if(format_modifiers & FM_y){
       /* TODO: check for failure to do something, and complain if so */
@@ -899,15 +899,15 @@ const char *process_sf_options(int localbroken){
       fmt_delete("NI");
       fn = do_one_spec("class", NULL);
       if(!fmt_add_after("PRI", fn))
-        return "Internal error, no PRI for -c option.";
+        return _("Internal error, no PRI for -c option.");
       fmt_delete("PRI"); /* we want a different one */
       fn = do_one_spec("pri", NULL);
-      if(!fmt_add_after("CLS", fn)) return "Lost my CLS!";
+      if(!fmt_add_after("CLS", fn)) return _("Lost my CLS!");
     }
     if(thread_flags & TF_U_T){
       fn = do_one_spec("spid", NULL);
       if(!fmt_add_after("PID", fn) && (thread_flags&TF_must_use))
-        return "-T with H/-m/m but no PID for SPID to follow";
+        return _("-T with H/-m/m but no PID for SPID to follow");
     }
     if(thread_flags & TF_U_L){
       fn = do_one_spec("lwp", NULL);
@@ -918,7 +918,7 @@ const char *process_sf_options(int localbroken){
       if(fmt_add_after("PPID", fn)) goto did_lwp;
       if(fmt_add_after("PID",  fn)) goto did_lwp;
       if(thread_flags&TF_must_use)
-        return "-L with H/-m/m but no PID/PGID/SID/SESS for NLWP to follow";
+        return _("-L with H/-m/m but no PID/PGID/SID/SESS for NLWP to follow");
 did_lwp:
       fn = do_one_spec("nlwp", NULL);
       fmt_add_after("%CPU",  fn);
diff --git a/ps/stacktrace.c b/ps/stacktrace.c
index 79814bb3..1e84188f 100644
--- a/ps/stacktrace.c
+++ b/ps/stacktrace.c
@@ -14,6 +14,8 @@
 #include <sys/wait.h>
 #include <sys/time.h>
 
+#include "common.h"
+
 #define INTERACTIVE 0
 #define STACK_TRACE 1
 
@@ -23,7 +25,7 @@ static int stack_trace_done;
 /***********/
 static void debug_stop(char **args){
   execvp (args[0], args);
-  perror ("exec failed");
+  perror (_("exec failed"));
   _exit (0);
 }
 
@@ -48,7 +50,7 @@ static void stack_trace(char **args){
   signal(SIGCHLD, stack_trace_sigchld);
   
   if((pipe (in_fd) == -1) || (pipe (out_fd) == -1)){
-    perror ("could open pipe");
+    perror (_("could open pipe"));
     _exit (0);
   }
 
@@ -58,11 +60,11 @@ static void stack_trace(char **args){
     close (1); dup (out_fd[1]);  /* set the stdout to the out pipe */
     close (2); dup (out_fd[1]);  /* set the stderr to the out pipe */
     execvp (args[0], args);      /* exec gdb */
-    perror ("exec failed");
+    perror (_("exec failed"));
     _exit (0);
   } else {
     if(pid == (pid_t) -1){
-      perror ("could not fork");
+      perror (_("could not fork"));
       _exit (0);
     }
   }
@@ -135,17 +137,17 @@ void debug(int method, char *prog_name){
   if(pid == 0){
     switch (method){
     case INTERACTIVE:
-      fprintf (stderr, "debug_stop\n");
+      fprintf (stderr, _("debug_stop\n"));
       debug_stop(args);
       break;
     case STACK_TRACE:
-      fprintf (stderr, "stack_trace\n");
+      fprintf (stderr, _("stack_trace\n"));
       stack_trace(args);
       break;
     }
     _exit(0);
   } else if(pid == (pid_t) -1){
-    perror ("could not fork");
+    perror (_("could not fork"));
     return;
   }