Index: intl.h =================================================================== --- intl.h (revision 157508) +++ intl.h (working copy) @@ -60,6 +60,8 @@ #endif extern char *get_spaces (const char *); +extern unsigned int get_aligned_len (const char *, unsigned int, + unsigned int); extern const char *open_quote; extern const char *close_quote; Index: intl.c =================================================================== --- intl.c (revision 157508) +++ 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,73 @@ return wcswidth (wmsgstr, nwcs); } +/* Return the number of bytes of multibyte string MSGSTR + that can be printed within the width ROOM. + REMAINING is the length of string MSGSTR counted by bytes. */ + +unsigned int +get_aligned_len (const char *msgstr, unsigned int room, + unsigned int remaining) +{ + size_t nbytes; + wchar_t wc[1]; + + size_t pre_nbytes; + wchar_t pre_wc; + + unsigned int len = 0; + unsigned int colwidth = 0; + unsigned int len_bk; + + mbstate_t state; + memset (&state, '\0', sizeof (state)); + + int length = remaining; + + while ((nbytes = mbrtowc (wc, msgstr, length, &state)) > 0) + { + if (nbytes >= (size_t) -2) + break; + colwidth += wcwidth (wc[0]); + length--; + if (length == 0) + len = remaining; + else if (iswspace (wc[0])) + len_bk = len = remaining - length - nbytes; + else if ((wc[0] == L'-' || wc[0] == L'/') + && iswalpha (pre_wc)) + len_bk = len = remaining - length; + else if (nbytes > 1) + { + len_bk = len; + length = length - nbytes + 1; + len = remaining - length; + pre_wc = wc[0]; + pre_nbytes = nbytes; + if ((nbytes = mbrtowc (wc, msgstr + nbytes, length, &state)) > 0) + { + if (iswpunct (wc[0]) && iswalpha (pre_wc)) + { + len = remaining - length + nbytes; + colwidth += wcwidth(wc[0]); + msgstr += nbytes; + length -= nbytes; + } + nbytes = pre_nbytes; + } + } + if (colwidth >= room) + { + if (colwidth > room) + len = len_bk; + break; + } + msgstr += nbytes; + pre_wc = wc[0]; + } + return len; +} + #else /* no wcswidth */ /* We don't have any way of knowing how wide the string is. Guess @@ -119,10 +187,8 @@ #endif -#endif /* ENABLE_NLS */ +#else /* Not defined ENABLE_NLS */ -#ifndef ENABLE_NLS - const char * fake_ngettext (const char *singular, const char *plural, unsigned long n) { @@ -132,6 +198,35 @@ return plural; } +#endif /* ENABLE_NLS */ + +#if !(defined ENABLE_NLS) || !(defined HAVE_WCHAR_H \ + && defined HAVE_WORKING_MBSTOWCS \ + && defined HAVE_WCSWIDTH) + +/* Return the length of MSGSTR that can be printed within the width ROOM. + REMAINING is the length of string MSGSTR counted by bytes. */ + +unsigned int +get_aligned_len (const char *msgstr, unsigned int room, + unsigned int remaining) +{ + unsigned int i; + unsigned int len = remaining; + for (i = 0; msgstr[i]; i++) + { + if (i >= room && len != remaining) + break; + if (msgstr[i] == ' ') + len = i; + else if ((msgstr[i] == '-' || msgstr[i] == '/') + && msgstr[i + 1] != ' ' + && i > 0 && ISALPHA (msgstr[i - 1])) + len = i + 1; + } + return len; +} + #endif /* Return the indent for successive lines, using the width of Index: opts.c =================================================================== --- opts.c (revision 157508) +++ opts.c (working copy) @@ -1149,45 +1149,40 @@ #define LEFT_COLUMN 27 -/* Output ITEM, of length ITEM_WIDTH, in the left column, - followed by word-wrapped HELP in a second column. */ +/* Output ITEM in the left column, followed by + word-wrapped HELP in a second column. */ static void wrap_help (const char *help, const char *item, - unsigned int item_width, unsigned int columns) { - unsigned int col_width = LEFT_COLUMN; unsigned int remaining, room, len; + unsigned int col_width = LEFT_COLUMN; + unsigned int item_width = gcc_gettext_width (item); remaining = strlen (help); do { + int n_spaces = col_width - item_width; + printf (" %s", item); + if (n_spaces > 0) + { + const char *space = " "; + printf ("%*s", n_spaces, space); + } + room = columns - 3 - MAX (col_width, item_width); if (room > columns) room = 0; len = remaining; if (room < len) - { - unsigned int i; + len = get_aligned_len (help, room, remaining); - 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); - item_width = 0; + printf ( " %.*s\n", len, help); + item = " "; + item_width = 1; while (help[len] == ' ') len++; help += len; @@ -1226,7 +1221,7 @@ /* Get the translation. */ help = _(help); - wrap_help (help, param, strlen (param), columns); + wrap_help (help, param, columns); } putchar ('\n'); return; @@ -1242,6 +1237,7 @@ unsigned int len; const char *opt; const char *tab; + char *buf; if (include_flags == 0 || ((option->flags & include_flags) != include_flags)) @@ -1278,7 +1274,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 @@ -1319,7 +1318,7 @@ help = new_help; } - wrap_help (help, opt, len, columns); + wrap_help (help, opt, columns); displayed = true; }