tttm

git clone https://orangeshoelaces.net/git/tttm.git

e63e5c7099b0d540e7c3edc4619896c1e36d8198

Author: Vasily Kolobkov on 04/25/2016

Committer: Vasily Kolobkov on 04/25/2016

Flesh out mailbox productions

Stats

imap.c | 233 +++++++-
1 file changed, 208 insertions(+), 25 deletions(-)

Patch

diff --git a/imap.c b/imap.c
index 1cd9315..5374836 100644
--- a/imap.c
+++ b/imap.c
@@ -1,7 +1,7 @@
 /*
-  Be warned! All the parse_* functions and associates bear unconventional
-  call semantics returning 1 on success and 0 otherwise. Where applicable
-  specific error code or 0 is dispensed to the parse context.
+   Be warned! Most internal parser functions bear unconventional call
+   semantics returning 1 on success and 0 otherwise. Where applicable
+   specific error code or 0 is dispensed to the parse context.
 */
 
 #include <stdarg.h>
@@ -30,7 +30,7 @@ static struct literal {
 	{ BAD, "BAD", 3 },
 	{ BADCS, "BADCHARSET", 10 },
 	{ CAP, "CAPABILITY", 10 },
-	{ CBR, "]", 1 },
+	{ CBRACK, "]", 1 },
 	{ CPAR, ")", 1 },
 	{ DELETED, "\\Deleted", 8 },
 	{ DQUOTE, "\"", 1 },
@@ -41,7 +41,7 @@ static struct literal {
 	{ LIST, "LIST", 4 },
 	{ NIL, "NIL", 3 },
 	{ NO, "NO", 2 },
-	{ OBR, "[", 1 },
+	{ OBRACK, "[", 1 },
 	{ OK, "OK", 2 },
 	{ OPAR, "(", 1 },
 	{ PARSE, "PARSE", 5 },
@@ -73,31 +73,47 @@ union marker {
 		char  *tok;
 		size_t len;
 	} str;
+	struct {
+		char  *tok;
+		size_t len;
+	} lstr;
+	struct {
+		size_t iob;
+		size_t len;
+	} oblstr;
+	struct {
+		char  *tok;
+		size_t len;
+	} qstr;
+	struct {
+		size_t val;
+	} num;
 };
 
 enum { PE_OK, PE_PARSE, PE_NOTENMK };
 
 struct parse_ctx {
-	const char      *tok;
-	const char      *tokend;
-	size_t           toklen;
-	union marker    *pt;
-	union marker    *ptend;
-	size_t           ptlen;
+	const char   *tok;
+	const char   *tokend;
+	size_t        toklen;
+	union marker *pt;
+	union marker *ptend;
+	size_t        ptlen;
 	struct parse_cur cur;
-	int              e;
+	size_t        oblth;
+	int           e;
 };
 
 typedef int parsefn(struct parse_ctx *);
 
 int
-read_respln(struct imap_ctx imap, union marker *pt, size_t ptlen)
+read_respln(const char *tok, size_t toklen, union marker *pt,
+    size_t ptlen, size_t oblth)
 {
-	char *resp;
-	size_t resplen;
-	prepare_resp(imap, &resp, &resplen);
-	struct parse_ctx p = { resp, resplen, acts, actlen, { resp, acts } };
-	return parse_respln(&p);
+	struct parse_ctx p = { tok, tok + toklen, toklen, pt,
+	    pt + ptlen, ptlen, { tok, pt }, oblth, 0 };
+	parse_respln(&p);
+	return p->e;
 }
 
 int
@@ -239,10 +255,29 @@ parse_3xcombo(struct parse_ctx *p, int ilit1, int ilit2, parsefn *prod)
 	    parse_lit(p, ilit2) && prod(p) || rollback(p, &b);
 }
 
+int
+parse_3xcombor(struct parse_ctx *p, parsefn *prod, int ilit1, int ilit2)
+{
+	struct parse_cur b;
+
+	return chkpoint(p, &b) && prod(p) && parse_lit(p, ilit1) &&
+	    parse_lit(p, ilit2) || rollback(p, &b);
+}
+
 /*
   IMAP parsers
 */
 
+int
+parse_astring(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return intbeg(p, &b, MK_ASTRING) &&
+	    (parse_repchr(p, astr_specials, MK_ASTRLIT) || parse_string(p)) &&
+	    intend(p, &b) || rollback(p, &b);
+}
+
 int
 parse_atom(struct parse_ctx *p)
 {
@@ -400,6 +435,12 @@ parse_mbdata(struct parse_ctx *p)
 	    parse_mbrecent(p);
 }
 
+int
+parse_mbexists(struct parse_ctx *p)
+{
+	return parse_3xcombor(p, parse_number, SP, EXISTS);
+}
+
 int
 parse_mbflags(struct parse_ctx *p)
 {
@@ -417,17 +458,106 @@ parse_mblist(struct parse_ctx *p)
 	struct parse_cur b;
 
 	return chkpoint(p, &b) && parse_lit(p, LIST) &&
-	    parse_lit(p, SP) && parse_lit(p, OPAR) &&
+	    parse_lit(p, SP) && parse_mblistdata(p) ||
+	    rollback(p, &b);
+}
+
+int
+parse_mblistdata(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return chkpoint(p, &b) && parse_lit(p, OPAR) &&
 	    (parse_list(p, parse_mblistfl) || opt(p)) &&
-	    parse_list(p, CPAR) && parse_lit(p, SP) &&
+	    parse_lit(p, CPAR) && parse_lit(p, SP) &&
 	    (parse_dquotedchar(p) || parse_lit(NIL)) &&
-	    parse_lit(p, SP) && parse_mailbox(p) || rollback(p);
+	    parse_lit(p, SP) && parse_mailbox(p) || rollback(p, &b);
 }
 
