diff --git a/src/bfu/hierbox.c b/src/bfu/hierbox.c index 751d4c574..399ff4d76 100644 --- a/src/bfu/hierbox.c +++ b/src/bfu/hierbox.c @@ -438,7 +438,7 @@ push_hierbox_info_button(struct dialog_data *dlg_data, struct widget_data *butto N_("Info"), ALIGN_LEFT, msg, context, 1, - N_("~OK"), done_listbox_context, B_ESC | B_ENTER); + MSG_BOX_BUTTON(N_("~OK"), done_listbox_context, B_ESC | B_ENTER)); return EVENT_PROCESSED; } @@ -751,8 +751,8 @@ query_delete_selected_item(void *context_) listbox_message(delete_folder_title), ALIGN_CENTER, msg_text(term, listbox_message(delete_folder), text), context, 2, - N_("~Yes"), push_ok_delete_button, B_ENTER, - N_("~No"), done_listbox_context, B_ESC); + MSG_BOX_BUTTON(N_("~Yes"), push_ok_delete_button, B_ENTER), + MSG_BOX_BUTTON(N_("~No"), done_listbox_context, B_ESC)); } else { unsigned char *msg = ops->get_info(item, term); @@ -763,8 +763,8 @@ query_delete_selected_item(void *context_) msg_text(term, listbox_message(delete_item), text, empty_string_or_(msg)), context, 2, - N_("~Yes"), push_ok_delete_button, B_ENTER, - N_("~No"), done_listbox_context, B_ESC); + MSG_BOX_BUTTON(N_("~Yes"), push_ok_delete_button, B_ENTER), + MSG_BOX_BUTTON(N_("~No"), done_listbox_context, B_ESC)); mem_free_if(msg); } mem_free(text); @@ -772,6 +772,12 @@ query_delete_selected_item(void *context_) return EVENT_PROCESSED; } +static void +dont_delete_marked_items(void *const context_) +{ + query_delete_selected_item(context_); +} + widget_handler_status_T push_hierbox_delete_button(struct dialog_data *dlg_data, struct widget_data *button) @@ -805,8 +811,8 @@ push_hierbox_delete_button(struct dialog_data *dlg_data, listbox_message(delete_marked_items_title), ALIGN_CENTER, listbox_message(delete_marked_items), context, 2, - N_("~Yes"), push_ok_delete_button, B_ENTER, - N_("~No"), query_delete_selected_item, B_ESC); + MSG_BOX_BUTTON(N_("~Yes"), push_ok_delete_button, B_ENTER), + MSG_BOX_BUTTON(N_("~No"), dont_delete_marked_items, B_ESC)); return EVENT_PROCESSED; } @@ -867,8 +873,8 @@ push_hierbox_clear_button(struct dialog_data *dlg_data, listbox_message(clear_all_items_title), ALIGN_CENTER, listbox_message(clear_all_items), context, 2, - N_("~Yes"), do_clear_browser, B_ENTER, - N_("~No"), NULL, B_ESC); + MSG_BOX_BUTTON(N_("~Yes"), do_clear_browser, B_ENTER), + MSG_BOX_BUTTON(N_("~No"), NULL, B_ESC)); return EVENT_PROCESSED; } diff --git a/src/bfu/msgbox.c b/src/bfu/msgbox.c index 00924cbd0..d7af62be5 100644 --- a/src/bfu/msgbox.c +++ b/src/bfu/msgbox.c @@ -71,7 +71,7 @@ msg_box(struct terminal *term, struct memory_list *ml, enum msgbox_flags flags, int bflags; label = va_arg(ap, unsigned char *); - done = va_arg(ap, void *); + done = va_arg(ap, done_handler_T *); bflags = va_arg(ap, int); if (!label) { @@ -170,7 +170,7 @@ refreshed_msg_box(struct terminal *term, enum msgbox_flags flags, title, align, info, data, 1, - N_("~OK"), NULL, B_ENTER | B_ESC); + MSG_BOX_BUTTON(N_("~OK"), NULL, B_ENTER | B_ESC)); if (!dlg_data) return; @@ -187,6 +187,9 @@ info_box(struct terminal *term, enum msgbox_flags flags, unsigned char *text) { /* [gettext_accelerator_context(info_box)] */ - return msg_box(term, NULL, flags, title, align, text, - NULL, 1, N_("~OK"), NULL, B_ENTER | B_ESC); + return msg_box(term, NULL, flags, + title, align, + text, + NULL, 1, + MSG_BOX_BUTTON(N_("~OK"), NULL, B_ENTER | B_ESC)); } diff --git a/src/bfu/msgbox.h b/src/bfu/msgbox.h index 3ed0848b0..2e06fe8ae 100644 --- a/src/bfu/msgbox.h +++ b/src/bfu/msgbox.h @@ -64,7 +64,7 @@ enum msgbox_flags { * @udata Is a reference to any data that should be passed to * the handlers associated with each button. NULL if none. * - * @buttons Denotes the number of buttons given as varadic arguments. + * @buttons Denotes the number of buttons given as variadic arguments. * For each button 3 arguments are extracted: * o First the label text. It is automatically localized * unless MSGBOX_NO_INTL is passed. If NULL, this button @@ -72,6 +72,10 @@ enum msgbox_flags { * o Second pointer to the handler function (taking * one (void *), which is incidentally the udata). * o Third any flags. + * Each triple should be wrapped in the MSG_BOX_BUTTON + * macro, which converts the values to the correct types. + * (The compiler can't do that on its own for variadic + * arguments.) * * Note that you should ALWAYS format the msg_box() call like: * @@ -79,9 +83,9 @@ enum msgbox_flags { * title, align, * text, * udata, M, - * label1, handler1, flags1, + * MSG_BOX_BUTTON(label1, handler1, flags1), * ..., - * labelM, handlerM, flagsM); + * MSG_BOX_BUTTON(labelM, handlerM, flagsM)); * * ...no matter that it could fit on one line in case of a tiny message box. */ struct dialog_data * @@ -89,6 +93,21 @@ msg_box(struct terminal *term, struct memory_list *mem_list, enum msgbox_flags flags, unsigned char *title, enum format_align align, unsigned char *text, void *udata, int buttons, ...); +/* Cast @value to @type and warn if the conversion is suspicious. + * If @value has side effects, this does them only once. + * The expression used here is intended to be standard C, but it is + * somewhat tricky. If it causes trouble on some compiler, you can + * #ifdef an alternative definition that skips the type check. */ +#define MSG_BOX_CAST(type, value) \ + (((void) sizeof(((int (*)(type)) 0)(value))), (type) (value)) + +/* A button in the variadic arguments of msg_box(). + * This macro expands into three arguments. */ +#define MSG_BOX_BUTTON(label, handler, flags) \ + MSG_BOX_CAST(const unsigned char *, label), \ + MSG_BOX_CAST(done_handler_T *, handler), \ + MSG_BOX_CAST(int, flags) + /* msg_text() is basically an equivalent to asprintf(), specifically to be used * inside of message boxes. Please always use msg_text() instead of asprintf() diff --git a/src/config/dialogs.c b/src/config/dialogs.c index 35d893c48..b90add053 100644 --- a/src/config/dialogs.c +++ b/src/config/dialogs.c @@ -54,8 +54,8 @@ write_config_dialog(struct terminal *term, unsigned char *config_file, msg_text(term, N_("Options were saved successfully to config file %s."), config_file), NULL, 2, - N_("~OK"), NULL, B_ENTER | B_ESC, - N_("~Do not show anymore"), disable_success_msgbox, 0); + MSG_BOX_BUTTON(N_("~OK"), NULL, B_ENTER | B_ESC), + MSG_BOX_BUTTON(N_("~Do not show anymore"), disable_success_msgbox, 0)); return; } @@ -815,8 +815,8 @@ really_add_keybinding(void *data, unsigned char *keystroke) canonical.length ? canonical.source : keystroke, get_action_name(hop->keymap_id, action_id)), new_hop, 2, - N_("~Yes"), really_really_add_keybinding, B_ENTER, - N_("~No"), NULL, B_ESC); + MSG_BOX_BUTTON(N_("~Yes"), really_really_add_keybinding, B_ENTER), + MSG_BOX_BUTTON(N_("~No"), NULL, B_ESC)); done_string(&canonical); /* safe even if init failed */ return; diff --git a/src/cookies/dialogs.c b/src/cookies/dialogs.c index 1b8101668..27bcab9f4 100644 --- a/src/cookies/dialogs.c +++ b/src/cookies/dialogs.c @@ -50,6 +50,18 @@ add_cookie_info_to_string(struct string *string, struct cookie *cookie, _(cookie->secure ? N_("yes") : N_("no"), term)); } +static void +accept_cookie_in_msg_box(void *cookie_) +{ + accept_cookie((struct cookie *) cookie_); +} + +static void +reject_cookie_in_msg_box(void *cookie_) +{ + done_cookie((struct cookie *) cookie_); +} + /* TODO: Store cookie in data arg. --jonas*/ void accept_cookie_dialog(struct session *ses, void *data) @@ -78,8 +90,8 @@ accept_cookie_dialog(struct session *ses, void *data) N_("Accept cookie?"), ALIGN_LEFT, string.source, cookie, 2, - N_("~Accept"), accept_cookie, B_ENTER, - N_("~Reject"), done_cookie, B_ESC); + MSG_BOX_BUTTON(N_("~Accept"), accept_cookie_in_msg_box, B_ENTER), + MSG_BOX_BUTTON(N_("~Reject"), reject_cookie_in_msg_box, B_ESC)); } diff --git a/src/dialogs/info.c b/src/dialogs/info.c index f9b6e8b4d..0117418fa 100644 --- a/src/dialogs/info.c +++ b/src/dialogs/info.c @@ -131,8 +131,8 @@ menu_keys(struct terminal *term, void *d_, void *xxx) N_("Keys"), ALIGN_LEFT, keys.source, info, 2, - N_("~OK"), NULL, B_ENTER | B_ESC, - N_("~Toggle display"), push_toggle_keys_display_button, B_ENTER); + MSG_BOX_BUTTON(N_("~OK"), NULL, B_ENTER | B_ESC), + MSG_BOX_BUTTON(N_("~Toggle display"), push_toggle_keys_display_button, B_ENTER)); } void diff --git a/src/dialogs/menu.c b/src/dialogs/menu.c index 101d97e7d..615e66e3e 100644 --- a/src/dialogs/menu.c +++ b/src/dialogs/menu.c @@ -100,15 +100,19 @@ save_url_as(struct session *ses) NULL); } -void -really_exit_prog(struct session *ses) +static void +really_exit_prog(void *ses_) { + struct session *ses = ses_; + register_bottom_half(destroy_terminal, ses->tab->term); } static inline void -dont_exit_prog(struct session *ses) +dont_exit_prog(void *ses_) { + struct session *ses = ses_; + ses->exit_query = 0; } @@ -124,8 +128,8 @@ query_exit(struct session *ses) "(and terminate all downloads)?") : N_("Do you really want to exit ELinks?"), ses, 2, - N_("~Yes"), (void (*)(void *)) really_exit_prog, B_ENTER, - N_("~No"), (void (*)(void *)) dont_exit_prog, B_ESC); + MSG_BOX_BUTTON(N_("~Yes"), really_exit_prog, B_ENTER), + MSG_BOX_BUTTON(N_("~No"), dont_exit_prog, B_ESC)); } void diff --git a/src/dialogs/menu.h b/src/dialogs/menu.h index 4d0077bd1..c5848c600 100644 --- a/src/dialogs/menu.h +++ b/src/dialogs/menu.h @@ -24,7 +24,6 @@ void free_history_lists(void); void query_file(struct session *, struct uri *, void *, void (*)(void *, unsigned char *), void (*)(void *), int); -void really_exit_prog(struct session *ses); void query_exit(struct session *ses); void exit_prog(struct session *ses, int query); diff --git a/src/formhist/formhist.c b/src/formhist/formhist.c index c1227f0ab..cea478a91 100644 --- a/src/formhist/formhist.c +++ b/src/formhist/formhist.c @@ -330,20 +330,31 @@ forget_forms_with_url(unsigned char *url) return count; } -/* Appends form data @form1 (url and submitted_value(s)) to the password file. - * Returns 1 on success, 0 otherwise. */ -static int -remember_form(struct formhist_data *form) +/* Appends form data @form_ (url and submitted_value(s)) to the password file. */ +static void +remember_form(void *form_) { + struct formhist_data *form = form_; + forget_forms_with_url(form->url); add_to_list(saved_forms, form); - return save_formhist_to_file(); + save_formhist_to_file(); } -static int -never_for_this_site(struct formhist_data *form) +static void +dont_remember_form(void *form_) { + struct formhist_data *form = form_; + + done_formhist_item(form); +} + +static void +never_for_this_site(void *form_) +{ + struct formhist_data *form = form_; + form->dontsave = 1; return remember_form(form); } @@ -416,9 +427,9 @@ memorize_form(struct session *ses, struct list_head *submit, "obscured (but unencrypted) in a file on your disk.\n\n" "If you are using a valuable password, answer NO."), form, 3, - N_("~Yes"), remember_form, B_ENTER, - N_("~No"), done_formhist_item, B_ESC, - N_("Ne~ver for this site"), never_for_this_site, NULL); + MSG_BOX_BUTTON(N_("~Yes"), remember_form, B_ENTER), + MSG_BOX_BUTTON(N_("~No"), dont_remember_form, B_ESC), + MSG_BOX_BUTTON(N_("Ne~ver for this site"), never_for_this_site, 0)); return; diff --git a/src/mime/dialogs.c b/src/mime/dialogs.c index fc90cc26e..2a67fcfde 100644 --- a/src/mime/dialogs.c +++ b/src/mime/dialogs.c @@ -67,8 +67,8 @@ menu_del_ext(struct terminal *term, void *fcp, void *xxx2) msg_text(term, N_("Delete extension %s -> %s?"), extension, opt->value.string), extension, 2, - N_("~Yes"), really_del_ext, B_ENTER, - N_("~No"), NULL, B_ESC); + MSG_BOX_BUTTON(N_("~Yes"), really_del_ext, B_ENTER), + MSG_BOX_BUTTON(N_("~No"), NULL, B_ESC)); } diff --git a/src/protocol/protocol.c b/src/protocol/protocol.c index 3ffca54c5..d7d2e71af 100644 --- a/src/protocol/protocol.c +++ b/src/protocol/protocol.c @@ -233,7 +233,7 @@ generic_external_protocol_handler(struct session *ses, struct uri *uri) "%s protocol support"), protocol_backends[uri->protocol].name), ses, 1, - N_("~OK"), NULL, B_ENTER | B_ESC); + MSG_BOX_BUTTON(N_("~OK"), NULL, B_ENTER | B_ESC)); return; } diff --git a/src/scripting/python/dialogs.c b/src/scripting/python/dialogs.c index 009ede76c..da096cb7c 100644 --- a/src/scripting/python/dialogs.c +++ b/src/scripting/python/dialogs.c @@ -83,7 +83,7 @@ python_info_box(PyObject *self, PyObject *args, PyObject *kwargs) title, ALIGN_LEFT, text, NULL, 1, - N_("~OK"), NULL, B_ENTER | B_ESC); + MSG_BOX_BUTTON(N_("~OK"), NULL, B_ENTER | B_ESC)); Py_INCREF(Py_None); return Py_None; diff --git a/src/session/download.c b/src/session/download.c index ee9917024..fdb41a191 100644 --- a/src/session/download.c +++ b/src/session/download.c @@ -493,16 +493,20 @@ struct cdf_hop { }; static void -lun_alternate(struct lun_hop *lun_hop) +lun_alternate(void *lun_hop_) { + struct lun_hop *lun_hop = lun_hop_; + lun_hop->callback(lun_hop->term, lun_hop->file, lun_hop->data, 0); mem_free_if(lun_hop->ofile); mem_free(lun_hop); } static void -lun_cancel(struct lun_hop *lun_hop) +lun_cancel(void *lun_hop_) { + struct lun_hop *lun_hop = lun_hop_; + lun_hop->callback(lun_hop->term, NULL, lun_hop->data, 0); mem_free_if(lun_hop->ofile); mem_free_if(lun_hop->file); @@ -510,8 +514,10 @@ lun_cancel(struct lun_hop *lun_hop) } static void -lun_overwrite(struct lun_hop *lun_hop) +lun_overwrite(void *lun_hop_) { + struct lun_hop *lun_hop = lun_hop_; + lun_hop->callback(lun_hop->term, lun_hop->ofile, lun_hop->data, 0); mem_free_if(lun_hop->file); mem_free(lun_hop); @@ -520,8 +526,9 @@ lun_overwrite(struct lun_hop *lun_hop) static void common_download_do(struct terminal *term, int fd, void *data, int resume); static void -lun_resume(struct lun_hop *lun_hop) +lun_resume(void *lun_hop_) { + struct lun_hop *lun_hop = lun_hop_; struct cdf_hop *cdf_hop = lun_hop->data; int magic = *(int *)cdf_hop->data; @@ -631,10 +638,10 @@ lookup_unique_name(struct terminal *term, unsigned char *ofile, int resume, empty_string_or_(lun_hop->ofile), empty_string_or_(file)), lun_hop, 4, - N_("Sa~ve under the alternative name"), lun_alternate, B_ENTER, - N_("~Overwrite the original file"), lun_overwrite, 0, - N_("~Resume download of the original file"), lun_resume, 0, - N_("~Cancel"), lun_cancel, B_ESC); + MSG_BOX_BUTTON(N_("Sa~ve under the alternative name"), lun_alternate, B_ENTER), + MSG_BOX_BUTTON(N_("~Overwrite the original file"), lun_overwrite, 0), + MSG_BOX_BUTTON(N_("~Resume download of the original file"), lun_resume, 0), + MSG_BOX_BUTTON(N_("~Cancel"), lun_cancel, B_ESC)); } diff --git a/src/session/session.c b/src/session/session.c index 79e4ea8ee..04d3f7c61 100644 --- a/src/session/session.c +++ b/src/session/session.c @@ -804,7 +804,7 @@ setup_first_session(struct session *ses, struct uri *uri) "Press ESC for menu. Documentation is available in " "Help menu."), ses, 1, - N_("~OK"), handler, B_ENTER | B_ESC); + MSG_BOX_BUTTON(N_("~OK"), handler, B_ENTER | B_ESC)); /* If there is no URI the goto dialog will pop up so there is * no need to call setup_session(). */ diff --git a/src/session/task.c b/src/session/task.c index 0595a8468..27e2f55cb 100644 --- a/src/session/task.c +++ b/src/session/task.c @@ -85,8 +85,10 @@ ses_load(struct session *ses, struct uri *uri, unsigned char *target_frame, } static void -post_yes(struct task *task) +post_yes(void *task_) { + struct task *task = task_; + abort_preloading(task->ses, 0); /* XXX: Make the session inherit the URI. */ @@ -96,8 +98,10 @@ post_yes(struct task *task) } static void -post_no(struct task *task) +post_no(void *task_) { + struct task *task = task_; + reload(task->ses, CACHE_MODE_NORMAL); done_uri(task->uri); } @@ -270,8 +274,8 @@ ses_goto(struct session *ses, struct uri *uri, unsigned char *target_frame, N_("Warning"), ALIGN_CENTER, message, task, 2, - N_("~Yes"), post_yes, B_ENTER, - N_("~No"), post_no, B_ESC); + MSG_BOX_BUTTON(N_("~Yes"), post_yes, B_ENTER), + MSG_BOX_BUTTON(N_("~No"), post_no, B_ESC)); } diff --git a/src/terminal/tab.c b/src/terminal/tab.c index 24ac7579f..8aaf8a38d 100644 --- a/src/terminal/tab.c +++ b/src/terminal/tab.c @@ -169,8 +169,9 @@ switch_current_tab(struct session *ses, int direction) } static void -really_close_tab(struct session *ses) +really_close_tab(void *ses_) { + struct session *ses = ses_; struct terminal *term = ses->tab->term; struct window *current_tab = get_current_tab(term); @@ -203,13 +204,14 @@ close_tab(struct terminal *term, struct session *ses) N_("Close tab"), ALIGN_CENTER, N_("Do you really want to close the current tab?"), ses, 2, - N_("~Yes"), (void (*)(void *)) really_close_tab, B_ENTER, - N_("~No"), NULL, B_ESC); + MSG_BOX_BUTTON(N_("~Yes"), really_close_tab, B_ENTER), + MSG_BOX_BUTTON(N_("~No"), NULL, B_ESC)); } static void -really_close_tabs(struct session *ses) +really_close_tabs(void *ses_) { + struct session *ses = ses_; struct terminal *term = ses->tab->term; struct window *current_tab = get_current_tab(term); struct window *tab; @@ -246,8 +248,8 @@ close_all_tabs_but_current(struct session *ses) N_("Close tab"), ALIGN_CENTER, N_("Do you really want to close all except the current tab?"), ses, 2, - N_("~Yes"), (void (*)(void *)) really_close_tabs, B_ENTER, - N_("~No"), NULL, B_ESC); + MSG_BOX_BUTTON(N_("~Yes"), really_close_tabs, B_ENTER), + MSG_BOX_BUTTON(N_("~No"), NULL, B_ESC)); }