tttm

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

77107bff270db2079a9ab2132106169d93c99644

Author: Vasily Kolobkov on 04/29/2016

Committer: Vasily Kolobkov on 04/29/2016

Parse message data responses

Stats

parse.c | 573 +++++++-
1 file changed, 562 insertions(+), 11 deletions(-)

Patch

diff --git a/parse.c b/parse.c
index af2e702..abc1ac6 100644
--- a/parse.c
+++ b/parse.c
@@ -8,8 +8,6 @@
 
 #include "parse.h"
 
-#define LEN(x) (sizeof x / sizeof x[0])
-
 static struct literal {
 	enum { OK, NO, BAD, SP } kind;
 	char  *val;
@@ -151,6 +149,16 @@ p_list(struct parse_ctx *p, parsefn *prod)
 	return res && p_opt(p);
 }
 
+int
+p_listsep(struct parse_ctx *p, parsefn *prod, int sep)
+{
+	int res;
+
+	for(res = prod(p); res && p_2xcombo(p, sep, prod);)
+		;
+	return res && p_opt(p);
+}
+
 /* 1*prod */
 int
 p_rep(struct parse_ctx *p, parsefn *prod)
@@ -207,7 +215,7 @@ p_3xcombo(struct parse_ctx *p, int lit1, int lit2, parsefn *prod)
 }
 
 int
-p_3xcombor(struct parse_ctx *p, parsefn *prod, int lit1, int lit2)
+p_r3xcombo(struct parse_ctx *p, parsefn *prod, int lit1, int lit2)
 {
 	struct parse_cur b;
 
@@ -215,17 +223,36 @@ p_3xcombor(struct parse_ctx *p, parsefn *prod, int lit1, int lit2)
 	    p_lit(p, lit2) || p_rwd(p, &b);
 }
 
+int
+p_sss(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_str(p) && p_sp(p) && p_str(p) ||
+	    p_rwd(p, &b);
+}
+
 /*
   IMAP parsers
 */
 
 int
-p_astring(struct parse_ctx *p)
+p_addr(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_opar(p) && p_nstr(p) && p_sp(p) &&
+	    p_nstr(p) && p_sp(p) && p_nstr(p) && p_sp(p) &&
+	    p_nstr(p) && p_cpar(p) || p_rwd(p, &b);
+}
+
+int
+p_astr(struct parse_ctx *p)
 {
 	struct parse_cur b;
 
 	return p_beg(p, &b, PR_ASTRING) &&
-	    (p_repchr(p, astr_specials, PN_STR) || p_string(p)) &&
+	    (p_repchr(p, astr_specials, PN_STR) || p_str(p)) &&
 	    p_end(p, &b) || p_rwd(p, &b);
 }
 
@@ -258,13 +285,197 @@ p_badcsopt(struct parse_ctx *p)
 	struct parse_cur b;
 
 	return p_chk(p, &b) && p_sp(p) && p_opar(p) &&
