]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Removed CONTEXT_TYPE_SAFETY macro and reimplemented its functionality better.
authorTimo Sirainen <tss@iki.fi>
Sun, 19 Aug 2012 13:17:32 +0000 (16:17 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 19 Aug 2012 13:17:32 +0000 (16:17 +0300)
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.

57 files changed:
src/anvil/anvil-connection.c
src/auth/auth-request-handler.h
src/auth/db-dict.c
src/auth/db-ldap.c
src/auth/db-sql.c
src/config/config-connection.c
src/doveadm/doveadm-mail-mailbox.c
src/doveadm/doveadm-stats.c
src/doveadm/doveadm.c
src/imap/imap-fetch.h
src/indexer/indexer-client.c
src/lib-dns/dns-lookup.c
src/lib-dns/dns-lookup.h
src/lib-imap-storage/imap-msgpart.c
src/lib-index/mail-index-util.c
src/lib-lda/mail-send.c
src/lib-mail/istream-header-filter.c
src/lib-mail/istream-header-filter.h
src/lib-mail/message-header-parser.h
src/lib-mail/message-parser.h
src/lib-mail/test-istream-header-filter.c
src/lib-master/master-service.c
src/lib-settings/settings.c
src/lib-settings/settings.h
src/lib-sql/sql-api.h
src/lib-storage/index/dbox-multi/mdbox-purge.c
src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c
src/lib-storage/index/imapc/imapc-mail-fetch.c
src/lib-storage/index/index-mail-binary.c
src/lib-storage/index/index-mail.c
src/lib-storage/index/index-search.c
src/lib-storage/index/index-sort-string.c
src/lib-storage/index/index-thread.c
src/lib-storage/index/maildir/maildir-mail.c
src/lib-storage/index/maildir/maildir-storage.h
src/lib-storage/index/maildir/maildir-sync-index.c
src/lib-storage/index/mbox/mbox-mail.c
src/lib-storage/index/pop3c/pop3c-sync.c
src/lib-storage/mail-search.h
src/lib-storage/mail-storage.h
src/lib-storage/mailbox-header.c
src/lib/array.h
src/lib/bsearch-insert-pos.c
src/lib/bsearch-insert-pos.h
src/lib/child-wait.h
src/lib/connection.c
src/lib/ioloop.h
src/lib/istream.h
src/lib/macros.h
src/lib/module-dir.c
src/lib/ostream.h
src/lib/strfuncs.c
src/lib/strfuncs.h
src/lib/test-bsearch-insert-pos.c
src/plugins/acl/acl-backend.c
src/plugins/fts-squat/squat-uidlist.c
src/plugins/pop3-migration/pop3-migration-plugin.c

index 55ad08a2c35114680ccc7522a48d77f607b69144..402dcdd8a36a96e2de9cbe3d66bfa1e692c8e198 100644 (file)
@@ -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 "
index b5cabdff43ef7fa42e6f8a287fd392a9c2a9eb8b..08e60f5d29ed80b6f69926248f3ce753d7f21259 100644 (file)
@@ -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);
index b43096f99de3695f38fd57f2311be9714ac4840f..199d3da87aa9f3dbe1cd206ab98e11f655a7ea56 100644 (file)
@@ -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)
index ce4f4cf1ac46277d422eb9c747f6c796846b0886..1b03149c35d410760014cb91db922ebb2fec9956 100644 (file)
@@ -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)
index 78028485418d73e2a683854c581264562fbf95f8..5770ea8c27aa25c561b26616ac632c92a567a7d3 100644 (file)
@@ -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)
index c0cdaa660647e466b6b4a4a1dcec3aca3a26bc6c..f97716b553841c892fc1ef9d6e931699aba0bae9 100644 (file)
@@ -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)) {
index 8780969b65698329b2fc50cd203e86ed8a50a967..897fedd38952f8029913c9cb163158f9f3f48a19 100644 (file)
@@ -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);
 }
 
index 2e1cc8496e3da169f4b6d61ce9e9f61aafabdf9e..83bc43f620b4482ba909dd3880f3a2e5c1d831be 100644 (file)
@@ -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;
 }
