dovecot-2.0: Added support for mail search input parsers. dovead...

dovecot at dovecot.org dovecot at dovecot.org
Tue Apr 20 14:57:41 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/4a98f01eaaac
changeset: 11175:4a98f01eaaac
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Apr 20 14:57:19 2010 +0300
description:
Added support for mail search input parsers. doveadm now uses command line parser.

diffstat:

 src/doveadm/Makefile.am                      |    3 +-
 src/doveadm/doveadm-mail-fetch.c             |   51 +-----
 src/imap/imap-search-args.c                  |   11 +-
 src/lib-storage/Makefile.am                  |    5 +
 src/lib-storage/mail-search-build.c          |  133 +++++++---------
 src/lib-storage/mail-search-build.h          |   29 +--
 src/lib-storage/mail-search-parser-cmdline.c |   98 ++++++++++++
 src/lib-storage/mail-search-parser-imap.c    |  122 +++++++++++++++
 src/lib-storage/mail-search-parser-private.h |   22 ++
 src/lib-storage/mail-search-parser.c         |   49 ++++++
 src/lib-storage/mail-search-parser.h         |   34 ++++
 src/lib-storage/mail-search-register-human.c |   45 ++---
 src/lib-storage/mail-search-register-imap.c  |  251 +++++++++++++------------------
 src/lib-storage/mail-search-register.h       |   10 +-
 src/plugins/virtual/virtual-config.c         |   23 +-
 15 files changed, 561 insertions(+), 325 deletions(-)

diffs (truncated from 1522 to 300 lines):

diff -r 422ab02950b7 -r 4a98f01eaaac src/doveadm/Makefile.am
--- a/src/doveadm/Makefile.am	Mon Apr 19 16:53:15 2010 +0300
+++ b/src/doveadm/Makefile.am	Tue Apr 20 14:57:19 2010 +0300
@@ -20,7 +20,8 @@
 if !BUILD_SHARED_LIBS
 unused_objects = \
 	../lib/mountpoint.o \
-	../lib-imap/imap-util.o
+	../lib-imap/imap-util.o \
+	../lib-storage/mail-search-parser-imap.o
 endif
 
 cmd_pw_libs = \
diff -r 422ab02950b7 -r 4a98f01eaaac src/doveadm/doveadm-mail-fetch.c
--- a/src/doveadm/doveadm-mail-fetch.c	Mon Apr 19 16:53:15 2010 +0300
+++ b/src/doveadm/doveadm-mail-fetch.c	Tue Apr 20 14:57:19 2010 +0300
@@ -6,60 +6,25 @@
 #include "base64.h"
 #include "randgen.h"
 #include "str.h"
-#include "imap-quote.h"
-#include "imap-parser.h"
 #include "mail-storage.h"
 #include "mail-search-build.h"
+#include "mail-search-parser.h"
 #include "doveadm-mail.h"
 
-static struct mail_search_args *search_args_from_str(const char *str)
+static struct mail_search_args *build_search_args(const char *const args[])
 {
-	struct istream *input;
-	struct imap_parser *parser;
-	const struct imap_arg *args;
+	struct mail_search_parser *parser;
 	struct mail_search_args *sargs;
 	const char *error;
-	bool fatal;
-	int ret;
 
-	input = i_stream_create_from_data(str, strlen(str));
-	(void)i_stream_read(input);
-
-	parser = imap_parser_create(input, NULL, (size_t)-1);
-	ret = imap_parser_finish_line(parser, 0,  0, &args);
-	if (ret < 0)
-		i_fatal("%s", imap_parser_get_error(parser, &fatal));
-	if (mail_search_build_from_imap_args(mail_search_register_human,
-					     args, "UTF-8", &sargs, &error) < 0)
+	parser = mail_search_parser_init_cmdline(args);
+	if (mail_search_build(mail_search_register_human, parser, "UTF-8",
+			      &sargs, &error) < 0)
 		i_fatal("%s", error);
-
-	imap_parser_destroy(&parser);
-	i_stream_destroy(&input);
+	mail_search_parser_deinit(&parser);
 	return sargs;
 }
 
