Mercurial > dovecot > original-hg > dovecot-1.2
changeset 5836:9f869a7a3d73 HEAD
Changed imap-parser API to use standard arrays for lists instead of its own
imap_arg_list struct.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 29 Jun 2007 19:15:39 +0300 |
parents | d59ed6a31b66 |
children | 5cd5f65a8dad |
files | src/imap/cmd-append.c src/imap/cmd-fetch.c src/imap/cmd-list.c src/imap/cmd-sort.c src/imap/cmd-status.c src/imap/cmd-store.c src/imap/imap-fetch-body.c src/imap/imap-search.c src/lib-imap/imap-bodystructure.c src/lib-imap/imap-envelope.c src/lib-imap/imap-parser.c src/lib-imap/imap-parser.h src/plugins/imap-quota/imap-quota-plugin.c |
diffstat | 13 files changed, 92 insertions(+), 121 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap/cmd-append.c Fri Jun 29 19:03:45 2007 +0300 +++ b/src/imap/cmd-append.c Fri Jun 29 19:15:39 2007 +0300 @@ -84,7 +84,7 @@ internal_date may be NULL as a result, but mailbox and msg_size are always set when successful. */ static int validate_args(const struct imap_arg *args, - const struct imap_arg_list **flags_r, + const struct imap_arg **flags_r, const char **internal_date_r, uoff_t *msg_size_r, bool *nonsync_r) { @@ -92,7 +92,7 @@ if (args->type != IMAP_ARG_LIST) *flags_r = NULL; else { - *flags_r = IMAP_ARG_LIST(args); + *flags_r = IMAP_ARG_LIST_ARGS(args); args++; } @@ -201,7 +201,7 @@ struct client *client = cmd->client; struct cmd_append_context *ctx = cmd->context; const struct imap_arg *args; - const struct imap_arg_list *flags_list; + const struct imap_arg *flags_list; enum mail_flags flags; const char *const *keywords_list; struct mail_keywords *keywords; @@ -294,7 +294,7 @@ } if (flags_list != NULL) { - if (!client_parse_mail_flags(cmd, flags_list->args, + if (!client_parse_mail_flags(cmd, flags_list, &flags, &keywords_list)) return cmd_append_cancel(ctx, nonsync); keywords = keywords_list == NULL ? NULL :
--- a/src/imap/cmd-fetch.c Fri Jun 29 19:03:45 2007 +0300 +++ b/src/imap/cmd-fetch.c Fri Jun 29 19:15:39 2007 +0300 @@ -46,7 +46,7 @@ } } } else { - arg = IMAP_ARG_LIST(arg)->args; + arg = IMAP_ARG_LIST_ARGS(arg); while (arg->type == IMAP_ARG_ATOM) { str = t_str_ucase(IMAP_ARG_STR(arg)); arg++;
--- a/src/imap/cmd-list.c Fri Jun 29 19:03:45 2007 +0300 +++ b/src/imap/cmd-list.c Fri Jun 29 19:15:39 2007 +0300 @@ -721,7 +721,7 @@ if (args[0].type == IMAP_ARG_LIST && !lsub) { /* LIST-EXTENDED selection options */ used_listext = TRUE; - if (!parse_select_flags(cmd, IMAP_ARG_LIST(&args[0])->args, + if (!parse_select_flags(cmd, IMAP_ARG_LIST_ARGS(&args[0]), &list_flags)) return TRUE; args++; @@ -744,7 +744,7 @@ strcasecmp(imap_arg_string(&args[0]), "RETURN") == 0) { /* LIST-EXTENDED return options */ used_listext = TRUE; - if (!parse_return_flags(cmd, IMAP_ARG_LIST(&args[1])->args, + if (!parse_return_flags(cmd, IMAP_ARG_LIST_ARGS(&args[1]), &list_flags)) return TRUE; args += 2;
--- a/src/imap/cmd-sort.c Fri Jun 29 19:03:45 2007 +0300 +++ b/src/imap/cmd-sort.c Fri Jun 29 19:15:39 2007 +0300 @@ -112,7 +112,7 @@ return TRUE; } - if (get_sort_program(cmd, IMAP_ARG_LIST(args)->args, sorting) < 0) + if (get_sort_program(cmd, IMAP_ARG_LIST_ARGS(args), sorting) < 0) return TRUE; args++;
--- a/src/imap/cmd-status.c Fri Jun 29 19:03:45 2007 +0300 +++ b/src/imap/cmd-status.c Fri Jun 29 19:15:39 2007 +0300 @@ -99,7 +99,7 @@ } /* get the items client wants */ - items = get_status_items(cmd, IMAP_ARG_LIST(&args[1])->args); + items = get_status_items(cmd, IMAP_ARG_LIST_ARGS(&args[1])); if (items == (enum mailbox_status_items)-1) { /* error */ return TRUE;
--- a/src/imap/cmd-store.c Fri Jun 29 19:03:45 2007 +0300 +++ b/src/imap/cmd-store.c Fri Jun 29 19:15:39 2007 +0300 @@ -72,7 +72,7 @@ if (args[2].type == IMAP_ARG_LIST) { if (!client_parse_mail_flags(cmd, - IMAP_ARG_LIST(&args[2])->args, + IMAP_ARG_LIST_ARGS(&args[2]), &flags, &keywords_list)) return TRUE; } else {
--- a/src/imap/imap-fetch-body.c Fri Jun 29 19:03:45 2007 +0300 +++ b/src/imap/imap-fetch-body.c Fri Jun 29 19:15:39 2007 +0300 @@ -724,7 +724,8 @@ static bool body_section_build(struct imap_fetch_context *ctx, struct imap_fetch_body_data *body, const char *prefix, - const struct imap_arg_list *list) + const struct imap_arg *args, + unsigned int args_count) { string_t *str; const char **arr; @@ -735,11 +736,11 @@ str_append(str, " ("); /* @UNSAFE: NULL-terminated list of headers */ - arr = p_new(ctx->cmd->pool, const char *, list->size + 1); + arr = p_new(ctx->cmd->pool, const char *, args_count + 1); - for (i = 0; i < list->size; i++) { - if (list->args[i].type != IMAP_ARG_ATOM && - list->args[i].type != IMAP_ARG_STRING) { + for (i = 0; i < args_count; i++) { + if (args[i].type != IMAP_ARG_ATOM && + args[i].type != IMAP_ARG_STRING) { client_send_command_error(ctx->cmd, "Invalid BODY[..] parameter: " "Header list contains non-strings"); @@ -748,9 +749,9 @@ if (i != 0) str_append_c(str, ' '); - arr[i] = t_str_ucase(IMAP_ARG_STR(&list->args[i])); + arr[i] = t_str_ucase(IMAP_ARG_STR(&args[i])); - if (list->args[i].type == IMAP_ARG_ATOM) + if (args[i].type == IMAP_ARG_ATOM) str_append(str, arr[i]); else { str_append_c(str, '"'); @@ -760,9 +761,9 @@ } str_append_c(str, ')'); - qsort(arr, list->size, sizeof(*arr), strcasecmp_p); + qsort(arr, args_count, sizeof(*arr), strcasecmp_p); body->fields = arr; - body->fields_count = list->size; + body->fields_count = args_count; body->section = str_c(str); return TRUE; } @@ -799,7 +800,8 @@ return FALSE; } if (!body_section_build(ctx, body, p+1, - IMAP_ARG_LIST(&(*args)[0]))) + IMAP_ARG_LIST_ARGS(&(*args)[0]), + IMAP_ARG_LIST_COUNT(&(*args)[0]))) return FALSE; p = IMAP_ARG_STR(&(*args)[1]); *args += 2;
--- a/src/imap/imap-search.c Fri Jun 29 19:03:45 2007 +0300 +++ b/src/imap/imap-search.c Fri Jun 29 19:15:39 2007 +0300 @@ -148,7 +148,7 @@ } if (arg->type == IMAP_ARG_LIST) { - const struct imap_arg *listargs = IMAP_ARG_LIST(arg)->args; + const struct imap_arg *listargs = IMAP_ARG_LIST_ARGS(arg); if (listargs->type == IMAP_ARG_EOL) { data->error = "Empty list not allowed";
--- a/src/lib-imap/imap-bodystructure.c Fri Jun 29 19:03:45 2007 +0300 +++ b/src/lib-imap/imap-bodystructure.c Fri Jun 29 19:15:39 2007 +0300 @@ -544,7 +544,7 @@ if (args->type != IMAP_ARG_LIST) return FALSE; - if (!imap_write_list(IMAP_ARG_LIST(args)->args, str)) + if (!imap_write_list(IMAP_ARG_LIST_ARGS(args), str)) return FALSE; } args++; @@ -560,15 +560,15 @@ string_t *str) { const struct imap_arg *subargs; - const struct imap_arg_list *list; + const struct imap_arg *list_args; bool multipart, text, message_rfc822; int i; multipart = FALSE; while (args->type == IMAP_ARG_LIST) { str_append_c(str, '('); - list = IMAP_ARG_LIST(args); - if (!imap_parse_bodystructure_args(list->args, str)) + list_args = IMAP_ARG_LIST_ARGS(args); + if (!imap_parse_bodystructure_args(list_args, str)) return FALSE; str_append_c(str, ')'); @@ -602,7 +602,7 @@ /* ("content type param key" "value" ...) | NIL */ if (args->type == IMAP_ARG_LIST) { str_append(str, " ("); - subargs = IMAP_ARG_LIST(args)->args; + subargs = IMAP_ARG_LIST_ARGS(args); for (; subargs->type != IMAP_ARG_EOL; ) { if (!str_append_imap_arg(str, &subargs[0])) return FALSE; @@ -647,14 +647,14 @@ str_append_c(str, ' '); - list = IMAP_ARG_LIST(&args[0]); - if (!imap_write_list(list->args, str)) + list_args = IMAP_ARG_LIST_ARGS(&args[0]); + if (!imap_write_list(list_args, str)) return FALSE; str_append(str, " ("); - list = IMAP_ARG_LIST(&args[1]); - if (!imap_parse_bodystructure_args(list->args, str)) + list_args = IMAP_ARG_LIST_ARGS(&args[1]); + if (!imap_parse_bodystructure_args(list_args, str)) return FALSE; str_append(str, ") ");
--- a/src/lib-imap/imap-envelope.c Fri Jun 29 19:03:45 2007 +0300 +++ b/src/lib-imap/imap-envelope.c Fri Jun 29 19:15:39 2007 +0300 @@ -214,24 +214,26 @@ static bool imap_address_arg_append(const struct imap_arg *arg, string_t *str, bool *in_group) { - const struct imap_arg_list *list; + const struct imap_arg *list_args; + unsigned int list_count; const char *args[4]; int i; if (arg->type != IMAP_ARG_LIST) return FALSE; - list = IMAP_ARG_LIST(arg); + list_args = IMAP_ARG_LIST_ARGS(arg); + list_count = IMAP_ARG_LIST_COUNT(arg); /* we require 4 arguments, strings or NILs */ - if (list->size < 4) + if (list_count < 4) return FALSE; for (i = 0; i < 4; i++) { - if (list->args[i].type == IMAP_ARG_NIL) + if (list_args[i].type == IMAP_ARG_NIL) args[i] = NULL; - else if (list->args[i].type == IMAP_ARG_STRING || - list->args[i].type == IMAP_ARG_ATOM) - args[i] = IMAP_ARG_STR(&list->args[i]); + else if (list_args[i].type == IMAP_ARG_STRING || + list_args[i].type == IMAP_ARG_ATOM) + args[i] = IMAP_ARG_STR(&list_args[i]); else return FALSE; } @@ -290,9 +292,8 @@ static const char *imap_envelope_parse_address(const struct imap_arg *arg) { - const struct imap_arg_list *list; + const struct imap_arg *list_args; string_t *str; - size_t i; bool in_group; if (arg->type != IMAP_ARG_LIST) @@ -301,9 +302,9 @@ in_group = FALSE; str = t_str_new(128); - list = IMAP_ARG_LIST(arg); - for (i = 0; i < list->size; i++) { - if (!imap_address_arg_append(&list->args[i], str, &in_group)) + list_args = IMAP_ARG_LIST_ARGS(arg); + for (; list_args->type != IMAP_ARG_EOL; list_args++) { + if (!imap_address_arg_append(list_args, str, &in_group)) return NULL; } @@ -312,25 +313,22 @@ static const char *imap_envelope_parse_first_mailbox(const struct imap_arg *arg) { - const struct imap_arg_list *list; + const struct imap_arg *list_args; - /* ((name route mailbox domain) ...) */ + /* ((...)(...) ...) */ if (arg->type != IMAP_ARG_LIST) return NULL; - list = IMAP_ARG_LIST(arg); - if (list->size == 0) + list_args = IMAP_ARG_LIST_ARGS(arg); + if (list_args->type == IMAP_ARG_EOL) return ""; - arg = IMAP_ARG_LIST(arg)->args; - if (arg->type != IMAP_ARG_LIST) + /* (name route mailbox domain) */ + if (IMAP_ARG_LIST_COUNT(list_args) != 4) return NULL; - list = IMAP_ARG_LIST(arg); - if (list->size != 4) - return NULL; - - return t_strdup(imap_arg_string(&list->args[2])); + list_args = IMAP_ARG_LIST_ARGS(list_args); + return t_strdup(imap_arg_string(&list_args[2])); } static bool
--- a/src/lib-imap/imap-parser.c Fri Jun 29 19:03:45 2007 +0300 +++ b/src/lib-imap/imap-parser.c Fri Jun 29 19:15:39 2007 +0300 @@ -9,7 +9,7 @@ #define is_linebreak(c) \ ((c) == '\r' || (c) == '\n') -#define LIST_ALLOC_SIZE 7 +#define LIST_INIT_COUNT 7 enum arg_parse_type { ARG_PARSE_NONE = 0, @@ -29,8 +29,8 @@ /* reset by imap_parser_reset(): */ size_t line_size; - struct imap_arg_list *root_list; - struct imap_arg_list *cur_list; + ARRAY_TYPE(imap_arg_list) root_list; + ARRAY_TYPE(imap_arg_list) *cur_list; struct imap_arg *list_arg; enum arg_parse_type cur_type; @@ -47,25 +47,6 @@ unsigned int fatal_error:1; }; -/* @UNSAFE */ -#define LIST_REALLOC(parser, old_list, new_size) \ - p_realloc((parser)->pool, old_list, \ - sizeof(struct imap_arg_list) + \ - (old_list == NULL ? 0 : \ - sizeof(struct imap_arg_list) * (old_list)->alloc), \ - sizeof(struct imap_arg_list) * (new_size)) - -static void imap_args_realloc(struct imap_parser *parser, size_t size) -{ - parser->cur_list = LIST_REALLOC(parser, parser->cur_list, size); - parser->cur_list->alloc = size; - - if (parser->list_arg == NULL) - parser->root_list = parser->cur_list; - else - parser->list_arg->_data.list = parser->cur_list; -} - struct imap_parser * imap_parser_create(struct istream *input, struct ostream *output, size_t max_line_size) @@ -78,7 +59,8 @@ parser->output = output; parser->max_line_size = max_line_size; - imap_args_realloc(parser, LIST_ALLOC_SIZE); + p_array_init(&parser->root_list, parser->pool, LIST_INIT_COUNT); + parser->cur_list = &parser->root_list; return parser; } @@ -95,8 +77,8 @@ parser->line_size = 0; - parser->root_list = NULL; - parser->cur_list = NULL; + p_array_init(&parser->root_list, parser->pool, LIST_INIT_COUNT); + parser->cur_list = &parser->root_list; parser->list_arg = NULL; parser->cur_type = ARG_PARSE_NONE; @@ -109,8 +91,6 @@ parser->literal_skip_crlf = FALSE; parser->eol = FALSE; - - imap_args_realloc(parser, LIST_ALLOC_SIZE); } const char *imap_parser_get_error(struct imap_parser *parser, bool *fatal) @@ -144,28 +124,18 @@ { struct imap_arg *arg; - i_assert(parser->cur_list != NULL); - - /* @UNSAFE */ - if (parser->cur_list->size == parser->cur_list->alloc) - imap_args_realloc(parser, parser->cur_list->alloc * 2); - - arg = &parser->cur_list->args[parser->cur_list->size]; + arg = array_append_space(parser->cur_list); arg->parent = parser->list_arg; - parser->cur_list->size++; - return arg; } static void imap_parser_open_list(struct imap_parser *parser) { parser->list_arg = imap_arg_create(parser); - - parser->cur_list = NULL; - imap_args_realloc(parser, LIST_ALLOC_SIZE); - parser->list_arg->type = IMAP_ARG_LIST; - parser->list_arg->_data.list = parser->cur_list; + p_array_init(&parser->list_arg->_data.list, parser->pool, + LIST_INIT_COUNT); + parser->cur_list = &parser->list_arg->_data.list; parser->cur_type = ARG_PARSE_NONE; } @@ -182,13 +152,12 @@ arg = imap_arg_create(parser); arg->type = IMAP_ARG_EOL; - parser->cur_list->size--; /* EOL doesn't belong to argument count */ parser->list_arg = parser->list_arg->parent; if (parser->list_arg == NULL) { - parser->cur_list = parser->root_list; + parser->cur_list = &parser->root_list; } else { - parser->cur_list = parser->list_arg->_data.list; + parser->cur_list = &parser->list_arg->_data.list; } parser->cur_type = ARG_PARSE_NONE; @@ -534,11 +503,13 @@ /* ARG_PARSE_NONE checks that last argument isn't only partially parsed. */ #define IS_UNFINISHED(parser) \ ((parser)->cur_type != ARG_PARSE_NONE || \ - (parser)->cur_list != parser->root_list) + (parser)->cur_list != &parser->root_list) static int finish_line(struct imap_parser *parser, unsigned int count, const struct imap_arg **args_r) { + struct imap_arg *arg; + parser->line_size += parser->cur_pos; i_stream_skip(parser->input, parser->cur_pos); parser->cur_pos = 0; @@ -549,17 +520,16 @@ return -1; } - if (count >= parser->root_list->alloc) { - /* unused arguments must be NIL-filled. */ - parser->root_list = - LIST_REALLOC(parser, parser->root_list, count+1); - parser->root_list->alloc = count+1; + /* fill the missing parameters with NILs */ + while (count > array_count(&parser->root_list)) { + arg = array_append_space(&parser->root_list); + arg->type = IMAP_ARG_NIL; } - - parser->root_list->args[parser->root_list->size].type = IMAP_ARG_EOL; + arg = array_append_space(&parser->root_list); + arg->type = IMAP_ARG_EOL; - *args_r = parser->root_list->args; - return parser->root_list->size; + *args_r = array_get(&parser->root_list, &count); + return count; } int imap_parser_read_args(struct imap_parser *parser, unsigned int count, @@ -568,8 +538,8 @@ { parser->flags = flags; - while (!parser->eol && (count == 0 || parser->root_list->size < count || - IS_UNFINISHED(parser))) { + while (!parser->eol && (count == 0 || IS_UNFINISHED(parser) || + array_count(&parser->root_list) < count)) { if (!imap_parser_read_arg(parser)) break; @@ -587,7 +557,7 @@ *args_r = NULL; return -1; } else if ((!IS_UNFINISHED(parser) && count > 0 && - parser->root_list->size >= count) || parser->eol) { + array_count(&parser->root_list) >= count) || parser->eol) { /* all arguments read / end of line. */ return finish_line(parser, count, args_r); } else { @@ -669,7 +639,7 @@ #endif } -struct imap_arg_list *_imap_arg_list_error(const struct imap_arg *arg) +ARRAY_TYPE(imap_arg_list) *_imap_arg_list_error(const struct imap_arg *arg) { i_panic("Tried to access imap_arg type %d as list", arg->type); #ifndef __attrs_used__
--- a/src/lib-imap/imap-parser.h Fri Jun 29 19:03:45 2007 +0300 +++ b/src/lib-imap/imap-parser.h Fri Jun 29 19:15:39 2007 +0300 @@ -1,6 +1,8 @@ #ifndef __IMAP_PARSER_H #define __IMAP_PARSER_H +#include "array.h" + /* FIXME: we don't have ']' here due to FETCH BODY[] handling failing with it.. also '%' and '*' are banned due to LIST, and '\' due to it being in flags. oh well.. */ @@ -36,6 +38,7 @@ struct imap_parser; +ARRAY_DEFINE_TYPE(imap_arg_list, struct imap_arg); struct imap_arg { enum imap_arg_type type; struct imap_arg *parent; /* always of type IMAP_ARG_LIST */ @@ -43,7 +46,7 @@ union { const char *str; uoff_t literal_size; - struct imap_arg_list *list; + ARRAY_TYPE(imap_arg_list) list; } _data; }; @@ -65,13 +68,11 @@ #define IMAP_ARG_LIST(arg) \ ((arg)->type == IMAP_ARG_LIST ? \ - (const struct imap_arg_list *)(arg)->_data.list : \ - _imap_arg_list_error(arg)) - -struct imap_arg_list { - size_t size, alloc; - struct imap_arg args[1]; /* variable size */ -}; + &(arg)->_data.list : _imap_arg_list_error(arg)) +#define IMAP_ARG_LIST_ARGS(arg) \ + array_idx(IMAP_ARG_LIST(arg), 0) +#define IMAP_ARG_LIST_COUNT(arg) \ + (array_count(IMAP_ARG_LIST(arg)) - 1) /* Create new IMAP argument parser. output is used for sending command continuation requests for literals. @@ -126,7 +127,7 @@ char *_imap_arg_str_error(const struct imap_arg *arg) __attr_noreturn__; uoff_t _imap_arg_literal_size_error(const struct imap_arg *arg) __attr_noreturn__; -struct imap_arg_list *_imap_arg_list_error(const struct imap_arg *arg) +ARRAY_TYPE(imap_arg_list) *_imap_arg_list_error(const struct imap_arg *arg) __attr_noreturn__; #endif
--- a/src/plugins/imap-quota/imap-quota-plugin.c Fri Jun 29 19:03:45 2007 +0300 +++ b/src/plugins/imap-quota/imap-quota-plugin.c Fri Jun 29 19:15:39 2007 +0300 @@ -158,7 +158,7 @@ return TRUE; } - arg = IMAP_ARG_LIST(&args[1])->args; + arg = IMAP_ARG_LIST_ARGS(&args[1]); for (; arg->type != IMAP_ARG_EOL; arg += 2) { name = imap_arg_string(arg); if (name == NULL || arg[1].type != IMAP_ARG_ATOM ||