1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

Type-check button arguments of msg_box.

Don't cast function pointers; calling functions via pointers of
incorrect types is not guaranteed to work.  Instead, define the
functions with the desired types, and make them cast the incoming
parameters.  Or define wrapper functions if the return types don't
match.

really_exit_prog wasn't being used outside src/dialogs/menu.c,
and I had to change its parameter type, so it's now static.
This commit is contained in:
Kalle Olavi Niemitalo 2007-03-10 23:50:56 +02:00 committed by Kalle Olavi Niemitalo
parent 1e8a61e09b
commit 2b7788614f
16 changed files with 130 additions and 63 deletions

View File

@ -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;
}

View File

@ -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));
}

View File

@ -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()

View File

@ -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;

View File

@ -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));
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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));
}

View File

@ -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(). */

View File

@ -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));
}

View File

@ -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));
}