Merge branch 'jk/utf-8-can-be-spelled-differently'
authorJunio C Hamano <gitster@pobox.com>
Thu, 21 Mar 2013 21:02:58 +0000 (14:02 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 21 Mar 2013 21:02:58 +0000 (14:02 -0700)
Some platforms and users spell UTF-8 differently; retry with the
most official "UTF-8" when the system does not understand the
user-supplied encoding name that are the common alternative
spellings of UTF-8.

* jk/utf-8-can-be-spelled-differently:
utf8: accept alternate spellings of UTF-8

1  2 
utf8.c
diff --combined utf8.c
index 1087870c51caff3dd86a852ec5e8bf5875f6d797,e7caef4721eafa66aba8f481675ebd69acdd6df8..8f6e84b7b3cf589f437a81ee81fd0228b2faf2f2
--- 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:
  
                c = *text;
                if (!c || isspace(c)) {
 -                      if (w < width || !space) {
 +                      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)
        return 0;
  }
  
 +int same_encoding(const char *src, const char *dst)
 +{
 +      if (is_encoding_utf8(src) && is_encoding_utf8(dst))
 +              return 1;
 +      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.
@@@ -507,9 -480,25 +507,25 @@@ char *reencode_string(const char *in, c
  
        if (!in_encoding)
                return NULL;
        conv = iconv_open(out_encoding, in_encoding);
-       if (conv == (iconv_t) -1)
-               return NULL;
+       if (conv == (iconv_t) -1) {
+               /*
+                * Some platforms do not have the variously spelled variants of
+                * UTF-8, so let's fall back to trying the most official
+                * spelling. We do so only as a fallback in case the platform
+                * does understand the user's spelling, but not our official
+                * one.
+                */
+               if (is_encoding_utf8(in_encoding))
+                       in_encoding = "UTF-8";
+               if (is_encoding_utf8(out_encoding))
+                       out_encoding = "UTF-8";
+               conv = iconv_open(out_encoding, in_encoding);
+               if (conv == (iconv_t) -1)
+                       return NULL;
+       }
        out = reencode_string_iconv(in, strlen(in), conv);
        iconv_close(conv);
        return out;