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)) {
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 "
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);
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)
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)
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)
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)) {
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);
}
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;
}
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++) {
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,
}
}
-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)) {
#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;
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);
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) {
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,
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);
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);
}
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) {
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,
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
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
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
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;
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);
}
}
-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. */
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;
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
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);
/* 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);
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)
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)
{
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,
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. */
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;
}
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 */
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)
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)
{
}
}
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:
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;
}
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)
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);
}
}
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;
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);
(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)
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_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);
}
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
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 *
/* @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 */
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
#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)
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
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);
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);
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);
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. */
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);
/* 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)
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];
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);
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);
}
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)
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);
#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;
}
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 {
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,
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
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);