From: Timo Sirainen Date: Sun, 19 Aug 2012 13:17:32 +0000 (+0300) Subject: Removed CONTEXT_TYPE_SAFETY macro and reimplemented its functionality better. X-Git-Tag: 2.2.alpha1~307 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=27a44fcfd8d19bffe0f267f20a2b5d3fe7600fdd;p=thirdparty%2Fdovecot%2Fcore.git Removed CONTEXT_TYPE_SAFETY macro and reimplemented its functionality better. gcc/clang now gives a compiler error in many places if callback isn't exactly what was expected. It's also now much easier to add more of these checks. --- diff --git a/src/anvil/anvil-connection.c b/src/anvil/anvil-connection.c index 55ad08a2c3..402dcdd8a3 100644 --- a/src/anvil/anvil-connection.c +++ b/src/anvil/anvil-connection.c @@ -129,9 +129,8 @@ anvil_connection_request(struct anvil_connection *conn, return 0; } -static void anvil_connection_input(void *context) +static void anvil_connection_input(struct anvil_connection *conn) { - struct anvil_connection *conn = context; const char *line, *const *args, *error; switch (i_stream_read(conn->input)) { @@ -153,7 +152,7 @@ static void anvil_connection_input(void *context) if (anvil_restarted && (conn->master || conn->fifo)) { /* old pending data. ignore input until we get the handshake. */ - anvil_connection_input(context); + anvil_connection_input(conn); return; } i_error("Anvil client not compatible with this server " diff --git a/src/auth/auth-request-handler.h b/src/auth/auth-request-handler.h index b5cabdff43..08e60f5d29 100644 --- a/src/auth/auth-request-handler.h +++ b/src/auth/auth-request-handler.h @@ -17,18 +17,14 @@ auth_request_callback_t(struct auth_stream_reply *reply, void *context); struct auth_request_handler * auth_request_handler_create(auth_request_callback_t *callback, void *context, auth_request_callback_t *master_callback); -#ifdef CONTEXT_TYPE_SAFETY -# define auth_request_handler_create(callback, context, master_callback)\ - ({(void)(1 ? 0 : callback((struct auth_stream_reply *)NULL, context)); \ +#define auth_request_handler_create(callback, context, master_callback)\ auth_request_handler_create( \ - (auth_request_callback_t *)callback, context, \ - master_callback); }) -#else -# define auth_request_handler_create(callback, context, master_callback)\ - auth_request_handler_create( \ - (auth_request_callback_t *)callback, context, \ + (auth_request_callback_t *)callback, \ + (void *)((char*)context + \ + CALLBACK_TYPECHECK(callback, void (*)( \ + struct auth_stream_reply *, typeof(context)))), \ master_callback) -#endif + void auth_request_handler_destroy(struct auth_request_handler **handler); void auth_request_handler_unref(struct auth_request_handler **handler); void auth_request_handler_abort_requests(struct auth_request_handler *handler); diff --git a/src/auth/db-dict.c b/src/auth/db-dict.c index b43096f99d..199d3da87a 100644 --- a/src/auth/db-dict.c +++ b/src/auth/db-dict.c @@ -81,8 +81,7 @@ struct dict_connection *db_dict_init(const char *config_path) conn->config_path = p_strdup(pool, config_path); conn->set = default_dict_settings; - if (!settings_read(config_path, NULL, parse_setting, - null_settings_section_callback, conn)) + if (!settings_read_nosection(config_path, parse_setting, conn)) exit(FATAL_DEFAULT); if (conn->set.uri == NULL) diff --git a/src/auth/db-ldap.c b/src/auth/db-ldap.c index ce4f4cf1ac..1b03149c35 100644 --- a/src/auth/db-ldap.c +++ b/src/auth/db-ldap.c @@ -1402,8 +1402,7 @@ struct ldap_connection *db_ldap_init(const char *config_path, bool userdb) conn->fd = -1; conn->config_path = p_strdup(pool, config_path); conn->set = default_ldap_settings; - if (!settings_read(config_path, NULL, parse_setting, - null_settings_section_callback, conn)) + if (!settings_read_nosection(config_path, parse_setting, conn)) exit(FATAL_DEFAULT); if (conn->set.base == NULL) diff --git a/src/auth/db-sql.c b/src/auth/db-sql.c index 7802848541..5770ea8c27 100644 --- a/src/auth/db-sql.c +++ b/src/auth/db-sql.c @@ -86,8 +86,7 @@ struct sql_connection *db_sql_init(const char *config_path, bool userdb) conn->config_path = p_strdup(pool, config_path); conn->set = default_sql_settings; - if (!settings_read(config_path, NULL, parse_setting, - null_settings_section_callback, conn)) + if (!settings_read_nosection(config_path, parse_setting, conn)) exit(FATAL_DEFAULT); if (conn->set.password_query == default_sql_settings.password_query) diff --git a/src/config/config-connection.c b/src/config/config-connection.c index c0cdaa6606..f97716b553 100644 --- a/src/config/config-connection.c +++ b/src/config/config-connection.c @@ -140,9 +140,8 @@ static int config_connection_request(struct config_connection *conn, return 0; } -static void config_connection_input(void *context) +static void config_connection_input(struct config_connection *conn) { - struct config_connection *conn = context; const char *const *args, *line; switch (i_stream_read(conn->input)) { diff --git a/src/doveadm/doveadm-mail-mailbox.c b/src/doveadm/doveadm-mail-mailbox.c index 8780969b65..897fedd389 100644 --- a/src/doveadm/doveadm-mail-mailbox.c +++ b/src/doveadm/doveadm-mail-mailbox.c @@ -261,10 +261,8 @@ static struct doveadm_mail_cmd_context *cmd_mailbox_create_alloc(void) return &ctx->ctx.ctx; } -static int i_strcmp_reverse_p(const void *p1, const void *p2) +static int i_strcmp_reverse_p(const char *const *s1, const char *const *s2) { - const char *const *s1 = p1, *const *s2 = p2; - return -strcmp(*s1, *s2); } diff --git a/src/doveadm/doveadm-stats.c b/src/doveadm/doveadm-stats.c index 2e1cc8496e..83bc43f620 100644 --- a/src/doveadm/doveadm-stats.c +++ b/src/doveadm/doveadm-stats.c @@ -372,7 +372,7 @@ static bool stats_top_round(struct top_context *ctx) stats_drop_stale(ctx); sort_ctx = ctx; - array_sort(&ctx->lines, ctx->lines_sort); + array_sort(&ctx->lines, *ctx->lines_sort); sort_ctx = NULL; return TRUE; } diff --git a/src/doveadm/doveadm.c b/src/doveadm/doveadm.c index e2a035e0db..05ff00bc10 100644 --- a/src/doveadm/doveadm.c +++ b/src/doveadm/doveadm.c @@ -55,15 +55,15 @@ static void doveadm_usage_compress_lines(FILE *out, const char *str, const char *prefix) { const char *cmd, *args, *p, *short_name, *prev_name = ""; - char **lines; + const char **lines; unsigned int i, count, prefix_len = strlen(prefix); /* split lines */ - lines = p_strsplit(pool_datastack_create(), str, "\n"); + lines = (void *)p_strsplit(pool_datastack_create(), str, "\n"); for (count = 0; lines[count] != NULL; count++) ; /* sort lines */ - qsort(lines, count, sizeof(*lines), i_strcmp_p); + i_qsort(lines, count, sizeof(*lines), i_strcmp_p); /* print lines, compress subcommands into a single line */ for (i = 0; i < count; i++) { diff --git a/src/imap/imap-fetch.h b/src/imap/imap-fetch.h index 448032b968..d51f2fdf83 100644 --- a/src/imap/imap-fetch.h +++ b/src/imap/imap-fetch.h @@ -97,17 +97,12 @@ void imap_fetch_add_handler(struct imap_fetch_init_context *ctx, const char *nil_reply, imap_fetch_handler_t *handler, void *context) ATTR_NULL(3, 5); -#ifdef CONTEXT_TYPE_SAFETY -# define imap_fetch_add_handler(ctx, flags, nil_reply, handler, context) \ - ({(void)(1 ? 0 : handler((struct imap_fetch_context *)NULL, \ - (struct mail *)NULL, context)); \ - imap_fetch_add_handler(ctx, flags, nil_reply, \ - (imap_fetch_handler_t *)handler, context); }) -#else -# define imap_fetch_add_handler(ctx, flags, nil_reply, handler, context) \ - imap_fetch_add_handler(ctx, flags, nil_reply, \ +#define imap_fetch_add_handler(ctx, flags, nil_reply, handler, context) \ + imap_fetch_add_handler(ctx, flags, nil_reply + \ + CALLBACK_TYPECHECK(handler, int (*)( \ + struct imap_fetch_context *, struct mail *, \ + typeof(context))), \ (imap_fetch_handler_t *)handler, context) -#endif int imap_fetch_att_list_parse(struct client *client, pool_t pool, const struct imap_arg *list, diff --git a/src/indexer/indexer-client.c b/src/indexer/indexer-client.c index d5b89efeda..ef5eb8c553 100644 --- a/src/indexer/indexer-client.c +++ b/src/indexer/indexer-client.c @@ -147,9 +147,8 @@ indexer_client_request(struct indexer_client *client, } } -static void indexer_client_input(void *context) +static void indexer_client_input(struct indexer_client *client) { - struct indexer_client *client = context; const char *line, *const *args, *error; switch (i_stream_read(client->input)) { diff --git a/src/lib-dns/dns-lookup.c b/src/lib-dns/dns-lookup.c index e4f5eec79b..ac50212462 100644 --- a/src/lib-dns/dns-lookup.c +++ b/src/lib-dns/dns-lookup.c @@ -121,8 +121,8 @@ static void dns_lookup_timeout(struct dns_lookup *lookup) #undef dns_lookup int dns_lookup(const char *host, const struct dns_lookup_settings *set, - struct dns_lookup **lookup_r, - dns_lookup_callback_t *callback, void *context) + dns_lookup_callback_t *callback, void *context, + struct dns_lookup **lookup_r) { struct dns_lookup *lookup; struct dns_lookup_result result; diff --git a/src/lib-dns/dns-lookup.h b/src/lib-dns/dns-lookup.h index 40e7671761..26b5d81ddb 100644 --- a/src/lib-dns/dns-lookup.h +++ b/src/lib-dns/dns-lookup.h @@ -29,12 +29,13 @@ typedef void dns_lookup_callback_t(const struct dns_lookup_result *result, When failing with -1, the callback is called before returning from the function. */ int dns_lookup(const char *host, const struct dns_lookup_settings *set, - struct dns_lookup **lookup_r, - dns_lookup_callback_t *callback, void *context) ATTR_NULL(5); + dns_lookup_callback_t *callback, void *context, + struct dns_lookup **lookup_r) ATTR_NULL(4); #define dns_lookup(host, set, callback, context, lookup_r) \ - CONTEXT_CALLBACK2(dns_lookup, dns_lookup_callback_t, \ - callback, const struct dns_lookup_result *, \ - context, host, set, lookup_r) + dns_lookup(host + \ + CALLBACK_TYPECHECK(callback, void (*)( \ + const struct dns_lookup_result *, typeof(context))), \ + set, (dns_lookup_callback_t *)callback, context, lookup_r) /* Abort the DNS lookup without calling the callback. */ void dns_lookup_abort(struct dns_lookup **lookup); diff --git a/src/lib-imap-storage/imap-msgpart.c b/src/lib-imap-storage/imap-msgpart.c index 473670386d..e3690bd820 100644 --- a/src/lib-imap-storage/imap-msgpart.c +++ b/src/lib-imap-storage/imap-msgpart.c @@ -339,14 +339,16 @@ imap_msgpart_get_partial_header(struct mail *mail, struct istream *mail_input, HEADER_FILTER_INCLUDE | HEADER_FILTER_HIDE_BODY, hdr_fields, hdr_count, - null_header_filter_callback, NULL); + *null_header_filter_callback, + (void *)NULL); } else { i_assert(msgpart->fetch_type == FETCH_HEADER_FIELDS_NOT); input = i_stream_create_header_filter(mail_input, HEADER_FILTER_EXCLUDE | HEADER_FILTER_HIDE_BODY, hdr_fields, hdr_count, - null_header_filter_callback, NULL); + *null_header_filter_callback, + (void *)NULL); } if (message_get_header_size(input, hdr_size_r, &has_nuls) < 0) { diff --git a/src/lib-index/mail-index-util.c b/src/lib-index/mail-index-util.c index 5d8e189618..f7ebd55797 100644 --- a/src/lib-index/mail-index-util.c +++ b/src/lib-index/mail-index-util.c @@ -103,23 +103,17 @@ int mail_index_unpack_num(const uint8_t **p, const uint8_t *end, return 0; } -static int mail_index_seq_record_cmp(const void *key, const void *data) +static int mail_index_seq_record_cmp(const uint32_t *key_seq, + const uint32_t *data_seq) { - const uint32_t *seq_p = key; - const uint32_t *data_seq = data; - - return *seq_p - *data_seq; + return *key_seq - *data_seq; } bool mail_index_seq_array_lookup(const ARRAY_TYPE(seq_array) *array, uint32_t seq, unsigned int *idx_r) { - const void *base; - unsigned int count; - - base = array_get(array, &count); - return bsearch_insert_pos(&seq, base, count, array->arr.element_size, - mail_index_seq_record_cmp, idx_r); + return array_bsearch_insert_pos(array, &seq, + mail_index_seq_record_cmp, idx_r); } bool mail_index_seq_array_add(ARRAY_TYPE(seq_array) *array, uint32_t seq, diff --git a/src/lib-lda/mail-send.c b/src/lib-lda/mail-send.c index 29b1fe0757..1c98ae017e 100644 --- a/src/lib-lda/mail-send.c +++ b/src/lib-lda/mail-send.c @@ -169,7 +169,7 @@ int mail_send_rejection(struct mail_deliver_context *ctx, const char *recipient, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR | HEADER_FILTER_HIDE_BODY, exclude_headers, N_ELEMENTS(exclude_headers), - null_header_filter_callback, NULL); + *null_header_filter_callback, (void *)NULL); ret = o_stream_send_istream(output, input); i_stream_unref(&input); @@ -207,7 +207,8 @@ int mail_send_forward(struct mail_deliver_context *ctx, const char *forwardto) input = i_stream_create_header_filter(input, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, hide_headers, N_ELEMENTS(hide_headers), - null_header_filter_callback, NULL); + *null_header_filter_callback, + (void *)NULL); (void)o_stream_send_istream(output, input); i_stream_unref(&input); diff --git a/src/lib-mail/istream-header-filter.c b/src/lib-mail/istream-header-filter.c index 8211d56354..bc4cd4eaa7 100644 --- a/src/lib-mail/istream-header-filter.c +++ b/src/lib-mail/istream-header-filter.c @@ -202,10 +202,10 @@ static ssize_t read_header(struct header_filter_istream *mstream) } matched = mstream->headers_count == 0 ? FALSE : - bsearch(hdr->name, mstream->headers, - mstream->headers_count, - sizeof(*mstream->headers), - bsearch_strcasecmp) != NULL; + i_bsearch(hdr->name, mstream->headers, + mstream->headers_count, + sizeof(*mstream->headers), + bsearch_strcasecmp) != NULL; if (mstream->callback == NULL) { /* nothing gets excluded */ } else if (mstream->cur_line > mstream->parsed_lines) { diff --git a/src/lib-mail/istream-header-filter.h b/src/lib-mail/istream-header-filter.h index 413b7b5d94..0370815700 100644 --- a/src/lib-mail/istream-header-filter.h +++ b/src/lib-mail/istream-header-filter.h @@ -35,20 +35,13 @@ i_stream_create_header_filter(struct istream *input, unsigned int headers_count, header_filter_callback *callback, void *context) ATTR_NULL(6); -#ifdef CONTEXT_TYPE_SAFETY -# define i_stream_create_header_filter(input, flags, headers, headers_count, \ +#define i_stream_create_header_filter(input, flags, headers, headers_count, \ callback, context) \ - ({(void)(1 ? 0 : callback((struct header_filter_istream *)0, \ - (struct message_header_line *)0, \ - (bool *)0, context)); \ - i_stream_create_header_filter(input, flags, headers, headers_count, \ - (header_filter_callback *)callback, context); }) -#else -# define i_stream_create_header_filter(input, flags, headers, headers_count, \ - callback, context) \ - i_stream_create_header_filter(input, flags, headers, headers_count, \ - (header_filter_callback *)callback, context) -#endif + i_stream_create_header_filter(input, flags, headers, headers_count + \ + CALLBACK_TYPECHECK(callback, void (*)( \ + struct header_filter_istream *, \ + struct message_header_line *, bool *, typeof(context))), \ + (header_filter_callback *)callback, context) /* Add more data to headers. Should called from the filter callback. */ void i_stream_header_filter_add(struct header_filter_istream *input, diff --git a/src/lib-mail/message-header-parser.h b/src/lib-mail/message-header-parser.h index 945b5ee71a..9db49b0b4f 100644 --- a/src/lib-mail/message-header-parser.h +++ b/src/lib-mail/message-header-parser.h @@ -63,15 +63,10 @@ void message_parse_header(struct istream *input, struct message_size *hdr_size, enum message_header_parser_flags flags, message_header_callback_t *callback, void *context) ATTR_NULL(2); -#ifdef CONTEXT_TYPE_SAFETY -# define message_parse_header(input, hdr_size, flags, callback, context) \ - ({(void)(1 ? 0 : callback((struct message_header_line *)0, context)); \ - message_parse_header(input, hdr_size, flags, \ - (message_header_callback_t *)callback, context); }) -#else -# define message_parse_header(input, hdr_size, flags, callback, context) \ - message_parse_header(input, hdr_size, flags, \ - (message_header_callback_t *)callback, context) -#endif +#define message_parse_header(input, hdr_size, flags, callback, context) \ + message_parse_header(input, hdr_size, flags + \ + CALLBACK_TYPECHECK(callback, void (*)( \ + struct message_header_line *hdr, typeof(context))), \ + (message_header_callback_t *)callback, context) #endif diff --git a/src/lib-mail/message-parser.h b/src/lib-mail/message-parser.h index c566208676..97bf7e0443 100644 --- a/src/lib-mail/message-parser.h +++ b/src/lib-mail/message-parser.h @@ -98,17 +98,12 @@ void message_parser_parse_header(struct message_parser_ctx *ctx, struct message_size *hdr_size, message_part_header_callback_t *callback, void *context) ATTR_NULL(4); -#ifdef CONTEXT_TYPE_SAFETY -# define message_parser_parse_header(ctx, hdr_size, callback, context) \ - ({(void)(1 ? 0 : callback((struct message_part *)0, \ - (struct message_header_line *)0, context)); \ - message_parser_parse_header(ctx, hdr_size, \ - (message_part_header_callback_t *)callback, context); }) -#else -# define message_parser_parse_header(ctx, hdr_size, callback, context) \ - message_parser_parse_header(ctx, hdr_size, \ +#define message_parser_parse_header(ctx, hdr_size, callback, context) \ + message_parser_parse_header(ctx, hdr_size + \ + CALLBACK_TYPECHECK(callback, void (*)( \ + struct message_part *, \ + struct message_header_line *, typeof(context))), \ (message_part_header_callback_t *)callback, context) -#endif /* Read and parse body. If message is a MIME multipart or message/rfc822 message, hdr_callback is called for all headers. body_callback is called @@ -116,16 +111,11 @@ void message_parser_parse_header(struct message_parser_ctx *ctx, void message_parser_parse_body(struct message_parser_ctx *ctx, message_part_header_callback_t *hdr_callback, void *context) ATTR_NULL(3); -#ifdef CONTEXT_TYPE_SAFETY -# define message_parser_parse_body(ctx, callback, context) \ - ({(void)(1 ? 0 : callback((struct message_part *)0, \ - (struct message_header_line *)0, context)); \ - message_parser_parse_body(ctx, \ - (message_part_header_callback_t *)callback, context); }) -#else -# define message_parser_parse_body(ctx, callback, context) \ +#define message_parser_parse_body(ctx, callback, context) \ message_parser_parse_body(ctx, \ - (message_part_header_callback_t *)callback, context) -#endif + (message_part_header_callback_t *)callback, \ + (void *)((char *)context + CALLBACK_TYPECHECK(callback, \ + void (*)(struct message_part *, \ + struct message_header_line *, typeof(context))))) #endif diff --git a/src/lib-mail/test-istream-header-filter.c b/src/lib-mail/test-istream-header-filter.c index bb94bb6c7a..363b652b54 100644 --- a/src/lib-mail/test-istream-header-filter.c +++ b/src/lib-mail/test-istream-header-filter.c @@ -35,12 +35,13 @@ static void test_istream_filter(void) HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, exclude_headers, 2, - filter_callback, NULL); + filter_callback, (void *)NULL); filter2 = i_stream_create_header_filter(filter, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, exclude_headers, 2, - null_header_filter_callback, NULL); + *null_header_filter_callback, + (void *)NULL); i_stream_unref(&filter); filter = filter2; @@ -86,7 +87,8 @@ static void test_istream_end_body_with_lf(void) HEADER_FILTER_NO_CR | HEADER_FILTER_END_BODY_WITH_LF, empty_strarray, 0, - null_header_filter_callback, NULL); + *null_header_filter_callback, + (void *)NULL); for (i = 1; i < input_len; i++) { test_istream_set_size(istream, i); diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c index 1c3fb3e036..7760c2e7ed 100644 --- a/src/lib-master/master-service.c +++ b/src/lib-master/master-service.c @@ -397,10 +397,8 @@ static void master_service_error(struct master_service *service) } } -static void master_status_error(void *context) +static void master_status_error(struct master_service *service) { - struct master_service *service = context; - /* status fd is a write-only pipe, so if we're here it means the master wants us to die (or died itself). don't die until all service connections are finished. */ diff --git a/src/lib-settings/settings.c b/src/lib-settings/settings.c index 5806a7f512..70e907c374 100644 --- a/src/lib-settings/settings.c +++ b/src/lib-settings/settings.c @@ -386,10 +386,9 @@ prevfile: return errormsg == NULL; } -#undef settings_read -bool settings_read(const char *path, const char *section, - settings_callback_t *callback, - settings_section_callback_t *sect_callback, void *context) +bool settings_read_i(const char *path, const char *section, + settings_callback_t *callback, + settings_section_callback_t *sect_callback, void *context) { bool ret; diff --git a/src/lib-settings/settings.h b/src/lib-settings/settings.h index 8c206f3938..e4bbe35f82 100644 --- a/src/lib-settings/settings.h +++ b/src/lib-settings/settings.h @@ -40,21 +40,23 @@ const char * parse_setting_from_defs(pool_t pool, const struct setting_def *defs, void *base, const char *key, const char *value); -bool settings_read(const char *path, const char *section, - settings_callback_t *callback, - settings_section_callback_t *sect_callback, void *context) +bool settings_read_i(const char *path, const char *section, + settings_callback_t *callback, + settings_section_callback_t *sect_callback, void *context) ATTR_NULL(2, 4, 5); -#ifdef CONTEXT_TYPE_SAFETY -# define settings_read(path, section, callback, sect_callback, context) \ - ({(void)(1 ? 0 : callback((const char *)0, (const char *)0, context)); \ - (void)(1 ? 0 : sect_callback((const char *)0, (const char *)0, \ - context, (const char **)0)); \ - settings_read(path, section, (settings_callback_t *)callback, \ - (settings_section_callback_t *)sect_callback, context); }) -#else -# define settings_read(path, section, callback, sect_callback, context) \ - settings_read(path, section, (settings_callback_t *)callback, \ +#define settings_read(path, section, callback, sect_callback, context) \ + settings_read_i(path + \ + CALLBACK_TYPECHECK(callback, const char *(*)( \ + const char *, const char *, typeof(context))) + \ + CALLBACK_TYPECHECK(sect_callback, bool (*)( \ + const char *, const char *, typeof(context), \ + const char **)), \ + section, (settings_callback_t *)callback, \ (settings_section_callback_t *)sect_callback, context) -#endif +#define settings_read_nosection(path, callback, context) \ + settings_read_i(path + \ + CALLBACK_TYPECHECK(callback, const char *(*)( \ + const char *, const char *, typeof(context))), \ + NULL, (settings_callback_t *)callback, NULL, context) #endif diff --git a/src/lib-sql/sql-api.h b/src/lib-sql/sql-api.h index 595832d96a..436d1d543a 100644 --- a/src/lib-sql/sql-api.h +++ b/src/lib-sql/sql-api.h @@ -78,15 +78,11 @@ void sql_exec(struct sql_db *db, const char *query); sql_result_next_row_get() */ void sql_query(struct sql_db *db, const char *query, sql_query_callback_t *callback, void *context); -#ifdef CONTEXT_TYPE_SAFETY -# define sql_query(db, query, callback, context) \ - ({(void)(1 ? 0 : callback((struct sql_result *)NULL, context)); \ - sql_query(db, query, \ - (sql_query_callback_t *)callback, context); }) -#else -# define sql_query(db, query, callback, context) \ - sql_query(db, query, (sql_query_callback_t *)callback, context) -#endif +#define sql_query(db, query, callback, context) \ + sql_query(db, query + \ + CALLBACK_TYPECHECK(callback, void (*)( \ + struct sql_result *, typeof(context))), \ + (sql_query_callback_t *)callback, context) /* Execute blocking SQL query and return result. */ struct sql_result *sql_query_s(struct sql_db *db, const char *query); @@ -131,16 +127,11 @@ struct sql_transaction_context *sql_transaction_begin(struct sql_db *db); /* Commit transaction. */ void sql_transaction_commit(struct sql_transaction_context **ctx, sql_commit_callback_t *callback, void *context); -#ifdef CONTEXT_TYPE_SAFETY -# define sql_transaction_commit(ctx, callback, context) \ - ({(void)(1 ? 0 : callback((const char *)NULL, context)); \ - sql_transaction_commit(ctx, \ - (sql_commit_callback_t *)callback, context); }) -#else -# define sql_transaction_commit(ctx, callback, context) \ - sql_transaction_commit(ctx, \ +#define sql_transaction_commit(ctx, callback, context) \ + sql_transaction_commit(ctx + \ + CALLBACK_TYPECHECK(callback, void (*)( \ + const char *, typeof(context))), \ (sql_commit_callback_t *)callback, context) -#endif /* Synchronous commit. Returns 0 if ok, -1 if error. */ int sql_transaction_commit_s(struct sql_transaction_context **ctx, const char **error_r); diff --git a/src/lib-storage/index/dbox-multi/mdbox-purge.c b/src/lib-storage/index/dbox-multi/mdbox-purge.c index 9a34c5cd61..f8a790bd12 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-purge.c +++ b/src/lib-storage/index/dbox-multi/mdbox-purge.c @@ -51,10 +51,9 @@ struct mdbox_purge_context { struct mdbox_map_append_context *append_ctx; }; -static int mdbox_map_file_msg_offset_cmp(const void *p1, const void *p2) +static int mdbox_map_file_msg_offset_cmp(const struct mdbox_map_file_msg *m1, + const struct mdbox_map_file_msg *m2) { - const struct mdbox_map_file_msg *m1 = p1, *m2 = p2; - if (m1->offset < m2->offset) return -1; else if (m1->offset > m2->offset) diff --git a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c index 889ee247e6..f6a0c08ec4 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c +++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c @@ -92,10 +92,10 @@ mdbox_storage_rebuild_deinit(struct mdbox_storage_rebuild_context *ctx) i_free(ctx); } -static int mdbox_rebuild_msg_offset_cmp(const void *p1, const void *p2) +static int +mdbox_rebuild_msg_offset_cmp(struct mdbox_rebuild_msg *const *m1, + struct mdbox_rebuild_msg *const *m2) { - const struct mdbox_rebuild_msg *const *m1 = p1, *const *m2 = p2; - if ((*m1)->file_id < (*m2)->file_id) return -1; if ((*m1)->file_id > (*m2)->file_id) @@ -307,17 +307,15 @@ static int rebuild_apply_map(struct mdbox_storage_rebuild_context *ctx) { struct mdbox_map *map = ctx->storage->map; const struct mail_index_header *hdr; - struct mdbox_rebuild_msg *const *msgs, **pos; + struct mdbox_rebuild_msg **pos; struct mdbox_rebuild_msg search_msg, *search_msgp = &search_msg; struct dbox_mail_lookup_rec rec; uint32_t seq; - unsigned int count; array_sort(&ctx->msgs, mdbox_rebuild_msg_offset_cmp); /* msgs now contains a list of all messages that exists in m.* files, sorted by file_id,offset */ - msgs = array_get_modifiable(&ctx->msgs, &count); hdr = mail_index_get_header(ctx->atomic->sync_view); for (seq = 1; seq <= hdr->messages_count; seq++) { if (mdbox_map_view_lookup_rec(map, ctx->atomic->sync_view, @@ -329,8 +327,8 @@ static int rebuild_apply_map(struct mdbox_storage_rebuild_context *ctx) search_msg.file_id = rec.rec.file_id; search_msg.offset = rec.rec.offset; search_msg.size = rec.rec.size; - pos = bsearch(&search_msgp, msgs, count, sizeof(*msgs), - mdbox_rebuild_msg_offset_cmp); + pos = array_bsearch(&ctx->msgs, &search_msgp, + mdbox_rebuild_msg_offset_cmp); if (pos == NULL || (*pos)->map_uid != 0) { /* map record points to nonexistent or a duplicate message. */ diff --git a/src/lib-storage/index/imapc/imapc-mail-fetch.c b/src/lib-storage/index/imapc/imapc-mail-fetch.c index b661fc35e3..2e166d81d5 100644 --- a/src/lib-storage/index/imapc/imapc-mail-fetch.c +++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c @@ -267,7 +267,7 @@ static void imapc_stream_filter(struct istream **input) filter_input = i_stream_create_header_filter(*input, HEADER_FILTER_EXCLUDE, imapc_hide_headers, N_ELEMENTS(imapc_hide_headers), - null_header_filter_callback, NULL); + *null_header_filter_callback, (void *)NULL); i_stream_unref(input); *input = filter_input; } diff --git a/src/lib-storage/index/index-mail-binary.c b/src/lib-storage/index/index-mail-binary.c index 1101547183..6a397e7825 100644 --- a/src/lib-storage/index/index-mail-binary.c +++ b/src/lib-storage/index/index-mail-binary.c @@ -138,7 +138,7 @@ add_binary_part(struct binary_ctx *ctx, const struct message_part *part, block->input = i_stream_create_header_filter(linput, HEADER_FILTER_EXCLUDE | HEADER_FILTER_HIDE_BODY, filter_headers, N_ELEMENTS(filter_headers), - binary_cte_filter_callback, ctx); + binary_cte_filter_callback, (void *)NULL); i_stream_unref(&linput); } else { /* copy everything as-is until the end of this header */ diff --git a/src/lib-storage/index/index-mail.c b/src/lib-storage/index/index-mail.c index d2f15ccb11..3a5a7ceabe 100644 --- a/src/lib-storage/index/index-mail.c +++ b/src/lib-storage/index/index-mail.c @@ -839,7 +839,7 @@ static int index_mail_parse_body(struct index_mail *mail, data->parsed_bodystructure = TRUE; } else { message_parser_parse_body(data->parser_ctx, - null_message_part_header_callback, NULL); + *null_message_part_header_callback, (void *)NULL); } ret = index_mail_stream_check_failure(mail); if (index_mail_parse_body_finish(mail, field) < 0) diff --git a/src/lib-storage/index/index-search.c b/src/lib-storage/index/index-search.c index 39aec75ad7..c1c4fe3ea0 100644 --- a/src/lib-storage/index/index-search.c +++ b/src/lib-storage/index/index-search.c @@ -59,8 +59,7 @@ static void search_parse_msgset_args(unsigned int messages_count, uint32_t *seq1_r, uint32_t *seq2_r); static void ATTR_NULL(2) -search_none(struct mail_search_arg *arg ATTR_UNUSED, - struct search_body_context *ctx ATTR_UNUSED) +search_none(struct mail_search_arg *arg ATTR_UNUSED, void *ctx ATTR_UNUSED) { } @@ -542,7 +541,7 @@ static void search_header_arg(struct mail_search_arg *arg, } static void search_header_unmatch(struct mail_search_arg *arg, - void *context ATTR_UNUSED) + struct search_header_context *ctx ATTR_UNUSED) { switch (arg->type) { case SEARCH_BEFORE: @@ -698,7 +697,7 @@ static int search_arg_match_text(struct mail_search_arg *args, if (have_headers) { /* see if the header search succeeded in finishing the search */ - ret = mail_search_args_foreach(args, search_none, NULL); + ret = mail_search_args_foreach(args, search_none, (void *)NULL); if (ret >= 0 || !have_body) return ret; } diff --git a/src/lib-storage/index/index-sort-string.c b/src/lib-storage/index/index-sort-string.c index cc81893c39..cf58774362 100644 --- a/src/lib-storage/index/index-sort-string.c +++ b/src/lib-storage/index/index-sort-string.c @@ -91,10 +91,9 @@ void index_sort_list_init_string(struct mail_search_sort_program *program) i_array_init(&ctx->nonzero_nodes, 128); } -static int sort_node_seq_cmp(const void *p1, const void *p2) +static int sort_node_seq_cmp(const struct mail_sort_node *n1, + const struct mail_sort_node *n2) { - const struct mail_sort_node *n1 = p1, *n2 = p2; - if (n1->seq < n2->seq) return -1; if (n1->seq > n2->seq) diff --git a/src/lib-storage/index/index-thread.c b/src/lib-storage/index/index-thread.c index 5392b0c191..2801f0f7cf 100644 --- a/src/lib-storage/index/index-thread.c +++ b/src/lib-storage/index/index-thread.c @@ -352,11 +352,9 @@ static int mail_thread_index_map_build(struct mail_thread_context *ctx) return ret; } -static int msgid_map_cmp(const void *key, const void *value) +static int msgid_map_cmp(const uint32_t *uid, + const struct mail_index_strmap_rec *rec) { - const uint32_t *uid = key; - const struct mail_index_strmap_rec *rec = value; - return *uid < rec->uid ? -1 : (*uid > rec->uid ? 1 : 0); } diff --git a/src/lib-storage/index/maildir/maildir-mail.c b/src/lib-storage/index/maildir/maildir-mail.c index 7d77c77f99..8fa6069c4f 100644 --- a/src/lib-storage/index/maildir/maildir-mail.c +++ b/src/lib-storage/index/maildir/maildir-mail.c @@ -628,8 +628,7 @@ static void maildir_mail_remove_sizes_from_uidlist(struct mail *mail) } static int -do_fix_size(struct maildir_mailbox *mbox, const char *path, - const char *wrong_key_p) +do_fix_size(struct maildir_mailbox *mbox, const char *path, char *wrong_key_p) { const char *fname, *newpath, *extra, *info, *dir; struct stat st; diff --git a/src/lib-storage/index/maildir/maildir-storage.h b/src/lib-storage/index/maildir/maildir-storage.h index 089be22e86..0eb1c54f69 100644 --- a/src/lib-storage/index/maildir/maildir-storage.h +++ b/src/lib-storage/index/maildir/maildir-storage.h @@ -101,16 +101,11 @@ typedef int maildir_file_do_func(struct maildir_mailbox *mbox, int maildir_file_do(struct maildir_mailbox *mbox, uint32_t uid, maildir_file_do_func *callback, void *context); -#ifdef CONTEXT_TYPE_SAFETY -# define maildir_file_do(mbox, seq, callback, context) \ - ({(void)(1 ? 0 : callback((struct maildir_mailbox *)NULL, \ - (const char *)NULL, context)); \ - maildir_file_do(mbox, seq, \ - (maildir_file_do_func *)callback, context); }) -#else -# define maildir_file_do(mbox, seq, callback, context) \ - maildir_file_do(mbox, seq, (maildir_file_do_func *)callback, context) -#endif +#define maildir_file_do(mbox, seq, callback, context) \ + maildir_file_do(mbox, seq + \ + CALLBACK_TYPECHECK(callback, int (*)( \ + struct maildir_mailbox *, const char *, typeof(context))), \ + (maildir_file_do_func *)callback, context) bool maildir_set_deleted(struct mailbox *box); uint32_t maildir_get_uidvalidity_next(struct mailbox_list *list); diff --git a/src/lib-storage/index/maildir/maildir-sync-index.c b/src/lib-storage/index/maildir/maildir-sync-index.c index cb1c6ebd36..e85f616813 100644 --- a/src/lib-storage/index/maildir/maildir-sync-index.c +++ b/src/lib-storage/index/maildir/maildir-sync-index.c @@ -356,10 +356,8 @@ void maildir_sync_index_rollback(struct maildir_index_sync_context **_ctx) (void)maildir_sync_index_finish(ctx, FALSE); } -static int uint_cmp(const void *p1, const void *p2) +static int uint_cmp(const unsigned int *i1, const unsigned int *i2) { - const unsigned int *i1 = p1, *i2 = p2; - if (*i1 < *i2) return -1; else if (*i1 > *i2) diff --git a/src/lib-storage/index/mbox/mbox-mail.c b/src/lib-storage/index/mbox/mbox-mail.c index 308e78d834..ad3c2c4d6b 100644 --- a/src/lib-storage/index/mbox/mbox-mail.c +++ b/src/lib-storage/index/mbox/mbox-mail.c @@ -359,7 +359,7 @@ static int mbox_mail_init_stream(struct index_mail *mail) i_stream_create_header_filter(raw_stream, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, mbox_hide_headers, mbox_hide_headers_count, - null_header_filter_callback, NULL); + *null_header_filter_callback, (void *)NULL); i_stream_unref(&raw_stream); return 0; } diff --git a/src/lib-storage/index/pop3c/pop3c-sync.c b/src/lib-storage/index/pop3c/pop3c-sync.c index bc079bfec8..acb66ab5d1 100644 --- a/src/lib-storage/index/pop3c/pop3c-sync.c +++ b/src/lib-storage/index/pop3c/pop3c-sync.c @@ -189,10 +189,8 @@ pop3c_sync_messages(struct pop3c_mailbox *mbox, index_mailbox_set_recent_seq(&mbox->box, sync_view, seq1, seq2); } -static int uint32_cmp(const void *p1, const void *p2) +static int uint32_cmp(const uint32_t *u1, const uint32_t *u2) { - const uint32_t *u1 = p1, *u2 = p2; - return *u1 < *u2 ? -1 : (*u1 > *u2 ? 1 : 0); } diff --git a/src/lib-storage/mail-search.h b/src/lib-storage/mail-search.h index 514fb3670c..2d2639788e 100644 --- a/src/lib-storage/mail-search.h +++ b/src/lib-storage/mail-search.h @@ -151,16 +151,11 @@ void mail_search_args_reset(struct mail_search_arg *args, bool full_reset); int mail_search_args_foreach(struct mail_search_arg *args, mail_search_foreach_callback_t *callback, void *context) ATTR_NULL(3); -#ifdef CONTEXT_TYPE_SAFETY -# define mail_search_args_foreach(args, callback, context) \ - ({(void)(1 ? 0 : callback((struct mail_search_arg *)NULL, context)); \ - mail_search_args_foreach(args, \ - (mail_search_foreach_callback_t *)callback, context); }) -#else -# define mail_search_args_foreach(args, callback, context) \ - mail_search_args_foreach(args, \ +#define mail_search_args_foreach(args, callback, context) \ + mail_search_args_foreach(args + \ + CALLBACK_TYPECHECK(callback, void (*)( \ + struct mail_search_arg *, typeof(context))), \ (mail_search_foreach_callback_t *)callback, context) -#endif /* Fills have_headers and have_body based on if such search argument exists that needs to be checked. Returns the headers that we're searching for, or diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index 36cf4a354a..365aeabcad 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -502,16 +502,10 @@ int mailbox_sync(struct mailbox *box, enum mailbox_sync_flags flags); void mailbox_notify_changes(struct mailbox *box, mailbox_notify_callback_t *callback, void *context) ATTR_NULL(3); -#ifdef CONTEXT_TYPE_SAFETY -# define mailbox_notify_changes(box, callback, context) \ - ({(void)(1 ? 0 : callback((struct mailbox *)NULL, context)); \ - mailbox_notify_changes(box, \ - (mailbox_notify_callback_t *)callback, context); }) -#else -# define mailbox_notify_changes(box, callback, context) \ - mailbox_notify_changes(box, \ - (mailbox_notify_callback_t *)callback, context) -#endif +#define mailbox_notify_changes(box, callback, context) \ + mailbox_notify_changes(box, (mailbox_notify_callback_t *)callback, \ + (void *)((char *)context + CALLBACK_TYPECHECK(callback, \ + void (*)(struct mailbox *, typeof(context))))) void mailbox_notify_changes_stop(struct mailbox *box); struct mailbox_transaction_context * diff --git a/src/lib-storage/mailbox-header.c b/src/lib-storage/mailbox-header.c index 9f049c3035..6c3f6a82ca 100644 --- a/src/lib-storage/mailbox-header.c +++ b/src/lib-storage/mailbox-header.c @@ -28,7 +28,7 @@ mailbox_header_lookup_init_real(struct mailbox *box, /* @UNSAFE: headers need to be sorted for filter stream. */ sorted_headers = t_new(const char *, count); memcpy(sorted_headers, headers, count * sizeof(*sorted_headers)); - qsort(sorted_headers, count, sizeof(*sorted_headers), i_strcasecmp_p); + i_qsort(sorted_headers, count, sizeof(*sorted_headers), i_strcasecmp_p); headers = sorted_headers; /* @UNSAFE */ diff --git a/src/lib/array.h b/src/lib/array.h index 6bf59e9212..80e9bd6fce 100644 --- a/src/lib/array.h +++ b/src/lib/array.h @@ -264,29 +264,18 @@ void array_reverse_i(struct array *array); array_reverse_i(&(array)->arr) void array_sort_i(struct array *array, int (*cmp)(const void *, const void *)); -#ifdef CONTEXT_TYPE_SAFETY #define array_sort(array, cmp) \ - ({(void)(1 ? 0 : cmp(ARRAY_TYPE_CAST_CONST(array)NULL, \ - ARRAY_TYPE_CAST_CONST(array)NULL)); \ - array_sort_i(&(array)->arr, \ - (int (*)(const void *, const void *))cmp); }) -#else -#define array_sort(array, cmp) \ - array_sort_i(&(array)->arr, (int (*)(const void *, const void *))cmp) -#endif + array_sort_i(&(array)->arr + \ + CALLBACK_TYPECHECK(cmp, int (*)(typeof(*(array)->v), \ + typeof(*(array)->v))), \ + (int (*)(const void *, const void *))cmp) void *array_bsearch_i(struct array *array, const void *key, int (*cmp)(const void *, const void *)); -#ifdef CONTEXT_TYPE_SAFETY #define array_bsearch(array, key, cmp) \ - ARRAY_TYPE_CAST_MODIFIABLE(array) \ - ({(void)(1 ? 0 : cmp(key, ARRAY_TYPE_CAST_CONST(array)NULL)); \ - array_bsearch_i(&(array)->arr, (const void *)key, \ - (int (*)(const void *, const void *))cmp); }) -#else -#define array_bsearch(array, key, cmp) \ - array_bsearch_i(&(array)->arr, (const void *)key, \ - (int (*)(const void *, const void *))cmp) -#endif + ARRAY_TYPE_CAST_MODIFIABLE(array)array_bsearch_i(&(array)->arr + \ + CALLBACK_TYPECHECK(cmp, int (*)(typeof(const typeof(*key) *), \ + typeof(*(array)->v))), \ + (const void *)key, (int (*)(const void *, const void *))cmp) #endif diff --git a/src/lib/bsearch-insert-pos.c b/src/lib/bsearch-insert-pos.c index 87dff34775..b8c62fc5b8 100644 --- a/src/lib/bsearch-insert-pos.c +++ b/src/lib/bsearch-insert-pos.c @@ -4,6 +4,7 @@ #include "array.h" #include "bsearch-insert-pos.h" +#undef bsearch_insert_pos bool bsearch_insert_pos(const void *key, const void *base, unsigned int nmemb, size_t size, int (*cmp)(const void *, const void *), unsigned int *idx_r) diff --git a/src/lib/bsearch-insert-pos.h b/src/lib/bsearch-insert-pos.h index 0eded217b2..64b547be89 100644 --- a/src/lib/bsearch-insert-pos.h +++ b/src/lib/bsearch-insert-pos.h @@ -25,22 +25,22 @@ where the key should be inserted. */ bool ATTR_NOWARN_UNUSED_RESULT bsearch_insert_pos(const void *key, const void *base, unsigned int nmemb, - size_t size, int (*cmp)(const void *, const void *), - unsigned int *idx_r); + size_t size, int (*cmp)(const void *, const void *), + unsigned int *idx_r); +#define bsearch_insert_pos(key, base, nmemb, size, cmp, idx_r) \ + bsearch_insert_pos(key, base, nmemb, size + \ + CALLBACK_TYPECHECK(cmp, int (*)(typeof(const typeof(*key) *), \ + typeof(const typeof(*base) *))), \ + (int (*)(const void *, const void *))cmp, idx_r) bool ATTR_NOWARN_UNUSED_RESULT array_bsearch_insert_pos_i(const struct array *array, const void *key, int (*cmp)(const void *, const void *), unsigned int *idx_r); -#ifdef CONTEXT_TYPE_SAFETY -#define array_bsearch_insert_pos(array, key, cmp, idx_r) \ - ({(void)(1 ? 0 : cmp(key, ARRAY_TYPE_CAST_CONST(array)NULL)); \ - array_bsearch_insert_pos_i(&(array)->arr, (const void *)key, \ - (int (*)(const void *, const void *))cmp, idx_r); }) -#else #define array_bsearch_insert_pos(array, key, cmp, idx_r) \ - array_bsearch_insert_pos_i(&(array)->arr, (const void *)key, \ - (int (*)(const void *, const void *))cmp, idx_r) -#endif + array_bsearch_insert_pos_i(&(array)->arr + \ + CALLBACK_TYPECHECK(cmp, int (*)(typeof(const typeof(*key) *), \ + typeof(*(array)->v))), \ + (const void *)key, (int (*)(const void *, const void *))cmp, idx_r) #endif diff --git a/src/lib/child-wait.h b/src/lib/child-wait.h index 4453d4002e..aa83b25fa0 100644 --- a/src/lib/child-wait.h +++ b/src/lib/child-wait.h @@ -14,15 +14,11 @@ typedef void child_wait_callback_t(const struct child_wait_status *status, struct child_wait * child_wait_new_with_pid(pid_t pid, child_wait_callback_t *callback, void *context) ATTR_NULL(3); -#ifdef CONTEXT_TYPE_SAFETY -# define child_wait_new_with_pid(pid, callback, context) \ - ({(void)(1 ? 0 : callback((const struct child_wait_status *)0, \ - context)); \ - child_wait_new_with_pid(pid, (child_wait_callback_t *)callback, context); }) -#else -# define child_wait_new_with_pid(pid, callback, context) \ - child_wait_new_with_pid(pid, (child_wait_callback_t *)callback, context) -#endif +#define child_wait_new_with_pid(pid, callback, context) \ + child_wait_new_with_pid(pid + \ + CALLBACK_TYPECHECK(callback, void (*)( \ + const struct child_wait_status *status, typeof(context))), \ + (child_wait_callback_t *)callback, context) #define child_wait_new(callback, context) \ child_wait_new_with_pid((pid_t)-1, callback, context) void child_wait_free(struct child_wait **wait); diff --git a/src/lib/connection.c b/src/lib/connection.c index 60053f47a7..7000442c0b 100644 --- a/src/lib/connection.c +++ b/src/lib/connection.c @@ -122,7 +122,7 @@ static void connection_init_streams(struct connection *conn) set->output_max_size, FALSE); o_stream_set_no_error_handling(conn->output, TRUE); } - conn->io = io_add(conn->fd_in, IO_READ, conn->list->v.input, conn); + conn->io = io_add(conn->fd_in, IO_READ, *conn->list->v.input, conn); if (set->input_idle_timeout_secs != 0) { conn->to = timeout_add(set->input_idle_timeout_secs*1000, connection_idle_timeout, conn); diff --git a/src/lib/ioloop.h b/src/lib/ioloop.h index 35a0b9578c..d83d24b5b2 100644 --- a/src/lib/ioloop.h +++ b/src/lib/ioloop.h @@ -49,19 +49,16 @@ struct io *io_add(int fd, enum io_condition condition, unsigned int source_linenum, io_callback_t *callback, void *context) ATTR_NULL(5); #define io_add(fd, condition, callback, context) \ - CONTEXT_CALLBACK(io_add, io_callback_t, \ - callback, context, fd, condition, __LINE__) + io_add(fd, condition, __LINE__ + \ + CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ + (io_callback_t *)callback, context) enum io_notify_result io_add_notify(const char *path, io_callback_t *callback, void *context, struct io **io_r) ATTR_NULL(3); -#ifdef CONTEXT_TYPE_SAFETY -# define io_add_notify(path, callback, context, io_r) \ - ({(void)(1 ? 0 : callback(context)); \ - io_add_notify(path, (io_callback_t *)callback, context, io_r); }) -#else -# define io_add_notify(path, callback, context, io_r) \ - io_add_notify(path, (io_callback_t *)callback, context, io_r) -#endif +#define io_add_notify(path, callback, context, io_r) \ + io_add_notify(path + \ + CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ + (io_callback_t *)callback, context, io_r) /* Remove I/O handler, and set io pointer to NULL. */ void io_remove(struct io **io); @@ -74,15 +71,18 @@ struct timeout * timeout_add(unsigned int msecs, unsigned int source_linenum, timeout_callback_t *callback, void *context) ATTR_NULL(4); #define timeout_add(msecs, callback, context) \ - CONTEXT_CALLBACK(timeout_add, timeout_callback_t, \ - callback, context, msecs, __LINE__), \ - (void)COMPILE_ERROR_IF_TRUE(__builtin_constant_p(msecs) && (msecs > 0 && msecs < 1000)) + timeout_add(msecs, __LINE__ + \ + CALLBACK_TYPECHECK(callback, void (*)(typeof(context))) + \ + COMPILE_ERROR_IF_TRUE(__builtin_constant_p(msecs) && \ + (msecs > 0 && msecs < 1000)), \ + (io_callback_t *)callback, context) struct timeout * timeout_add_short(unsigned int msecs, unsigned int source_linenum, timeout_callback_t *callback, void *context) ATTR_NULL(4); #define timeout_add_short(msecs, callback, context) \ - CONTEXT_CALLBACK(timeout_add_short, timeout_callback_t, \ - callback, context, msecs, __LINE__) + timeout_add_short(msecs, __LINE__ + \ + CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ + (io_callback_t *)callback, context) /* Remove timeout handler, and set timeout pointer to NULL. */ void timeout_remove(struct timeout **timeout); /* Reset timeout so it's next run after now+msecs. */ diff --git a/src/lib/istream.h b/src/lib/istream.h index faed6ea37f..80bf620341 100644 --- a/src/lib/istream.h +++ b/src/lib/istream.h @@ -53,8 +53,9 @@ void i_stream_set_destroy_callback(struct istream *stream, istream_callback_t *callback, void *context) ATTR_NULL(3); #define i_stream_set_destroy_callback(stream, callback, context) \ - CONTEXT_CALLBACK(i_stream_set_destroy_callback, istream_callback_t, \ - callback, context, stream) + i_stream_set_destroy_callback(stream + \ + CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ + (istream_callback_t *)callback, context) /* Remove the destroy callback. */ void i_stream_unset_destroy_callback(struct istream *stream); diff --git a/src/lib/macros.h b/src/lib/macros.h index f675ad08eb..5ab43ec419 100644 --- a/src/lib/macros.h +++ b/src/lib/macros.h @@ -143,20 +143,11 @@ /* Macros to provide type safety for callback functions' context parameters */ #ifdef __GNUC__ -# define CONTEXT_TYPE_SAFETY -#endif -#ifdef CONTEXT_TYPE_SAFETY -# define CONTEXT_CALLBACK(name, callback_type, callback, context, ...) \ - ({(void)(1 ? 0 : callback(context)); \ - name(__VA_ARGS__, (callback_type *)callback, context); }) -# define CONTEXT_CALLBACK2(name, callback_type, callback, arg1_type, context, ...) \ - ({(void)(1 ? 0 : callback((arg1_type)0, context)); \ - name(__VA_ARGS__, (callback_type *)callback, context); }) +# define CALLBACK_TYPECHECK(callback, type) \ + (COMPILE_ERROR_IF_TRUE(!__builtin_types_compatible_p( \ + typeof(&callback), type)) ? 1 : 0) #else -# define CONTEXT_CALLBACK(name, callback_type, callback, context, ...) \ - name(__VA_ARGS__, (callback_type *)callback, context) -# define CONTEXT_CALLBACK2(name, callback_type, callback, arg1_type, context, ...) \ - name(__VA_ARGS__, (callback_type *)callback, context) +# define CALLBACK_TYPECHECK(callback, type) 0 #endif #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0)) && !defined(__cplusplus) diff --git a/src/lib/module-dir.c b/src/lib/module-dir.c index aad6568c20..4d33b4bb53 100644 --- a/src/lib/module-dir.c +++ b/src/lib/module-dir.c @@ -327,7 +327,7 @@ static void module_names_fix(const char **module_names) module_names[i] = module_file_get_name(module_names[i]); /* @UNSAFE: drop duplicates */ - qsort(module_names, i, sizeof(*module_names), i_strcmp_p); + i_qsort(module_names, i, sizeof(*module_names), i_strcmp_p); for (i = j = 1; module_names[i] != NULL; i++) { if (strcmp(module_names[i-1], module_names[i]) != 0) module_names[j++] = module_names[i]; diff --git a/src/lib/ostream.h b/src/lib/ostream.h index 84886cc291..aa56da6155 100644 --- a/src/lib/ostream.h +++ b/src/lib/ostream.h @@ -62,8 +62,9 @@ void o_stream_set_flush_callback(struct ostream *stream, stream_flush_callback_t *callback, void *context) ATTR_NULL(3); #define o_stream_set_flush_callback(stream, callback, context) \ - CONTEXT_CALLBACK(o_stream_set_flush_callback, stream_flush_callback_t, \ - callback, context, stream) + o_stream_set_flush_callback(stream + \ + CALLBACK_TYPECHECK(callback, int (*)(typeof(context))), \ + (stream_flush_callback_t *)callback, context) void o_stream_unset_flush_callback(struct ostream *stream); /* Change the maximum size for stream's output buffer to grow. */ void o_stream_set_max_buffer_size(struct ostream *stream, size_t max_size); diff --git a/src/lib/strfuncs.c b/src/lib/strfuncs.c index 4387b89913..63bd3c8307 100644 --- a/src/lib/strfuncs.c +++ b/src/lib/strfuncs.c @@ -354,33 +354,23 @@ int i_memcasecmp(const void *p1, const void *p2, size_t size) return 0; } -int bsearch_strcmp(const void *p1, const void *p2) +int bsearch_strcmp(const char *key, const char *const *member) { - const char *key = p1; - const char *const *member = p2; - return strcmp(key, *member); } -int i_strcmp_p(const void *p1, const void *p2) +int i_strcmp_p(const char *const *s1, const char *const *s2) { - const char *const *s1 = p1, *const *s2 = p2; - return strcmp(*s1, *s2); } -int bsearch_strcasecmp(const void *p1, const void *p2) +int bsearch_strcasecmp(const char *key, const char *const *member) { - const char *key = p1; - const char *const *member = p2; - return strcasecmp(key, *member); } -int i_strcasecmp_p(const void *p1, const void *p2) +int i_strcasecmp_p(const char *const *s1, const char *const *s2) { - const char *const *s1 = p1, *const *s2 = p2; - return strcasecmp(*s1, *s2); } diff --git a/src/lib/strfuncs.h b/src/lib/strfuncs.h index aab3a19a23..243551c9ca 100644 --- a/src/lib/strfuncs.h +++ b/src/lib/strfuncs.h @@ -50,11 +50,11 @@ const char *t_str_lcase(const char *str); const char *t_str_ucase(const char *str); int null_strcmp(const char *s1, const char *s2) ATTR_PURE; -int bsearch_strcmp(const void *p1, const void *p2) ATTR_PURE; -int bsearch_strcasecmp(const void *p1, const void *p2) ATTR_PURE; +int bsearch_strcmp(const char *p1, const char *const *member) ATTR_PURE; +int bsearch_strcasecmp(const char *key, const char *const *member) ATTR_PURE; int i_memcasecmp(const void *p1, const void *p2, size_t size) ATTR_PURE; -int i_strcmp_p(const void *p1, const void *p2) ATTR_PURE; -int i_strcasecmp_p(const void *p1, const void *p2) ATTR_PURE; +int i_strcmp_p(const char *const *p1, const char *const *p2) ATTR_PURE; +int i_strcasecmp_p(const char *const *p1, const char *const *p2) ATTR_PURE; /* separators is an array of separator characters, not a separator string. */ char **p_strsplit(pool_t pool, const char *data, const char *separators) @@ -88,6 +88,18 @@ bool str_array_icase_find(const char *const *arr, const char *value); return value. */ const char **p_strarray_dup(pool_t pool, const char *const *arr); +#define i_qsort(base, nmemb, size, cmp) \ + qsort(base, nmemb, size + \ + CALLBACK_TYPECHECK(cmp, int (*)(typeof(const typeof(*base) *), \ + typeof(const typeof(*base) *))), \ + (int (*)(const void *, const void *))cmp) +#define i_bsearch(key, base, nmemb, size, cmp) \ + bsearch(key, base, nmemb, size + \ + CALLBACK_TYPECHECK(cmp, int (*)(typeof(const typeof(*key) *), \ + typeof(const typeof(*base) *))), \ + (int (*)(const void *, const void *))cmp) + + /* INTERNAL */ char *t_noalloc_strdup_vprintf(const char *format, va_list args, unsigned int *size_r) ATTR_FORMAT(1, 0); diff --git a/src/lib/test-bsearch-insert-pos.c b/src/lib/test-bsearch-insert-pos.c index aa254c66f1..2792977ef8 100644 --- a/src/lib/test-bsearch-insert-pos.c +++ b/src/lib/test-bsearch-insert-pos.c @@ -3,10 +3,8 @@ #include "test-lib.h" #include "bsearch-insert-pos.h" -static int cmp_uint(const void *p1, const void *p2) +static int cmp_uint(const unsigned int *i1, const unsigned int *i2) { - const unsigned int *i1 = p1, *i2 = p2; - return *i1 - *i2; } diff --git a/src/plugins/acl/acl-backend.c b/src/plugins/acl/acl-backend.c index 325fb77232..be2642d0a0 100644 --- a/src/plugins/acl/acl-backend.c +++ b/src/plugins/acl/acl-backend.c @@ -67,8 +67,8 @@ acl_backend_init(const char *data, struct mailbox_list *list, p_new(backend->pool, const char *, group_count); for (i = 0; i < group_count; i++) backend->groups[i] = p_strdup(backend->pool, groups[i]); - qsort(backend->groups, group_count, sizeof(const char *), - i_strcmp_p); + i_qsort(backend->groups, group_count, sizeof(const char *), + i_strcmp_p); } T_BEGIN { @@ -127,8 +127,8 @@ bool acl_backend_user_name_equals(struct acl_backend *backend, bool acl_backend_user_is_in_group(struct acl_backend *backend, const char *group_name) { - return bsearch(group_name, backend->groups, backend->group_count, - sizeof(const char *), bsearch_strcmp) != NULL; + return i_bsearch(group_name, backend->groups, backend->group_count, + sizeof(const char *), bsearch_strcmp) != NULL; } bool acl_backend_rights_match_me(struct acl_backend *backend, diff --git a/src/plugins/fts-squat/squat-uidlist.c b/src/plugins/fts-squat/squat-uidlist.c index cbaf442344..92ea2ea4c5 100644 --- a/src/plugins/fts-squat/squat-uidlist.c +++ b/src/plugins/fts-squat/squat-uidlist.c @@ -1385,11 +1385,9 @@ squat_uidlist_get_at_offset(struct squat_uidlist *uidlist, uoff_t offset, return 0; } -static int uint32_cmp(const void *key, const void *data) +static int uint32_cmp(const uint32_t *key, const uint32_t *data) { - const uint32_t *i1 = key, *i2 = data; - - return (int)*i1 - (int)*i2; + return (int)*key - (int)*data; } static int diff --git a/src/plugins/pop3-migration/pop3-migration-plugin.c b/src/plugins/pop3-migration/pop3-migration-plugin.c index 26094a40f8..727e7afa4d 100644 --- a/src/plugins/pop3-migration/pop3-migration-plugin.c +++ b/src/plugins/pop3-migration/pop3-migration-plugin.c @@ -130,7 +130,7 @@ static int get_hdr_sha1(struct mail *mail, unsigned char sha1[SHA1_RESULTLEN]) HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR, hdr_hash_skip_headers, N_ELEMENTS(hdr_hash_skip_headers), - null_header_filter_callback, NULL); + *null_header_filter_callback, (void *)NULL); i_stream_unref(&input2); sha1_init(&sha1_ctx);