From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31509 invoked by alias); 7 Dec 2009 17:57:49 -0000 Received: (qmail 31498 invoked by uid 22791); 7 Dec 2009 17:57:48 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.33.17) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 07 Dec 2009 17:57:43 +0000 Received: from kpbe13.cbf.corp.google.com (kpbe13.cbf.corp.google.com [172.25.105.77]) by smtp-out.google.com with ESMTP id nB7HvedB013160 for ; Mon, 7 Dec 2009 17:57:40 GMT Received: from ruffy.mtv.corp.google.com (ruffy.mtv.corp.google.com [172.18.118.116]) by kpbe13.cbf.corp.google.com with ESMTP id nB7HvbQg017403 for ; Mon, 7 Dec 2009 09:57:37 -0800 Received: by ruffy.mtv.corp.google.com (Postfix, from userid 67641) id 3708F8456F; Mon, 7 Dec 2009 09:57:37 -0800 (PST) To: gdb-patches@sourceware.org Subject: [RFA] Handle older iconv programs Message-Id: <20091207175737.3708F8456F@ruffy.mtv.corp.google.com> Date: Mon, 07 Dec 2009 17:57:00 -0000 From: dje@google.com (Doug Evans) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-12/txt/msg00081.txt.bz2 Hi. Older iconv programs emit the human readable form even if stdout is not a tty. Note: This patch requires a libiberty fix: http://gcc.gnu.org/ml/gcc-patches/2009-12/msg00380.html Ok to check in? [after the libiberty patch goes in] 2009-12-07 Doug Evans * charset.c: Include environ.h. (ignore_line_p): New function. (find_charset_names): Handle older versions of iconv that print human-readable output even if stdout is not a tty. ==== //depot2/gcctools/google_vendor_src_branch/gdb/gdb-7.0.x-prod/gdb/charset.c#1 - /usr/local/google/home/dje/ctools/gdb/7.0.x-prod/depot2/gcctools/google_vendor_src_branch/gdb/gdb-7.0.x-prod/gdb/charset.c ==== --- /tmp/g4-67641/cache/depot2/gcctools/google_vendor_src_branch/gdb/gdb-7.0.x-prod/gdb/charset.c#1 2009-12-06 12:30:44.000000000 -0800 +++ /usr/local/google/home/dje/ctools/gdb/7.0.x-prod/depot2/gcctools/google_vendor_src_branch/gdb/gdb-7.0.x-prod/gdb/charset.c 2009-12-06 12:01:12.000000000 -0800 @@ -25,6 +25,7 @@ #include "gdb_wait.h" #include "charset-list.h" #include "vec.h" +#include "environ.h" #include #include "gdb_string.h" @@ -705,6 +706,35 @@ #else +/* Return non-zero if LINE (output from iconv) should be ignored. + Older iconv programs (e.g. 2.2.2) include the human readable + introduction even when stdout is not a tty. Newer versions omit + the intro if stdout is not a tty. */ + +static int +ignore_line_p (const char *line) +{ + /* This table is used to filter the output. If this text appears + anywhere in the line, it is ignored (strstr is used). */ + static const char * const ignore_lines[] = + { + "The following", + "not necessarily", + "the FROM and TO", + "listed with several", + NULL + }; + int i; + + for (i = 0; ignore_lines[i] != NULL; ++i) + { + if (strstr (line, ignore_lines[i]) != NULL) + return 1; + } + + return 0; +} + static void find_charset_names (void) { @@ -712,6 +742,15 @@ char *args[3]; int err, status; int fail = 1; + struct gdb_environ *iconv_env; + + /* Older iconvs, e.g. 2.2.2, don't omit the intro text if stdout is not + a tty. We need to recognize it and ignore it. This text is subject + to translation, so force LANGUAGE=en. */ + iconv_env = make_environ (); + init_environ (iconv_env); + set_in_environ (iconv_env, "LANGUAGE", "en"); + set_in_environ (iconv_env, "LC_ALL", "C"); child = pex_init (0, "iconv", NULL); @@ -719,14 +758,16 @@ args[1] = "-l"; args[2] = NULL; /* Note that we simply ignore errors here. */ - if (!pex_run (child, PEX_SEARCH | PEX_STDERR_TO_STDOUT, "iconv", - args, NULL, NULL, &err)) + if (!pex_run_in_environment (child, PEX_SEARCH | PEX_STDERR_TO_STDOUT, + "iconv", args, environ_vector (iconv_env), + NULL, NULL, &err)) { FILE *in = pex_read_output (child, 0); /* POSIX says that iconv -l uses an unspecified format. We parse the glibc and libiconv formats; feel free to add others as needed. */ + while (!feof (in)) { /* The size of buf is chosen arbitrarily. */ @@ -740,6 +781,9 @@ len = strlen (r); if (len <= 3) continue; + if (ignore_line_p (r)) + continue; + /* Strip off the newline. */ --len; /* Strip off one or two '/'s. glibc will print lines like @@ -751,15 +795,21 @@ buf[len] = '\0'; /* libiconv will print multiple entries per line, separated - by spaces. */ + by spaces. Older iconvs will print multiple entries per line, + indented by two spaces, and separated by ", " + (i.e. the human readable form). */ start = buf; while (1) { int keep_going; char *p; - /* Find the next space, or end-of-line. */ - for (p = start; *p && *p != ' '; ++p) + /* Skip leading blanks. */ + for (p = start; *p && *p == ' '; ++p) + ; + start = p; + /* Find the next space, comma, or end-of-line. */ + for ( ; *p && *p != ' ' && *p != ','; ++p) ; /* Ignore an empty result. */ if (p == start) @@ -782,6 +832,7 @@ } pex_free (child); + free_environ (iconv_env); if (fail) {