git clone https://orangeshoelaces.net/git/tttm.git
Author: Vasily Kolobkov on 04/25/2016
Committer: Vasily Kolobkov on 04/25/2016
Flesh out mailbox productions
imap.c | 233 +++++++-
1 file changed, 208 insertions(+), 25 deletions(-)
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)
{