index e2a035e0db024b84b591995b7f1b6194d3051851..05ff00bc1050163e37fbeaf88bdc247855fa0a3b 100644 (file)
@@ -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++) {
index 448032b9681d6d6329037a9dd35aae49b0bb3f28..d51f2fdf838a4a42e649f475cc241babb6c83f67 100644 (file)
@@ -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,
index d5b89efedadecb27d582e2201cc700a0f43cf4d4..ef5eb8c553b215a8ae782c84305e90415bc98bd7 100644 (file)
@@ -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)) {
index e4f5eec79b3d1bea12622a4ea0bc9ef5f03dfef4..ac502124623ea996c8756c65f406f3faa962a68e 100644 (file)
@@ -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;
index 40e7671761cfb3164e394b8c9f73957e74421980..26b5d81ddbacd6e7b92ba778fca7d69662167a2e 100644 (file)
@@ -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);
 
index 473670386d17d52c7e1edb877dcbe3f2ee008861..e3690bd82062aacfb167dfee6a22ff0df29215cf 100644 (file)
@@ -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) {
index 5d8e189618deed15bfed534470faba8507f99443..f7ebd55797bbb757461003b86254437306e9567f 100644 (file)
@@ -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,
index 29b1fe07575f16befc9c8ab5066989f135859f41..1c98ae017e310b713ddd0b2865645fbb19d7167b 100644 (file)
@@ -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);
index 8211d56354dc2a5ac1b6b9e657f0e5c3af1649d0..bc4cd4eaa7c3bb0a85f0717e528e45f4f3940289 100644 (file)
@@ -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) {
index 413b7b5d94cf0c69347312e96528707cdc14fe33..03708157004919878ac5b0371d9e7141569e8b36 100644 (file)
@@ -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,
index 945b5ee71afe9add6b4d88eef61684b8209aba4b..9db49b0b4f75e8d2dd3a31c5f805f23572af92df 100644 (file)
@@ -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
index c566208676e5353bce984f3e5713ff2ea1ab3bd7..97bf7e0443f8ae1c5a2b0deb4869cce6b2a4d5d2 100644 (file)
@@ -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
index bb94bb6c7a325b8e2d68f0b8b54394883ef1dc24..363b652b54f018d1a9d4f9edf054a751132b6fb4 100644 (file)
@@ -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);
index 1c3fb3e0367dfad8f383ab6ef91841a4a91e486e..7760c2e7ede8c1d8664937990b6919d61ab64fec 100644 (file)
@@ -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. */
index 5806a7f512bec72fff06b358403a8103ebc63ca6..70e907c374ade174693e56c1861487de1c922589 100644 (file)
@@ -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;
 
index 8c206f3938548761af3383b2fac60c4ddbf4f8c8..e4bbe35f8257f43219e8c807012c3997240a3216 100644 (file)
@@ -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
index 595832d96a9b87b02b05799dc124a2de59fec6ee..436d1d543a98a1cd3e59bc803ac268fc3040f5ca 100644 (file)
@@ -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);
index 9a34c5cd6199307e5ef9cd9b35c4976d21577079..f8a790bd12aef8b35fa609229c53374a7c458c53 100644 (file)
@@ -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)
index 889ee247e6f208f79b91ea9c998f4f128f2291d1..f6a0c08ec4c7e47808d2adf1f057fb551ff31c8e 100644 (file)
@@ -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. */
index b661fc35e3b64245bfb1853658124e3c22f246d6..2e166d81d5ec7aeea5be3be25949c446cb9969d4 100644 (file)
@@ -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;
 }
index 1101547183bb5bf9c8c1d8ab6e338c1ee30048be..6a397e78250a1fd940016358511cf3e0401b3085 100644 (file)
@@ -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 */
index d2f15ccb11bd66b6c16f75611b5ba706acc8dbb1..3a5a7ceabe6976e7cd80830c6e49e869ed862a17 100644 (file)
@@ -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)
index 39aec75ad7d7fb75ff9e71b673663126523c7374..c1c4fe3ea0d698085fec83c51192d40e132e41c9 100644 (file)
@@ -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;
        }
index cc81893c3925d98ecd61aa1113efe95189abdd97..cf58774362992c446300922e51c8c87df70e1789 100644 (file)
@@ -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)
index 5392b0c1917afd1d6edada4f6cbf1ee600847268..2801f0f7cfb54f011b28e5c52f879b42a9d254f0 100644 (file)
@@ -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);
 }
