#include "cache.h"
#include "config.h"
#include "utf8.h"
#include "strbuf.h"
#include "mailinfo.h"
static void cleanup_space(struct strbuf *sb)
{
size_t pos, cnt;
for (pos = 0; pos < sb->len; pos++) {
if (isspace(sb->buf[pos])) {
sb->buf[pos] = ' ';
for (cnt = 0; isspace(sb->buf[pos + cnt + 1]); cnt++);
strbuf_remove(sb, pos + 1, cnt);
}
}
}
static void get_sane_name(struct strbuf *out, struct strbuf *name, struct strbuf *email)
{
struct strbuf *src = name;
if (!name->len || 60 < name->len || strpbrk(name->buf, "@<>"))
src = email;
else if (name == out)
return;
strbuf_reset(out);
strbuf_addbuf(out, src);
}
static void parse_bogus_from(struct mailinfo *mi, const struct strbuf *line)
{
/* John Doe <johndoe> */
char *bra, *ket;
/* This is fallback, so do not bother if we already have an
* e-mail address.
*/
if (mi->email.len)
return;
bra = strchr(line->buf, '<');
if (!bra)
return;
ket = strchr(bra, '>');
if (!ket)
return;
strbuf_reset(&mi->email);
strbuf_add(&mi->email, bra + 1, ket - bra - 1);
strbuf_reset(&mi->name);
strbuf_add(&mi->name, line->buf, bra - line->buf);
strbuf_trim(&mi->name);
get_sane_name(&mi->name, &mi->name, &mi->email);
}
static const char *unquote_comment(struct strbuf *outbuf, const char *in)
{
int c;
int take_next_literally = 0;
strbuf_addch(outbuf, '(');
while ((c = *in++) != 0) {
if (take_next_literally == 1) {
take_next_literally = 0;
} else {
switch (c) {
case '\\':
take_next_literally = 1;
continue;
case '(':
in = unquote_comment(outbuf, in);
continue;
case ')':
strbuf_addch(outbuf, ')');
return in;
}
}
strbuf_addch(outbuf, c);
}
return in;
}
static const char *unquote_quoted_string(struct strbuf *outbuf, const char *in)
{
int c;
int take_next_literally = 0;
while ((c = *in++) != 0) {
if (take_next_literally == 1) {
take_next_literally = 0;
} else {
switch (c) {
case '\\':
take_next_literally = 1;
continue;
case '"':
return in;
}
}
strbuf_addch(outbuf, c);
}
return in;
}
static void unquote_quoted_pair(struct strbuf *line)
{
struct strbuf outbuf;
const char *in = line->buf;
int c;
strbuf_init(&outbuf, line->len);
while ((c = *in++) != 0) {
switch (c) {
case '"':
in = unquote_quoted_string(&outbuf, in);
continue;
case '(':
in = unquote_comment(&outbuf, in);
continue;
}
strbuf_addch(&outbuf, c);
}
strbuf_swap(&outbuf, line);
strbuf_release(&outbuf);
}
static void handle_from(struct mailinfo *mi, const struct strbuf *from)
{
char *at;
size_t el;
|