-	    p_list(p, parse_astring) && p_cpar(p) || p_rwd(p, &b);
+	    p_list(p, parse_astr) && p_cpar(p) || p_rwd(p, &b);
 }
 
 int
 p_base64(struct parse_ctx *p)
 {
-	/* DO ME */
+	/* you won't get far w/o b64 */
+}
+
+int
+p_body(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_opar(p) && (p_body1pt(p) ||
+	    p_bodympt(p)) && p_cpar(p) || p_rwd(p, &b);
+}
+
+int
+p_body1pt(struct parse_ctx *p)
+{
+	struct parse_cur b, o;
+
+	return p_chk(p, &b) &&
+	    (p_bodybas(p) || p_bodymsg(p) || p_bodytxt(p)) &&
+	    (p_chk(p, &o) && p_sp(p) && p_bodyx1pt(p) ||
+	    p_rwd(p, &o) || p_opt(p)) || p_rwd(p, &b);
+}
+
+int
+p_bodybas(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_medbas(p) && p_sp(p) &&
+	    p_bodyf(p) || p_rwd(p, &b);
+}
+
+int
+p_bodyext(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_nstr(p) || p_num(p) ||
+	    (p_opar(p) && p_list(p, p_bodyext) && p_cpar(p)) ||
+	    p_rwd(p, &b);
+}
+
+int
+p_bodyf(struct parse_ctx *p)
+{
+	return p_chk(p, &b) && p_bodyfpar(p) && p_sp(p) &&
+	    p_bodyfid(p) && p_sp(p) && p_bodyfdes(p) && p_sp(p) &&
+	    p_bodyfenc(p) && p_sp(p) && p_bodyfoct(p) || p_rwd(p, &b);
+}
+
+int
+p_bodyfdes(struct parse_ctx *p)
+{
+	return p_nstr(p);
+}
+
+int
+p_bodyfdsp(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && (p_opar(p) && p_str(p) && p_sp(p) &&
+	    p_bodyfpar(p) && p_cpar(p) || p_rwd(p, &b)) || p_lit(p, NIL);
+}
+
+int
+p_bodyfenc(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && (p_dquote(p) && (p_lit(p, 7BIT) ||
+	    p_lit(p, 8BIT) || p_lit(p, BIN) || p_lit(p, B64) ||
+	    p_lit(p, QPRN)) && p_dquote(p) || p_rwd(p, &b)) ||
+	    p_str(p);
+}
+
+int
+p_bodyfid(struct parse_ctx *p)
+{
+	return p_nstr(p);
+}
+
+int
+p_bodyflan(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_nstr(p) || (p_opar(p) &&
+	    p_list(p, p_str) && p_cpar(p) || p_rwd(p, &b));
+}
+
+int
+p_bodyflin(struct parse_ctx *p)
+{
+	return p_num(p);
+}
+
+int
+p_bodyfloc(struct parse_ctx *p)
+{
+	return p_nstr(p);
+}
+
+int
+p_bodyfmd5(struct parse_ctx *p)
+{
+	return p_nstr(p);
+}
+
+int
+p_bodyfoct(struct parse_ctx *p)
+{
+	return p_num(p);
+}
+
+int
+p_bodyfpar(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && (p_opar(p) && p_list(p, p_sss) &&
+	    p_cpar(p) || p_rwd(p, &b)) || p_lit(p, NIL);
+}
+
+int
+p_bodympt(struct parse_ctx *p)
+{
+	struct parse_cur b, o;
+
+	return p_chk(p, &b) && p_rep(p, p_body) && p_sp(p) &&
+	    p_medsubt(p) && (p_chk(p, &o) && p_sp(p) && p_bodyxmpt(p) ||
+	    p_rwd(p, &o) || p_opt(p)) || p_rwd(p, &b);
+}
+
+int
+p_bodymsg(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_medmsg(p) && p_sp(p) && p_bodyf(p) &&
+	    p_sp(p) && p_env(p) && p_sp(p) && p_body(p) && p_sp(p) &&
+	    p_bodyflin(p) || p_rwd(p, &b);
+}
+
+int
+p_bodytxt(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_medtxt(p) && p_sp(p) && p_bodyf(p) &&
+	    p_sp(p) && p_bodyflin(p) || p_rwd(p, &b);
+}
+
+int
+p_bodyx1pt(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_bodyfmd5(p) &&
+	    p_bodyxcmn(p) || p_rwd(p, &b);
+}
+
+/* TODO: this one's extra gross, prob needs a good factoring */
+int
+p_bodyxcmn(struct parse_ctx *p)
+{
+	struct parse_cur o1, o2, o3, o4;
+
+	return p_chk(p, &o1) && p_sp(p) && p_bodyfdsp(p) &&
+	    (p_chk(p, &o2) && p_sp(p) && p_bodyflan(p) &&
+	    (p_chk(p, &o3) && p_sp(p) && p_bodyfloc(p) &&
+	    (p_chk(p, &o4) && p_sp(p) && p_list(p, p_bodyext) ||
+	    p_rwd(p, &o4) || p_opt(p)) ||
+	    p_rwd(p, &o3) || p_opt(p)) ||
+	    p_rwd(p, &o2) || p_opt(p)) ||
+	    p_rwd(p, &o1) || p_opt(p);
+}
+
+int
+p_bodyxmpt(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_bodyfpar(p) &&
+	    p_bodyxcmn(p) || p_rwd(p, &b);
 }
 
 int