+/*
+   TODO: will 1*(SFL|OFL) with a soundness check afterwards
+   be simpler and more readable?
+*/
 int
 parse_mblistfl(struct parse_ctx *p)
 {
-	/* nice to meet you, `next thing to do after morning coffee' */
+	return parse_mblistosfl(p) || parse_list(p, parse_mblistofl);
+}
+
+int
+parse_mblistofl(struct parse_ctx *p)
+{
+	return parse_lit(p, NOINFERIORS) || parse_flext(p);
+}
+
+int
+parse_mblistosfl(struc parse_ctx *p)
+{
+	int res;
+	struct parse_cur b;
+
+	checkpoint(p, &b);
+
+	res = parse_list(p, parse_mblistofl) &&
+	    parse_lit(p, SP) || rollback(p, &b) || opt(p);
+
+	res = res && parse_mblistsfl(p);
+
+	res = res && chkpoint(p, &s) && parse_lit(p, SP) &&
+	    parse_list(p, parse_mblistofl) || rollback(p, &s) || opt(p);
+
+	return res || rollback(p, &b);
+}
+
+int
+parse_mblistsfl(struct parse_ctx *p)
+{
+	return parse_lit(p, NOSEL) || parse_lit(p, MARKED) ||
+	    parse_lit(p, UNMARKED);
+}
+
+int
+parse_mblsub(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return chkpoint(p, &b) && parse_lit(p, LSUB) &&
+	    parse_lit(p, SP) && parse_mblistdata(p) ||
+	    rollback(p, &b);
+}
+
+int
+parse_mbrecent(struct parse_ctx *p)
+{
+	return parse_3xcombor(p, parse_number, SP, RECENT);
+}
+
+int
+parse_mbsearch(struct parse_ctx *p)
+{
+	struct parse_cur b, o;
+
+	return chkpoint(p, &b) && parse_lit(p, SEARCH) &&
+	    (chkpoint(p, &o) && parse_lit(p, SP) &&
+	    parse_list(p, parse_nznumber) || rollback(p, &o) || opt(p)) ||
+	    rollback(p, &b);
+}
+
+int
+parse_mbstatus(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return chkpoint(p, &b) && parse_lit(p, STATUS) && parse_lit(p, SP) &&
+	    parse_mailbox(p) && parse_lit(p, SP) && parse_lit(p, OPAR) &&
+	    (parse_list(p, parse_stattrec) || opt(p)) && parse_lit(p, CPAR) ||
+	    rollback(p, &b);
+}
+
+int
+parse_number(struct parse_ctx *p)
+{
+	/* DO ME */
 }
 
 int
@@ -489,6 +619,16 @@ parse_quotedcharclean(struct parse_ctx *p)
 	return !p->e;
 }
 
+int
+parse_quotstr(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return intbeg(p, &b, MK_QUOTSTR) && parse_lit(p, DQUOTE) &&
+	    (parse_rep(p, parse_quotedchar) || opt(p)) &&
+	    parse_lit(p, DQUOTE) || rollback(p, &b);
+}
+
 int
 parse_respbye(struct parse_ctx *p)
 {
@@ -531,13 +671,14 @@ parse_respstate(struct parse_ctx *p)
 int
 parse_resptext(struct parse_ctx *p)
 {
+	int res;
 	struct parse_cur b;
 
-	chkpoint(p, &b) && parse_lit(p, OBR) &&
-	    parse_resptextcode(p) && parse_lit(p, CBR) &&
+	res = chkpoint(p, &b) && parse_lit(p, OBRACK) &&
+	    parse_resptextcode(p) && parse_lit(p, CBRACK) &&
 	    parse_lit(p, SP) || rollback(p, &b) || opt(p);
 
-	return parse_text(p);
+	return res && parse_text(p);
 }
 
 int
@@ -551,6 +692,29 @@ parse_resptextcode(struct parse_ctx *p)
 	    parse_unseencode(p) || parse_gencode(p);
 }
 
+int
+parse_statt(struct parse_ctx *p)
+{
+	return parse_lit(p, MESSAGES) || parse_lit(p, RECENT) ||
+	    parse_lit(p, UIDNEXT) || parse_lit(p, UIDVAL) ||
+	    parse_lit(p, UNSEEN);
+}
+
+int
+parse_stattrec(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return chkpoint(p, &b) && parse_statt(p) && parse_lit(p, SP) &&
+	    parse_number(p) || rollback(p, &b);
+}
+
+int
+parse_string(struct parse_ctx *p)
+{
+	return parse_qoutstr(p) || parse_litstr(p);
+}
+
 int
 parse_tag(struct parse_ctx *p)
 {
@@ -593,6 +757,25 @@ parse_lit(int i, struct parse_ctx *p)
 	return !p->e;
 }
 
+int
+parse_litstr(struct parse_ctx *p)
+{
+	int res;
+	size_t len;
+	struct parse_cur b;
+
+	res = intbeg(p, MK_LITSTR, &b) && par_lit(p, OBRACE) &&
+	    par_number(p) && par_lit(p, CBRACE) && par_lit(p, EOL) &&
+	    intend(p, &b) || rollback(p, &b);
+
+	if (res) {
+		len = b.pt[4].num.val;
+		if (len < p->oblth)
+			p->cur.tok += len;
+	}
+	return res;
+}
+
 int
 parse_uidncode(struct parse_ctx *p)
 {