#include "mess822.h"
#include "str.h"
static stralloc tokens = {0};
static stralloc comment = {0};
static stralloc addr = {0};
static int state; /* 0: no address; 1: address without @; 2: address with @ */
static int docomment(out)
stralloc *out;
{
int i;
int j;
char ch;
for (j = i = 0;j < comment.len;++j) {
ch = comment.s[j];
if (ch == ' ') if (!i || (comment.s[i - 1] == ' ')) continue;
comment.s[i++] = ch;
}
while (i && (comment.s[i - 1] == ' ')) --i;
comment.len = 0;
if (i) {
if (!stralloc_0(out)) return 0;
if (!stralloc_catb(out,comment.s,i)) return 0;
if (!stralloc_append(out,"(")) return 0;
}
return 1;
}
static int doit(out)
stralloc *out;
{
int i;
if (!state) return 1;
if (!stralloc_0(out)) return 0;
if (state == 1)
if (!stralloc_append(out,"@")) return 0;
if (!stralloc_catb(out,addr.s,addr.len)) return 0;
if (!stralloc_append(out,"+")) return 0;
if (!docomment(out)) return 0;
state = 0;
addr.len = 0;
return 1;
}
static int addcomment(tok)
char *tok;
{
int i;
if (*tok == ',') return 1;
if (*tok == ':') return 1;
if (*tok == ';') return 1;
if (*tok == '<') return 1;
if (*tok == '>') return 1;
if ((*tok == '=') || (*tok == '(')) ++tok;
i = str_len(tok);
while (i--)
if (!stralloc_append(&comment,tok + i)) return 0;
return 1;
}
static int addaddr(tok)
char *tok;
{
int i;
if ((*tok != '=') && (*tok != '.') && (*tok != '@'))
return addcomment(tok);
if (!state) state = 1;
if (*tok == '@') state = 2;
if (*tok == '=') ++tok;
i = str_len(tok);
while (i--)
if (!stralloc_append(&addr,tok + i)) return 0;
return 1;
}
int mess822_addrlist(out,in)
stralloc *out;
char *in;
{
int flagwordok = 1;
int flagphrase = 0;
int j;
int i;
char ch;
if (!mess822_token(&tokens,in)) return 0;
if (!stralloc_copys(out,"")) return 0;
if (!stralloc_copys(&comment,"")) return 0;
if (!stralloc_copys(&addr,"")) return 0;
state = 0;
j = tokens.len;
while (j) {
while (j--) if (!j || !tokens.s[j - 1]) break;
ch = tokens.s[j];
if (flagphrase) {
if ((ch != ',') && (ch != ';') && (ch != ':') && (ch != '>')) {
if (!addcomment(tokens.s + j)) return 0;
continue;
}
if (!doit(out)) return 0;
flagphrase = 0;
flagwordok = 1;
}
switch(tokens.s[j]) {
case ' ': case '\t':
if (!addcomment(" ")) return 0;
break;
case ';': case ',':
if (!doit(out)) return 0;
if (!docomment(out)) return 0;
flagwordok = 1;
break;
case '(':
if (!addcomment(" ")) return 0;
if (!addcomment(tokens.s + j)) return 0;
if (!addcomment(" ")) return 0;
break;
case '=':
if (!flagwordok)
if (!doit(out)) return 0;
if (!addaddr(tokens.s + j)) return 0;
flagwordok = 0;
break;
case '>':
if (!doit(out)) return 0;
if (!state) state = 1; /* <> is an address */
for (;;) {
if (!addaddr(tokens.s + j)) return 0;
if (!j) break;
while (j--) if (!j || !tokens.s[j - 1]) break;
if (tokens.s[j] == ':') break;
if (tokens.s[j] == '<') break;
}
if (tokens.s[j] == ':')
for (;;) {
if (!addcomment(tokens.s + j)) return 0;
if (!j) break;
while (j--) if (!j || !tokens.s[j - 1]) break;
if (tokens.s[j] == '<') break;
}
/* fall through */
case ':':
flagphrase = 1;
break;
default:
if (!addaddr(tokens.s + j)) return 0;
flagwordok = 1;
break;
}
}
if (!doit(out)) return 0;
if (!docomment(out)) return 0;
i = 0;
j = out->len - 1;
while (i < j) {
ch = out->s[i];
out->s[i] = out->s[j];
out->s[j] = ch;
++i;
--j;
}
return 1;
}
syntax highlighted by Code2HTML, v. 0.9.1