git clone https://orangeshoelaces.net/git/tttm.git
Author: Vasily Kolobkov on 04/29/2016
Committer: Vasily Kolobkov on 04/29/2016
Parse message data responses
parse.c | 573 +++++++-
1 file changed, 562 insertions(+), 11 deletions(-)
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 */