From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10285 invoked by alias); 15 Mar 2010 10:53:15 -0000 Received: (qmail 10267 invoked by uid 22791); 15 Mar 2010 10:53:14 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from rcsinet11.oracle.com (HELO rcsinet11.oracle.com) (148.87.113.123) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 15 Mar 2010 10:53:09 +0000 Received: from acsinet15.oracle.com (acsinet15.oracle.com [141.146.126.227]) by rcsinet11.oracle.com (Switch-3.4.2/Switch-3.4.2) with ESMTP id o2FAr3iV029161 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 15 Mar 2010 10:53:05 GMT Received: from acsmt353.oracle.com (acsmt353.oracle.com [141.146.40.153]) by acsinet15.oracle.com (Switch-3.4.2/Switch-3.4.1) with ESMTP id o2EMQlg5016429; Mon, 15 Mar 2010 10:53:02 GMT Received: from abhmt021.oracle.com by acsmt353.oracle.com with ESMTP id 81045041268650306; Mon, 15 Mar 2010 03:51:46 -0700 Received: from [10.182.121.28] (/10.182.121.28) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 15 Mar 2010 03:51:46 -0700 Message-ID: <4B9E1110.9020802@oracle.com> Date: Mon, 15 Mar 2010 10:58:00 -0000 From: Shujing Zhao User-Agent: Thunderbird 2.0.0.23 (X11/20090812) MIME-Version: 1.0 To: "Joseph S. Myers" CC: GCC Patches , Paolo Carlini Subject: Re: [PATCH PR/42686] Align the help text output References: <4B863559.4000407@oracle.com> <4B976D51.8010705@oracle.com> <4B9A1E65.4080506@oracle.com> <4B9DFA37.9010303@oracle.com> In-Reply-To: <4B9DFA37.9010303@oracle.com> Content-Type: multipart/mixed; boundary="------------020506030205050508070402" X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2010-03/txt/msg00576.txt.bz2 This is a multi-part message in MIME format. --------------020506030205050508070402 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 651 On 03/15/2010 05:13 PM, Shujing Zhao wrote: > Yes. Breaking the printf makes the code clearer and easier. Thanks to > point out it. At the new patch, I broke the printf into output item and > output help string. The code to output the item that includes wide > character is moved back to opts.c, for it doesn't use any wcs functions. > The others are kept with the old patch. > Thanks for your patience reviewing the patches. I reconsider the design of get_aligned_len after reading some material of line break at gnulib. And get_aligned_len should be changed to keep with the change of output item at the last patch. Is it ok? Thanks Pearly --------------020506030205050508070402 Content-Type: text/x-patch; name="03151742.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="03151742.patch" Content-length: 6155 Index: intl.h =================================================================== --- intl.h (revision 157453) +++ intl.h (working copy) @@ -30,6 +30,8 @@ #include extern void gcc_init_libintl (void); extern size_t gcc_gettext_width (const char *); +extern unsigned int get_aligned_len (const char *, unsigned int, + unsigned int); #else /* Stubs. */ # undef textdomain @@ -41,6 +43,7 @@ # define ngettext(singular,plural,n) fake_ngettext(singular,plural,n) # define gcc_init_libintl() /* nothing */ # define gcc_gettext_width(s) strlen(s) +# define get_aligned_len (s, room, remaining) remaining extern const char *fake_ngettext(const char *singular,const char *plural, unsigned long int n); Index: intl.c =================================================================== --- intl.c (revision 157453) +++ intl.c (working copy) @@ -92,6 +92,7 @@ #if defined HAVE_WCHAR_H && defined HAVE_WORKING_MBSTOWCS && defined HAVE_WCSWIDTH #include +#include /* Returns the width in columns of MSGSTR, which came from gettext. This is for indenting subsequent output. */ @@ -106,6 +107,87 @@ return wcswidth (wmsgstr, nwcs); } +/* Return the number of bytes when converts the wide character WC + to its multibyte representation. */ + +static int +wctomb_nbytes (wchar_t wc) +{ + char *pmb = (char *)xmalloc (MB_CUR_MAX); + int nbytes = wctomb (pmb, wc); + if (pmb) + free (pmb); + return nbytes; +} + +/* Return the length of MSGSTR that can be printed within the width ROOM. */ + +unsigned int +get_aligned_len (const char *msgstr, unsigned int room, + unsigned int remaining) +{ + unsigned int i; + unsigned int len = 0; + unsigned int pos = 0; + int nbytes; + int len_bk; + wchar_t *buf; + unsigned int colwide = 0; + size_t remaining_width; + + size_t nwcs = mbstowcs (0, msgstr, 0); + wchar_t *wmsgstr = XALLOCAVEC (wchar_t, nwcs + 1); + + mbstowcs (wmsgstr, msgstr, nwcs + 1); + remaining_width = wcswidth (wmsgstr, nwcs); + + for (i = 0; i < nwcs; i++) + { + unsigned int maybe_width = colwide + (i - pos); + nbytes = wctomb_nbytes (wmsgstr [i]); + if (maybe_width == remaining_width) + len = remaining; + else if (colwide > room) + { + len = len_bk; + break; + } + else if (colwide == room || maybe_width > room) + break; + else if (nbytes > 1) + { + buf = XALLOCAVEC (wchar_t, i + 2); + wcsncpy (buf, wmsgstr, i + 1); + buf [i + 1] = L'\0'; + len_bk = len; + len = wcstombs (0, buf, 0); + colwide = wcswidth (buf, i + 1); + /* Keep the puncts printed with the previous word. */ + if (iswpunct (wmsgstr [i + 1]) + && iswalpha (wmsgstr [i -1])) + { + i++; + nbytes = wctomb_nbytes (wmsgstr [i]); + if (nbytes > 1) + { + buf = XALLOCAVEC (wchar_t, i + 2); + wcsncpy (buf, wmsgstr, i + 1); + buf [i + 1] = '\0'; + len = wcstombs (0, buf, 0); + colwide = wcswidth (buf, i + 1); + } + else + { + len = len + 1; + colwide = colwide + 1; + } + } + pos = i; + } + } + return len; +} + #else /* no wcswidth */ /* We don't have any way of knowing how wide the string is. Guess @@ -117,6 +199,13 @@ return strlen (msgstr); } +unsigned int +get_aligned_len (const char *msgstr, unsigned int room, + unsigned int remaining) +{ + return remaining; +} + #endif #endif /* ENABLE_NLS */ Index: opts.c =================================================================== --- opts.c (revision 157453) +++ opts.c (working copy) @@ -1158,12 +1158,29 @@ unsigned int columns) { unsigned int col_width = LEFT_COLUMN; - unsigned int remaining, room, len; + unsigned int remaining, room, len, item_col_width; + unsigned int i; remaining = strlen (help); + item_col_width = gcc_gettext_width (item); do { + if (item_width == item_col_width + || item_width == 0) + printf (" %-*.*s", col_width, item_width, item); + else + { + printf (" %s", item); + if (item_col_width < col_width) + { + unsigned int n_spaces = col_width - item_col_width; + const char *space = " "; + for (i = 0; i < n_spaces; i++) + printf ("%s", space); + } + } + room = columns - 3 - MAX (col_width, item_width); if (room > columns) room = 0; @@ -1171,22 +1188,25 @@ if (room < len) { - unsigned int i; - - for (i = 0; help[i]; i++) + if (len != gcc_gettext_width (help)) + len = get_aligned_len (help, room, remaining); + else { - if (i >= room && len != remaining) - break; - if (help[i] == ' ') - len = i; - else if ((help[i] == '-' || help[i] == '/') - && help[i + 1] != ' ' - && i > 0 && ISALPHA (help[i - 1])) - len = i + 1; + for (i = 0; help[i]; i++) + { + if (i >= room && len != remaining) + break; + if (help[i] == ' ') + len = i; + else if ((help[i] == '-' || help[i] == '/') + && help[i + 1] != ' ' + && i > 0 && ISALPHA (help[i - 1])) + len = i + 1; + } } } - printf( " %-*.*s %.*s\n", col_width, item_width, item, len, help); + printf ( " %.*s\n", len, help); item_width = 0; while (help[len] == ' ') len++; @@ -1242,6 +1262,7 @@ unsigned int len; const char *opt; const char *tab; + char *buf; if (include_flags == 0 || ((option->flags & include_flags) != include_flags)) @@ -1278,7 +1299,10 @@ if (tab) { len = tab - help; - opt = help; + buf = (char *)alloca (len + 1); + strncpy (buf, help, len); + buf[len] = '\0'; + opt = buf; help = tab + 1; } else --------------020506030205050508070402--