@@ -297,6 +508,26 @@ p_contreq(struct parse_ctx *p)
 	    p_lit(p, EOL) || p_rwd(p, &b);
 }
 
+int
+p_datetime(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_dquote(p) && p_dayfix(p) &&
+	    p_lit(p, MINUS) && p_month(p) && p_lit(p, MINUS) &&
+	    p_year(p) && p_sp(p) && p_time(p) && p_sp(p) && p_zone(p) &&
+	    p_dquote(p) || p_rwd(p, &b);
+}
+
+int
+p_dayfix(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_sp(p) && p_dig(p, 1) ||
+	    p_rwd(p, &b) || p_dig(p, 2);
+}
+
 int
 p_dquotedchar(struct parse_ctx *p)
 {
@@ -307,6 +538,88 @@ p_dquotedchar(struct parse_ctx *p)
 	    p_rwd(p, &b);
 }
 
+int
+p_env(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_opar(p) && p_envdate(p) && p_sp(p) &&
+	    p_envsubj(p) && p_sp(p) && p_envfrom(p) && p_sp(p) &&
+	    p_envsender(p) && p_sp(p) && p_envrepto(p) && p_sp(p) &&
+	    p_envto(p) && p_sp(p) && p_envcc(p) && p_sp(p) &&
+	    p_envbcc(p) && p_sp(p) && p_envinrepto(p) && p_sp(p) &&
+	    p_envmsgid(p) && p_cpar(p) || p_rwd(p, &b);
+}
+
+int
+p_envaddr(struct parse_ctx *p, int prod)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_opar(p) && p_rep(p, p_addr) && p_cpar(p) ||
+	    p_rwd(p, &b) || p_lit(p, NIL);
+}
+
+int
+p_envbcc(struct parse_ctx *p)
+{
+	return p_envaddr(p, PR_ENVBCC);
+}
+
+int
+p_envcc(struct parse_ctx *p)
+{
+	return p_envaddr(p, cc);
+}
+
+int
+p_envdate(struct parse_ctx *p)
+{
+	return p_nstr(p);
+}
+
+int
+p_envfrom(struct parse_ctx *p)
+{
+	return p_envaddr(p, PR_ENVFROM)
+}
+
+int
+p_envinrepto(struct parse_ctx *p)
+{
+	return p_nstr(p);
+}
+
+int
+p_envmsgid(struct parse_ctx *p)
+{
+	return p_nstr(p);
+}
+
+int
+p_envrepto(struct parse_ctx *p)
+{
+	return p_envaddr(p, PR_ENVREPTO)
+}
+
+int
+p_envsender(struct parse_ctx *p)
+{
+	return p_envaddr(p, PR_ENVSENDER)
+}
+
+int
+p_envsubj(struct parse_ctx *p)
+{
+	return p_nstr(p);
+}
+
+int
+p_envto(struct parse_ctx *p)
+{
+	return p_envaddr(p, PR_ENVTO)
+}
+
 int
 p_escqspec(struct parse_ctx *p)
 {
@@ -317,6 +630,15 @@ p_escqspec(struct parse_ctx *p)
 	    p_rwd(p, &b);
 }
 
+int
+p_fetchrec(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_lit(p, FETCH) && p_sp(p) &&
+	    p_opar(p) && p_list(p, p_msgatt) && p_cpar(p) || p_rwd(p, &b);
+}
+
 int
 p_flag(struct parse_ctx *p)
 {
@@ -335,6 +657,12 @@ p_flext(struct parse_ctx *p)
 	    p_atom(p) || p_rwd(p, &b);
 }
 
+int
+p_flfetch(struct parse_ctx *p)
+{
+	return p_flag(p) || p_lit(p, FLRECENT);
+}
+
 int
 p_flkeyword(struct parse_ctx *p)
 {
@@ -371,6 +699,21 @@ p_genctext(struct parse_ctx *p)
 	return res;
 }
 
