+ switch (my_lex(buffer)) {
+ case LX_ATOM:
+ case LX_QSTR:
+ pers = add(buffer, add(" ", pers));
+ more_phrase: ; /* sigh (1) */
+ if (phrase(buffer) == NOTOK)
+ return NOTOK;
+
+ switch (last_lex) {
+ case LX_LBRK:
+ get_addr: ;
+ if (route_addr(buffer) == NOTOK)
+ return NOTOK;
+ if (last_lex == LX_RBRK)
+ return OK;
+ sprintf(err, "missing right-bracket (%s)", buffer);
+ return NOTOK;
+
+ case LX_COLN:
+ get_group: ;
+ if (glevel++ > 0) {
+ sprintf(err, "nested groups not allowed (%s)", pers);
+ return NOTOK;
+ }
+ grp = add(": ", pers);
+ pers = NULL;
+ {
+ char *pp = cp;
+
+ for (;;)
+ switch (my_lex(buffer)) {
+ case LX_SEMI:
+ case LX_END: /* tsk, tsk */
+ glevel--;
+ return OK;
+
+ case LX_COMA:
+ continue;
+
+ default:
+ cp = pp;
+ return parse_address();
+ }
+ }
+
+ case LX_DOT: /* sigh (1) */
+ pers = add(".", pers);
+ goto more_phrase;
+
+ default:
+ sprintf(err, "no mailbox in address, only a phrase (%s%s)", pers, buffer);
+ return NOTOK;
+ }
+
+ case LX_LBRK:
+ goto get_addr;
+
+ case LX_COLN:
+ goto get_group;
+
+ case LX_DOT:
+ mbox = add(buffer, pers);
+ pers = NULL;
+ if (route_addr(buffer) == NOTOK)
+ return NOTOK;
+ goto check_end;
+
+ case LX_AT:
+ ingrp = glevel;
+ mbox = pers;
+ pers = NULL;
+ if (domain(buffer) == NOTOK)
+ return NOTOK;
+ check_end: ;
+ switch (last_lex) {
+ case LX_SEMI:
+ if (glevel-- <= 0) {
+ strcpy(err, "extraneous semi-colon");
+ return NOTOK;
+ }
+ case LX_COMA:
+ case LX_END:
+ return OK;
+
+ default:
+ sprintf(err, "junk after local@domain (%s)", buffer);
+ return NOTOK;
+ }
+
+ case LX_SEMI: /* no host */
+ case LX_COMA:
+ case LX_END:
+ ingrp = glevel;
+ if (last_lex == LX_SEMI && glevel-- <= 0) {
+ strcpy(err, "extraneous semi-colon");
+ return NOTOK;
+ }
+ mbox = pers;
+ pers = NULL;
+ return OK;