Merge branch 'jx/utf8-printf-width'
authorJunio C Hamano <gitster@pobox.com>
Thu, 14 Feb 2013 18:29:08 +0000 (10:29 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 14 Feb 2013 18:29:08 +0000 (10:29 -0800)
Use a new helper that prints a message and counts its display width
to align the help messages parse-options produces.

* jx/utf8-printf-width:
Add utf8_fprintf helper that returns correct number of columns

1  2 
parse-options.c
utf8.c
utf8.h
diff --combined parse-options.c
index 67e98a6323e2dd4e3b4b8003806f7dffaff29a64,670bf09b452e5e74a76df17535ea53b133d26091..a6ce9efb79df18ab433904024cce9cce2b1e56ce
@@@ -3,6 -3,7 +3,7 @@@
  #include "cache.h"
  #include "commit.h"
  #include "color.h"
+ #include "utf8.h"
  
  static int parse_options_usage(struct parse_opt_ctx_t *ctx,
                               const char * const *usagestr,
@@@ -18,6 -19,15 +19,6 @@@ int optbug(const struct option *opt, co
        return error("BUG: switch '%c' %s", opt->short_name, reason);
  }
  
 -int opterror(const struct option *opt, const char *reason, int flags)
 -{
 -      if (flags & OPT_SHORT)
 -              return error("switch `%c' %s", opt->short_name, reason);
 -      if (flags & OPT_UNSET)
 -              return error("option `no-%s' %s", opt->long_name, reason);
 -      return error("option `%s' %s", opt->long_name, reason);
 -}
 -
  static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
                   int flags, const char **arg)
  {
@@@ -482,7 -492,7 +483,7 @@@ static int usage_argh(const struct opti
                        s = literal ? "[%s]" : "[<%s>]";
        else
                s = literal ? " %s" : " <%s>";
-       return fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
+       return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
  }
  
  #define USAGE_OPTS_WIDTH 24
@@@ -541,7 -551,7 +542,7 @@@ static int usage_with_options_internal(
                if (opts->long_name)
                        pos += fprintf(outfile, "--%s", opts->long_name);
                if (opts->type == OPTION_NUMBER)
-                       pos += fprintf(outfile, "-NUM");
+                       pos += utf8_fprintf(outfile, _("-NUM"));
  
                if ((opts->flags & PARSE_OPT_LITERAL_ARGHELP) ||
                    !(opts->flags & PARSE_OPT_NOARG))
@@@ -585,12 -595,3 +586,12 @@@ static int parse_options_usage(struct p
        return usage_with_options_internal(ctx, usagestr, opts, 0, err);
  }
  
 +#undef opterror
 +int opterror(const struct option *opt, const char *reason, int flags)
 +{
 +      if (flags & OPT_SHORT)
 +              return error("switch `%c' %s", opt->short_name, reason);
 +      if (flags & OPT_UNSET)
 +              return error("option `no-%s' %s", opt->long_name, reason);
 +      return error("option `%s' %s", opt->long_name, reason);
 +}
diff --combined utf8.c
index a4ee6650ef6c4c487c083aabf0a950b8ec317b09,c7bda66e3800abfd49eea2d6fafd95a2403a6b90..1087870c51caff3dd86a852ec5e8bf5875f6d797
--- 1/utf8.c
--- 2/utf8.c
+++ b/utf8.c
@@@ -323,7 -323,7 +323,7 @@@ static size_t display_mode_esc_sequence
   * If indent is negative, assume that already -indent columns have been
   * consumed (and no extra indent is necessary for the first line).
   */
 -int strbuf_add_wrapped_text(struct strbuf *buf,
 +void strbuf_add_wrapped_text(struct strbuf *buf,
                const char *text, int indent1, int indent2, int width)
  {
        int indent, w, assume_utf8 = 1;
  
        if (width <= 0) {
                strbuf_add_indented_text(buf, text, indent1, indent2);
 -              return 1;
 +              return;
        }
  
  retry:
                        if (w <= width || !space) {
                                const char *start = bol;
                                if (!c && text == start)
 -                                      return w;
 +                                      return;
                                if (space)
                                        start = space;
                                else
                                        strbuf_addchars(buf, ' ', indent);
                                strbuf_add(buf, start, text - start);
                                if (!c)
 -                                      return w;
 +                                      return;
                                space = text;
                                if (c == '\t')
                                        w |= 0x07;
@@@ -405,12 -405,13 +405,12 @@@ new_line
        }
  }
  
 -int strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
 +void strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
                             int indent, int indent2, int width)
  {
        char *tmp = xstrndup(data, len);
 -      int r = strbuf_add_wrapped_text(buf, tmp, indent, indent2, width);
 +      strbuf_add_wrapped_text(buf, tmp, indent, indent2, width);
        free(tmp);
 -      return r;
  }
  
  int is_encoding_utf8(const char *name)
@@@ -429,6 -430,27 +429,27 @@@ int same_encoding(const char *src, cons
        return !strcasecmp(src, dst);
  }
  
+ /*
+  * Wrapper for fprintf and returns the total number of columns required
+  * for the printed string, assuming that the string is utf8.
+  */
+ int utf8_fprintf(FILE *stream, const char *format, ...)
+ {
+       struct strbuf buf = STRBUF_INIT;
+       va_list arg;
+       int columns;
+       va_start(arg, format);
+       strbuf_vaddf(&buf, format, arg);
+       va_end(arg);
+       columns = fputs(buf.buf, stream);
+       if (0 <= columns) /* keep the error from the I/O */
+               columns = utf8_strwidth(buf.buf);
+       strbuf_release(&buf);
+       return columns;
+ }
  /*
   * Given a buffer and its encoding, return it re-encoded
   * with iconv.  If the conversion fails, returns NULL.
diff --combined utf8.h
index a214238bdd70c6b4eb41edf6626c5b396489ab50,3ca85c7737bff0b3df449cc9dc32f32230b522e1..501b2bd9c4fd3fdce6dcbba1a3e3f7c0211d6c8f
--- 1/utf8.h
--- 2/utf8.h
+++ b/utf8.h
@@@ -8,10 -8,11 +8,11 @@@ int utf8_strwidth(const char *string)
  int is_utf8(const char *text);
  int is_encoding_utf8(const char *name);
  int same_encoding(const char *, const char *);
+ int utf8_fprintf(FILE *, const char *, ...);
  
 -int strbuf_add_wrapped_text(struct strbuf *buf,
 +void strbuf_add_wrapped_text(struct strbuf *buf,
                const char *text, int indent, int indent2, int width);
 -int strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
 +void strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len,
                             int indent, int indent2, int width);
  
  #ifndef NO_ICONV