+int
+p_hdrfname(struct parse_ctx *p)
+{
+	return p_astr(p);
+}
+
+int
+p_hdrlist(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_opar(p) && p_list(p, p_hdrfname) &&
+	    p_cpar(p) || p_rwd(p, &b);
+}
+
 int
 p_lit(struct parse_ctx *p, int lit)
 {
@@ -419,7 +762,62 @@ p_litstr(struct parse_ctx *p)
 int
 p_mailbox(struct parse_ctx *p)
 {
-	return p_lit(p, INBOX) || p_astring(p);
+	return p_lit(p, INBOX) || p_astr(p);
+}
+
+int
+p_matbody(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_lit(p, BODY) &&
+	    (p_lit(p, STRUCT) || p_opt(p)) && p_sp(p) &&
+	    p_body(p) || p_rwd(p, &b);
+}
+
+int
+p_matbsect(struct parse_ctx *p)
+{
+	struct parse_cur b, o;
+
+	return p_chk(p, &b) && p_lit(p, BODY) && p_section(p) &&
+	    (p_chk(p, &o) && p_lit(p, LT) && p_num(p) && p_lit(p, GT) ||
+	    p_rwd(p, &o) || p_opt(p)) && p_sp(p) && p_nstr(p) || p_rwd(p, &b);
+}
+
+int
+p_matenv(struct parse_ctx *p)
+{
+	return p_3xcombo(p, EVELOPE, SP, p_env);
+}
+
+int
+p_mathdrotxt(struct parse_ctx *p)
+{
+	struct parse_cur b, o;
+
+	return p_chk(p, &b) && p_lit(p, RFC822) &&
+	    (p_chk(p, &o) && p_lit(p, DHDR) || p_lit(p, DTXT) ||
+	    p_rwd(p, &o) || p_opt(p)) && p_sp(p) && p_nstr(p) ||
+	    p_rwd(p, &b);
+}
+
+int
+p_matintdate(struct parse_ctx *p)
+{
+	return p_3xcombo(p, INTDATE, SP, p_datetime);
+}
+
+int
+p_matsize(struct parse_ctx *p)
+{
+	return p_3xcombo(p, RFC822SIZE, SP, p_num);
+}
+
+int
+p_matuid(struct parse_ctx *p)
+{
+	return p_3xcombo(p, UID, SP, p_uid);
 }
 
 int
@@ -434,7 +832,7 @@ p_mbdata(struct parse_ctx *p)
 int
 p_mbexists(struct parse_ctx *p)
 {
-	return p_3xcombor(p, parse_number, SP, EXISTS);
+	return p_r3xcombo(p, parse_number, SP, EXISTS);
 }
 
 int
@@ -525,7 +923,7 @@ p_mblsub(struct parse_ctx *p)
 int
 p_mbrecent(struct parse_ctx *p)
 {
-	return p_3xcombor(p, parse_number, SP, RECENT);
+	return p_r3xcombo(p, parse_number, SP, RECENT);
 }
 
 int
@@ -550,6 +948,87 @@ p_mbstatus(struct parse_ctx *p)
 	    p_rwd(p, &b);
 }
 
