Move encoding conversion routine out of mailinfo to utf8.c
This moves the body of convert_to_utf8() routine used in mailinfo to the utf8.c i18n library. Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
6934dec895
commit
b45974a655
@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
static FILE *cmitmsg, *patchfile, *fin, *fout;
|
static FILE *cmitmsg, *patchfile, *fin, *fout;
|
||||||
|
|
||||||
@ -510,40 +511,18 @@ static int decode_b_segment(char *in, char *ot, char *ep)
|
|||||||
|
|
||||||
static void convert_to_utf8(char *line, char *charset)
|
static void convert_to_utf8(char *line, char *charset)
|
||||||
{
|
{
|
||||||
#ifndef NO_ICONV
|
|
||||||
char *in, *out;
|
|
||||||
size_t insize, outsize, nrc;
|
|
||||||
char outbuf[4096]; /* cheat */
|
|
||||||
static char latin_one[] = "latin1";
|
static char latin_one[] = "latin1";
|
||||||
char *input_charset = *charset ? charset : latin_one;
|
char *input_charset = *charset ? charset : latin_one;
|
||||||
iconv_t conv = iconv_open(metainfo_charset, input_charset);
|
char *out = reencode_string(line, metainfo_charset, input_charset);
|
||||||
|
|
||||||
if (conv == (iconv_t) -1) {
|
if (!out) {
|
||||||
static int warned_latin1_once = 0;
|
fprintf(stderr, "cannot convert from %s to %s\n",
|
||||||
if (input_charset != latin_one) {
|
input_charset, metainfo_charset);
|
||||||
fprintf(stderr, "cannot convert from %s to %s\n",
|
*charset = 0;
|
||||||
input_charset, metainfo_charset);
|
|
||||||
*charset = 0;
|
|
||||||
}
|
|
||||||
else if (!warned_latin1_once) {
|
|
||||||
warned_latin1_once = 1;
|
|
||||||
fprintf(stderr, "tried to convert from %s to %s, "
|
|
||||||
"but your iconv does not work with it.\n",
|
|
||||||
input_charset, metainfo_charset);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
in = line;
|
strcpy(line, out);
|
||||||
insize = strlen(in);
|
free(out);
|
||||||
out = outbuf;
|
|
||||||
outsize = sizeof(outbuf);
|
|
||||||
nrc = iconv(conv, &in, &insize, &out, &outsize);
|
|
||||||
iconv_close(conv);
|
|
||||||
if (nrc == (size_t) -1)
|
|
||||||
return;
|
|
||||||
*out = 0;
|
|
||||||
strcpy(line, outbuf);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode_header_bq(char *it)
|
static int decode_header_bq(char *it)
|
||||||
|
54
utf8.c
54
utf8.c
@ -276,3 +276,57 @@ void print_wrapped_text(const char *text, int indent, int indent2, int width)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given a buffer and its encoding, return it re-encoded
|
||||||
|
* with iconv. If the conversion fails, returns NULL.
|
||||||
|
*/
|
||||||
|
#ifndef NO_ICONV
|
||||||
|
char *reencode_string(const char *in, const char *out_encoding, const char *in_encoding)
|
||||||
|
{
|
||||||
|
iconv_t conv;
|
||||||
|
size_t insz, outsz, outalloc;
|
||||||
|
char *out, *outpos, *cp;
|
||||||
|
|
||||||
|
if (!in_encoding)
|
||||||
|
return NULL;
|
||||||
|
conv = iconv_open(out_encoding, in_encoding);
|
||||||
|
if (conv == (iconv_t) -1)
|
||||||
|
return NULL;
|
||||||
|
insz = strlen(in);
|
||||||
|
outsz = insz;
|
||||||
|
outalloc = outsz + 1; /* for terminating NUL */
|
||||||
|
out = xmalloc(outalloc);
|
||||||
|
outpos = out;
|
||||||
|
cp = (char *)in;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
size_t cnt = iconv(conv, &cp, &insz, &outpos, &outsz);
|
||||||
|
|
||||||
|
if (cnt == -1) {
|
||||||
|
size_t sofar;
|
||||||
|
if (errno != E2BIG) {
|
||||||
|
free(out);
|
||||||
|
iconv_close(conv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* insz has remaining number of bytes.
|
||||||
|
* since we started outsz the same as insz,
|
||||||
|
* it is likely that insz is not enough for
|
||||||
|
* converting the rest.
|
||||||
|
*/
|
||||||
|
sofar = outpos - out;
|
||||||
|
outalloc = sofar + insz * 2 + 32;
|
||||||
|
out = xrealloc(out, outalloc);
|
||||||
|
outpos = out + sofar;
|
||||||
|
outsz = outalloc - sofar - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*outpos = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iconv_close(conv);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
6
utf8.h
6
utf8.h
@ -5,4 +5,10 @@ int utf8_width(const char **start);
|
|||||||
int is_utf8(const char *text);
|
int is_utf8(const char *text);
|
||||||
void print_wrapped_text(const char *text, int indent, int indent2, int len);
|
void print_wrapped_text(const char *text, int indent, int indent2, int len);
|
||||||
|
|
||||||
|
#ifndef NO_ICONV
|
||||||
|
char *reencode_string(const char *in, const char *out_encoding, const char *in_encoding);
|
||||||
|
#else
|
||||||
|
#define reencode_string(a,b,c) NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user