index 7d77c77f998272c80b2b2de3c74452da1fd23f28..8fa6069c4f6e3747d91b007e997ef7c5e3a25a26 100644 (file)
@@ -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;
index 089be22e864fa184031efbc0491391566ecf9c9f..0eb1c54f698a92a9b5770c12fd84e88cf1788b62 100644 (file)
@@ -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);
index cb1c6ebd36051c9365cc8416f549f9432bab3724..e85f616813cd59c3797b428e13cc13f2afa68e59 100644 (file)
@@ -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)
index 308e78d83413bf10b9557a2cfc64b9f0c02ad762..ad3c2c4d6ba3b8664f6a908bdb7db79cfe88f3b4 100644 (file)
@@ -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;
 }
index bc079bfec8cda9e5697dafa3d355dcde85ce19e7..acb66ab5d1238b707fe7fff607b74c4bee90d951 100644 (file)
@@ -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);
 }
index 514fb3670cb3aba69de879fc0485a62c2929ee08..2d2639788ed76a47ca4451bb9d63bafce963fb28 100644 (file)
@@ -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
index 36cf4a354aaed6d623792a6f1eae390640fa7466..365aeabcada719ed490a82eb00f9a87403aa505c 100644 (file)
@@ -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 *
index 9f049c3035c46e509987196d07dbf4b0a61767fb..6c3f6a82ca2a5c707c1d86f9ab9ca71e05063640 100644 (file)
@@ -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 */
index 6bf59e921203fae1671347448cffe35597f682e3..80e9bd6fced306628e03dca0aedfe9ce5673586b 100644 (file)
@@ -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
index 87dff347752fa5f4733e60554aa6fe1b83c4f173..b8c62fc5b801d3390236b77380cc62742f6f3bb1 100644 (file)
@@ -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)
index 0eded217b2884ae4969c6c94d1b81668733f6531..64b547be89271b0142659b9f5155d996c1d7c8ff 100644 (file)
    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
index 4453d4002ec988fd26f1598ce4db6f272797ea4b..aa83b25fa0bf027a7dff42f90c171912b7c80f2f 100644 (file)
@@ -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);
index 60053f47a75233445d5026f9b87b65cf35b2f6af..7000442c0b30b19c8daeb4cd778888aec8687386 100644 (file)
@@ -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);
index 35a0b9578c45bdddb9be57a775a9d64565d2abec..d83d24b5b2d11c6f30e155c56e641811c07a6db9 100644 (file)
@@ -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. */
index faed6ea37fc9e5e96466e390aef6ef096c3ba427..80bf620341e048e71c9a9df51d68334ee618a767 100644 (file)
@@ -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);
 
index f675ad08ebfd7a55cdddce031a4325ae000e7aa9..5ab43ec4190292ec8006c13679f2a0a8fb836c08 100644 (file)
 
 /* 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)
index aad6568c208ddc5195ff3ff8d4b0708bcf680c6c..4d33b4bb5389d6375690336a957871a05f85e616 100644 (file)
@@ -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];
index 84886cc2911eeb18c9218d7df12d2fa28b210f8b..aa56da615580320db48223bd510021efd0de1b89 100644 (file)
@@ -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);
index 4387b89913f0325f188248c470f18ee2fce08a03..63bd3c8307fbfaf7f091eb8480d9e73299bd7aa6 100644 (file)
@@ -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);
 }
 
index aab3a19a23a2b3de3abb9394c004c6db793e992a..243551c9ca9b52a01285d31e914c28b7f0573821 100644 (file)
@@ -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);
index aa254c66f11b362bcc9519d3d96413c9adb0e3cc..2792977ef842da55f335a7ee002e8f6d939e7d60 100644 (file)
@@ -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;
 }
 
index 325fb77232198d9f41492f2f5564e6c1e21265dc..be2642d0a09fb3e8be3c78bdbb56eaba0e7fb641 100644 (file)
@@ -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,
index cbaf442344e7c64f87e0e86f214adcf0066ed7f7..92ea2ea4c518ce834fa30753224ba223cf57ad71 100644 (file)
@@ -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
index 26094a40f88d7e2086a417f93c3d610950e115e1..727e7afa4dabaf07af183ceb1fdb1f64603d3815 100644 (file)
@@ -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);