-static const char *params_to_imap_args_string(const char *const args[])
-{
-	string_t *str;
-	const char *p;
-
-	str = t_str_new(256);
-	for (; *args != NULL; args++) {
-		for (p = *args; *p != '\0'; p++) {
-			if (IS_ATOM_SPECIAL_INPUT(*p))
-				break;
-		}
-		if (*p == '\0' ||
-		    strcmp(*args, "(") == 0 ||
-		    strcmp(*args, ")") == 0)
-			str_append(str, *args);
-		else
-			imap_dquote_append(str, *args);
-		str_append_c(str, ' ');
-	}
-	return str_c(str);
-}
-
 void cmd_fetch(struct mail_user *user, const char *const args[])
 {
 	const char *mailbox = args[0];
@@ -77,7 +42,7 @@
 
 	if (mailbox == NULL || args[1] == NULL)
 		doveadm_mail_help_name("fetch");
-	search_args = search_args_from_str(params_to_imap_args_string(args+1));
+	search_args = build_search_args(args+1);
 
 	random_fill_weak(prefix_buf, sizeof(prefix_buf));
 	prefix = t_str_new(32);
diff -r 422ab02950b7 -r 4a98f01eaaac src/imap/imap-search-args.c
--- a/src/imap/imap-search-args.c	Mon Apr 19 16:53:15 2010 +0300
+++ b/src/imap/imap-search-args.c	Tue Apr 20 14:57:19 2010 +0300
@@ -2,6 +2,7 @@
 
 #include "imap-common.h"
 #include "mail-storage.h"
+#include "mail-search-parser.h"
 #include "mail-search-build.h"
 #include "imap-search-args.h"
 #include "imap-parser.h"
@@ -39,17 +40,21 @@
 			   const struct imap_arg *args, const char *charset,
 			   struct mail_search_args **search_args_r)
 {
+	struct mail_search_parser *parser;
 	struct mail_search_args *sargs;
 	const char *error;
+	int ret;
 
 	if (IMAP_ARG_IS_EOL(args)) {
 		client_send_command_error(cmd, "Missing search parameters");
 		return -1;
 	}
 
-	if (mail_search_build_from_imap_args(mail_search_register_imap,
-					     args, charset,
-					     &sargs, &error) < 0) {
+	parser = mail_search_parser_init_imap(args);
+	ret = mail_search_build(mail_search_register_imap, parser, charset,
+				&sargs, &error);
+	mail_search_parser_deinit(&parser);
+	if (ret < 0) {
 		client_send_command_error(cmd, error);
 		return -1;
 	}
diff -r 422ab02950b7 -r 4a98f01eaaac src/lib-storage/Makefile.am
--- a/src/lib-storage/Makefile.am	Mon Apr 19 16:53:15 2010 +0300
+++ b/src/lib-storage/Makefile.am	Tue Apr 20 14:57:19 2010 +0300
@@ -22,6 +22,9 @@
 	mail-namespace.c \
 	mail-search.c \
 	mail-search-build.c \
+	mail-search-parser.c \
+	mail-search-parser-imap.c \
+	mail-search-parser-cmdline.c \
 	mail-search-register.c \
 	mail-search-register-human.c \
 	mail-search-register-imap.c \
@@ -47,6 +50,8 @@
 	mail-search-register.h \
 	mail-thread.h \
 	mail-storage.h \
+	mail-search-parser.h \
+	mail-search-parser-private.h \
 	mail-storage-private.h \
 	mail-storage-hooks.h \
 	mail-storage-service.h \
diff -r 422ab02950b7 -r 4a98f01eaaac src/lib-storage/mail-search-build.c
--- a/src/lib-storage/mail-search-build.c	Mon Apr 19 16:53:15 2010 +0300
+++ b/src/lib-storage/mail-search-build.c	Tue Apr 20 14:57:19 2010 +0300
@@ -1,29 +1,15 @@
 /* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
-#include "imap-arg.h"
 #include "mail-storage-private.h"
 #include "mail-search-register.h"
+#include "mail-search-parser.h"
 #include "mail-search-build.h"
 
 #include <stdlib.h>
 
-int mail_search_build_next_astring(struct mail_search_build_context *ctx,
-				   const struct imap_arg **imap_args,
-				   const char **value_r)
-{
-	if (IMAP_ARG_IS_EOL(*imap_args)) {
-		ctx->error = "Missing parameter for argument";
-		return -1;
-	}
-	if (!imap_arg_get_astring(*imap_args, value_r)) {
-		ctx->error = "Invalid parameter for argument";
-		return -1;
-	}
-
-	*imap_args += 1;
-	return 0;
-}
+static int mail_search_build_list(struct mail_search_build_context *ctx,
+				  struct mail_search_arg **arg_r);
 
 struct mail_search_arg *
 mail_search_build_new(struct mail_search_build_context *ctx,
@@ -38,93 +24,88 @@
 
 struct mail_search_arg *
 mail_search_build_str(struct mail_search_build_context *ctx,
-		      const struct imap_arg **imap_args,
 		      enum mail_search_arg_type type)
 {
 	struct mail_search_arg *sarg;
 	const char *value;
 
 	sarg = mail_search_build_new(ctx, type);
-	if (mail_search_build_next_astring(ctx, imap_args, &value) < 0)
+	if (mail_search_parse_string(ctx->parser, &value) < 0)
 		return NULL;
 	sarg->value.str = p_strdup(ctx->pool, value);
 	return sarg;
 }
 
-struct mail_search_arg *
-mail_search_build_next(struct mail_search_build_context *ctx,
-		       struct mail_search_arg *parent,
-		       const struct imap_arg **imap_args)
+static int
+mail_search_build_key_int(struct mail_search_build_context *ctx,
+			  struct mail_search_arg *parent,
+			  struct mail_search_arg **arg_r)
 {
 	struct mail_search_arg *sarg;
 	struct mail_search_arg *old_parent = ctx->parent;
-	const struct imap_arg *listargs;
 	const char *key;
 	const struct mail_search_register_arg *reg_arg;
 	mail_search_register_fallback_t *fallback;
+	int ret;
 
 	ctx->parent = parent;
 
-	if (IMAP_ARG_IS_EOL(*imap_args)) {
-		ctx->error = "Missing argument";
-		return NULL;
+	if ((ret = mail_search_parse_key(ctx->parser, &key)) <= 0)
+		return ret;
+
+	if (strcmp(key, MAIL_SEARCH_PARSER_KEY_LIST) == 0) {
+		if (mail_search_build_list(ctx, &sarg) < 0)
+			return -1;
+		i_assert(sarg->value.subargs != NULL);
+		ctx->parent = old_parent;
+		*arg_r = sarg;
+		return 1;
 	}
-
-	if ((*imap_args)->type == IMAP_ARG_NIL) {
-		/* NIL not allowed */
-		ctx->error = "NIL not allowed";
-		return NULL;
-	}
-
-	if (imap_arg_get_list(*imap_args, &listargs)) {
-		if (IMAP_ARG_IS_EOL(listargs)) {
-			ctx->error = "Empty list not allowed";
-			return NULL;
-		}
-
-		sarg = mail_search_build_list(ctx, listargs);
-		*imap_args += 1;
-		ctx->parent = old_parent;
-		return sarg;
-	}
-
-	/* string argument - get the name and jump to next */
-	key = imap_arg_as_astring(*imap_args);
-	*imap_args += 1;
 	key = t_str_ucase(key);
 
 	reg_arg = mail_search_register_find(ctx->reg, key);
 	if (reg_arg != NULL)
-		sarg = reg_arg->build(ctx, imap_args);
+		sarg = reg_arg->build(ctx);
 	else if (mail_search_register_get_fallback(ctx->reg, &fallback))
-		sarg = fallback(ctx, key, imap_args);
+		sarg = fallback(ctx, key);
 	else {
 		sarg = NULL;
-		ctx->error = p_strconcat(ctx->pool, "Unknown argument ",
-					 key, NULL);
+		ctx->_error = p_strconcat(ctx->pool, "Unknown argument ",
+					  key, NULL);
 	}
 
 	ctx->parent = old_parent;
-	return sarg;
+	*arg_r = sarg;
+	return sarg == NULL ? -1 : 1;
 }
 
-struct mail_search_arg *
-mail_search_build_list(struct mail_search_build_context *ctx,
-		       const struct imap_arg *imap_args)
+int mail_search_build_key(struct mail_search_build_context *ctx,
+			  struct mail_search_arg *parent,
+			  struct mail_search_arg **arg_r)
+{
+	int ret;
+
+	ret = mail_search_build_key_int(ctx, parent, arg_r);
+	if (ret <= 0) {
+		if (ret == 0)
+			ctx->_error = "Missing argument";
+		return -1;
+	}
+	return 0;
+}


More information about the dovecot-cvs mailing list