- if (strpbrk (value, specials)) {
- char tmp[256], *pc = tmp;
- size_t tmplen = sizeof (tmp) - 3;
-
- *pc++ = '"';
- for (; *value && tmplen > 1; value++) {
- if (*value == '\\' || *value == '"') {
- *pc++ = '\\';
- tmplen--;
- }
- *pc++ = *value;
- tmplen--;
+ static_buf comment = {"", 0};
+ static_buf phrase = {"", 0};
+
+ address_t **last = address_list_last(&top);
+ int ws_pending = 0;
+
+ for (;;) {
+ ws_pending = ISSPACE(*s);
+ s = skipspaces(s);
+
+ switch (*s) {
+ address_t *cur;
+
+ default:
+ if (ws_pending)
+ stbuf_append_sp(&phrase);
+ s = next_phrase(s, &phrase);
+ if (!s) {
+ address_delete(&top);
+ return NULL;
+ }
+ continue;
+
+ case '(':
+ stbuf_append_sp(&comment);
+ s = parse_comment(s + 1, &comment);
+ if (!s) {
+ address_delete(&top);
+ return NULL;
+ }
+ continue;
+
+
+ case '<':
+ cur = address_new();
+ if (phrase.len) {
+ /* if we get something like "Michael R. Elkins" remove the quotes */
+ cur->personal = rfc822_dequote_comment(&phrase);
+ }
+
+ s = parse_address(skipspaces(s + 1), &comment, cur);
+ if (!s || *s != '>' || !cur->mailbox) {
+ address_delete(&top);
+ address_delete(&cur);
+ return NULL;
+ }
+
+ *last = cur;
+ last = &(*last)->next;
+ break;
+
+ case ',':
+ last = rfc822_eotoken(last, &phrase, &comment);
+ break;
+
+ case ':': /* group start */
+ *last = address_new();
+ (*last)->mailbox = p_dupstr(phrase.buf, phrase.len);
+ (*last)->group = 1;
+ last = &(*last)->next;
+ break;
+
+ case ';':
+ last = rfc822_eotoken(last, &phrase, &comment);
+ /* add group terminator */
+ *last = address_new();
+ last = &(*last)->next;
+ break;
+
+ case '\0':
+ last = rfc822_eotoken(last, &phrase, &comment);
+ return top;
+ }
+
+ comment.len = phrase.len = 0;
+ s++;