+int
+p_medbas(struct parse_ctx *p)
+{
+	return p_chk(p, &b) && (p_dquote(p) &&
+	    (p_lit(p, APP) || p_lit(p, AUDIO) || p_lit(p, IMG) ||
+	    p_lit(p, MSG) || p_lit(p, VIDEO)) && p_dquote(p) ||
+	    (p_rwd(p, &b) || p_str(p))) &&
+	    p_sp(p) && p_medsubt(p) || p_rwd(p, &b);
+}
+
+int
+p_medmsg(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) &&
+	    p_dquote(p) && p_lit(p, MSG) && p_dquote(p) && p_sp(p) &&
+	    p_dquote(p) && p_lit(p, RFC822) && p_dquote(p) || p_rwd(p, &b);
+}
+
+int
+p_medsubt(struct parse_ctx *p)
+{
+	return p_str(p);
+}
+
+int
+p_medtxt(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_dquote(p) && p_lit(p, TXT) && p_dquote(p) &&
+	    p_sp(p) && p_medsubt(p) || p_rwd(p, &b);
+}
+
+int
+p_month(struct parse_ctx *p)
+{
+	return p_lit(p, JAN) || p_lit(p, FEB) || p_lit(p, MAR) ||
+	    p_lit(p, APR) || p_lit(p, MAY) || p_lit(p, JUN) ||
+	    p_lit(p, JUL) || p_lit(p, AUG) || p_lit(p, SEP) ||
+	    p_lit(p, OCT) || p_lit(p, NOV) || p_lit(p, DEC);
+}
+
+int
+p_msgdata(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_nznum(p) && p_sp(p) &&
+	    (p_lit(p, EXPUNGE) || p_fetchrec(p)) || p_rwd(p, &b);
+}
+
+int
+p_msgatt(struct parse_ctx *p)
+{
+	return p_msgattstat(p) || p_msgattdyn(p);
+}
+
+int
+p_msgattdyn(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_lit(p, FLAGS) && p_sp(p) && p_opar(p) &&
+	    (p_list(p, p_flfetch) || p_opt(p)) && p_cpar(p) || p_rwd(p, &b);
+}
+
+int
+p_msgattstat(struct parse_ctx *p)
+{
+	return p_matenv(p) || p_matintdate(p) || p_mathdrotxt(p) ||
+	    p_matsize(p) || p_matbody(p) || p_matbsect(p) || p_matuid(p);
+}
+
+int
+p_nstr(struct parse_ctx *p)
+{
+	return p_str(p) || p_lit(p, NIL);
+}
+
 int
 p_number(struct parse_ctx *p)
 {
@@ -685,6 +1164,48 @@ p_resptextcode(struct parse_ctx *p)
 	    p_unseencode(p) || p_gencode(p);
 }
 
+int
+p_secmsgtxt(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_lit(p, HEADER) ||
+	    (p_lit(p, HDRFLDS) && (p_lit(p, DNOT) || p_opt(p)) &&
+	    p_sp(p) && p_hdrlist(p) || p_rwd(p, &b)) || p_lit(p, TXT);
+}
+
+int
+p_secpt(struct parse_ctx *p)
+{
+	return p_listsep(p, p_nznum, DOT);
+}
+
+int
+p_secspec(struct parse_ctx *p)
+{
+	struct parse_cur b, o;
+
+	return p_chk(p, &b) && p_secmsgtxt(p) || (p_secpt(p) &&
+	    (p_chk(p, &o) && p_lit(p, DOT) && p_sectxt(p) ||
+	    p_rwd(p, &o) || p_opt(p))) || p_rwd(p, &b);
+}
+
+int
+p_section(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_lit(p, OBRACK) &&
+	    (p_secspec(p) || p_opt(p)) &&
+	    p_lit(p, CBRACK) || p_rwd(p, &b);
+}
+
+int
+p_sectxt(struct parse_ctx *p)
+{
+	return p_secmsgtxt(p) || p_lit(p, MIME);
+}
+
 int
 p_statt(struct parse_ctx *p)
 {
@@ -703,7 +1224,7 @@ p_stattrec(struct parse_ctx *p)
 }
 
 int
-p_string(struct parse_ctx *p)
+p_str(struct parse_ctx *p)
 {
 	return p_qoutstr(p) || p_litstr(p);
 }
@@ -723,6 +1244,21 @@ p_taggedresp(struct parse_ctx *p)
 	    p_respstate(p) && p_eol(p) || p_rwd(p, &b);
 }
 
+int
+p_time(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && p_dig(p, 2) && p_lit(p, COLON) &&
+	    p_dig(p, 2) && p_lit(p, COLON) && p_dig(p, 2) || p_rwd(p, &b);
+}
+
+int
+p_uid(struct parse_ctx *p)
+{
+	return p_nznumber(p);
+}
+
 int
 p_uidncode(struct parse_ctx *p)
 {
@@ -741,6 +1277,21 @@ p_unseencode(struct parse_ctx *p)
 	return p_3xcombo(UNSEEN, SP, parse_nznumber);
 }
 
+int
+p_year(struct parse_ctx *p)
+{
+	return p_dig(p, 4);
+}
+
+int
+p_zone(struct parse_ctx *p)
+{
+	struct parse_cur b;
+
+	return p_chk(p, &b) && (p_lit(p, PLUS) || p_lit(p, MINUS)) &&
+	    p_dig(p, 4) || p_rwd(p, &b);
+}
+
 /* shortcuts for some common literals and means
    of imrpoving legibility of bulky productions */